SceneBuilder.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using BabylonExport.Entities;
  5. using JsonFx.Json;
  6. using UnityEngine;
  7. using Object = UnityEngine.Object;
  8. using JsonFx.Serialization;
  9. using JsonFx.Serialization.Resolvers;
  10. using UnityEditor;
  11. namespace Unity3D2Babylon
  12. {
  13. public partial class SceneBuilder
  14. {
  15. public string OutputPath { get; private set; }
  16. public string SceneName { get; private set; }
  17. readonly Dictionary<string, BabylonMaterial> materialsDictionary;
  18. readonly Dictionary<string, BabylonMultiMaterial> multiMatDictionary;
  19. readonly Dictionary<int, string> uniqueGuids;
  20. readonly BabylonScene babylonScene;
  21. GameObject[] gameObjects;
  22. readonly ExportationOptions exportationOptions;
  23. public SceneBuilder(string outputPath, string sceneName, ExportationOptions exportationOptions)
  24. {
  25. OutputPath = outputPath;
  26. SceneName = string.IsNullOrEmpty(sceneName) ? "scene" : sceneName;
  27. materialsDictionary = new Dictionary<string, BabylonMaterial>();
  28. multiMatDictionary = new Dictionary<string, BabylonMultiMaterial>();
  29. uniqueGuids = new Dictionary<int, string>();
  30. babylonScene = new BabylonScene(OutputPath);
  31. this.exportationOptions = exportationOptions;
  32. }
  33. public void WriteToBabylonFile()
  34. {
  35. babylonScene.Prepare();
  36. var outputFile = Path.Combine(OutputPath, SceneName + ".babylon");
  37. var jsWriter = new JsonWriter(new DataWriterSettings(new DataContractResolverStrategy()));
  38. string babylonJSformat = jsWriter.Write(babylonScene);
  39. using (var sw = new StreamWriter(outputFile))
  40. {
  41. sw.Write(babylonJSformat);
  42. sw.Close();
  43. }
  44. }
  45. public void GenerateStatus(List<string> logs)
  46. {
  47. var initialLog = new List<string>
  48. {
  49. "*Exportation Status:",
  50. babylonScene.meshes.Length + " mesh(es)",
  51. babylonScene.lights.Length + " light(s)",
  52. babylonScene.cameras.Length + " camera(s)",
  53. babylonScene.materials.Length + " material(s)",
  54. babylonScene.multiMaterials.Length + " multi-material(s)",
  55. "",
  56. "*Log:"
  57. };
  58. logs.InsertRange(0, initialLog);
  59. }
  60. string GetParentID(Transform transform)
  61. {
  62. if (transform.parent == null)
  63. {
  64. return null;
  65. }
  66. return GetID(transform.parent.gameObject);
  67. }
  68. string GetID(GameObject gameObject)
  69. {
  70. var key = gameObject.GetInstanceID();
  71. if (!uniqueGuids.ContainsKey(key))
  72. {
  73. uniqueGuids[key] = Guid.NewGuid().ToString();
  74. }
  75. return uniqueGuids[key];
  76. }
  77. public void ConvertFromUnity()
  78. {
  79. ExporterWindow.ReportProgress(0, "Starting Babylon.js exportation process...");
  80. gameObjects = Object.FindObjectsOfType(typeof(GameObject)) as GameObject[];
  81. if (gameObjects.Length == 0)
  82. {
  83. ExporterWindow.ShowMessage("No gameobject! - Please add at least a gameobject to export");
  84. return;
  85. }
  86. var itemsCount = gameObjects.Length;
  87. var index = 0;
  88. //Dictionary to store prefabs and their instances
  89. Dictionary<GameObject, List<BabylonAbstractMesh>> dicPrefabs = new Dictionary<GameObject, List<BabylonAbstractMesh>>();
  90. foreach (var gameObject in gameObjects)
  91. {
  92. var progress = ((float)index / itemsCount);
  93. index++;
  94. /*
  95. The order of processing is important here.
  96. We will only check if this is a mesh prefab if it is not a light or camera
  97. */
  98. // Light
  99. var light = gameObject.GetComponent<Light>();
  100. if (light != null)
  101. {
  102. ConvertUnityLightToBabylon(light, progress);
  103. continue;
  104. }
  105. // Camera
  106. var camera = gameObject.GetComponent<Camera>();
  107. if (camera != null)
  108. {
  109. ConvertUnityCameraToBabylon(camera, progress);
  110. continue;
  111. }
  112. // Check if this is a prefab instance
  113. GameObject gobjPrefab = (GameObject)PrefabUtility.GetPrefabParent(gameObject);
  114. if (gobjPrefab != null)
  115. {
  116. //Add prefab to dictionary if it doesn't already exist
  117. if (!dicPrefabs.ContainsKey(gobjPrefab))
  118. {
  119. dicPrefabs[gobjPrefab] = new List<BabylonAbstractMesh>();
  120. }
  121. List<BabylonAbstractMesh> lstInstances = dicPrefabs[gobjPrefab];
  122. BabylonAbstractMesh instance = ConvertUnityMeshToInstance(gameObject);
  123. lstInstances.Add(instance);
  124. continue;
  125. }
  126. // Static meshes
  127. var meshFilter = gameObject.GetComponent<MeshFilter>();
  128. if (meshFilter != null)
  129. {
  130. ConvertUnityMeshToBabylon(meshFilter.sharedMesh, meshFilter.transform, gameObject, progress);
  131. continue;
  132. }
  133. // Skinned meshes
  134. var skinnedMesh = gameObject.GetComponent<SkinnedMeshRenderer>();
  135. if (skinnedMesh != null)
  136. {
  137. ConvertUnityMeshToBabylon(skinnedMesh.sharedMesh, skinnedMesh.transform, gameObject, progress);
  138. continue;
  139. }
  140. // Empty
  141. ConvertUnityEmptyObjectToBabylon(gameObject);
  142. }
  143. // Materials
  144. foreach (var mat in materialsDictionary)
  145. {
  146. babylonScene.MaterialsList.Add(mat.Value);
  147. }
  148. foreach (var multiMat in multiMatDictionary)
  149. {
  150. babylonScene.MultiMaterialsList.Add(multiMat.Value);
  151. }
  152. // Collisions
  153. if (exportationOptions.ExportCollisions)
  154. {
  155. babylonScene.gravity = exportationOptions.Gravity.ToFloat();
  156. }
  157. }
  158. }
  159. }