CTriangleSelector and COctTree u32 indices BUG

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
alisima
Posts: 3
Joined: Fri Aug 28, 2009 10:28 am

CTriangleSelector and COctTree u32 indices BUG

Post by alisima »

Hello,

Have downloaded the newest 1.5.1 library, and am using the new CDynamicMesh buffer (for my terrain) which allows more than 65536 indices due to switching over from 16 bit indices to 32 bit indices.

Anyways, it renders fine. Next step was implementing a camera which could float over the terrain. For this one needs the height of the terrain at each camera spot (so the camera does not end up under the terrain). This is done with the CollisionManager's getCollisionPoint and creating a CTriangleSelector for the terrain. I have done this before, and it always worked fine.

Except now, the data I got back from the getCollisionPoint was corrupted. For instance, I only got a true returned from getCollisionPoint for approximately 40% of the mesh. And for every time one of the vertices of the outTriangle from getCollisionPoint was always pointing to the FIRST vertex of the mesh.

I looked into it, done some tests and found out that regardless of whether you use 32 bit indices (EIT_32BIT) or 16 bit indices (EIT_16BIT), the CTriangleSelector treats them ALL the same...

Here we have the CTriangleSelector's constructor:

Code: Select all

//! constructor
CTriangleSelector::CTriangleSelector(const IMesh* mesh, const ISceneNode* node)
: SceneNode(node)
{
	#ifdef _DEBUG
	setDebugName("CTriangleSelector");
	#endif

	const u32 cnt = mesh->getMeshBufferCount();
	u32 totalFaceCount = 0;
	for (u32 j=0; j<cnt; ++j)
		totalFaceCount += mesh->getMeshBuffer(j)->getIndexCount();
	totalFaceCount /= 3;
	Triangles.reallocate(totalFaceCount);

	for (u32 i=0; i<cnt; ++i)
	{
		const IMeshBuffer* buf = mesh->getMeshBuffer(i);

		const u32 idxCnt = buf->getIndexCount();
		const u16* const indices = buf->getIndices();

		for (u32 j=0; j<idxCnt; j+=3)
		{
			Triangles.push_back(core::triangle3df(
					buf->getPosition(indices[j+0]),
					buf->getPosition(indices[j+1]),
					buf->getPosition(indices[j+2])));
		}
	}
}
As you can see the indices are placed in a const u16* const indices variable, thus ALWAYS assuming the indices are u16.

Simply change the constructor to this:

Code: Select all

//! constructor
CTriangleSelector::CTriangleSelector(const IMesh* mesh, const ISceneNode* node)
: SceneNode(node)
{
	#ifdef _DEBUG
	setDebugName("CTriangleSelector");
	#endif

	const u32 cnt = mesh->getMeshBufferCount();
	u32 totalFaceCount = 0;
	for (u32 j=0; j<cnt; ++j)
		totalFaceCount += mesh->getMeshBuffer(j)->getIndexCount();
	totalFaceCount /= 3;
	Triangles.reallocate(totalFaceCount);

	for (u32 i=0; i<cnt; ++i)
	{
		const IMeshBuffer* buf = mesh->getMeshBuffer(i);

		const u32 idxCnt = buf->getIndexCount();

		if (buf->getIndexType() == EIT_32BIT)
		{
			const u32* const indices = (u32*) buf->getIndices();

			for (u32 j=0; j<idxCnt; j+=3)
			{
				Triangles.push_back(core::triangle3df(
						buf->getPosition(indices[j+0]),
						buf->getPosition(indices[j+1]),
						buf->getPosition(indices[j+2])));
			}
		} else
		{
			const u16* const indices =  buf->getIndices();

			for (u32 j=0; j<idxCnt; j+=3)
			{
				Triangles.push_back(core::triangle3df(
						buf->getPosition(indices[j+0]),
						buf->getPosition(indices[j+1]),
						buf->getPosition(indices[j+2])));
			}
		}
	}
}
The same problem is in the COctTreeTriangleSelector.

Greetings,

Bas.
Post Reply