Reading vertices out of a ms3d's meshbuff.

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Reading vertices out of a ms3d's meshbuff.

Post by cheesehound »

I'm trying to get the vertex data out of a MeshNode generated from a .ms3d file for use as a collision geom for ODE. Since my mesh collisions weren't looking too accurate, I decided to step through the vertices and found that my 8 vertex test box's mesh node had 24 vertices, many of which simply repeated alternatingly. Are there any known issues with this kind of thing? I tried it with a model in the .x format and experienced similar issues.

I'm using code that is more or less equivalent to the code at http://irrlicht.sourceforge.net/tut_ode.html 's setGeomData.

Code: Select all

			for( j = 0; j < theMeshBuff-> getVertexCount() ; ++j )
			{
				int theBaseIndex = theCurrentVertex * 3;
				theVertices[theBaseIndex] = theBufferVertices[j].Pos.X;
				theVertices[theBaseIndex + 1] = theBufferVertices[j].Pos.Y;
				theVertices[theBaseIndex + 2] = theBufferVertices[j].Pos.Z;

				std::ostringstream theDebugMsg;
				theDebugMsg << "\nVertex " << theCurrentVertex << ": (" <<	theBufferVertices[j].Pos.X << ", " << theBufferVertices[j].Pos.Y << ", " << theBufferVertices[j].Pos.Z << ")";

				OutputDebugString( theDebugMsg.str().c_str() );

				++theCurrentVertex;
			} 
outputs the following:
Vertex 0: (-109.868, 4.03141, 14.4375)
Vertex 1: (-109.868, 0.949764, 14.4375)
Vertex 2: (119.868, 4.03141, 14.4375)
Vertex 3: (119.868, 0.949764, 14.4375)
Vertex 4: (119.868, 4.03141, 14.4375)
Vertex 5: (119.868, 0.949764, 14.4375)
Vertex 6: (119.868, 4.03141, -14.4375)
Vertex 7: (119.868, 0.949764, -14.4375)
Vertex 8: (119.868, 4.03141, -14.4375)
Vertex 9: (119.868, 0.949764, -14.4375)
Vertex 10: (-109.868, 4.03141, -14.4375)
Vertex 11: (-109.868, 0.949764, -14.4375)
Vertex 12: (-109.868, 4.03141, -14.4375)
Vertex 13: (-109.868, 0.949764, -14.4375)
Vertex 14: (-109.868, 4.03141, 14.4375)
Vertex 15: (-109.868, 0.949764, 14.4375)
Vertex 16: (-109.868, 4.03141, -14.4375)
Vertex 17: (-109.868, 4.03141, 14.4375)
Vertex 18: (119.868, 4.03141, -14.4375)
Vertex 19: (119.868, 4.03141, 14.4375)
Vertex 20: (-109.868, 0.949764, 14.4375)
Vertex 21: (-109.868, 0.949764, -14.4375)
Vertex 22: (119.868, 0.949764, 14.4375)
Vertex 23: (119.868, 0.949764, -14.4375)
and I exported my .ms3d to plain text as proof that it's actually 8 vertices:

Code: Select all

SimpleMeshFormat 1
1
Box01
8
-109.868 4.03141 14.4375
-109.868 0.949764 14.4375
119.868 4.03141 14.4375
119.868 0.949764 14.4375
119.868 4.03141 -14.4375
119.868 0.949764 -14.4375
-109.868 4.03141 -14.4375
-109.868 0.949764 -14.4375
12
1 0 1 2 0 0 1 0 0 1 0 0 1 0 0 0 1 1 0
1 1 3 2 0 0 1 0 0 1 0 0 1 0 1 1 1 1 0
2 2 3 4 1 0 0 1 0 0 1 0 0 0 0 0 1 1 0
2 3 5 4 1 0 0 1 0 0 1 0 0 0 1 1 1 1 0
1 4 5 6 0 0 -1 0 0 -1 0 0 -1 0 0 0 1 1 0
1 5 7 6 0 0 -1 0 0 -1 0 0 -1 0 1 1 1 1 0
2 6 7 0 -1 0 0 -1 0 0 -1 0 0 0 0 0 1 1 0
2 7 1 0 -1 0 0 -1 0 0 -1 0 0 0 1 1 1 1 0
3 6 0 4 0 1 0 0 1 0 0 1 0 0 0 0 1 1 0
3 0 2 4 0 1 0 0 1 0 0 1 0 0 1 1 1 1 0
3 1 7 3 0 -1 0 0 -1 0 0 -1 0 0 0 0 1 1 0
3 7 5 3 0 -1 0 0 -1 0 0 -1 0 0 1 1 1 1 0
Chiefly I'm just confused as to why the vertex data I'm getting here seems so apparently wrong. Any wisdom would be most appreciated.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Irrlicht binds vertex position, vertex normals, vertex colors, and texture coordinates together into a S3DVertex struct. If the positions are equal, but normals or any other part differ, a new vertex is created. The ms3d file has 12 quads defined, which means 24 triangles, and those are composed from those 24 vertices you find in your mesh.
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

Thanks hybrid.

I guess the problem is that I'm taking this data to represent a trimesh when in fact it doesn't?

