private UnityEngine.Mesh ConvertMesh(MeshDecimator.Mesh fatMesh) { if (fatMesh.VertexCount == 0) { return(new UnityEngine.Mesh()); } // Merge Same Verts Dictionary <MeshDecimator.Math.Vector3d, int> newVertIndexes = new Dictionary <MeshDecimator.Math.Vector3d, int>(); List <MeshDecimator.Math.Vector3d> newVerts = new List <MeshDecimator.Math.Vector3d>(); int[] newIndicies = new int[fatMesh.Indices.Length]; for (int i = 0; i < fatMesh.Vertices.Length; i++) { if (!newVertIndexes.ContainsKey(fatMesh.Vertices[i])) { newVerts.Add(fatMesh.Vertices[i]); newVertIndexes[fatMesh.Vertices[i]] = newVerts.Count - 1; } } for (int i = 0; i < fatMesh.Indices.Length; i++) { MeshDecimator.Math.Vector3d v = fatMesh.Vertices[fatMesh.Indices[i]]; newIndicies[i] = newVertIndexes[v]; } MeshDecimator.Mesh mergedMesh = new MeshDecimator.Mesh(newVerts.ToArray(), newIndicies); UnityEngine.Mesh result = MeshDecimator.Unity.MeshDecimatorUtility.DecimateMeshBasic(mergedMesh, Matrix4x4.identity, m_decimatePct, true, Callback); result.RecalculateBounds(); result.RecalculateNormals(); Vector2[] uv = Unwrapping.GeneratePerTriangleUV(result); MeshUtility.SetPerTriangleUV2(result, uv); // Unwrapping.GenerateSecondaryUVSet(result); return(result); }
static void FromMeshDecimatorMesh(DMesh mesh, bool recalculateNormals, ref WMesh destMesh) { if (recalculateNormals) { // If we recalculate the normals, we also recalculate the tangents mesh.RecalculateNormals(); mesh.RecalculateTangents(); } int subMeshCount = mesh.SubMeshCount; var newNormals = FromVector3(mesh.Normals); var newTangents = FromVector4(mesh.Tangents); var newUV1 = FromVector2(mesh.UV1); var newUV2 = FromVector2(mesh.UV2); var newUV3 = FromVector2(mesh.UV3); var newUV4 = FromVector2(mesh.UV4); var newColors = FromColor(mesh.Colors); //var newBoneWeights = FromSimplifyBoneWeights(mesh.BoneWeights); //if (bindposes != null) newMesh.bindposes = bindposes; destMesh.subMeshCount = subMeshCount; destMesh.vertices = FromVector3d(mesh.Vertices); if (newNormals != null) { destMesh.normals = newNormals; } if (newTangents != null) { destMesh.tangents = newTangents; } if (newUV1 != null) { destMesh.uv = newUV1; } if (newUV2 != null) { destMesh.uv2 = newUV2; } if (newUV3 != null) { destMesh.uv3 = newUV3; } if (newUV4 != null) { destMesh.uv4 = newUV4; } if (newColors != null) { destMesh.colors = newColors; } //if (newBoneWeights != null) // newMesh.boneWeights = newBoneWeights; for (int i = 0; i < subMeshCount; i++) { var subMeshIndices = mesh.GetIndices(i); destMesh.SetTriangles(subMeshIndices, i); } destMesh.RecalculateBounds(); }
DMesh ToMeshDecimatorMesh(WMesh mesh, out int totalTriangleCount) { var vertices = ToVector3d(mesh.vertices); int subMeshCount = mesh.subMeshCount; var meshNormals = mesh.normals; var meshTangents = mesh.tangents; var meshUV1 = mesh.uv; var meshUV2 = mesh.uv2; var meshUV3 = mesh.uv3; var meshUV4 = mesh.uv4; var meshColors = mesh.colors; //var meshBoneWeights = mesh.boneWeights; //var meshBindposes = mesh.bindposes; totalTriangleCount = 0; var meshIndices = new int[subMeshCount][]; for (int i = 0; i < subMeshCount; i++) { meshIndices[i] = mesh.GetTriangles(i); totalTriangleCount += meshIndices[i].Length / 3; } var dmesh = new DMesh(vertices, meshIndices); if (meshNormals != null && meshNormals.Length > 0) { dmesh.Normals = ToVector3(meshNormals); } if (meshTangents != null && meshTangents.Length > 0) { dmesh.Tangents = ToVector4(meshTangents); } if (meshUV1 != null && meshUV1.Length > 0) { dmesh.UV1 = ToVector2(meshUV1); } if (meshUV2 != null && meshUV2.Length > 0) { dmesh.UV2 = ToVector2(meshUV2); } if (meshUV3 != null && meshUV3.Length > 0) { dmesh.UV3 = ToVector2(meshUV3); } if (meshUV4 != null && meshUV4.Length > 0) { dmesh.UV4 = ToVector2(meshUV4); } if (meshColors != null && meshColors.Length > 0) { dmesh.Colors = ToVector4(meshColors); } //if (meshBoneWeights != null && meshBoneWeights.Length > 0) // dmesh.BoneWeights = ToSimplifyBoneWeights(meshBoneWeights); return(dmesh); }
public async void SimplifyObj(string sourcePath, string destPath, float quality) { simplifyTask = new Task(() => { quality = MathHelper.Clamp01(quality); ObjMesh sourceObjMesh = new ObjMesh(); sourceObjMesh.ReadFile(sourcePath); var sourceVertices = sourceObjMesh.Vertices; var sourceNormals = sourceObjMesh.Normals; var sourceTexCoords2D = sourceObjMesh.TexCoords2D; var sourceTexCoords3D = sourceObjMesh.TexCoords3D; var sourceSubMeshIndices = sourceObjMesh.SubMeshIndices; var sourceMesh = new MeshDecimator.Mesh(sourceVertices, sourceSubMeshIndices); sourceMesh.Normals = sourceNormals; if (sourceTexCoords2D != null) { sourceMesh.SetUVs(0, sourceTexCoords2D); } else if (sourceTexCoords3D != null) { sourceMesh.SetUVs(0, sourceTexCoords3D); } int currentTriangleCount = 0; for (int i = 0; i < sourceSubMeshIndices.Length; i++) { currentTriangleCount += (sourceSubMeshIndices[i].Length / 3); } int targetTriangleCount = (int)Math.Ceiling(currentTriangleCount * quality); string info_1 = string.Format("Input: {0} vertices, {1} triangles (target {2}) \n", sourceVertices.Length, currentTriangleCount, targetTriangleCount); // Console.WriteLine(info_1); simplifyInfo.Invoke(info_1); var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Reset(); stopwatch.Start(); var algorithm = MeshDecimation.CreateAlgorithm(Algorithm.Default); algorithm.Verbose = true; MeshDecimator.Mesh destMesh = MeshDecimation.DecimateMesh(algorithm, sourceMesh, targetTriangleCount); stopwatch.Stop(); var destVertices = destMesh.Vertices; var destNormals = destMesh.Normals; var destIndices = destMesh.GetSubMeshIndices(); ObjMesh destObjMesh = new ObjMesh(destVertices, destIndices); destObjMesh.Normals = destNormals; destObjMesh.MaterialLibraries = sourceObjMesh.MaterialLibraries; destObjMesh.SubMeshMaterials = sourceObjMesh.SubMeshMaterials; if (sourceTexCoords2D != null) { var destUVs = destMesh.GetUVs2D(0); destObjMesh.TexCoords2D = destUVs; } else if (sourceTexCoords3D != null) { var destUVs = destMesh.GetUVs3D(0); destObjMesh.TexCoords3D = destUVs; } destObjMesh.WriteFile(destPath); int outputTriangleCount = 0; for (int i = 0; i < destIndices.Length; i++) { outputTriangleCount += (destIndices[i].Length / 3); } float reduction = (float)outputTriangleCount / (float)currentTriangleCount; float timeTaken = (float)stopwatch.Elapsed.TotalSeconds; string info_2 = string.Format("Output: {0} vertices, {1} triangles ({2} reduction; {3:0.0000} sec) \n", destVertices.Length, outputTriangleCount, reduction, timeTaken); // Console.WriteLine(info_2); simplifyInfo.Invoke(info_2); simplifyInfo.Invoke("finish"); DisposeTask(); }); simplifyTask.Start(); }