Mesh Combine(Mesh mesh)
    {
        Mesh combinedMesh = InstanceMesh(mesh);

        SubmeshInfo[] initialSubmeshData = new SubmeshInfo[mesh.subMeshCount];
        for (int submeshIndex = 0; submeshIndex < mesh.subMeshCount; submeshIndex++)
        {
            initialSubmeshData[submeshIndex].triangles = new List <int>();
            int[] submeshTriangles = mesh.GetTriangles(submeshIndex);
            for (int triangleIndex = 0; triangleIndex < submeshTriangles.Length; triangleIndex++)
            {
                initialSubmeshData[submeshIndex].triangles.Add(submeshTriangles[triangleIndex]);
            }
        }
        List <int> affectedSubmeshes = new List <int>();

        SubmeshInfo[] combinedSubInfo = new SubmeshInfo[submeshesToCombine.Length];
        for (int combinedSubmeshesIndex = 0; combinedSubmeshesIndex < submeshesToCombine.Length; combinedSubmeshesIndex++)
        {
            combinedSubInfo[combinedSubmeshesIndex].triangles = new List <int>();
            for (int affectedSubmeshesIndex = 0; affectedSubmeshesIndex < submeshesToCombine[combinedSubmeshesIndex].submeshesToCombine.Length; affectedSubmeshesIndex++)
            {
                int affectedSubmesh = submeshesToCombine[combinedSubmeshesIndex].submeshesToCombine[affectedSubmeshesIndex];
                combinedSubInfo[combinedSubmeshesIndex].triangles.AddRange(initialSubmeshData[affectedSubmesh].triangles);
                affectedSubmeshes.Add(affectedSubmesh);
            }
        }
        int unaffectedSubmeshCount = mesh.subMeshCount - affectedSubmeshes.Count;
        int newSubmeshCount        = submeshesToCombine.Length + unaffectedSubmeshCount;

        combinedMesh.subMeshCount = newSubmeshCount;

        int currentSubmesh = 0;

        for (int combinedSubmeshesIndex = 0; combinedSubmeshesIndex < combinedSubInfo.Length; combinedSubmeshesIndex++)
        {
            combinedMesh.SetTriangles(combinedSubInfo[combinedSubmeshesIndex].triangles, currentSubmesh);
            currentSubmesh++;
        }
        for (int originalSubmeshIndex = 0; originalSubmeshIndex < mesh.subMeshCount; originalSubmeshIndex++)
        {
            if (!affectedSubmeshes.Contains(originalSubmeshIndex))
            {
                combinedMesh.SetTriangles(initialSubmeshData[originalSubmeshIndex].triangles, currentSubmesh);
                currentSubmesh++;
            }
        }
        return(combinedMesh);
    }
Exemple #2
0
            public int Compare(SubmeshInfo x, SubmeshInfo y)
            {
                int result = x.VertexBufferIndex - y.VertexBufferIndex;

                if (result == 0)
                {
                    result = x.MaterialIndex - y.MaterialIndex;
                }

                if (result == 0)
                {
                    result = x.OriginalIndex - y.OriginalIndex;
                }

                return(result);
            }
	Mesh Combine (Mesh mesh)
	{
		Mesh combinedMesh = InstanceMesh(mesh);
		SubmeshInfo[] initialSubmeshData = new SubmeshInfo[mesh.subMeshCount];
		for (int submeshIndex = 0; submeshIndex < mesh.subMeshCount; submeshIndex++)
		{
			initialSubmeshData[submeshIndex].triangles = new List<int>();
			int[] submeshTriangles = mesh.GetTriangles(submeshIndex);
			for (int triangleIndex = 0; triangleIndex < submeshTriangles.Length; triangleIndex++)
			{
				initialSubmeshData[submeshIndex].triangles.Add(submeshTriangles[triangleIndex]);
			}
		}
		List<int> affectedSubmeshes = new List<int>();
		SubmeshInfo[] combinedSubInfo = new SubmeshInfo[submeshesToCombine.Length];
		for (int combinedSubmeshesIndex = 0; combinedSubmeshesIndex < submeshesToCombine.Length; combinedSubmeshesIndex++)
		{
			combinedSubInfo[combinedSubmeshesIndex].triangles = new List<int>();
			for (int affectedSubmeshesIndex = 0; affectedSubmeshesIndex < submeshesToCombine[combinedSubmeshesIndex].submeshesToCombine.Length; affectedSubmeshesIndex++)
			{
				int affectedSubmesh = submeshesToCombine[combinedSubmeshesIndex].submeshesToCombine[affectedSubmeshesIndex];
				combinedSubInfo[combinedSubmeshesIndex].triangles.AddRange(initialSubmeshData[affectedSubmesh].triangles);
				affectedSubmeshes.Add(affectedSubmesh);
			}
		}
		int unaffectedSubmeshCount = mesh.subMeshCount - affectedSubmeshes.Count;
		int newSubmeshCount = submeshesToCombine.Length + unaffectedSubmeshCount;
		combinedMesh.subMeshCount = newSubmeshCount;

		int currentSubmesh = 0;
		for (int combinedSubmeshesIndex = 0; combinedSubmeshesIndex < combinedSubInfo.Length; combinedSubmeshesIndex++)
		{
			combinedMesh.SetTriangles(combinedSubInfo[combinedSubmeshesIndex].triangles, currentSubmesh);
			currentSubmesh++;
		}
		for (int originalSubmeshIndex = 0; originalSubmeshIndex < mesh.subMeshCount; originalSubmeshIndex++)
		{
			if (!affectedSubmeshes.Contains(originalSubmeshIndex))
			{
				combinedMesh.SetTriangles(initialSubmeshData[originalSubmeshIndex].triangles, currentSubmesh);
				currentSubmesh++;
			}
		}
		return combinedMesh;
	}
