Commit c7f82100 authored by rogerborg's avatar rogerborg

https://sourceforge.net/tracker2/?func=detail&aid=2473520&group_id=74339&atid=540676

http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?p=181419

Partial fix for CSceneCollisionManager::getPickedNodeBB(), but we should push on and do a proper test for the actual intersection point with each hit cube.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1991 dfc29bdd-3216-0410-991c-e03cc46cb475
parent d635ca95
...@@ -64,7 +64,7 @@ ISceneNode* CSceneCollisionManager::getSceneNodeFromRayBB(core::line3d<f32> ray, ...@@ -64,7 +64,7 @@ ISceneNode* CSceneCollisionManager::getSceneNodeFromRayBB(core::line3d<f32> ray,
ISceneNode* best = 0; ISceneNode* best = 0;
f32 dist = FLT_MAX; f32 dist = FLT_MAX;
getPickedNodeBB(SceneManager->getRootSceneNode(), ray, getPickedNodeBB(SceneManager->getRootSceneNode(), ray,
idBitMask, bNoDebugObjects, dist, best); idBitMask, bNoDebugObjects, dist, best);
return best; return best;
...@@ -105,7 +105,8 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, ...@@ -105,7 +105,8 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
const core::aabbox3df& box = current->getBoundingBox(); const core::aabbox3df& box = current->getBoundingBox();
// do intersection test in object space // do the initial intersection test in object space, since the
// object space box is more accurate.
if (box.intersectsWithLine(line)) if (box.intersectsWithLine(line))
{ {
box.getEdges(edges); box.getEdges(edges);
...@@ -113,7 +114,17 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, ...@@ -113,7 +114,17 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
for (s32 e=0; e<8; ++e) for (s32 e=0; e<8; ++e)
{ {
f32 t = edges[e].getDistanceFromSQ(line.start); // Transform the corner into world coordinates, to take
// scaling into account.
current->getAbsoluteTransformation().transformVect(edges[e]);
// and compare it against the world space ray start position
f32 t = edges[e].getDistanceFromSQ(ray.start);
// We're looking for the furthest corner; this is a crude
// test; we should be checking the actual ray/plane
// intersection.
// http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?p=181419
if (t > distance) if (t > distance)
distance = t; distance = t;
} }
...@@ -130,7 +141,7 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root, ...@@ -130,7 +141,7 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
getPickedNodeBB(current, ray, bits, bNoDebugObjects, outbestdistance, outbestnode); getPickedNodeBB(current, ray, bits, bNoDebugObjects, outbestdistance, outbestnode);
} }
} }
} }
...@@ -501,7 +512,7 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld( ...@@ -501,7 +512,7 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld(
const core::vector3df& radius, const core::vector3df& velocity, const core::vector3df& radius, const core::vector3df& velocity,
f32 slidingSpeed, f32 slidingSpeed,
const core::vector3df& gravity, const core::vector3df& gravity,
core::triangle3df& triout, core::triangle3df& triout,
core::vector3df& hitPosition, core::vector3df& hitPosition,
bool& outFalling) bool& outFalling)
{ {
...@@ -587,7 +598,7 @@ core::vector3df CSceneCollisionManager::collideWithWorld(s32 recursionDepth, ...@@ -587,7 +598,7 @@ core::vector3df CSceneCollisionManager::collideWithWorld(s32 recursionDepth,
core::matrix4 scaleMatrix; core::matrix4 scaleMatrix;
scaleMatrix.setScale( scaleMatrix.setScale(
core::vector3df(1.0f / colData.eRadius.X, core::vector3df(1.0f / colData.eRadius.X,
1.0f / colData.eRadius.Y, 1.0f / colData.eRadius.Y,
1.0f / colData.eRadius.Z) 1.0f / colData.eRadius.Z)
); );
......
...@@ -21,7 +21,7 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device, ...@@ -21,7 +21,7 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device,
vector3df hitPosition; vector3df hitPosition;
bool falling; bool falling;
vector3df resultPosition = vector3df resultPosition =
collMgr->getCollisionResultPosition(cubeSelector, collMgr->getCollisionResultPosition(cubeSelector,
vector3df(0, 50, 0), vector3df(0, 50, 0),
vector3df(10, 20, 10), vector3df(10, 20, 10),
...@@ -38,14 +38,14 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device, ...@@ -38,14 +38,14 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device,
result = false; result = false;
} }
if(!equals(hitPosition.Y, 5.f, 0.01f)) if(!equals(hitPosition.Y, 5.f, 0.01f))
{ {
logTestString("Unexpected collision position\n"); logTestString("Unexpected collision position\n");
assert(false); assert(false);
result = false; result = false;
} }
resultPosition = resultPosition =
collMgr->getCollisionResultPosition(cubeSelector, collMgr->getCollisionResultPosition(cubeSelector,
vector3df(-20, 0, 0), vector3df(-20, 0, 0),
vector3df(10, 20, 10), vector3df(10, 20, 10),
...@@ -61,7 +61,7 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device, ...@@ -61,7 +61,7 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device,
result = false; result = false;
} }
if(!equals(hitPosition.X, -5.f, 0.01f)) if(!equals(hitPosition.X, -5.f, 0.01f))
{ {
logTestString("Unexpected collision position\n"); logTestString("Unexpected collision position\n");
assert(false); assert(false);
...@@ -105,7 +105,7 @@ static bool testGetSceneNodeFromScreenCoordinatesBB(IrrlichtDevice * device, ...@@ -105,7 +105,7 @@ static bool testGetSceneNodeFromScreenCoordinatesBB(IrrlichtDevice * device,
result = false; result = false;
} }
// Make cubeNode1 the parent of cubeNode2. // Make cubeNode1 the parent of cubeNode2.
cubeNode2->setParent(cubeNode1); cubeNode2->setParent(cubeNode1);
// Check visibility. // Check visibility.
...@@ -166,6 +166,40 @@ static bool testGetSceneNodeFromScreenCoordinatesBB(IrrlichtDevice * device, ...@@ -166,6 +166,40 @@ static bool testGetSceneNodeFromScreenCoordinatesBB(IrrlichtDevice * device,
} }
static bool getScaledPickedNodeBB(IrrlichtDevice * device,
ISceneManager * smgr,
ISceneCollisionManager * collMgr)
{
ISceneNode* farTarget = smgr->addCubeSceneNode(1.f);
farTarget->setScale(vector3df(100.f, 100.f, 10.f));
farTarget->setPosition(vector3df(0.f, 0.f, 500.f));
farTarget->updateAbsolutePosition();
ISceneNode* nearTarget = smgr->addCubeSceneNode(10.f);
nearTarget->setPosition(vector3df(0.f, 0.f, 100.f));
nearTarget->updateAbsolutePosition();
line3df ray(0.f, 0.f, 0.f, 0.f, 0.f, 500.f);
const ISceneNode * const hit = collMgr->getSceneNodeFromRayBB(ray);
bool result = (hit == nearTarget);
if(hit == 0)
logTestString("getSceneNodeFromRayBB() didn't hit anything.\n");
else if(hit == farTarget)
logTestString("getSceneNodeFromRayBB() hit the far (scaled) target.\n");
device->drop();
if(!result)
assert(false);
return result;
}
/** Test functionality of the sceneCollisionManager */ /** Test functionality of the sceneCollisionManager */
bool sceneCollisionManager(void) bool sceneCollisionManager(void)
{ {
...@@ -178,9 +212,11 @@ bool sceneCollisionManager(void) ...@@ -178,9 +212,11 @@ bool sceneCollisionManager(void)
ISceneCollisionManager * collMgr = smgr->getSceneCollisionManager(); ISceneCollisionManager * collMgr = smgr->getSceneCollisionManager();
bool result = testGetCollisionResultPosition(device, smgr, collMgr); bool result = testGetCollisionResultPosition(device, smgr, collMgr);
result &= testGetSceneNodeFromScreenCoordinatesBB(device, smgr, collMgr); result &= testGetSceneNodeFromScreenCoordinatesBB(device, smgr, collMgr);
result &= getScaledPickedNodeBB(device, smgr, collMgr);
device->drop(); device->drop();
return result; return result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment