Archived

This topic is now archived and is closed to further replies.

How do I retrieve Triangles from a Mesh (.X) ?

This topic is 5015 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

HiD3DXLoadMeshFromX( path , D3DXMESH_SYSTEMMEM, pd3dDevice, NULL, &pMaterialBuffer, NULL, &NumOfMaterials, &CurrentMesh ) This is the code I use to load a mesh from file. I used the the mesh converter executable to convert my meshes from 3ds MAX files. I am wanting to implement a collision detection algorithm which needs to be able to check a ray against each triangle of a mesh... How can I retrieve each triangle from a mesh? Thanks! P.S. I look forward to contributing to the community here, I really like the website!

Share this post


Link to post
Share on other sites
I''m wondering.... are the first 3 vertices that I get from the vertex buffer the first triangle.... then I retrieve 3 more for the 2nd triangle, and so on?

I also have an index buffer, I wonder if I should go through this instead?

Thanks for the help!

Share this post


Link to post
Share on other sites
If you''re using an ID3DXMesh object, then you need to use the index buffer. Triangles are stored as indexed triangle lists. The first three indices are the first triangle, the next three indices are the second triangle, etc....

neneboricua

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by neneboricua19
If you''re using an ID3DXMesh object, then you need to use the index buffer. Triangles are stored as indexed triangle lists. The first three indices are the first triangle, the next three indices are the second triangle, etc....

neneboricua




can u show an example? like small example of how to get them and say draw a simple small VB just based on the first 3 nothing big just to u know show how to get the x,y,z of each triangles vertexs

Share this post


Link to post
Share on other sites
Okay, having a little bit of a problem...

I am able to retrieve index buffer information using code similar to this:

DWORD * pIndexList;
pMesh->LockIndexBuffer(D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK, (LPVOID*)&pIndexList);
DWORD index = (short) pIndexList[15];
pMesh->UnlockIndexBuffer();

Now, I have the correct indices for my VertexBuffer that I need in order to retrieve my triangles.

Question 1: How do I get a particular vertex from the vertex buffer?

Question 2: How do I transfer the X,Y,Z coords of my vertex to a D3DXVECTOR3?

If you aren't familiar with D3DXVECTOR3, you can build one by simply D3DXVECTOR3(X,Y,Z)

Thanks for the help, it is much appreciated!

[edited by - oxygen_728 on March 23, 2004 3:29:47 AM]

Share this post


Link to post
Share on other sites
1) You need to figure out what type of vertices (i.e. what bits of data they contain) are in the vertex buffer of the mesh, use GetFVF() to do that.

Suppose you found out all they had was a position and nothing else, the following is an example of how you might get at the vertex buffer (I didn''t test this, so some of it may not be 100% spot on):



D3DXVECTOR3 *pVertList;
pMesh->LockVertexBuffer(D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK, (LPVOID*)&pVertList);

D3DXVECTOR3 firstVertexPosition = pVertList[0];

pMesh->UnlockVertexBuffer();



Obviously, if you had mroe than just position in your vertices (interpret the FVF to figure it) then you''d have to make up some structure to represent the vertex and lock with that instead.

Hope that helps.

-Mezz

Share this post


Link to post
Share on other sites
The question about how to access the vertices of an ID3DXMesh object has been asked and answered many times on this forum. But for some reason I can''t find one of the threads so I''ll answer it again here...

If you only want to access the position of a vertex and not other things like normals, texture coordinates, etc... then you can get by with only using the stride of the vertex in bytes. What I mean is that once you have access to the data inside a vertex buffer, you can offset by the number of bytes in each vertex and then access the position value as a D3DXVECTOR3 variable.

But to make this information more complete, I will assume that you want to access all the data inside a mesh (position, normals, tex coords, etc...).

Remember that to access the vertices of an .x model, you need to know what format the vertices are in and have a struct defined that uses that format.

Your engine will usually want data to be in one of a certain number of formats because no engine can handle every single possible combination of vertex formats in the world.

The easiest way to do this is to clone the mesh so that it has the format that you want. In the code I''m about to post, I don''t do any error checking to keep things simple. You''ll want to check the results of return variables in your code. Say you want your model to have this format:

struct sModelVertex{
D3DXVECTOR3 vPosition;
D3DXVECTOR3 vNormal;
FLOAT tu, tv;
};
const DWORD D3DFVF_MODELVERTEX = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

Then you can make your model use this format by doing the following (do this during the init of the model):

// Using the 32bit flag means that you have to use a DWORD array to access your index buffer instead of a WORD array.

DWORD dwOptions = D3DXMESH_32BIT | D3DXMESH_MANAGED;
LPD3DXMESH pNewMesh = NULL;
m_pMesh->CloneMeshFVF( dwOptions, D3DFVF_MODELVERTEX, pd3dDevice, &pNewMesh );
SAFE_RELEASE( m_pMesh );
m_pMesh = pNewMesh;
pNewMesh = NULL;

// Generate the adjacency info of the mesh. I just have a

// temporary here but you may want to make this a class level

// variable so you can keep the adjacency info for other

// things.

