SceneBuilder.Meshes.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. using System;
  2. using BabylonExport.Entities;
  3. using UnityEngine;
  4. namespace Unity3D2Babylon
  5. {
  6. partial class SceneBuilder
  7. {
  8. private BabylonAbstractMesh ConvertUnityMeshToInstance(GameObject gameObject)
  9. {
  10. BabylonAbstractMesh babylonMesh = new BabylonAbstractMesh();
  11. Transform transform = gameObject.transform;
  12. babylonMesh.name = gameObject.name;
  13. babylonMesh.position = new float[3];
  14. babylonMesh.position[0] = transform.position.x;
  15. babylonMesh.position[1] = transform.position.y;
  16. babylonMesh.position[2] = transform.position.z;
  17. babylonMesh.rotation = new float[3];
  18. babylonMesh.rotation[0] = transform.rotation.eulerAngles.x * (float)Math.PI / 180;
  19. babylonMesh.rotation[1] = transform.rotation.eulerAngles.y * (float)Math.PI / 180;
  20. babylonMesh.rotation[2] = transform.rotation.eulerAngles.z * (float)Math.PI / 180;
  21. babylonMesh.scaling = new float[3];
  22. babylonMesh.scaling[0] = transform.localScale.x;
  23. babylonMesh.scaling[1] = transform.localScale.y;
  24. babylonMesh.scaling[2] = transform.localScale.z;
  25. return babylonMesh;
  26. }
  27. private void ConvertTransform(BabylonMesh babylonMesh, Transform transform, GameObject gameObject, BabylonAbstractMesh[] instances = null)
  28. {
  29. Action SetTransform = () =>
  30. {
  31. babylonMesh.position = transform.localPosition.ToFloat();
  32. babylonMesh.rotation = new float[3];
  33. babylonMesh.rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
  34. babylonMesh.rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
  35. babylonMesh.rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180;
  36. babylonMesh.scaling = transform.localScale.ToFloat();
  37. };
  38. //Check if this is a prefab
  39. if (instances != null)
  40. {
  41. /*
  42. Unity3D prefabs don't have transforms (position, rotation, scale) because they are just a template and are not drawn on screen
  43. but Babylon.js meshes must have a transform because they are drawn on the screen
  44. so what we do is take the first instance
  45. copy its transform (position, rotation, scale) into the prefab mesh
  46. then remove that first instance
  47. */
  48. BabylonAbstractMesh first = instances[0];
  49. babylonMesh.instances = new BabylonAbstractMesh[instances.Length - 1];
  50. //Effectively remove first instance from list of all instances
  51. for (int i = 0; i < instances.Length - 1; i++)
  52. {
  53. babylonMesh.instances[i] = instances[i + 1];
  54. }
  55. //If this is the root object then copy values directly from first instance
  56. if (GetParentID(transform) == null)
  57. {
  58. babylonMesh.position = new float[3];
  59. babylonMesh.position[0] = first.position[0];
  60. babylonMesh.position[1] = first.position[1];
  61. babylonMesh.position[2] = first.position[2];
  62. babylonMesh.rotation = new float[3];
  63. babylonMesh.rotation[0] = first.rotation[0];
  64. babylonMesh.rotation[1] = first.rotation[1];
  65. babylonMesh.rotation[2] = first.rotation[2];
  66. babylonMesh.scaling = new float[3];
  67. babylonMesh.scaling[0] = first.scaling[0];
  68. babylonMesh.scaling[1] = first.scaling[1];
  69. babylonMesh.scaling[2] = first.scaling[2];
  70. }
  71. else
  72. {
  73. SetTransform();
  74. }
  75. }
  76. else
  77. {
  78. SetTransform();
  79. }
  80. }
  81. private void ConvertUnityEmptyObjectToBabylon(GameObject gameObject, BabylonAbstractMesh[] instances = null)
  82. {
  83. BabylonMesh babylonMesh = new BabylonMesh { name = gameObject.name, id = GetID(gameObject) };
  84. var transform = gameObject.transform;
  85. babylonMesh.parentId = GetParentID(transform);
  86. ConvertTransform(babylonMesh, transform, gameObject, instances);
  87. babylonScene.MeshesList.Add(babylonMesh);
  88. // Animations
  89. ExportAnimations(transform, babylonMesh);
  90. if (IsRotationQuaternionAnimated(babylonMesh))
  91. {
  92. babylonMesh.rotationQuaternion = transform.localRotation.ToFloat();
  93. }
  94. }
  95. private void ConvertUnityMeshToBabylon(Mesh mesh, Transform transform, GameObject gameObject, float progress)
  96. {
  97. BabylonMesh babylonMesh = new BabylonMesh();
  98. var renderer = gameObject.GetComponent<Renderer>();
  99. ExporterWindow.ReportProgress(progress, "Exporting mesh: " + gameObject.name);
  100. babylonMesh.name = gameObject.name;
  101. babylonMesh.id = GetID(transform.gameObject);
  102. babylonMesh.receiveShadows = renderer.receiveShadows;
  103. babylonMesh.parentId = GetParentID(transform);
  104. babylonMesh.position = transform.localPosition.ToFloat();
  105. babylonMesh.rotation = new float[3];
  106. babylonMesh.rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
  107. babylonMesh.rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
  108. babylonMesh.rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180;
  109. babylonMesh.scaling = transform.localScale.ToFloat();
  110. babylonMesh.positions = new float[mesh.vertexCount * 3];
  111. for (int i = 0; i < mesh.vertices.Length; i++)
  112. {
  113. babylonMesh.positions[i * 3] = mesh.vertices[i].x;
  114. babylonMesh.positions[(i * 3) + 1] = mesh.vertices[i].y;
  115. babylonMesh.positions[(i * 3) + 2] = mesh.vertices[i].z;
  116. // Computing world extends
  117. var worldPosition = transform.TransformPoint(mesh.vertices[i]);
  118. if (worldPosition.x > babylonScene.MaxVector.X)
  119. {
  120. babylonScene.MaxVector.X = worldPosition.x;
  121. }
  122. if (worldPosition.y > babylonScene.MaxVector.Y)
  123. {
  124. babylonScene.MaxVector.Y = worldPosition.y;
  125. }
  126. if (worldPosition.z > babylonScene.MaxVector.Z)
  127. {
  128. babylonScene.MaxVector.Z = worldPosition.z;
  129. }
  130. if (worldPosition.x < babylonScene.MinVector.X)
  131. {
  132. babylonScene.MinVector.X = worldPosition.x;
  133. }
  134. if (worldPosition.y < babylonScene.MinVector.Y)
  135. {
  136. babylonScene.MinVector.Y = worldPosition.y;
  137. }
  138. if (worldPosition.z < babylonScene.MinVector.Z)
  139. {
  140. babylonScene.MinVector.Z = worldPosition.z;
  141. }
  142. }
  143. babylonMesh.normals = new float[mesh.vertexCount * 3];
  144. for (int i = 0; i < mesh.normals.Length; i++)
  145. {
  146. babylonMesh.normals[i * 3] = mesh.normals[i].x;
  147. babylonMesh.normals[(i * 3) + 1] = mesh.normals[i].y;
  148. babylonMesh.normals[(i * 3) + 2] = mesh.normals[i].z;
  149. }
  150. babylonMesh.uvs = new float[mesh.vertexCount * 2];
  151. for (int i = 0; i < mesh.uv.Length; i++)
  152. {
  153. babylonMesh.uvs[i * 2] = mesh.uv[i].x;
  154. babylonMesh.uvs[(i * 2) + 1] = mesh.uv[i].y;
  155. }
  156. if (mesh.uv2 != null)
  157. {
  158. babylonMesh.uvs2 = new float[mesh.vertexCount * 2];
  159. for (int i = 0; i < mesh.uv2.Length; i++)
  160. {
  161. babylonMesh.uvs2[i * 2] = mesh.uv2[i].x;
  162. babylonMesh.uvs2[(i * 2) + 1] = mesh.uv2[i].y;
  163. }
  164. }
  165. babylonMesh.indices = new int[mesh.triangles.Length];
  166. for (int i = 0; i < mesh.triangles.Length; i += 3)
  167. {
  168. babylonMesh.indices[i] = mesh.triangles[i + 2];
  169. babylonMesh.indices[i + 1] = mesh.triangles[i + 1];
  170. babylonMesh.indices[i + 2] = mesh.triangles[i];
  171. }
  172. if (mesh.subMeshCount > 1) // Multimaterials
  173. {
  174. BabylonMultiMaterial bMultiMat;
  175. if (!multiMatDictionary.ContainsKey(renderer.sharedMaterial.name))
  176. {
  177. bMultiMat = new BabylonMultiMaterial
  178. {
  179. materials = new string[mesh.subMeshCount],
  180. id = Guid.NewGuid().ToString(),
  181. name = renderer.sharedMaterial.name
  182. };
  183. for (int i = 0; i < renderer.sharedMaterials.Length; i++)
  184. {
  185. var bMat = DumpMaterial(renderer.sharedMaterials[i], renderer);
  186. bMultiMat.materials[i] = bMat.id;
  187. }
  188. if (mesh.subMeshCount > 1)
  189. {
  190. multiMatDictionary.Add(bMultiMat.name, bMultiMat);
  191. }
  192. }
  193. else
  194. {
  195. bMultiMat = multiMatDictionary[renderer.sharedMaterial.name];
  196. }
  197. babylonMesh.materialId = bMultiMat.id;
  198. babylonMesh.subMeshes = new BabylonSubMesh[mesh.subMeshCount];
  199. var offset = 0;
  200. for (int materialIndex = 0; materialIndex < mesh.subMeshCount; materialIndex++)
  201. {
  202. var unityTriangles = mesh.GetTriangles(materialIndex);
  203. babylonMesh.subMeshes[materialIndex] = new BabylonSubMesh
  204. {
  205. verticesStart = 0,
  206. verticesCount = mesh.vertexCount,
  207. materialIndex = materialIndex,
  208. indexStart = offset,
  209. indexCount = unityTriangles.Length
  210. };
  211. offset += unityTriangles.Length;
  212. }
  213. }
  214. else
  215. {
  216. babylonMesh.materialId = DumpMaterial(renderer.sharedMaterial, renderer).id;
  217. }
  218. babylonScene.MeshesList.Add(babylonMesh);
  219. // Animations
  220. ExportAnimations(transform, babylonMesh);
  221. if (IsRotationQuaternionAnimated(babylonMesh))
  222. {
  223. babylonMesh.rotationQuaternion = transform.localRotation.ToFloat();
  224. }
  225. // Collisions
  226. if (exportationOptions.ExportCollisions)
  227. {
  228. var collider = gameObject.GetComponent<Collider>();
  229. if (collider != null)
  230. {
  231. babylonMesh.checkCollisions = true;
  232. }
  233. }
  234. }
  235. }
  236. }