Creating an ODE trimesh

Started by
6 comments, last by sirSolarius 19 years ago
I keep getting errors when I create a trimesh in ODE from my heightmap, and I have no idea why. I've looked through tons of example code and it doesn't seem to help. Here is my setup:

void HeightMap::LoadMap(std::string mapfile)
{
	...boring file stuff gets the heightmap data...

	float *mapData=new float[m_mapLength*m_mapWidth*3];
	
	m_indices=new int[m_mapLength*m_mapWidth*2];
	
	m_tallestPoint=-HEIGHT_CONSTANT;
	float tempHeight;
	for(int x=0; x < m_mapWidth; ++x)
	{
		for(int z=0; z < m_mapLength; ++z)
		{
			int j=x+m_mapWidth*z;

			mapData[3*j]=MAP_SPACING*x;
		        mapData[3*j+1]=GetHeight(x, z)
			mapData[3*j+2]=MAP_SPACING*z;
		}
	}

	int index=0;
	for(int c=0; c < m_mapWidth*(m_mapLength-1); ++c)
	{
		m_indices[index++]=c;
		m_indices[index++]=c + m_mapWidth;
	}

	m_dataID = dGeomTriMeshDataCreate();
	dGeomTriMeshDataBuildSimple (m_dataID, (dReal*)mapData, m_mapLength*m_mapWidth,
							m_indices, m_mapWidth*m_mapLength*2);
	m_geomID = dCreateTriMesh(Entity::m_space, m_dataID, 0, 0, 0);

       ...boring VBO stuff...
}

If I comment out the ODE lines, everything is great and the VBO displays, etc. With those two lines in, however, I get an Unhandled Exception: Access Violation on the dGeomTriMeshDataBuildSimple line. What is going wrong?
Advertisement
I have not dived deeply into it but two thoughts come to mind:

1. Aren't the indices supposed to define triangles i.e. three indices per loop in:
m_indices[index++]=c;m_indices[index++]=c + m_mapWidth;


2. Did you link with a build of ODE that includes trimesh support? Not all builds do; but they just might contain a dummy function that always throws an error.

Greetz,

Illco
Ok, I'm fairly sure that it's problem #1 since I downloaded ODE with trimesh support.

I was specifying my old indices for a triangle strip, and understandably ODE doesn't like that. So I now have a new index array that puts in the redundent vertex like so:

        int index=0;	for(int c=0; c < m_mapWidth*(m_mapLength-1); ++c)	{		m_indices[index++]=c;		m_indices[index++]=c + m_mapWidth;	}	int *physicsIndices=new int[m_mapWidth*m_mapLength*3];	index=0;	for(int c=0; c < m_mapWidth*m_mapLength; ++c)	{		physicsIndices[index++]=c;		physicsIndices[index++]=c+m_mapWidth;		physicsIndices[index++]=c+1;	}	m_dataID = dGeomTriMeshDataCreate();	dGeomTriMeshDataBuildSimple (m_dataID, (dReal*)mapData, m_mapLength*m_mapWidth,							physicsIndices, m_mapWidth*m_mapLength*3);	m_geomID = dCreateTriMesh(Entity::m_space, m_dataID, 0, 0, 0);		delete [] physicsIndices;


That should work correctly, right? It's the vertex, the vertex above it, and the vertex next to it... boom, next triangle. But now I get a scary memory error in "heap_alloc_dbg" on this line:

 /* fill data with silly value (but non-zero) */        memset((void *)pbData(pHead), _bCleanLandFill, nSize);


Any idea what's going on now?

Thanks for the help!
Ok, so I decided to use the test_trimesh trimesh to make sure everything was working ok.

float Size[3], Vertices[15];	int Indices[12];	Size[0] = 5.0f;	Size[1] = 5.0f;	Size[2] = 2.5f;	Vertices[0] = -Size[0];	Vertices[1] = -Size[1];	Vertices[2] = Size[2];	Vertices[3] = Size[0];	Vertices[4] = -Size[1];	Vertices[5] = Size[2];	Vertices[6] = Size[0];	Vertices[7] = Size[1];	Vertices[8] = Size[2];	Vertices[9] = -Size[0];	Vertices[10] = Size[1];	Vertices[11] = Size[2];	Vertices[12] = 0;	Vertices[13] = 0;	Vertices[14] = 0;	Indices[0] = 0;	Indices[1] = 1;	Indices[2] = 4;	Indices[3] = 1;	Indices[4] = 2;	Indices[5] = 4;	Indices[6] = 2;	Indices[7] = 3;	Indices[8] = 4;	Indices[9] = 3;	Indices[10] = 0;	Indices[11] = 4;	dTriMeshDataID Data = dGeomTriMeshDataCreate();	dGeomTriMeshDataBuildSimple(Data, (dReal*)Vertices, 5, Indices, 12);	m_geomID = dCreateTriMesh(Entity::m_space, Data, 0, 0, 0);


