MegaCacheMeshConstructor.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. public class MegaCacheMatFaces
  4. {
  5. public List<int> tris = new List<int>();
  6. }
  7. public class MegaCacheFace
  8. {
  9. public MegaCacheFace(Vector3 _v0, Vector3 _v1, Vector3 _v2, Vector3 _n0, Vector3 _n1, Vector3 _n2, Vector2 _uv0, Vector2 _uv1, Vector2 _uv2, int _sg, int _mid)
  10. {
  11. v30 = _v0;
  12. v31 = _v1;
  13. v32 = _v2;
  14. uv0 = _uv0;
  15. uv1 = _uv1;
  16. uv2 = _uv2;
  17. n0 = _n0;
  18. n1 = _n1;
  19. n2 = _n2;
  20. smthgrp = _sg;
  21. mtlid = _mid;
  22. }
  23. public int v0,v1,v2;
  24. public Vector3 v30;
  25. public Vector3 v31;
  26. public Vector3 v32;
  27. public Vector3 n0 = Vector3.zero;
  28. public Vector3 n1 = Vector3.zero;
  29. public Vector3 n2 = Vector3.zero;
  30. public Vector2 uv0;
  31. public Vector2 uv1;
  32. public Vector2 uv2;
  33. public Vector2 uv10;
  34. public Vector2 uv11;
  35. public Vector2 uv12;
  36. public Color col1;
  37. public Color col2;
  38. public Color col3;
  39. public int smthgrp;
  40. public int mtlid;
  41. public Vector3 faceNormal = Vector3.zero;
  42. public int t0,t1,t2;
  43. }
  44. public class MegaCacheMeshConstructor
  45. {
  46. static public List<Vector3> verts = new List<Vector3>();
  47. static public List<Vector3> norms = new List<Vector3>();
  48. static public List<Vector2> uvs = new List<Vector2>();
  49. static public List<int> tris = new List<int>();
  50. static public List<MegaCacheMatFaces> matfaces = new List<MegaCacheMatFaces>();
  51. public class MegaCacheFaceGrid
  52. {
  53. public List<int> verts = new List<int>();
  54. }
  55. static public MegaCacheFaceGrid[,,] checkgrid;
  56. static public Vector3 min;
  57. static public Vector3 max;
  58. static public Vector3 size;
  59. static public int subdivs = 16; //16;
  60. static public void BuildGrid(Vector3[] verts)
  61. {
  62. checkgrid = new MegaCacheFaceGrid[subdivs, subdivs, subdivs];
  63. min = verts[0];
  64. max = verts[0];
  65. for ( int i = 1; i < verts.Length; i++ )
  66. {
  67. Vector3 p = verts[i];
  68. if ( p.x < min.x )
  69. min.x = p.x;
  70. if ( p.x > max.x )
  71. max.x = p.x;
  72. if ( p.y < min.y )
  73. min.y = p.y;
  74. if ( p.y > max.y )
  75. max.y = p.y;
  76. if ( p.z < min.z )
  77. min.z = p.z;
  78. if ( p.z > max.z )
  79. max.z = p.z;
  80. }
  81. size = max - min;
  82. }
  83. static public void BuildTangents(Mesh mesh)
  84. {
  85. int triangleCount = mesh.triangles.Length;
  86. int vertexCount = mesh.vertices.Length;
  87. Vector3[] tan1 = new Vector3[vertexCount];
  88. Vector3[] tan2 = new Vector3[vertexCount];
  89. Vector4[] tangents = new Vector4[vertexCount];
  90. Vector3[] verts = mesh.vertices;
  91. Vector2[] uvs = mesh.uv;
  92. Vector3[] norms = mesh.normals;
  93. int[] tris = mesh.triangles;
  94. if ( uvs.Length > 0 )
  95. {
  96. for ( int a = 0; a < triangleCount; a += 3 )
  97. {
  98. long i1 = tris[a];
  99. long i2 = tris[a + 1];
  100. long i3 = tris[a + 2];
  101. Vector3 v1 = verts[i1];
  102. Vector3 v2 = verts[i2];
  103. Vector3 v3 = verts[i3];
  104. Vector2 w1 = uvs[i1];
  105. Vector2 w2 = uvs[i2];
  106. Vector2 w3 = uvs[i3];
  107. float x1 = v2.x - v1.x;
  108. float x2 = v3.x - v1.x;
  109. float y1 = v2.y - v1.y;
  110. float y2 = v3.y - v1.y;
  111. float z1 = v2.z - v1.z;
  112. float z2 = v3.z - v1.z;
  113. float s1 = w2.x - w1.x;
  114. float s2 = w3.x - w1.x;
  115. float t1 = w2.y - w1.y;
  116. float t2 = w3.y - w1.y;
  117. float r = 1.0f / (s1 * t2 - s2 * t1);
  118. Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
  119. Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
  120. tan1[i1] += sdir;
  121. tan1[i2] += sdir;
  122. tan1[i3] += sdir;
  123. tan2[i1] += tdir;
  124. tan2[i2] += tdir;
  125. tan2[i3] += tdir;
  126. }
  127. for ( int a = 0; a < vertexCount; a++ )
  128. {
  129. Vector3 n = norms[a].normalized;
  130. Vector3 t = tan1[a].normalized;
  131. Vector3.OrthoNormalize(ref n, ref t);
  132. tangents[a].x = t.x;
  133. tangents[a].y = t.y;
  134. tangents[a].z = t.z;
  135. tangents[a].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
  136. tangents[a] = tangents[a].normalized;
  137. }
  138. mesh.tangents = tangents;
  139. }
  140. }
  141. }
  142. public class MegaCacheMeshConstructorOBJ : MegaCacheMeshConstructor
  143. {
  144. static int FindVertGrid(Vector3 p, Vector3 n, Vector2 uv)
  145. {
  146. int sd = subdivs - 1;
  147. int gx = 0;
  148. int gy = 0;
  149. int gz = 0;
  150. if ( size.x > 0.0f )
  151. gx = (int)(sd * ((p.x - min.x) / size.x));
  152. if ( size.y > 0.0f )
  153. gy = (int)(sd * ((p.y - min.y) / size.y));
  154. if ( size.z > 0.0f )
  155. gz = (int)(sd * ((p.z - min.z) / size.z));
  156. MegaCacheFaceGrid fg = checkgrid[gx, gy, gz];
  157. if ( fg == null )
  158. {
  159. fg = new MegaCacheFaceGrid();
  160. checkgrid[gx, gy, gz] = fg;
  161. }
  162. for ( int i = 0; i < fg.verts.Count; i++ )
  163. {
  164. int ix = fg.verts[i];
  165. if ( verts[ix].x == p.x && verts[ix].y == p.y && verts[ix].z == p.z )
  166. {
  167. if ( norms[ix].x == n.x && norms[ix].y == n.y && norms[ix].z == n.z )
  168. {
  169. if ( uvs[ix].x == uv.x && uvs[ix].y == uv.y )
  170. return ix;
  171. }
  172. }
  173. }
  174. fg.verts.Add(verts.Count);
  175. verts.Add(p);
  176. norms.Add(n);
  177. uvs.Add(uv);
  178. return verts.Count - 1;
  179. }
  180. static public void Construct(List<MegaCacheFace> faces, Mesh mesh, Vector3[] meshverts, bool optimize, bool recalc, bool tangents)
  181. {
  182. mesh.Clear();
  183. if ( meshverts == null || meshverts.Length == 0 || faces.Count == 0 )
  184. return;
  185. verts.Clear();
  186. norms.Clear();
  187. uvs.Clear();
  188. tris.Clear();
  189. matfaces.Clear();
  190. BuildGrid(meshverts);
  191. int maxmat = 0;
  192. for ( int i = 0; i < faces.Count; i++ )
  193. {
  194. if ( faces[i].mtlid > maxmat )
  195. maxmat = faces[i].mtlid;
  196. }
  197. maxmat++;
  198. for ( int i = 0; i < maxmat; i++ )
  199. matfaces.Add(new MegaCacheMatFaces());
  200. for ( int i = 0; i < faces.Count; i++ )
  201. {
  202. int mtlid = faces[i].mtlid;
  203. int v0 = FindVertGrid(faces[i].v30, faces[i].n0, faces[i].uv0);
  204. int v1 = FindVertGrid(faces[i].v31, faces[i].n1, faces[i].uv1);
  205. int v2 = FindVertGrid(faces[i].v32, faces[i].n2, faces[i].uv2);
  206. matfaces[mtlid].tris.Add(v0);
  207. matfaces[mtlid].tris.Add(v1);
  208. matfaces[mtlid].tris.Add(v2);
  209. }
  210. mesh.vertices = verts.ToArray();
  211. mesh.subMeshCount = matfaces.Count;
  212. mesh.uv = uvs.ToArray();
  213. for ( int i = 0; i < matfaces.Count; i++ )
  214. mesh.SetTriangles(matfaces[i].tris.ToArray(), i);
  215. if ( recalc )
  216. mesh.RecalculateNormals();
  217. else
  218. mesh.normals = norms.ToArray();
  219. if ( tangents )
  220. BuildTangents(mesh);
  221. #if UNITY_5_5 || UNITY_2017 || UNITY_5_6 || UNITY_2018 || UNITY_2019 || UNITY_2020
  222. #else
  223. if ( optimize )
  224. mesh.Optimize();
  225. #endif
  226. mesh.RecalculateBounds();
  227. checkgrid = null;
  228. }
  229. }
  230. public class MegaCacheMeshConstructorOBJNoUV : MegaCacheMeshConstructor
  231. {
  232. static int FindVertGrid(Vector3 p, Vector3 n)
  233. {
  234. int sd = subdivs - 1;
  235. int gx = 0;
  236. int gy = 0;
  237. int gz = 0;
  238. if ( size.x > 0.0f )
  239. gx = (int)(sd * ((p.x - min.x) / size.x));
  240. if ( size.y > 0.0f )
  241. gy = (int)(sd * ((p.y - min.y) / size.y));
  242. if ( size.z > 0.0f )
  243. gz = (int)(sd * ((p.z - min.z) / size.z));
  244. MegaCacheFaceGrid fg = checkgrid[gx, gy, gz];
  245. if ( fg == null )
  246. {
  247. fg = new MegaCacheFaceGrid();
  248. checkgrid[gx, gy, gz] = fg;
  249. }
  250. for ( int i = 0; i < fg.verts.Count; i++ )
  251. {
  252. int ix = fg.verts[i];
  253. if ( verts[ix].x == p.x && verts[ix].y == p.y && verts[ix].z == p.z )
  254. {
  255. if ( norms[ix].x == n.x && norms[ix].y == n.y && norms[ix].z == n.z )
  256. return ix;
  257. }
  258. }
  259. fg.verts.Add(verts.Count);
  260. verts.Add(p);
  261. norms.Add(n);
  262. return verts.Count - 1;
  263. }
  264. static public void Construct(List<MegaCacheFace> faces, Mesh mesh, Vector3[] meshverts, bool optimize, bool recalc, bool tangents)
  265. {
  266. mesh.Clear();
  267. if ( meshverts == null || meshverts.Length == 0 || faces.Count == 0 )
  268. return;
  269. verts.Clear();
  270. norms.Clear();
  271. tris.Clear();
  272. matfaces.Clear();
  273. BuildGrid(meshverts);
  274. int maxmat = 0;
  275. for ( int i = 0; i < faces.Count; i++ )
  276. {
  277. if ( faces[i].mtlid > maxmat )
  278. maxmat = faces[i].mtlid;
  279. }
  280. maxmat++;
  281. for ( int i = 0; i < maxmat; i++ )
  282. {
  283. matfaces.Add(new MegaCacheMatFaces());
  284. }
  285. for ( int i = 0; i < faces.Count; i++ )
  286. {
  287. int mtlid = faces[i].mtlid;
  288. int v0 = FindVertGrid(faces[i].v30, faces[i].n0);
  289. int v1 = FindVertGrid(faces[i].v31, faces[i].n1);
  290. int v2 = FindVertGrid(faces[i].v32, faces[i].n2);
  291. matfaces[mtlid].tris.Add(v0);
  292. matfaces[mtlid].tris.Add(v1);
  293. matfaces[mtlid].tris.Add(v2);
  294. }
  295. mesh.vertices = verts.ToArray();
  296. mesh.subMeshCount = matfaces.Count;
  297. for ( int i = 0; i < matfaces.Count; i++ )
  298. mesh.SetTriangles(matfaces[i].tris.ToArray(), i);
  299. if ( recalc )
  300. mesh.RecalculateNormals();
  301. else
  302. mesh.normals = norms.ToArray();
  303. if ( tangents )
  304. BuildTangents(mesh);
  305. #if UNITY_5_5 || UNITY_2017 || UNITY_5_6 || UNITY_2018 || UNITY_2019 || UNITY_2020
  306. #else
  307. if ( optimize )
  308. mesh.Optimize();
  309. #endif
  310. mesh.RecalculateBounds();
  311. checkgrid = null;
  312. }
  313. }