public void Simplify(WMesh inputMesh, WMesh outputMesh, float quality) { var enableLogging = false; int totalTriangleCount; var sourceMesh = ToMeshDecimatorMesh(inputMesh, out totalTriangleCount); int targetTriangleCount = Mathf.CeilToInt(totalTriangleCount * quality); var algorithm = MeshDecimation.CreateAlgorithm(Algorithm.Default); algorithm.KeepLinkedVertices = false; DecimationAlgorithm.StatusReportCallback statusCallback = (iteration, tris, currentTris, targetTris) => { Debug.LogFormat("Iteration {0}: tris {1} current {2} target {3}", iteration, tris, currentTris, targetTris); }; if (enableLogging) { algorithm.StatusReport += statusCallback; } var destMesh = MeshDecimation.DecimateMesh(algorithm, sourceMesh, targetTriangleCount); if (enableLogging) { algorithm.StatusReport -= statusCallback; } FromMeshDecimatorMesh(destMesh, false, ref outputMesh); }
public static WorkingMesh ToWorkingMesh(this Mesh mesh) { var wm = new WorkingMesh(); mesh.ApplyToWorkingMesh(wm); return(wm); }
public static void ApplyToWorkingMesh(this Mesh mesh, WorkingMesh wm) { #if UNITY_2017_3_OR_NEWER wm.indexFormat = mesh.indexFormat; #endif wm.vertices = mesh.vertices; wm.normals = mesh.normals; wm.tangents = mesh.tangents; wm.uv = mesh.uv; wm.uv2 = mesh.uv2; wm.colors = mesh.colors; wm.boneWeights = mesh.boneWeights; wm.bindposes = mesh.bindposes; wm.subMeshCount = mesh.subMeshCount; for (int i = 0; i < mesh.subMeshCount; i++) { wm.SetTriangles(mesh.GetTriangles(i), i); } wm.name = mesh.name; wm.bounds = mesh.bounds; }
public void Simplify(Mesh inputMesh, Mesh outputMesh, float quality) { var meshSimplifier = new MeshSimplifier(); meshSimplifier.Vertices = inputMesh.vertices; meshSimplifier.Normals = inputMesh.normals; meshSimplifier.Tangents = inputMesh.tangents; meshSimplifier.UV1 = inputMesh.uv; meshSimplifier.UV2 = inputMesh.uv2; meshSimplifier.UV3 = inputMesh.uv3; meshSimplifier.UV4 = inputMesh.uv4; meshSimplifier.Colors = inputMesh.colors; var triangles = new int[inputMesh.subMeshCount][]; for (var submesh = 0; submesh < inputMesh.subMeshCount; submesh++) { triangles[submesh] = inputMesh.GetTriangles(submesh); } meshSimplifier.AddSubMeshTriangles(triangles); meshSimplifier.SimplifyMesh(quality); outputMesh.vertices = meshSimplifier.Vertices; outputMesh.normals = meshSimplifier.Normals; outputMesh.tangents = meshSimplifier.Tangents; outputMesh.uv = meshSimplifier.UV1; outputMesh.uv2 = meshSimplifier.UV2; outputMesh.uv3 = meshSimplifier.UV3; outputMesh.uv4 = meshSimplifier.UV4; outputMesh.colors = meshSimplifier.Colors; outputMesh.subMeshCount = meshSimplifier.SubMeshCount; for (var submesh = 0; submesh < outputMesh.subMeshCount; submesh++) { outputMesh.SetTriangles(meshSimplifier.GetSubMeshTriangles(submesh), submesh); } }
public void Simplify(Mesh inputMesh, Mesh outputMesh, float quality) { Vector3[] vertices = inputMesh.vertices; Vector2[] uv = inputMesh.uv; Vector2[] uv2 = inputMesh.uv2; Color[] colors = inputMesh.colors; Vector3[] normals = inputMesh.normals; Vector4[] tangents = inputMesh.tangents; var usedVertices = new Dictionary <int, Vector3>(); var submeshTriangles = new Dictionary <int, List <int> >(); for (int i = 0; i < inputMesh.subMeshCount; i++) { var triangles = new List <int>(inputMesh.GetTriangles(i)); var targetCount = Mathf.FloorToInt(triangles.Count * quality); targetCount = Mathf.Max(0, targetCount - targetCount % 3); var random = new System.Random(); while (triangles.Count > targetCount) { var randomTriangle = Mathf.CeilToInt((float)random.NextDouble() * (triangles.Count - 1)); randomTriangle -= randomTriangle % 3; triangles.RemoveRange(randomTriangle, 3); } for (int t = 0; t < triangles.Count; t++) { var index = triangles[t]; usedVertices[index] = vertices[index]; } submeshTriangles[i] = triangles; } var trimmedVertices = new List <Vector3>(); var trimmedUVs = new List <Vector2>(); var trimmedUV2s = new List <Vector2>(); var trimmedColors = new List <Color>(); var trimmedNormals = new List <Vector3>(); var trimmedTangents = new List <Vector4>(); var vertexRemap = new Dictionary <int, int>(); for (int i = 0; i < vertices.Length; i++) { Vector3 vertex; if (usedVertices.TryGetValue(i, out vertex)) { vertexRemap[i] = trimmedVertices.Count; trimmedVertices.Add(vertex); if (uv.Length > 0) { trimmedUVs.Add(uv[i]); } if (uv2.Length > 0) { trimmedUV2s.Add(uv2[i]); } if (colors.Length > 0) { trimmedColors.Add(colors[i]); } if (normals.Length > 0) { trimmedNormals.Add(normals[i]); } if (tangents.Length > 0) { trimmedTangents.Add(tangents[i]); } } } outputMesh.vertices = trimmedVertices.ToArray(); for (int i = 0; i < inputMesh.subMeshCount; i++) { var triangles = submeshTriangles[i]; for (int t = 0; t < triangles.Count; t++) { triangles[t] = vertexRemap[triangles[t]]; } outputMesh.SetTriangles(triangles.ToArray(), i); } outputMesh.uv = trimmedUVs.ToArray(); outputMesh.uv2 = trimmedUV2s.ToArray(); outputMesh.colors = trimmedColors.ToArray(); outputMesh.normals = trimmedNormals.ToArray(); outputMesh.tangents = trimmedTangents.ToArray(); outputMesh.RecalculateBounds(); outputMesh.RecalculateNormals(); outputMesh.RecalculateTangents(); }
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); }