Create a TriangleMeshObject from ModelInstance

Aug 6, 2010 at 8:20 PM


I'm trying to create a trianglemesh object using the new Jitter physics engine but I cant find away to extract the mesh data. Specifically the vertex and index buffers found in the standard model class. Here is the standard code:

public void ExtractData(List<JVector> vertices, List<JOctree.TriangleVertexIndices> indices, Model model)
            Matrix[] bones_ = new Matrix[model.Bones.Count];
            foreach (ModelMesh mm in model.Meshes)
                Matrix xform = bones_[mm.ParentBone.Index];
                foreach (ModelMeshPart mmp in mm.MeshParts)
                    int offset = vertices.Count;
                    Vector3[] a = new Vector3[mmp.NumVertices];
                    mm.VertexBuffer.GetData<Vector3>(mmp.StreamOffset + mmp.BaseVertex * mmp.VertexStride,
                        a, 0, mmp.NumVertices, mmp.VertexStride);
                    for (int i = 0; i != a.Length; ++i)
                        Vector3.Transform(ref a[i], ref xform, out a[i]);

                    for (int i = 0; i < a.Length; i++) vertices.Add(new JVector(a[i].X, a[i].Y, a[i].Z));

                    if (mm.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
                        throw new Exception(
                            String.Format("Model uses 32-bit indices, which are not supported."));
                    short[] s = new short[mmp.PrimitiveCount * 3];
                    mm.IndexBuffer.GetData<short>(mmp.StartIndex * 2, s, 0, mmp.PrimitiveCount * 3);
                    JOctree.TriangleVertexIndices[] tvi = new JOctree.TriangleVertexIndices[mmp.PrimitiveCount];
                    for (int i = 0; i != tvi.Length; ++i)
                        tvi[i].I0 = s[i * 3 + 2] + offset;
                        tvi[i].I1 = s[i * 3 + 1] + offset;
                        tvi[i].I2 = s[i * 3 + 0] + offset;
            for (int i = 0; i < vertices.Count; i++)
                vertices[i] = Conversion.ToJitterVector(Matrix.Multiply(Matrix.CreateTranslation(Conversion.ToXNAVector(vertices[i])), Matrix.CreateScale(2f)).Translation); //Matrix.CreateScale(0.35f)).Translation);

Maybe this has already been done by the processor and I can just pass in the geometryData's vertices and indices??

Thanks for any help :)


Aug 9, 2010 at 8:39 PM

Unfortunately it's not going to be that simple... There are a number of problems preventing this.

Firstly, the vertex and index buffers are all internal / private objects. So direct access would require exposing them (not ideal).
A work around is to add data extraction methods into the IVertices/IIndices interfaces. This actually works quite nicely.

This just exposes another problem. All vertex / index buffers in Xen are created as WriteOnly. So you can't read back the data.
You don't want to make all vertex buffers read/write, so it would need to be a buffer specific flag to allow this. Then, that adds the additional problem that the model would require a property flagging it to create read/write vertex data too!

So you can see, it's not simple set of changes. I'm still thinking if there is a better way to do this, but there may not be.

Btw, remember that raw triangle meshes are also extremely slow to perform collision tests against. So just make sure this is exactly what you need. if it's for a character model (for example) it may be simpler to just extract bounding spheres on the bones. I'll have a mess about

Aug 10, 2010 at 3:45 PM
Edited Aug 10, 2010 at 3:46 PM
Hey StatusUnknown, Thanks for the reply, but I found a much easier solution :) I just created a copy of the model to be imported using the standard xna processor and extract the data from that, it seems to be working perfectly! Sorry about that :) Love the engine, and looking forward to version 2! Thanks again.
Aug 10, 2010 at 5:24 PM

hehe :D

Nice. Just make sure it's not duplicating textures!

I'll make sure 2 has the ability to extract the data if needed.