merging two meshes

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

Recommended Posts

I have two mesh: SourceMesh and MergeMesh, both have Position, Normal and Text1, both have identical Position and Normals, but has diferent texture coordinates I like to create another one, having all the data in the SourceMesh, plus another texture channel which I have from the second. This is what I had done:
        public struct myVertex
{
public Vector3 Position;
public Vector3 Normal;
public Vector2 Text1;
public Vector2 Text2;
}

//--------------------------
VertexElement[] elements = new VertexElement[]
{
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
new VertexElement(0, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
new VertexElement(0, 32, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 1),
VertexElement.VertexDeclarationEnd
};

Mesh NewMesh = new Mesh(SourceMesh.NumberFaces, SourceMesh.NumberFaces * 3, SourceMesh.Options.Value, elements, Form_Main.Form.device);

// Set the indices into the NewMesh
short[] aIndices = (short[])SourceMesh.LockIndexBuffer(typeof(short), LockFlags.ReadOnly, SourceMesh.NumberFaces * 3);
NewMesh.SetIndexBufferData(aIndices, LockFlags.None);

// Create 3 vertices per face
myVertex[] NewVertex = new myVertex[NewMesh.NumberFaces * 3];

CustomVertex.PositionNormalTextured[] SourceVertex = (CustomVertex.PositionNormalTextured[])SourceMesh.LockVertexBuffer(typeof(CustomVertex.PositionNormalTextured), LockFlags.ReadOnly, SourceMesh.NumberVertices);
CustomVertex.PositionNormalTextured[] MergeVertex = (CustomVertex.PositionNormalTextured[])MergeMesh.LockVertexBuffer(typeof(CustomVertex.PositionNormalTextured), LockFlags.ReadOnly, MergeMesh.NumberVertices);

// Copy the info
foreach (short Index in aIndices)
{
NewVertex[Index].Position = SourceVertex[aIndices[Index]].Position;
NewVertex[Index].Normal   = SourceVertex[aIndices[Index]].Normal;
NewVertex[Index].Text1 = new Vector2(SourceVertex[aIndices[Index]].Tu, SourceVertex[aIndices[Index]].Tv);
NewVertex[Index].Text2 = new Vector2(MergeVertex[aIndices[Index]].Tu, MergeVertex[aIndices[Index]].Tv);
}

// Set the vertices into NewMesh
NewMesh.SetVertexBufferData(NewVertex, LockFlags.None);

MergeMesh.UnlockVertexBuffer();
SourceMesh.UnlockVertexBuffer();

SourceMesh.UnlockIndexBuffer();

// Copy attributes
int[] SourceAttributes = SourceMesh.LockAttributeBufferArray(LockFlags.None);
int[] NewAttributes = NewMesh.LockAttributeBufferArray(LockFlags.None);
SourceAttributes.CopyTo(NewAttributes, 0);
NewMesh.UnlockAttributeBuffer();
SourceMesh.UnlockAttributeBuffer();

NewMesh.SetAttributeTable(SourceMesh.GetAttributeTable());


The problem is that in fact it create another mesh, but when I render the new one, there are some faces which are ok, but there are others that take random vertices in the mesh. So it looks like a bunch of random triangles with the form of the source mesh. Any tip why this code doesn't work?

Share on other sites
I don't have time to step through your code, but you might want to check out the D3DXConcatenateMeshes() function since you are already using meshes.

Share on other sites
what the D3DXConcatenateMeshes() does is to attash to meshes
(newfaces = sourceFaces + mergeFaces),
what I want to do is to keep the original sourceFaces and add a second texture channel from the mergeMesh.

I fix a bit the code and now it generate the correct positions. The problem was that the vertex ordering of the newMesh is not same of the sourceMesh since I expand the vertices into 3 unique vertices per face, and so I have to generate new indices, not just copying the original index buffer from the source.

But now arrice another problem, I what to keep the attributes. So I have to copy the source attribute buffer to the newBuffer and this is what I do:

int[] FromAttributes = SourceMesh.LockAttributeBufferArray(LockFlags.None);int[] ToAttributes = NewMesh.LockAttributeBufferArray(LockFlags.None);    // Copy the complete array    FromAttributes.CopyTo(ToAttributes, 0);NewMesh.UnlockAttributeBuffer();SourceMesh.UnlockAttributeBuffer();

That code should copy the attributes from the source mesh to the newMesh. But inmediatly after that I did this just to check:

int[] Attributess = NewMesh.LockAttributeBufferArray(LockFlags.None);

and Attributess returns an array with the correct length but filled of ceros.

Whats the problem? Why the buffer is not copying? Am I missing something? Maybe some flag?