For example, the vertices
Vertex 6: (119.868, 4.03141, -14.4375)
Vertex 7: (119.868, 0.949764, -14.4375)
Vertex 8: (119.868, 4.03141, -14.4375)
don't make a face, but show up sequentially in the mesh data and have indices that indicate (to me) that they belong to the same face.

Will I have to check for these kinds of issues if I want a valid trimesh for use in ODE, or am I barking up the wrong tree here?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

To be honest, your loop seems to extract rather random values from the vertex list. Simply because you take the x value of the first vertex, the y value of the second, and Z from the third vertex of a face. Instead, you should print all x,y,z for each of the three, forming a face. Or just print each vertex in the vertex list without taking into account the indices...
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

I think you may be misreading it. It's just iterating through the members of theBufferVertices from 0 to theMeshbuff->getVertexCount().

theVertices is a float* with a length of 3 * the total vertex count, and I'm sticking the x,y, and z coords each into sequential indices of theVertices. The values I'm actually printing are the ones inside theBufferVertices, though, so regardless of where I'm sticking them, what I'm reading out of my irr::video::S3DVertex* theBuffVertices seems pretty off.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

oh yes, you're right. So why don't you take into account the indices :P Faces are build based on the indices, you need to check vertex[index[0]],...,vertex[index[2]] for the first triangle!
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

I am copying my indices data into an array and passing it along to

Code: Select all

ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g,
                                 const dReal* Vertices, int VertexCount,
                                 const dTriIndex* Indices, int IndexCount);
a dTriIndex is a typedef of a uint32, so I figured all was right in my copying of indices and passing it on to ODE via this call. I'm posting my code below, but it really does follow the ODE tutorial so far as I can figure. I'm pretty sure this is a regularly done thing in Irrlicht. Is there another resource I should be looking at for pointers on getting this rolling? I'd feel less guilty if you didn't have to read all this :P.

Code: Select all

    int theIndexCount = 0;
    int theVertexCount = 0;
    // count vertices and indices
    for( int i = 0; i < theMesh->getMeshBufferCount(); ++i)
	{
		irr::scene::IMeshBuffer* theMeshBuff= theMesh->getMeshBuffer( i );
		theIndexCount += theMeshBuff->getIndexCount();
		theVertexCount += theMeshBuff->getVertexCount();
    }

	int theMeshBuffCount = theMesh->getMeshBufferCount();

    // build structure for ode trimesh geom
    float* theVertices = new float[theVertexCount * 3];
    dTriIndex* theIndices = new dTriIndex[theIndexCount];

    // fill trimesh geom
	int theCurrentIndex = 0;
	int theIrrVertexOffset = 0;
	int theCurrentVertex = 0;

	int i;
	int j;

    for( i = 0 ; i < theMesh->getMeshBufferCount(); ++i)
	{
		irr::scene::IMeshBuffer* theMeshBuff = theMesh->getMeshBuffer( i );
		// fill indices
		irr::u16* theBufferIndices = theMeshBuff->getIndices();

		for( j = 0; j < theMeshBuff->getIndexCount(); j++)
		{
			// scale the indices from multiple meshbuffers to single index array
			theIndices[theCurrentIndex] = theIrrVertexOffset + theBufferIndices[j];

			std::ostringstream theDebugMsg;
			theDebugMsg << "\n Index " << theCurrentIndex << ": " << theBufferIndices[j] << " + offset:" << theIrrVertexOffset;
			OutputDebugString( theDebugMsg.str().c_str() );

			++theCurrentIndex;
		}

		// update the offset for the next meshbuffer
		theIrrVertexOffset = theIrrVertexOffset + theMeshBuff->getVertexCount();
		
		// fill vertices
		if( theMeshBuff->getVertexType() == irr::video::EVT_STANDARD )
		{
			irr::video::S3DVertex* theBufferVertices=
				  (irr::video::S3DVertex*) theMeshBuff->getVertices();

			for( j = 0; j < theMeshBuff-> getVertexCount() ; ++j )
			{
				int theBaseIndex = theCurrentVertex * 3;
				theVertices[theBaseIndex] = theBufferVertices[j].Pos.X;
				theVertices[theBaseIndex + 1] = theBufferVertices[j].Pos.Y;
				theVertices[theBaseIndex + 2] = theBufferVertices[j].Pos.Z;

				std::ostringstream theDebugMsg;
				theDebugMsg << "\nVertex " << theCurrentVertex << ": (" <<	theBufferVertices[j].Pos.X << ", " << theBufferVertices[j].Pos.Y << ", " << theBufferVertices[j].Pos.Z << ")";

				OutputDebugString( theDebugMsg.str().c_str() );

				++theCurrentVertex;
			} 
		}
	}

	irr::core::vector3df thePosition = aMeshNode->getPosition();

	// build the trimesh data
	dTriMeshDataID theData = dGeomTriMeshDataCreate();
	//TODO: check on memory management of Data.  Is it destroyed with our Geom?

	dGeomTriMeshDataBuildSimple( theData,(dReal*)theVertices, 
					  theVertexCount, theIndices, theIndexCount);
	// build the trimesh geom 
	mPhysicsInfo.geomId = dCreateTriMesh( aWorldInfo.spaceId, theData, 0, 0, 0);

	// set the geom position 
	dGeomSetPosition( mPhysicsInfo.geomId, thePosition.X, thePosition.Y, thePosition.Z);
}
And these are the indices I'm getting output by my test code.
Index 0: 0 + offset:0
Index 1: 1 + offset:0
Index 2: 2 + offset:0
Index 3: 1 + offset:0
Index 4: 3 + offset:0
Index 5: 2 + offset:0
Index 6: 4 + offset:0
Index 7: 5 + offset:0
Index 8: 6 + offset:0
Index 9: 5 + offset:0
Index 10: 7 + offset:0
Index 11: 6 + offset:0
Index 12: 8 + offset:0
Index 13: 9 + offset:0
Index 14: 10 + offset:0
Index 15: 9 + offset:0
Index 16: 11 + offset:0
Index 17: 10 + offset:0
Index 18: 12 + offset:0
Index 19: 13 + offset:0
Index 20: 14 + offset:0
Index 21: 13 + offset:0
Index 22: 15 + offset:0
Index 23: 14 + offset:0
Index 24: 16 + offset:0
Index 25: 17 + offset:0
Index 26: 18 + offset:0
Index 27: 17 + offset:0
Index 28: 19 + offset:0
Index 29: 18 + offset:0
Index 30: 20 + offset:0
Index 31: 21 + offset:0
Index 32: 22 + offset:0
Index 33: 21 + offset:0
Index 34: 23 + offset:0
Index 35: 22 + offset:0
Thanks again.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Ok, so 36 indices makes 12 faces, which is correct according to the ms3d file output. So you just need to check the vertices which are referenced by the indices, instead of doing it via the 0,1,2,3,4,5,6,... scheme.
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

