SceneBuilder.Meshes.cs 11 KB

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