Getting triangles and indicies from TSMesh
by Brett Fattori · in Torque Game Engine · 01/02/2004 (8:42 pm) · 9 replies
Is there a way to get the triangle mesh (and indicies) from TSMesh, TSShapeInstance, or something like that? Right now, I see that TGE takes care of all the rendering for you... It sets up the object/sub-objects, animates them, and then sends the VB(s) to OpenGL. It would be nice to be able to access the mesh, and its indicies, directly. However, the optimizations of tri-strips and the like are causing me headaches.
I'll be honest.. I'm working on a stencil shadow implementation, and I'm stuck at the point of generating edge lists. If I access TSMesh and grab its primitive and index lists, am I guaranteed that the indicies will line up with verts in the primitives? Where can I look, within the engine, to get an example of this? I've been pouring over TSShapeInstance->render() and TSMesh->fillVB() but I don't know if/think I'm in the right place.
Any help from y'all master coders would be mucho appreciated.
- Brett
I'll be honest.. I'm working on a stencil shadow implementation, and I'm stuck at the point of generating edge lists. If I access TSMesh and grab its primitive and index lists, am I guaranteed that the indicies will line up with verts in the primitives? Where can I look, within the engine, to get an example of this? I've been pouring over TSShapeInstance->render() and TSMesh->fillVB() but I don't know if/think I'm in the right place.
Any help from y'all master coders would be mucho appreciated.
- Brett
#3
i tried looping through the meshes, then the meshes prims, then adding up the .numelements, but it was giving ridiculously highnumbers.. :S
04/27/2004 (12:59 pm)
How would i find the number of triangles for a whole shape?i tried looping through the meshes, then the meshes prims, then adding up the .numelements, but it was giving ridiculously highnumbers.. :S
#4
- Brett
06/01/2004 (12:42 pm)
There is a polycount method on the TSMesh class. It will give you a count of all the polys in a mesh... Just remember that an object can consist of many sub-objects.- Brett
#5
Uh... just wondering... Would it be possible to use this way of accesing the mesh to create something like an 'automatic LOD' :m I saw that gluBuild2DMipmaps() creates mipmap levels from a certain image... Would it be possible to create different LOD levels merging near mesh vertices and storing the new shape like a normal LOD loaded from a file?
06/01/2004 (1:23 pm)
This is great, I was looking for something similar :D How about accessing to textures? I guess it will be much more complex... I would like to give bump mapping a try, but I don't know how to find a texture and alter its pixels... Anyway, this thread is a nice clue!Uh... just wondering... Would it be possible to use this way of accesing the mesh to create something like an 'automatic LOD' :m I saw that gluBuild2DMipmaps() creates mipmap levels from a certain image... Would it be possible to create different LOD levels merging near mesh vertices and storing the new shape like a normal LOD loaded from a file?
#6
Is it the render transform for the object?
11/01/2005 (9:28 pm)
@Joakim: What is 'transforms' in the following code:transforms->mulP(v1); transforms->mulP(v2); transforms->mulP(v3);
Is it the render transform for the object?
#7
I did get it to work though, as I might hav said my goal were to create a ray-polygon (used for picking in the RTS kit) collision handler, and to check the polygons for collision I had to get the geometry data as triangles and this is how I did it.
I start by looping through the meshes (in a class derived from ShapeBase) and find submeshes, and get a pointer to the mesh (referring to the pointer as 'mesh' which is a tsMesh pointer as this:
then I get the node transform, this is (if I did understand it right the "offset transform" from the parrent, like in any scenegraph system)
then just for the ease of my work I create some placeholders for the current primitive and the three verts, in a for loop ( we will have to loop through all primitives)
and to get the right transformed vertex data per polygon I loop through the elements and transforming the data:
And if I have not forgot something (except for the actuall collision code, which I left out to save place) this is what I did, and although it seem to work great under Windows it didn't perform as well under Linux.
Anyone have any idea why that is?
is the representation different under Linux?
11/03/2005 (6:10 am)
Ok, sorry I haven't had the time to update this thread, and BTW I removed the prev. threads which did not give anything to the discussion.I did get it to work though, as I might hav said my goal were to create a ray-polygon (used for picking in the RTS kit) collision handler, and to check the polygons for collision I had to get the geometry data as triangles and this is how I did it.
I start by looping through the meshes (in a class derived from ShapeBase) and find submeshes, and get a pointer to the mesh (referring to the pointer as 'mesh' which is a tsMesh pointer as this:
TSMesh *mesh = getShape()->meshes[mesh_index];
then I get the node transform, this is (if I did understand it right the "offset transform" from the parrent, like in any scenegraph system)
MatrixF *transforms = mShapeInstance->mNodeTransforms.address();
then just for the ease of my work I create some placeholders for the current primitive and the three verts, in a for loop ( we will have to loop through all primitives)
for(S32 i=0; i<mesh->primitives.size(); i++) {
TSDrawPrimitive &draw = mesh->primitives[i];
Point3F = v1, v2, v3;and to get the right transformed vertex data per polygon I loop through the elements and transforming the data:
for(S32 j=0; j<draw.numElements; j+=3)
{
S32 ind = j+draw.start;
// fetch the verts of the current triangle
v1 = mesh->verts[mesh->indices[ind]];
v2 = mesh->verts[mesh->indices[ind+1]];
v3 = mesh->verts[mesh->indices[ind+2]];
// and this is the named translation
transforms->mulP(v1);
transforms->mulP(v2);
transforms->mulP(v3);
}And if I have not forgot something (except for the actuall collision code, which I left out to save place) this is what I did, and although it seem to work great under Windows it didn't perform as well under Linux.
Anyone have any idea why that is?
is the representation different under Linux?
#8
Does anyone know why i am not getting actual position of the vertex in the world by applying following transform?
MatrixF *transforms = mShapeInstance->mNodeTransforms.address();
...
...
transforms->mulP(v1);
Appreciate if someone can point me what is the right transform matrix to convert vertex position from a TSMesh to world.
01/11/2008 (1:03 am)
Hi!!Does anyone know why i am not getting actual position of the vertex in the world by applying following transform?
MatrixF *transforms = mShapeInstance->mNodeTransforms.address();
...
...
transforms->mulP(v1);
Appreciate if someone can point me what is the right transform matrix to convert vertex position from a TSMesh to world.
#9
02/24/2008 (12:05 am)
@Viren? If you still need help. take a look at GetMountNodeTransform, or whatever it's called, to get an idea how to convert your local coords to world coords.
Torque Owner Chris \"Hobbiticus\" Weiland
for (U32 objIndex = 0; objIndex < objects.size(); objIndex++) { TSObject * obj = &objects[objIndex]; for (S32 meshIndex = 0; meshIndex < obj->numMeshes; meshIndex++) { TSMesh * mesh = meshes[obj->startMeshIndex+meshIndex]; //do some checking here if it's a skinmesh, i.e.: TSSkinMesh* sMesh = dynamic_cast<TSSkinMesh*>(mesh); ToolVector<Point3F>* vertexList = &mesh->verts; if (sMesh) { //if it's a skin mesh, use the "initial" data vertexList = &sMesh->initialVerts; } if (!mesh) continue; //make sure we have vertices... S32 numVerts = vertexList->size(); if (!numVerts) continue; //make sure there are some primitives... S32 numPrims = mesh->primitives.size(); if (!numPrims) continue; //make sure we have some indices... S32 numIndices = mesh->indices.size(); if (!numIndices) continue; for (S32 primIndex = 0; primIndex < numPrims; primIndex++) { S16 start = mesh->primitives[primIndex].start; S16 numElements = mesh->primitives[primIndex].numElements; if ( (mesh->primitives[primIndex].matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles) { for (S16 triIndex = 0; triIndex < numElements; triIndex+=3) { U32 triStart = start + triIndex; //DO STUFF HERE //each triangle will start at index triStart //and the other vertices are the 2 following this //use triStart to lookup into the indices to lookup //into the vertices. i.e. verts[indices[triIndex]] } } else { U16 idx0 = mesh->indices[start + 0]; U16 idx1; U16 idx2 = mesh->indices[start + 1]; U16 * nextIdx = &idx1; for (S32 triIndex=2; triIndex < numElements; triIndex++) { *nextIdx = idx2; // nextIdx = (j%2)==0 ? &idx0 : &idx1; nextIdx = (U16*) ( (dsize_t)nextIdx ^ (dsize_t)&idx0 ^ (dsize_t)&idx1); idx2 = mesh->indices[start + triIndex]; if (idx0 == idx1 || idx0 == idx2 || idx1 == idx2) continue; //DO STUFF HERE //idx0, idx1, idx2 will be used to lookup indices //for lookup into the vertices. //i.e. verts[indices[idx0]] } } } //next mesh! } }Hope that helps.