I swear I'd typed that they looked fine to me after a cursory glance, but that's definitely not anywhere in the post. I'll take a closer look at it the next chance I get, though.

My main hope in posting this was that it was a common (but something I failed searching for) issue and that there would be something terribly obvious I was off on via outdated info or good ol' dumbness. Oh well. I'll take another swat at it tonight :).
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

Does vertex order matter here? I've noticed that some of my faces appear to be defined in counter-clockwise order while others are defined in clockwise order. That said, the top of my box is all defined counter-clockwise, so I may just have gotten cross-eyed halfway through this. And if the top's fine, my lame "drop objects on it" test should be working.

This unfortunately seems to put me back at square 1, with no idea about just what in my fairly vanilla looking code might be causing this. What I've done seems to match the ODE tutorial pretty directly, and also follows what I saw done in examples of creating a trimesh I found for PAL and Newton. I must be doing something impressively stupid :). Back to le code.
jddevnet
Posts: 17
Joined: Mon Oct 06, 2008 8:27 pm

Post by jddevnet »

I've been learning about this recently as well.

The order of the vertices are important, as the indices are defining the triangles based on that. This little picture from Hybrid helped me understand it immensely:
hybrid wrote: Also note that you need to use clockwise orientation of the faces. So the following quad results in indices 0,1,2,1,3,2

Code: Select all

0---1
|  / |
| /  |
2---3
From: http://irrlicht.sourceforge.net/phpBB2/ ... highlight=
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

Oh, damn. I'm used to seeing faces defined in counter-clockwise order, so figured that was correct. Is this a known issue with ms3d-generated files? Anyone have an idea for an app that could save out a simple cube model with the correct vertices order? I'll try creating something with Blender and crossing my fingers that it defines the vertices in the right order, otherwise :P.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

jddevnet wrote:I've been learning about this recently as well.

The order of the vertices are important, as the indices are defining the triangles based on that. This little picture from Hybrid helped me understand it immensely:
hybrid wrote: Also note that you need to use clockwise orientation of the faces. So the following quad results in indices 0,1,2,1,3,2

Code: Select all

0---1
|  / |
| /  |
2---3
From: http://irrlicht.sourceforge.net/phpBB2/ ... highlight=
it's right that the order is important, but it must not be clockwise, it must be anti-clockwise (I mentioned this in the same thread, 2 posts after hybrid's post: http://irrlicht.sourceforge.net/phpBB2/ ... 123#175123) !!! ;)

maybe this post is also usefull to understand this: http://irrlicht.sourceforge.net/phpBB2/ ... 367#171367
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
jddevnet
Posts: 17
Joined: Mon Oct 06, 2008 8:27 pm

Post by jddevnet »

Ah, yes - my apologies Acki! I do recall seeing that, although I guess I didn't quite get the implication at the time..

I never saw this before your link, but it sure does clear up why my initial attempts placed the image on the back. lol

Acki wrote:remember the order of the indices !!!
to see the face from the front the order must be anti-clockwise !!!
to see the face from the back the order must be clockwise !!!
cheesehound
Posts: 13
Joined: Sun Oct 12, 2008 4:27 pm

Post by cheesehound »

Well, heck. Looks like there's nothing wrong with my mesh, then. I'll go back to staring at my code. Thanks, guys :).
Post Reply