From cf349f9953841c3b8aedaf4d7e78eea34e1bd63a Mon Sep 17 00:00:00 2001 From: Rogerborg Date: Thu, 22 Jan 2009 18:24:33 +0000 Subject: [PATCH] More collision additions. ISceneCollisionManager::getCollisionResultPosition() now returns the node that was hit. ISceneNodeAnimatorCollisionResponse stores and exposes the node that was hit. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2127 dfc29bdd-3216-0410-991c-e03cc46cb475 --- include/ISceneCollisionManager.h | 2 ++ include/ISceneNodeAnimatorCollisionResponse.h | 3 +++ source/Irrlicht/CSceneCollisionManager.cpp | 24 ++++++++++++------- source/Irrlicht/CSceneCollisionManager.h | 12 ++++++++-- .../CSceneNodeAnimatorCollisionResponse.cpp | 4 +++- .../CSceneNodeAnimatorCollisionResponse.h | 4 ++++ tests/sceneCollisionManager.cpp | 22 +++++++++++++++-- tests/tests-last-passed-at.txt | 2 +- 8 files changed, 58 insertions(+), 15 deletions(-) diff --git a/include/ISceneCollisionManager.h b/include/ISceneCollisionManager.h index 9c9d5842..ba028661 100644 --- a/include/ISceneCollisionManager.h +++ b/include/ISceneCollisionManager.h @@ -64,6 +64,7 @@ namespace scene causing a collision is stored, if there is a collision. \param outFalling: Is set to true if the ellipsoid is falling down, caused by gravity. + \param outNode: the node with which the ellipoid collided (if any) \param slidingSpeed: DOCUMENTATION NEEDED. \param gravityDirectionAndSpeed: Direction and force of gravity. \return New position of the ellipsoid. */ @@ -75,6 +76,7 @@ namespace scene core::triangle3df& triout, core::vector3df& hitPosition, bool& outFalling, + const ISceneNode*& outNode, f32 slidingSpeed = 0.0005f, const core::vector3df& gravityDirectionAndSpeed = core::vector3df(0.0f, 0.0f, 0.0f)) = 0; diff --git a/include/ISceneNodeAnimatorCollisionResponse.h b/include/ISceneNodeAnimatorCollisionResponse.h index 1abcf4fa..5e30d11c 100644 --- a/include/ISceneNodeAnimatorCollisionResponse.h +++ b/include/ISceneNodeAnimatorCollisionResponse.h @@ -148,6 +148,9 @@ namespace scene move fully to the position that caused the collision to occur. */ virtual const core::vector3df & getCollisionResultPosition(void) const = 0; + //! Returns the node that was collided with. + virtual const ISceneNode* getCollisionNode(void) const = 0; + //! Sets a callback interface which will be called if a collision occurs. /** \param callback: collision callback handler that will be called when a collision occurs. Set this to 0 to disable the callback. diff --git a/source/Irrlicht/CSceneCollisionManager.cpp b/source/Irrlicht/CSceneCollisionManager.cpp index 0b1705d8..063c2d2d 100644 --- a/source/Irrlicht/CSceneCollisionManager.cpp +++ b/source/Irrlicht/CSceneCollisionManager.cpp @@ -313,6 +313,7 @@ core::vector3df CSceneCollisionManager::getCollisionResultPosition( core::triangle3df& triout, core::vector3df& hitPosition, bool& outFalling, + const ISceneNode*& outNode, f32 slidingSpeed, const core::vector3df& gravity) { @@ -320,18 +321,18 @@ core::vector3df CSceneCollisionManager::getCollisionResultPosition( return position; return collideEllipsoidWithWorld(selector, position, - radius, direction, slidingSpeed, gravity, triout, hitPosition, outFalling); + radius, direction, slidingSpeed, gravity, triout, hitPosition, outFalling, outNode); } -void CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData, +bool CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData, const core::triangle3df& triangle) { const core::plane3d trianglePlane = triangle.getPlane(); // only check front facing polygons if ( !trianglePlane.isFrontFacing(colData->normalizedVelocity) ) - return; + return false; // get interval of plane intersection @@ -350,7 +351,7 @@ void CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData, // sphere is traveling parallel to plane if (fabs(signedDistToTrianglePlane) >= 1.0f) - return; // no collision possible + return false; // no collision possible else { // sphere is embedded in plane @@ -372,7 +373,7 @@ void CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData, // check if at least one value is within the range if (t0 > 1.0f || t1 < 0.0f) - return; // both t values are outside 1 and 0, no collision possible + return false; // both t values are outside 1 and 0, no collision possible // clamp to 0 and 1 t0 = core::clamp ( t0, 0.f, 1.f ); @@ -565,9 +566,11 @@ void CSceneCollisionManager::testTriangleIntersection(SCollisionData* colData, colData->foundCollision = true; colData->intersectionTriangle = triangle; ++colData->triangleHits; + return true; } - }// end found collision + + return false; } @@ -581,7 +584,8 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld( const core::vector3df& gravity, core::triangle3df& triout, core::vector3df& hitPosition, - bool& outFalling) + bool& outFalling, + const ISceneNode*& outNode) { if (!selector || radius.X == 0.0f || radius.Y == 0.0f || radius.Z == 0.0f) return position; @@ -597,6 +601,7 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld( colData.selector = selector; colData.slidingSpeed = slidingSpeed; colData.triangleHits = 0; + colData.triangleIndex = -1; core::vector3df eSpacePosition = colData.R3Position / colData.eRadius; core::vector3df eSpaceVelocity = colData.R3Velocity / colData.eRadius; @@ -630,6 +635,7 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld( triout.pointA *= colData.eRadius; triout.pointB *= colData.eRadius; triout.pointC *= colData.eRadius; + outNode = selector->getSceneNodeForTriangle(colData.triangleIndex); } finalPos *= colData.eRadius; @@ -672,10 +678,10 @@ core::vector3df CSceneCollisionManager::collideWithWorld(s32 recursionDepth, s32 triangleCnt = 0; colData.selector->getTriangles(Triangles.pointer(), totalTriangleCnt, triangleCnt, box, &scaleMatrix); - //colData.selector->getTriangles(Triangles.pointer(), totalTriangleCnt, triangleCnt, &scaleMatrix); for (s32 i=0; igetSceneCollisionManager()->getCollisionResultPosition( World, LastPosition-Translation, - Radius, vel, CollisionTriangle, CollisionPoint, f, SlidingSpeed, FallingVelocity); + Radius, vel, CollisionTriangle, CollisionPoint, f, + CollisionNode, SlidingSpeed, FallingVelocity); CollisionOccurred = (CollisionTriangle != RefTriangle); diff --git a/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.h b/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.h index 3c334644..d425d226 100644 --- a/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.h +++ b/source/Irrlicht/CSceneNodeAnimatorCollisionResponse.h @@ -106,6 +106,9 @@ namespace scene virtual const core::vector3df & getCollisionResultPosition(void) const { return CollisionResultPosition; } + virtual const ISceneNode* getCollisionNode(void) const { return CollisionNode; } + + //! Sets a callback interface which will be called if a collision occurs. /** \param callback: collision callback handler that will be called when a collision occurs. Set this to 0 to disable the callback. @@ -137,6 +140,7 @@ namespace scene core::vector3df CollisionPoint; core::triangle3df CollisionTriangle; core::vector3df CollisionResultPosition; + const ISceneNode * CollisionNode; ICollisionCallback* CollisionCallback; }; diff --git a/tests/sceneCollisionManager.cpp b/tests/sceneCollisionManager.cpp index f76d612b..0a4f6378 100644 --- a/tests/sceneCollisionManager.cpp +++ b/tests/sceneCollisionManager.cpp @@ -20,6 +20,7 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device, triangle3df triOut; vector3df hitPosition; bool falling; + const ISceneNode* hitNode; vector3df resultPosition = collMgr->getCollisionResultPosition(cubeSelector, @@ -28,9 +29,18 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device, vector3df(0, -100, 0), triOut, hitPosition, - falling); + falling, + hitNode); bool result = true; + + if(hitNode != cubeNode) + { + logTestString("Unexpected collision node\n"); + assert(false); + result = false; + } + if(!equals(resultPosition.Y, 25.f, 0.01f)) { logTestString("Unexpected collision response position\n"); @@ -52,7 +62,15 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device, vector3df(100, 0, 0), triOut, hitPosition, - falling); + falling, + hitNode); + + if(hitNode != cubeNode) + { + logTestString("Unexpected collision node\n"); + assert(false); + result = false; + } if(!equals(resultPosition.X, -15.f, 0.01f)) { diff --git a/tests/tests-last-passed-at.txt b/tests/tests-last-passed-at.txt index f3ea6f40..16e40035 100644 --- a/tests/tests-last-passed-at.txt +++ b/tests/tests-last-passed-at.txt @@ -1,2 +1,2 @@ -Test suite pass at GMT Thu Jan 22 15:48:42 2009 +Test suite pass at GMT Thu Jan 22 18:20:21 2009