Read Vertices from a mesh

Started by
3 comments, last by DonnieDarko 18 years, 3 months ago
Hi, i wanna read vertices from a mesh. the problem is: i dont know the format of the vertices. I tried to read the vertex format from the mesh and pass the type via the GetType method to the lockvertex buffer method:

VertexFormats meshVertexFormat = mesh.VertexFormat;
Array verts = mesh.LockVertexBuffer(meshVertexFormat.GetType(), LockFlags.None, mesh.NumberVertices);

but if i execute this code ill get an unhandled exception of type 'System.ArgumentException': Additional information: Object contains non-primitive or non-blittable data. and even if this would work i still wouldnt know how to cast verts to the appropriate array type. so i need something like this (which doesnt compile in this form):

Type t = mesh.VertexFormat.GetType();
t[] verts = (t[])mesh.LockVertexBuffer(t, LockFlags.None, mesh.NumberVertices);

anybody knows how to get the vertices? (maybe with some kind of reflection?)
Advertisement
In fact you do not really know the format of vertices of your mesh.you can use DirectX's CustomVertex type, but also you can implement your own custom vertex type.

CustomVertex.PositionNormalTextured[] modelVertices;modelVertices = (CustomVertex.PositionNormalTextured[])mesh.VertexBuffer.Lock(/*_VERTEXSTART_*/, typeof(CustomVertex.PositionNormalTextured), LockFlags.ReadOnly, /*_VERTEXCOUNT_*/);                vertexBuffers = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), /*_VERTEXCOUNT_*/, device, Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Default);                vertexBuffers.SetData(modelVertices, 0, LockFlags.None);


The concept is like that.Maybe this snippet helps you
wake up your sleepin' brains...
i guess u didnt understand me. i DONT know which vertex format the mesh has so i cant just use CustomVertex.PositionNormalTextured. It also could be PositionOnly or anything else. Did nobody ever had this problem? ;(
I've done this sort of thing before, but I've not done it via MDX...

There are two approaches:

1. Identify the format (in Native DX you can extract the FVF/declaration and work backwards) and then try and match it up to an appropriate format. This makes for slightly clunky code and you can only accept a pre-determined number of formats.

2. Identify the components you are actually interested in extracting (e.g. if you only want the diffuse colour or the tex coords) and construct a vertex structure that matches the desired output. Then determine if the mesh's format is a superset of your desired output (e.g. it contains as much or more information), if it's not then the call fails - the input mesh doesn't have the appropriate data. Otherwise, clone the mesh to a temporary instance with your desired format. You now know the vertex format of the temporary mesh and can extract as you wish.

The second one is a little more involved, but is pretty robust..

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

The UVAtlas SDK sample contains the CD3DXCrackDecl class which simplifies reading and writing arbitrary vertex components. Here's some sample code reading vertex positions from ID3DXMesh:

void *pVertexData;hr = mesh->LockVertexBuffer(D3DLOCK_NOSYSLOCK, &pVertexData);D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];hr = mesh->GetDeclaration(decl);CD3DXCrackDecl cd;cd.SetDeclaration(decl);cd.SetStreamSource(0, pVertexData, 0);D3DXVECTOR3 pos;int vertexIndex = 0;cd.DecodeSemantic(D3DDECLUSAGE_POSITION, 0, vertexIndex, (float*)&pos, 3);


It's not managed, but maybe the CD3DXCrackDecl class can be of some help to you.

This topic is closed to new replies.

Advertisement