MeshCombineUtility.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. using UnityEngine;
  2. using System.Collections;
  3. public class MeshCombineUtility
  4. {
  5. public struct MeshInstance
  6. {
  7. public Mesh mesh;
  8. public int subMeshIndex;
  9. public Matrix4x4 transform;
  10. }
  11. public static Mesh Combine(MeshInstance[] combines, bool generateStrips)
  12. {
  13. int vertexCount = 0;
  14. int triangleCount = 0;
  15. int stripCount = 0;
  16. foreach (MeshInstance combine in combines)
  17. {
  18. if (combine.mesh)
  19. {
  20. vertexCount += combine.mesh.vertexCount;
  21. if (generateStrips)
  22. {
  23. // SUBOPTIMAL FOR PERFORMANCE
  24. int curStripCount = combine.mesh.GetTriangles(combine.subMeshIndex).Length;
  25. if (curStripCount != 0)
  26. {
  27. if (stripCount != 0)
  28. {
  29. if ((stripCount & 1) == 1)
  30. stripCount += 3;
  31. else
  32. stripCount += 2;
  33. }
  34. stripCount += curStripCount;
  35. }
  36. else
  37. {
  38. generateStrips = false;
  39. }
  40. }
  41. }
  42. }
  43. // Precomputed how many triangles we need instead
  44. if (!generateStrips)
  45. {
  46. foreach (MeshInstance combine in combines)
  47. {
  48. if (combine.mesh)
  49. {
  50. triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length;
  51. }
  52. }
  53. }
  54. Vector3[] vertices = new Vector3[vertexCount];
  55. Vector3[] normals = new Vector3[vertexCount];
  56. Vector4[] tangents = new Vector4[vertexCount];
  57. Vector2[] uv = new Vector2[vertexCount];
  58. Vector2[] uv1 = new Vector2[vertexCount];
  59. Color[] colors = new Color[vertexCount];
  60. int[] triangles = new int[triangleCount];
  61. int[] strip = new int[stripCount];
  62. int offset;
  63. offset = 0;
  64. foreach (MeshInstance combine in combines)
  65. {
  66. if (combine.mesh)
  67. Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform);
  68. }
  69. offset = 0;
  70. foreach (MeshInstance combine in combines)
  71. {
  72. if (combine.mesh)
  73. {
  74. Matrix4x4 invTranspose = combine.transform;
  75. invTranspose = invTranspose.inverse.transpose;
  76. CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose);
  77. }
  78. }
  79. offset = 0;
  80. foreach (MeshInstance combine in combines)
  81. {
  82. if (combine.mesh)
  83. {
  84. Matrix4x4 invTranspose = combine.transform;
  85. invTranspose = invTranspose.inverse.transpose;
  86. CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose);
  87. }
  88. }
  89. offset = 0;
  90. foreach (MeshInstance combine in combines)
  91. {
  92. if (combine.mesh)
  93. Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset);
  94. }
  95. offset = 0;
  96. foreach (MeshInstance combine in combines)
  97. {
  98. if (combine.mesh)
  99. Copy(combine.mesh.vertexCount, combine.mesh.uv2, uv1, ref offset);
  100. }
  101. offset = 0;
  102. foreach (MeshInstance combine in combines)
  103. {
  104. if (combine.mesh)
  105. CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset);
  106. }
  107. int triangleOffset = 0;
  108. int stripOffset = 0;
  109. int vertexOffset = 0;
  110. foreach (MeshInstance combine in combines)
  111. {
  112. if (combine.mesh)
  113. {
  114. if (generateStrips)
  115. {
  116. int[] inputstrip = combine.mesh.GetTriangles(combine.subMeshIndex);
  117. if (stripOffset != 0)
  118. {
  119. if ((stripOffset & 1) == 1)
  120. {
  121. strip[stripOffset + 0] = strip[stripOffset - 1];
  122. strip[stripOffset + 1] = inputstrip[0] + vertexOffset;
  123. strip[stripOffset + 2] = inputstrip[0] + vertexOffset;
  124. stripOffset += 3;
  125. }
  126. else
  127. {
  128. strip[stripOffset + 0] = strip[stripOffset - 1];
  129. strip[stripOffset + 1] = inputstrip[0] + vertexOffset;
  130. stripOffset += 2;
  131. }
  132. }
  133. for (int i = 0; i < inputstrip.Length; i++)
  134. {
  135. strip[i + stripOffset] = inputstrip[i] + vertexOffset;
  136. }
  137. stripOffset += inputstrip.Length;
  138. }
  139. else
  140. {
  141. int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex);
  142. for (int i = 0; i < inputtriangles.Length; i++)
  143. {
  144. triangles[i + triangleOffset] = inputtriangles[i] + vertexOffset;
  145. }
  146. triangleOffset += inputtriangles.Length;
  147. }
  148. vertexOffset += combine.mesh.vertexCount;
  149. }
  150. }
  151. Mesh mesh = new Mesh();
  152. mesh.name = "Combined Mesh";
  153. mesh.vertices = vertices;
  154. mesh.normals = normals;
  155. mesh.colors = colors;
  156. mesh.uv = uv;
  157. mesh.uv2 = uv1;
  158. mesh.tangents = tangents;
  159. if (generateStrips)
  160. mesh.SetTriangles(strip, 0);
  161. else
  162. mesh.triangles = triangles;
  163. return mesh;
  164. }
  165. static void Copy(int vertexcount, Vector3[] src, Vector3[] dst, ref int offset, Matrix4x4 transform)
  166. {
  167. for (int i = 0; i < src.Length; i++)
  168. dst[i + offset] = transform.MultiplyPoint(src[i]);
  169. offset += vertexcount;
  170. }
  171. static void CopyNormal(int vertexcount, Vector3[] src, Vector3[] dst, ref int offset, Matrix4x4 transform)
  172. {
  173. for (int i = 0; i < src.Length; i++)
  174. dst[i + offset] = transform.MultiplyVector(src[i]).normalized;
  175. offset += vertexcount;
  176. }
  177. static void Copy(int vertexcount, Vector2[] src, Vector2[] dst, ref int offset)
  178. {
  179. for (int i = 0; i < src.Length; i++)
  180. dst[i + offset] = src[i];
  181. offset += vertexcount;
  182. }
  183. static void CopyColors(int vertexcount, Color[] src, Color[] dst, ref int offset)
  184. {
  185. for (int i = 0; i < src.Length; i++)
  186. dst[i + offset] = src[i];
  187. offset += vertexcount;
  188. }
  189. static void CopyTangents(int vertexcount, Vector4[] src, Vector4[] dst, ref int offset, Matrix4x4 transform)
  190. {
  191. for (int i = 0; i < src.Length; i++)
  192. {
  193. Vector4 p4 = src[i];
  194. Vector3 p = new Vector3(p4.x, p4.y, p4.z);
  195. p = transform.MultiplyVector(p).normalized;
  196. dst[i + offset] = new Vector4(p.x, p.y, p.z, p4.w);
  197. }
  198. offset += vertexcount;
  199. }
  200. }