SceneBuilder.Meshes.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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)
  82. {
  83. BabylonMesh babylonMesh = new BabylonMesh { name = gameObject.name, id = GetID(gameObject) };
  84. var transform = gameObject.transform;
  85. babylonMesh.parentId = GetParentID(transform);
  86. babylonMesh.position = transform.localPosition.ToFloat();
  87. babylonMesh.rotation = new float[3];
  88. babylonMesh.rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
  89. babylonMesh.rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
  90. babylonMesh.rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180;
  91. babylonMesh.scaling = transform.localScale.ToFloat();
  92. babylonScene.MeshesList.Add(babylonMesh);
  93. // Animations
  94. ExportAnimations(transform, babylonMesh);
  95. if (IsRotationQuaternionAnimated(babylonMesh))
  96. {
  97. babylonMesh.rotationQuaternion = transform.localRotation.ToFloat();
  98. }
  99. }
  100. private void ConvertUnityMeshToBabylon(Mesh mesh, Transform transform, GameObject gameObject, float progress)
  101. {
  102. BabylonMesh babylonMesh = new BabylonMesh();
  103. var renderer = gameObject.GetComponent<Renderer>();
  104. ExporterWindow.ReportProgress(progress, "Exporting mesh: " + gameObject.name);
  105. babylonMesh.name = gameObject.name;
  106. babylonMesh.id = GetID(transform.gameObject);
  107. babylonMesh.receiveShadows = renderer.receiveShadows;
  108. babylonMesh.parentId = GetParentID(transform);
  109. babylonMesh.position = transform.localPosition.ToFloat();
  110. babylonMesh.rotation = new float[3];
  111. babylonMesh.rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
  112. babylonMesh.rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
  113. babylonMesh.rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180;
  114. babylonMesh.scaling = transform.localScale.ToFloat();
  115. babylonMesh.positions = new float[mesh.vertexCount * 3];
  116. for (int i = 0; i < mesh.vertices.Length; i++)
  117. {
  118. babylonMesh.positions[i * 3] = mesh.vertices[i].x;
  119. babylonMesh.positions[(i * 3) + 1] = mesh.vertices[i].y;
  120. babylonMesh.positions[(i * 3) + 2] = mesh.vertices[i].z;
  121. // Computing world extends
  122. var worldPosition = transform.TransformPoint(mesh.vertices[i]);
  123. if (worldPosition.x > babylonScene.MaxVector.X)
  124. {
  125. babylonScene.MaxVector.X = worldPosition.x;
  126. }
  127. if (worldPosition.y > babylonScene.MaxVector.Y)
  128. {
  129. babylonScene.MaxVector.Y = worldPosition.y;
  130. }
  131. if (worldPosition.z > babylonScene.MaxVector.Z)
  132. {
  133. babylonScene.MaxVector.Z = worldPosition.z;
  134. }
  135. if (worldPosition.x < babylonScene.MinVector.X)
  136. {
  137. babylonScene.MinVector.X = worldPosition.x;
  138. }
  139. if (worldPosition.y < babylonScene.MinVector.Y)
  140. {
  141. babylonScene.MinVector.Y = worldPosition.y;
  142. }
  143. if (worldPosition.z < babylonScene.MinVector.Z)
  144. {
  145. babylonScene.MinVector.Z = worldPosition.z;
  146. }
  147. }
  148. babylonMesh.normals = new float[mesh.vertexCount * 3];
  149. for (int i = 0; i < mesh.normals.Length; i++)
  150. {
  151. babylonMesh.normals[i * 3] = mesh.normals[i].x;
  152. babylonMesh.normals[(i * 3) + 1] = mesh.normals[i].y;
  153. babylonMesh.normals[(i * 3) + 2] = mesh.normals[i].z;
  154. }
  155. babylonMesh.uvs = new float[mesh.vertexCount * 2];
  156. for (int i = 0; i < mesh.uv.Length; i++)
  157. {
  158. babylonMesh.uvs[i * 2] = mesh.uv[i].x;
  159. babylonMesh.uvs[(i * 2) + 1] = mesh.uv[i].y;
  160. }
  161. if (mesh.uv2 != null)
  162. {
  163. babylonMesh.uvs2 = new float[mesh.vertexCount * 2];
  164. for (int i = 0; i < mesh.uv2.Length; i++)
  165. {
  166. babylonMesh.uvs2[i * 2] = mesh.uv2[i].x;
  167. babylonMesh.uvs2[(i * 2) + 1] = mesh.uv2[i].y;
  168. }
  169. }
  170. babylonMesh.indices = new int[mesh.triangles.Length];
  171. for (int i = 0; i < mesh.triangles.Length; i += 3)
  172. {
  173. babylonMesh.indices[i] = mesh.triangles[i + 2];
  174. babylonMesh.indices[i + 1] = mesh.triangles[i + 1];
  175. babylonMesh.indices[i + 2] = mesh.triangles[i];
  176. }
  177. if (mesh.subMeshCount > 1) // Multimaterials
  178. {
  179. BabylonMultiMaterial bMultiMat;
  180. if (!multiMatDictionary.ContainsKey(renderer.sharedMaterial.name))
  181. {
  182. bMultiMat = new BabylonMultiMaterial
  183. {
  184. materials = new string[mesh.subMeshCount],
  185. id = Guid.NewGuid().ToString(),
  186. name = renderer.sharedMaterial.name
  187. };
  188. for (int i = 0; i < renderer.sharedMaterials.Length; i++)
  189. {
  190. var bMat = DumpMaterial(renderer.sharedMaterials[i], renderer);
  191. bMultiMat.materials[i] = bMat.id;
  192. }
  193. if (mesh.subMeshCount > 1)
  194. {
  195. multiMatDictionary.Add(bMultiMat.name, bMultiMat);
  196. }
  197. }
  198. else
  199. {
  200. bMultiMat = multiMatDictionary[renderer.sharedMaterial.name];
  201. }
  202. babylonMesh.materialId = bMultiMat.id;
  203. babylonMesh.subMeshes = new BabylonSubMesh[mesh.subMeshCount];
  204. var offset = 0;
  205. for (int materialIndex = 0; materialIndex < mesh.subMeshCount; materialIndex++)
  206. {
  207. var unityTriangles = mesh.GetTriangles(materialIndex);
  208. babylonMesh.subMeshes[materialIndex] = new BabylonSubMesh
  209. {
  210. verticesStart = 0,
  211. verticesCount = mesh.vertexCount,
  212. materialIndex = materialIndex,
  213. indexStart = offset,
  214. indexCount = unityTriangles.Length
  215. };
  216. offset += unityTriangles.Length;
  217. }
  218. }
  219. else
  220. {
  221. babylonMesh.materialId = DumpMaterial(renderer.sharedMaterial, renderer).id;
  222. }
  223. babylonScene.MeshesList.Add(babylonMesh);
  224. // Animations
  225. ExportAnimations(transform, babylonMesh);
  226. if (IsRotationQuaternionAnimated(babylonMesh))
  227. {
  228. babylonMesh.rotationQuaternion = transform.localRotation.ToFloat();
  229. }
  230. // Collisions
  231. if (exportationOptions.ExportCollisions)
  232. {
  233. var collider = gameObject.GetComponent<Collider>();
  234. if (collider != null)
  235. {
  236. babylonMesh.checkCollisions = true;
  237. }
  238. }
  239. }
  240. }
  241. }