DWORD *pAdjacency = new DWORD[3*m_pMesh->GetNumFaces()];
m_pMesh->GenerateAdjacency( 0.001f, pAdjacency );

// Just in case the mesh didn''t have normals before, we

// recompute them.

D3DXComputeNormals( m_pMesh, pAdjacency );
SAFE_DELETE_ARRAY( pAdjacency );

Remember that ID3DXMesh objects store triangles as an index triangle list. To access the data inside your mesh, you would then do this...

DWORD *pIndices = NULL;
sModelVertex *pVertices = NULL;
m_pMesh->LockIndexBuffer( D3DLOCK_READONLY, (VOID**)&pIndices );
m_pMesh->LockVertexBuffer( D3DLOCK_READONLY, (VOID**)&pVertices );

// Now we''ll access the data in each face (triangle) of the mesh

for( DWORD i = 0; i < m_pMesh->GetNumFaces(); i++ )
{
// Access data in first vertex of triangle and read the data..

pVertices[pIndices[i*3]].vPosition;
pVertices[pIndices[i*3]].vNormal;
pVertices[pIndices[i*3]].tu;
pVertices[pIndices[i*3]].tu;


// Access data in second vertex of triangle...

pVertices[pIndices[i*3+1]].vPosition;
pVertices[pIndices[i*3+1]].vNormal;
pVertices[pIndices[i*3+1]].tu;
pVertices[pIndices[i*3+1]].tv;

// Access data in third vertex of triangle...

pVertices[pIndices[i*3+2]].vPosition;
pVertices[pIndices[i*3+2]].vNormal;
pVertices[pIndices[i*3+2]].tu;
pVertices[pIndices[i*3+2]].tv;
}
m_pMesh->UnlockVertexBuffer();
m_pMesh->UnlockIndexBuffer();

Hope this helps,
neneboricua

Share this post


Link to post
Share on other sites
You are an enormous help, I can''t thank you enough.

I searched for "mesh", "vertex", and a combination of things and read through atleast 100 posts ... and never found an "end all" answer to my question. However, you have provided that and I thank you.


One last little bit of clarification...

I am starting to see why one would clone a mesh... I''m guessing that you would clone a mesh whose properties you are not sure of (unknown FVF)... into one whose properties you ARE sure of (Your newly created FVF).

I''m assuming that cloning a mesh will put the appropriate bits in the appropriate places based on your new FVF.

Fortunately, the meshes that I created and converted from 3dsMAX just happned to be in the same format as your example above (position, normal, texture coords (2)) 32 bytes long.

I am still a little curious as to how a program would look at a mesh (.x) and say...

"Oh, Look what we have here,

We have a Vertex Buffer full of Vertecies whose FVF has:
This many Vectors of ## size.
This many other options of ## size.
And they are in THIS order."


It is very difficult for me to find a way to do this (hours of searching); However, I am now capable of continuing on with my collision detection, but I am a little curious as to the streamlined way to do this for future projects.

Thanks again

Share this post


Link to post
Share on other sites
quote:
Original post by oxygen_728
I am still a little curious as to how a program would look at a mesh (.x) and say...

"Oh, Look what we have here,

We have a Vertex Buffer full of Vertecies whose FVF has:
This many Vectors of ## size.
This many other options of ## size.
And they are in THIS order."


It is very difficult for me to find a way to do this (hours of searching); However, I am now capable of continuing on with my collision detection, but I am a little curious as to the streamlined way to do this for future projects.


What it basically comes down to is taking a *really* close look at the FVF (or the VertexDeclaration when dealing with shaders) associated with a model.

The DX docs say that model vertices can have many different kinds of info, but that the info MUST be in a specific order. Take a look at this page from the DX docs:

http://msdn.microsoft.com/library/en-us/directx9_c/directx/graphics/programmingguide/gettingstarted/direct3dresources/vertexbuffers/vertexdeclaration/fixedfunctionfvfcodes.asp

The FVF will tell you how many bytes are in the vertex. The .x file is saved with data specifing how many vertices are in the model and an index buffer to use when rendering or accessing the vertices. You have to use bit-wise comparisons to check an unknown FVF for different features.

An FVF is really just a DWORD, so say you wanted to see if an FVF (and therefore, its associated vertex structure) contained a diffuse color. You would do this:

if( UNKNOWN_FVF & D3DFVF_DIFFUSE )
// Vertex contains a diffuse color.

In my opinion, I think that the best way is to just clone the mesh into a format that your engine can deal with. If a model has a whole bunch of blending weight information that your engine isn''t designed to use, does it really matter if that blending info is there?

If your engine isn''t designed to use it, then there is no harm in getting rid of it by cloning the mesh into a format that you know. Since you still have the original model, you can always update your engine to deal with blending weights and then use the model without cloning it and loosing that info.

Hope this clears things up for ya,
neneboricua

Share this post


Link to post
Share on other sites
The problem as stated above was:

"I am wanting to implement a collision detection algorithm which needs to be able to check a ray against each triangle of a mesh..."

D3DXIntersect is an easy way to do this.

Share this post


Link to post
Share on other sites