getPickedNodeFromBBAndSelector returns wrong ISceneNode

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
turboferret
Posts: 49
Joined: Thu Aug 12, 2004 12:42 pm
Location: Sweden
Contact:

getPickedNodeFromBBAndSelector returns wrong ISceneNode

Post by turboferret »

Hey hey,

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);
	}
}
Changing

Code: Select all

outBestNode = current;
to

Code: Select all

outBestNode = (ISceneNode*)hitNode;
seems to fix this. Unless this is wanted behaviour or did I miss something?
This monkey is useless, it only has ONE ass!!!
Post Reply