I have a project with a collision system setup like this:
CNodeA derived from ISceneNode
|
> unknown number of children of CNodeB derived from ISceneNode with IMetaTriangleSelector
|
> this IMetaTriangleSelector contains a number of CSelector derived from ITriangleSelector that is returning CNodeC (not derived from ISceneNode, but that's beside the point)
When I call getSceneNodeAndCollisionPointFromRay on CNodeA I get the correct triangle and point, but the node returned is CNodeB, when I would expect CNodeC.
I found the error in CSceneCollisionManager.cpp.
It's in the function getPickedNodeFromBBAndSelector:
Code: Select all
void CSceneCollisionManager::getPickedNodeFromBBAndSelector(
ISceneNode * root,
core::line3df & ray,
s32 bits,
bool noDebugObjects,
f32 & outBestDistanceSquared,
ISceneNode * & outBestNode,
core::vector3df & outBestCollisionPoint,
core::triangle3df & outBestTriangle)
{
const ISceneNodeList& children = root->getChildren();
ISceneNodeList::ConstIterator it = children.begin();
for (; it != children.end(); ++it)
{
ISceneNode* current = *it;
ITriangleSelector * selector = current->getTriangleSelector();
if (selector && current->isVisible() &&
(noDebugObjects ? !current->isDebugObject() : true) &&
(bits==0 || (bits != 0 && (current->getID() & bits))))
{
// get world to object space transform
core::matrix4 mat;
if (!current->getAbsoluteTransformation().getInverse(mat))
continue;
// transform vector from world space to object space
core::line3df line(ray);
mat.transformVect(line.start);
mat.transformVect(line.end);
const core::aabbox3df& box = current->getBoundingBox();
core::vector3df candidateCollisionPoint;
core::triangle3df candidateTriangle;
// do intersection test in object space
const ISceneNode * hitNode = 0;
if (box.intersectsWithLine(line) &&
getCollisionPoint(ray, selector, candidateCollisionPoint, candidateTriangle, hitNode))
{
const f32 distanceSquared = (candidateCollisionPoint - ray.start).getLengthSQ();
if(distanceSquared < outBestDistanceSquared)
{
outBestDistanceSquared = distanceSquared;
outBestNode = current;
outBestCollisionPoint = candidateCollisionPoint;
outBestTriangle = candidateTriangle;
const core::vector3df rayVector = ray.getVector().normalize();
ray.end = ray.start + (rayVector * sqrtf(distanceSquared));
}
}
}
getPickedNodeFromBBAndSelector(current, ray, bits, noDebugObjects,
outBestDistanceSquared, outBestNode,
outBestCollisionPoint, outBestTriangle);
}
}
Code: Select all
outBestNode = current;
Code: Select all
outBestNode = (ISceneNode*)hitNode;