So everything seems to work fine, but I get an error in my collide callback on this line:
****if (int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom, sizeof(dContact))) 	{		dMatrix3 RI;		dRSetIdentity (RI);		const dReal ss[3] = {0.02,0.02,0.02};		for (i=0; i<numc; i++) 		{			dJointID c = dJointCreateContact (b.world,b.joints,contact+i);			dJointAttach (c,b1,b2);		}	}


I get a fat access violation.

Urrrrrrrrrrrrrgh this triangle collider is really making me mad ><
Your problem is that dVector3 in ODE is not defined as dReal[3] as anyone would asume, but as dReal[4].

When you cast your mapData array into a dReal, internaly dGeomTriMeshDataBuildSimple is expecting 4 floats per vertice not 3.

Try using dGeomTriMeshDataBuild paying atention to the "stride" parameter, I think you want it to be 3.
Quote:Original post by Kwizatz
Your problem is that dVector3 in ODE is not defined as dReal[3] as anyone would asume, but as dReal[4].

When you cast your mapData array into a dReal, internaly dGeomTriMeshDataBuildSimple is expecting 4 floats per vertice not 3.

Try using dGeomTriMeshDataBuild paying atention to the "stride" parameter, I think you want it to be 3.


Are you sure about this? Here is the example code from test_trimesh.cpp:
#define VertexCount 5#define IndexCount 12static dVector3 Size;static dVector3 Vertices[VertexCount];static int Indices[IndexCount];....  Size[0] = 5.0f;  Size[1] = 5.0f;  Size[2] = 2.5f;    Vertices[0][0] = -Size[0];  Vertices[0][1] = -Size[1];  Vertices[0][2] = Size[2];    Vertices[1][0] = Size[0];  Vertices[1][1] = -Size[1];  Vertices[1][2] = Size[2];    Vertices[2][0] = Size[0];  Vertices[2][1] = Size[1];  Vertices[2][2] = Size[2];    Vertices[3][0] = -Size[0];  Vertices[3][1] = Size[1];  Vertices[3][2] = Size[2];    Vertices[4][0] = 0;  Vertices[4][1] = 0;  Vertices[4][2] = 0;    Indices[0] = 0;  Indices[1] = 1;  Indices[2] = 4;    Indices[3] = 1;  Indices[4] = 2;  Indices[5] = 4;    Indices[6] = 2;  Indices[7] = 3;  Indices[8] = 4;    Indices[9] = 3;  Indices[10] = 0;  Indices[11] = 4;  dTriMeshDataID Data = dGeomTriMeshDataCreate();  dGeomTriMeshDataBuildSimple(Data, (dReal*)Vertices, VertexCount, Indices, IndexCount);    TriMesh = dCreateTriMesh(space, Data, 0, 0, 0);


Just to make sure, I did this with my own code:
	int *physicsIndices=new int[m_mapWidth*m_mapLength*3];	dVector3 *physicsVertices=new dVector3[m_mapWidth*m_mapLength];	index=0;	for(int i=0; i < m_mapWidth*m_mapLength; ++i)	{		physicsVertices[0]=mapData[index++];		physicsVertices[1]=mapData[index++];		physicsVertices[2]=mapData[index++];	}	index=0;	for(int c=0; c < m_mapWidth*m_mapLength; ++c)	{		physicsIndices[index++]=c;		physicsIndices[index++]=c+m_mapWidth;		physicsIndices[index++]=c+1;	}	m_dataID = dGeomTriMeshDataCreate();	dGeomTriMeshDataBuildSimple (m_dataID, (dReal*)physicsVertices, m_mapLength*m_mapWidth,							physicsIndices, m_mapWidth*m_mapLength*3);	m_geomID = dCreateTriMesh(Entity::m_space, m_dataID, 0, 0, 0);		delete [] physicsIndices;	delete [] physicsVertices;


Same error =(
now your problem is declaring physicsVertices as dVector3[m_mapWidth*m_mapLength];
and then referencing it as physicsVertices[][]

try dVector3 *physicsVertices=new dVector3[m_mapWidth][m_mapLength] instead of
dVector3 *physicsVertices=new dVector3[m_mapWidth*m_mapLength]

Edit: scratch that, it may not work you may be better off accessing the array as a unidimentional array, so if declaring it as 2 dimentional didnt work, try it the other way around.
I actually can't access it as a one-dimensional array... it gives me errors casting from float to dReal[4]. I essentially do the physicsVertices[x] and that returns a dReal[4]. Then I index into the dReal[4] by putting another set of brackets in there. It should work, theoretically.

Is there anything else I can try?

This topic is closed to new replies.

Advertisement