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,
ISceneNode* best = 0;
f32 dist = FLT_MAX;
getPickedNodeBB(SceneManager->getRootSceneNode(), ray,
getPickedNodeBB(SceneManager->getRootSceneNode(), ray,
idBitMask, bNoDebugObjects, dist, best);
return best;
......@@ -105,7 +105,8 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
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))
{
box.getEdges(edges);
......@@ -113,7 +114,17 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
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)
distance = t;
}
......@@ -130,7 +141,7 @@ void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
getPickedNodeBB(current, ray, bits, bNoDebugObjects, outbestdistance, outbestnode);
}
}
}
}
......@@ -501,7 +512,7 @@ core::vector3df CSceneCollisionManager::collideEllipsoidWithWorld(
const core::vector3df& radius, const core::vector3df& velocity,
f32 slidingSpeed,
const core::vector3df& gravity,
core::triangle3df& triout,
core::triangle3df& triout,
core::vector3df& hitPosition,
bool& outFalling)
{
......@@ -587,7 +598,7 @@ core::vector3df CSceneCollisionManager::collideWithWorld(s32 recursionDepth,
core::matrix4 scaleMatrix;
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.Z)
);
......
......@@ -21,7 +21,7 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device,
vector3df hitPosition;
bool falling;
vector3df resultPosition =
vector3df resultPosition =
collMgr->getCollisionResultPosition(cubeSelector,
vector3df(0, 50, 0),
vector3df(10, 20, 10),
......@@ -38,14 +38,14 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device,
result = false;
}
if(!equals(hitPosition.Y, 5.f, 0.01f))
if(!equals(hitPosition.Y, 5.f, 0.01f))
{
logTestString("Unexpected collision position\n");
assert(false);
result = false;
}
resultPosition =
resultPosition =
collMgr->getCollisionResultPosition(cubeSelector,
vector3df(-20, 0, 0),
vector3df(10, 20, 10),
......@@ -61,7 +61,7 @@ static bool testGetCollisionResultPosition(IrrlichtDevice * device,
result = false;
}
if(!equals(hitPosition.X, -5.f, 0.01f))
if(!equals(hitPosition.X, -5.f, 0.01f))
{
logTestString("Unexpected collision position\n");
assert(false);
......@@ -105,7 +105,7 @@ static bool testGetSceneNodeFromScreenCoordinatesBB(IrrlichtDevice * device,
result = false;
}
// Make cubeNode1 the parent of cubeNode2.
// Make cubeNode1 the parent of cubeNode2.
cubeNode2->setParent(cubeNode1);
// Check visibility.
......@@ -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 */
bool sceneCollisionManager(void)
{
......@@ -178,9 +212,11 @@ bool sceneCollisionManager(void)
ISceneCollisionManager * collMgr = smgr->getSceneCollisionManager();
bool result = testGetCollisionResultPosition(device, smgr, collMgr);
result &= testGetSceneNodeFromScreenCoordinatesBB(device, smgr, collMgr);
result &= getScaledPickedNodeBB(device, smgr, collMgr);
device->drop();
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