From c6eec21cec7b074998f48f85ce06ffbf662b33ca Mon Sep 17 00:00:00 2001 From: cutealien Date: Sun, 19 Apr 2015 19:55:07 +0000 Subject: [PATCH] Cameras return again an empty boundingbox (at 0,0,0) instead of returning the frustum boundingbox. Thx @robmar for reporting this. You can still access the frustum boundingbox through the frustum itself. Also CSceneCollisionManager collision functions ignore now empty collision boxes. This means cameras no longer show up in the node-collision of the SceneCollisionManager. Tests have been adapted correspondingly. Note that this behavior was once before changed in Irrlicht (rev. 345). But it was one of many changes and there was no documentation or log-message about why anyone would like the cameras to show up in node-collisions based on their frustum boundingbox. Without any hints about the why I decided to change it back as it's just confusing. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5094 dfc29bdd-3216-0410-991c-e03cc46cb475 --- changes.txt | 4 ++++ include/ICameraSceneNode.h | 9 ++++----- source/Irrlicht/CCameraSceneNode.cpp | 8 ++++++-- source/Irrlicht/CCameraSceneNode.h | 4 +++- source/Irrlicht/CSceneCollisionManager.cpp | 7 +++++-- tests/sceneCollisionManager.cpp | 22 ++++------------------ tests/tests-last-passed-at.txt | 8 ++++---- 7 files changed, 30 insertions(+), 32 deletions(-) diff --git a/changes.txt b/changes.txt index debd2978..dbf29036 100644 --- a/changes.txt +++ b/changes.txt @@ -1,6 +1,10 @@ -------------------------- Changes in 1.9 (not yet released) +- Node-collision functions of SceneCollisionManager like getSceneNodeFromScreenCoordinatesBB will now ignore collisions against empty boundingboxes. +- Cameras return again an empty boundingbox (at 0,0,0) instead of returning the frustum boundingbox (was changed in very old Irrlicht version). + You can access the frustum boundingbox through the frustum itself. + This means cameras no longer show up in the node-collision of the SceneCollisionManager (showing up there because of their frustum bounding-box was too confusing). - Fix problem in IrrlichtDevice::setResizable on X11 that caused window titlebars to hide occasionally under the taskbar in some systems (Ubuntu, Mint). - Added new IRenderTarget interface. - Replace the swprintf and snprintf defines by swprintf_irr and snprintf_irr to avoid conflicts with the standard libraries (and other libraries). diff --git a/include/ICameraSceneNode.h b/include/ICameraSceneNode.h index 64f4f994..e576256a 100644 --- a/include/ICameraSceneNode.h +++ b/include/ICameraSceneNode.h @@ -14,9 +14,9 @@ namespace scene { struct SViewFrustum; - //! Scene Node which is a (controlable) camera. + //! Scene Node which is a (controllable) camera. /** The whole scene will be rendered from the cameras point of view. - Because the ICameraScenNode is a SceneNode, it can be attached to any + Because the ICameraSceneNode is a SceneNode, it can be attached to any other scene node, and will follow its parents movement, rotation and so on. */ @@ -135,8 +135,7 @@ namespace scene virtual void setFOV(f32 fovy) =0; //! Get the view frustum. - /** Needed sometimes by bspTree or LOD render nodes. - \return The current view frustum. */ + /** \return The current view frustum. */ virtual const SViewFrustum* getViewFrustum() const =0; //! Disables or enables the camera to get key or mouse inputs. @@ -160,7 +159,7 @@ namespace scene point at the target point. FPS camera use this binding by default; other cameras do not. \param bound True to bind the camera's scene node rotation - and targetting, false to unbind them. + and targeting, false to unbind them. @see getTargetAndRotationBinding() */ virtual void bindTargetAndRotation(bool bound) =0; diff --git a/source/Irrlicht/CCameraSceneNode.cpp b/source/Irrlicht/CCameraSceneNode.cpp index ea8c94c3..6105dd16 100644 --- a/source/Irrlicht/CCameraSceneNode.cpp +++ b/source/Irrlicht/CCameraSceneNode.cpp @@ -17,6 +17,7 @@ namespace scene CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id, const core::vector3df& position, const core::vector3df& lookat) : ICameraSceneNode(parent, mgr, id, position), + BoundingBox(core::vector3df(0, 0, 0)), // Camera has no size. Still not sure if FLT_MAX might be the better variant Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f), InputReceiverEnabled(true), TargetAndRotationAreBound(false) { @@ -283,11 +284,14 @@ void CCameraSceneNode::updateMatrices() //! returns the axis aligned bounding box of this node const core::aabbox3d& CCameraSceneNode::getBoundingBox() const { - return ViewArea.getBoundingBox(); + // NOTE: We deliberately don't return the boundingbox of the ViewArea. People can access that already. + // We want to prevent cameras from having their bounding box colliding in the SceneCollisionManager. + // If another boundingbox is ever necessary then please move BoundingBox to ICameraSceneNode and make it accessible (via a setter or an enum with options). + return BoundingBox; } -//! returns the view frustum. needed sometimes by bsp or lod render nodes. +//! returns the view frustum. const SViewFrustum* CCameraSceneNode::getViewFrustum() const { return &ViewArea; diff --git a/source/Irrlicht/CCameraSceneNode.h b/source/Irrlicht/CCameraSceneNode.h index 6fdc6f55..b1cd13c8 100644 --- a/source/Irrlicht/CCameraSceneNode.h +++ b/source/Irrlicht/CCameraSceneNode.h @@ -119,7 +119,7 @@ namespace scene //! Returns the axis aligned bounding box of this node virtual const core::aabbox3d& getBoundingBox() const _IRR_OVERRIDE_; - //! Returns the view area. Sometimes needed by bsp or lod render nodes. + //! Returns the view area. virtual const SViewFrustum* getViewFrustum() const _IRR_OVERRIDE_; //! Disables or enables the camera to get key or mouse inputs. @@ -153,6 +153,8 @@ namespace scene void recalculateProjectionMatrix(); void recalculateViewArea(); + core::aabbox3d BoundingBox; + core::vector3df Target; core::vector3df UpVector; diff --git a/source/Irrlicht/CSceneCollisionManager.cpp b/source/Irrlicht/CSceneCollisionManager.cpp index 110f9a16..48b870d2 100644 --- a/source/Irrlicht/CSceneCollisionManager.cpp +++ b/source/Irrlicht/CSceneCollisionManager.cpp @@ -87,6 +87,11 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, if((noDebugObjects ? !current->isDebugObject() : true) && (bits==0 || (bits != 0 && (current->getID() & bits)))) { + // Assume that single-point bounding-boxes are not meant for collision + const core::aabbox3df & objectBox = current->getBoundingBox(); + if ( objectBox.isEmpty() ) + continue; + // get world to object space transform core::matrix4 worldToObject; if (!current->getAbsoluteTransformation().getInverse(worldToObject)) @@ -97,8 +102,6 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, worldToObject.transformVect(objectRay.start); worldToObject.transformVect(objectRay.end); - const core::aabbox3df & objectBox = current->getBoundingBox(); - // Do the initial intersection test in object space, since the // object space box test is more accurate. if(objectBox.isPointInside(objectRay.start)) diff --git a/tests/sceneCollisionManager.cpp b/tests/sceneCollisionManager.cpp index 65b3e3cd..7b8c3d2c 100644 --- a/tests/sceneCollisionManager.cpp +++ b/tests/sceneCollisionManager.cpp @@ -204,29 +204,15 @@ static bool testGetSceneNodeFromScreenCoordinatesBB(IrrlichtDevice * device, } - // Make cubeNode3 invisible and check that the camera node is hit (since it has a valid bounding box). - cubeNode3->setVisible(false); - hitNode = collMgr->getSceneNodeFromScreenCoordinatesBB(position2d(80, 60)); - if(hitNode != camera) - { - logTestString("Unexpected node hit. Expected the camera node.\n"); - result = false; - } - // Now verify bitmasking - camera->setID(0xAAAAAAAA); // == 101010101010101010101010101010 - hitNode = collMgr->getSceneNodeFromScreenCoordinatesBB(position2d(80, 60), 0x02); - if(hitNode != camera) - { - logTestString("Unexpected node hit. Expected the camera node.\n"); - result = false; - } // Test the 01010101010101010101010101010101 bitmask (0x55555555) + cubeNode1->setVisible(true); + cubeNode1->setID(0xAAAAAAAA); hitNode = collMgr->getSceneNodeFromScreenCoordinatesBB(position2d(80, 60), 0x55555555); - if(hitNode != 0) + if(hitNode != cubeNode2) { - logTestString("A node was hit when none was expected.\n"); + logTestString("Unexpected node hit. Expected cubeNode2.\n"); result = false; } assert_log(result); diff --git a/tests/tests-last-passed-at.txt b/tests/tests-last-passed-at.txt index ff071a4b..09c90efd 100644 --- a/tests/tests-last-passed-at.txt +++ b/tests/tests-last-passed-at.txt @@ -1,4 +1,4 @@ -Tests finished. 1 test of 1 passed. -Compiled as DEBUG -Test suite pass at GMT Sat Apr 11 16:04:54 2015 - +Tests finished. 1 test of 1 passed. +Compiled as DEBUG +Test suite pass at GMT Sun Apr 19 19:36:40 2015 +