Exemple #4
0
        // Build a SubmeshInfo for each GeometryContent.
        private SubmeshInfo[] BuildSubmeshInfos(MeshContent mesh, List <MeshContent> inputMorphs)
        {
            bool hasMorphTargets = (inputMorphs != null && inputMorphs.Count > 0);

            // A lookup table that maps each material to its index.
            // The key is the name of the XML file (string) or the local material (MaterialContent).
            var materialLookupTable = new Dictionary <object, int>();

            int numberOfSubmeshes = mesh.Geometry.Count;
            var submeshInfos      = new SubmeshInfo[numberOfSubmeshes];

            for (int i = 0; i < numberOfSubmeshes; i++)
            {
                var geometry = mesh.Geometry[i];

                // Build morph targets for current submesh.
                List <DRMorphTargetContent> morphTargets = null;
                if (hasMorphTargets)
                {
                    morphTargets = BuildMorphTargets(geometry, inputMorphs, i);
                    if (morphTargets != null && morphTargets.Count > 0)
                    {
                        // When morph targets are used remove the "BINORMAL" channel. (Otherwise,
                        // the number of vertex attributes would exceed the limit. Binormals need
                        // to be reconstructed from normal and tangent in the vertex shader.)
                        string binormalName          = VertexChannelNames.Binormal(0);
                        bool   containsTangentFrames = geometry.Vertices.Channels.Remove(binormalName);

                        if (containsTangentFrames)
                        {
                            // A submesh cannot use vertex colors and tangents at the same time.
                            // This would also exceed the vertex attribute limit.
                            string colorName = VertexChannelNames.Color(0);
                            if (geometry.Vertices.Channels.Contains(colorName))
                            {
                                geometry.Vertices.Channels.Remove(colorName);
                            }
                        }
                    }
                }

                var submeshInfo = new SubmeshInfo
                {
                    Geometry      = geometry,
                    OriginalIndex = i,
                    VertexBuffer  = geometry.Vertices.CreateVertexBuffer(),
                    MorphTargets  = morphTargets
                };
                submeshInfo.VertexBufferIndex = GetVertexBufferIndex(submeshInfo.VertexBuffer.VertexDeclaration);

                // Get material file or local material.
                object material = (object)GetExternalMaterial(mesh, geometry) ?? geometry.Material;
                if (material == null)
                {
                    var message = string.Format(CultureInfo.InvariantCulture, "Mesh \"{0}\" does not have a material.", mesh);
                    throw new InvalidContentException(message, mesh.Identity);
                }

                int materialIndex;
                if (!materialLookupTable.TryGetValue(material, out materialIndex))
                {
                    materialIndex = materialLookupTable.Count;
                    materialLookupTable.Add(material, materialIndex);
                }

                submeshInfo.MaterialIndex = materialIndex;
                submeshInfo.Material      = material;

                submeshInfos[i] = submeshInfo;
            }

            return(submeshInfos);
        }
Exemple #5
0
 public void EndSubmesh()
 {
     if (currentSubmesh != null)
     {
         submeshes.Add(currentSubmesh);
         currentSubmesh = null;
     }
 }
Exemple #6
0
 public void BeginSubmesh()
 {
     if(currentSubmesh == null)
         currentSubmesh = new SubmeshInfo();
 }