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 +