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
master
Rogerborg 2009-01-22 18:24:33 +00:00
parent eee1d97306
commit cf349f9953
8 changed files with 58 additions and 15 deletions

View File

@ -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;

View File

@ -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.

View File

@ -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<f32> 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; i<triangleCnt; ++i)
testTriangleIntersection(&colData, Triangles[i]);
if(testTriangleIntersection(&colData, Triangles[i]))
colData.triangleIndex = i;
//---------------- end collide with world

View File

@ -57,6 +57,7 @@ namespace scene
core::triangle3df& triout,
core::vector3df& hitPosition,
bool& outFalling,
const ISceneNode*& outNode,
f32 slidingSpeed,
const core::vector3df& gravityDirectionAndSpeed);
@ -94,6 +95,7 @@ namespace scene
core::vector3df intersectionPoint;
core::triangle3df intersectionTriangle;
s32 triangleIndex;
s32 triangleHits;
f32 slidingSpeed;
@ -101,7 +103,12 @@ namespace scene
ITriangleSelector* selector;
};
void testTriangleIntersection(SCollisionData* colData,
//! Tests the current collision data against an individual triangle.
/**
\param colData: the collision data.
\param triangle: the triangle to test against.
\return true if the triangle is hit (and is the closest hit), false otherwise */
bool testTriangleIntersection(SCollisionData* colData,
const core::triangle3df& triangle);
//! recursive method for doing collision response
@ -111,7 +118,8 @@ namespace scene
f32 slidingSpeed,
const core::vector3df& gravity, core::triangle3df& triout,
core::vector3df& hitPosition,
bool& outFalling);
bool& outFalling,
const ISceneNode*& outNode);
core::vector3df collideWithWorld(s32 recursionDepth, SCollisionData &colData,
core::vector3df pos, core::vector3df vel);

View File

@ -159,6 +159,7 @@ void CSceneNodeAnimatorCollisionResponse::animateNode(ISceneNode* node, u32 time
CollisionTriangle = RefTriangle;
CollisionPoint = core::vector3df();
CollisionResultPosition = core::vector3df();
CollisionNode = 0;
core::vector3df force = vel + FallingVelocity;
@ -172,7 +173,8 @@ void CSceneNodeAnimatorCollisionResponse::animateNode(ISceneNode* node, u32 time
CollisionResultPosition
= SceneManager->getSceneCollisionManager()->getCollisionResultPosition(
World, LastPosition-Translation,
Radius, vel, CollisionTriangle, CollisionPoint, f, SlidingSpeed, FallingVelocity);
Radius, vel, CollisionTriangle, CollisionPoint, f,
CollisionNode, SlidingSpeed, FallingVelocity);
CollisionOccurred = (CollisionTriangle != RefTriangle);

View File

@ -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;
};

View File

@ -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))
{

View File

@ -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