SceneBuilder.cs 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Collections.Generic;
  7. using System.Runtime.Serialization;
  8. using BabylonExport.Entities;
  9. using UnityEngine;
  10. using UnityEditor;
  11. using UnityEngine.AI;
  12. using Object = UnityEngine.Object;
  13. using JsonFx.Json;
  14. using JsonFx.Json.Resolvers;
  15. using JsonFx.Serialization;
  16. using JsonFx.Serialization.Resolvers;
  17. namespace Unity3D2Babylon
  18. {
  19. public partial class SceneBuilder
  20. {
  21. public const int MAX_VERTEX_COUNT = 65000;
  22. public string OutputPath { get; private set; }
  23. public string SceneName { get; private set; }
  24. public string ManifestData { get; private set; }
  25. public string SceneJavascriptPath { get; private set; }
  26. public BabylonSceneController SceneController { get; private set; }
  27. public List<MonoScript> MonoRuntimeScripts { get; private set; }
  28. readonly Dictionary<string, BabylonMaterial> materialsDictionary;
  29. readonly Dictionary<string, BabylonMultiMaterial> multiMatDictionary;
  30. readonly Dictionary<int, string> uniqueGuids;
  31. readonly BabylonScene babylonScene;
  32. GameObject[] gameObjects;
  33. readonly ExportationOptions exportationOptions;
  34. BabylonTexture sceneReflectionTexture;
  35. public static SceneMetaData Metadata = new SceneMetaData();
  36. public SceneBuilder(string outputPath, string sceneName, ExportationOptions exportationOptions, BabylonSceneController controller, string scriptPath)
  37. {
  38. OutputPath = outputPath;
  39. SceneName = string.IsNullOrEmpty(sceneName) ? "scene" : sceneName;
  40. SceneController = controller;
  41. SceneJavascriptPath = scriptPath;
  42. materialsDictionary = new Dictionary<string, BabylonMaterial>();
  43. multiMatDictionary = new Dictionary<string, BabylonMultiMaterial>();
  44. uniqueGuids = new Dictionary<int, string>();
  45. babylonScene = new BabylonScene(OutputPath);
  46. babylonScene.producer = new BabylonProducer
  47. {
  48. file = Path.GetFileName(outputPath),
  49. version = "Unity3D",
  50. name = SceneName,
  51. exporter_version = "0.8.1"
  52. };
  53. this.exportationOptions = exportationOptions;
  54. this.ManifestData = String.Empty;
  55. if (SceneController != null)
  56. {
  57. this.ManifestData = "{" + String.Format("\n\t\"version\" : {0},\n\t\"enableSceneOffline\" : {1},\n\t\"enableTexturesOffline\" : {2}\n", SceneController.manifestOptions.manifestVersion, SceneController.manifestOptions.storeSceneOffline.ToString().ToLower(), SceneController.manifestOptions.storeTextureOffline.ToString().ToLower()) + "}";
  58. }
  59. }
  60. public void WriteToBabylonFile(string outputFile)
  61. {
  62. ExporterWindow.ReportProgress(1, "Preparing babylon scene file...");
  63. babylonScene.Prepare(false);
  64. if (SceneController != null && SceneController.manifestOptions.exportManifest)
  65. {
  66. if (!String.IsNullOrEmpty(this.ManifestData))
  67. {
  68. var manifestFile = outputFile + ".manifest";
  69. File.WriteAllText(manifestFile, this.ManifestData);
  70. }
  71. }
  72. ExporterWindow.ReportProgress(1, "Serializing babylon scene file... This may take a while.");
  73. using (var file = File.CreateText(outputFile))
  74. {
  75. var settings = new DataWriterSettings(new BabylonSceneContractResolver()) { PrettyPrint = true };
  76. var jsWriter = new JsonWriter(settings);
  77. jsWriter.Write(babylonScene, file);
  78. }
  79. }
  80. public void GenerateStatus(List<string> logs)
  81. {
  82. var initialLog = new List<string> {
  83. "*Exportation Status:",
  84. babylonScene.meshes.Length + " mesh(es)",
  85. babylonScene.lights.Length + " light(s)",
  86. babylonScene.cameras.Length + " camera(s)",
  87. babylonScene.materials.Length + " material(s)",
  88. babylonScene.multiMaterials.Length + " multi-material(s)",
  89. "",
  90. "*Log:"
  91. };
  92. logs.InsertRange(0, initialLog);
  93. }
  94. string GetParentID(Transform transform)
  95. {
  96. if (transform.parent == null)
  97. {
  98. return null;
  99. }
  100. return GetID(transform.parent.gameObject);
  101. }
  102. string GetID(GameObject gameObject)
  103. {
  104. var key = gameObject.GetInstanceID();
  105. if (!uniqueGuids.ContainsKey(key))
  106. {
  107. uniqueGuids[key] = Guid.NewGuid().ToString();
  108. }
  109. return uniqueGuids[key];
  110. }
  111. public void ConvertFromUnity()
  112. {
  113. ExporterWindow.ReportProgress(0, "Starting exportation process...");
  114. gameObjects = Object.FindObjectsOfType(typeof(GameObject)) as GameObject[];
  115. if (gameObjects.Length == 0)
  116. {
  117. ExporterWindow.ShowMessage("No gameobject! - Please add at least a gameobject to export");
  118. return;
  119. }
  120. // Create scene metadata
  121. SceneBuilder.Metadata = new SceneMetaData();
  122. // Parse all scene game objects
  123. var index = 0;
  124. var itemsCount = gameObjects.Length;
  125. var particleSystems = new List<BabylonExport.Entities.BabylonParticleSystem>();
  126. var lensFlareSystems = new List<UnityFlareSystem>();
  127. ExporterWindow.ReportProgress(0, "Exporting game objects from scene...");
  128. babylonScene.physicsEngine = (exportationOptions.DefaultPhysicsEngine == 1) ? "oimo" : "cannon";
  129. try
  130. {
  131. bool foundController = false;
  132. foreach (var gameObject in gameObjects)
  133. {
  134. var progress = ((float)index / itemsCount);
  135. index++;
  136. // Unity metadata
  137. var metaData = new UnityMetaData();
  138. metaData.objectId = GetID(gameObject);
  139. metaData.objectName = gameObject.name;
  140. metaData.tagName = gameObject.tag;
  141. metaData.layerIndex = gameObject.layer;
  142. metaData.layerName = LayerMask.LayerToName(gameObject.layer);
  143. // Export hooking
  144. var exportObject = gameObject;
  145. var exportOptions = exportationOptions;
  146. BabylonScene sceneBuilder = babylonScene;
  147. if (SceneController != null)
  148. {
  149. SceneController.OnExportGameObject(ref exportOptions, ref exportObject, ref metaData, ref sceneBuilder, OutputPath);
  150. }
  151. // Components tags
  152. string componentTags = String.Empty;
  153. if (!String.IsNullOrEmpty(gameObject.tag) && !gameObject.tag.Equals("Untagged", StringComparison.OrdinalIgnoreCase))
  154. {
  155. componentTags = gameObject.tag;
  156. }
  157. // Navigation area
  158. metaData.areaIndex = -1;
  159. bool navigationStatic = GameObjectUtility.AreStaticEditorFlagsSet(gameObject, StaticEditorFlags.NavigationStatic);
  160. if (navigationStatic)
  161. {
  162. metaData.areaIndex = GameObjectUtility.GetNavMeshArea(gameObject);
  163. }
  164. // Navigation agent
  165. metaData.navAgent = null;
  166. var navigationAgent = gameObject.GetComponent<NavMeshAgent>();
  167. if (navigationAgent != null)
  168. {
  169. componentTags += " [NAVAGENT]";
  170. Dictionary<string, object> agentInfo = new Dictionary<string, object>();
  171. agentInfo.Add("name", navigationAgent.name);
  172. agentInfo.Add("radius", navigationAgent.radius);
  173. agentInfo.Add("height", navigationAgent.height);
  174. agentInfo.Add("speed", navigationAgent.speed);
  175. agentInfo.Add("acceleration", navigationAgent.acceleration);
  176. agentInfo.Add("angularSpeed", navigationAgent.angularSpeed);
  177. agentInfo.Add("areaMask", navigationAgent.areaMask);
  178. agentInfo.Add("autoBraking", navigationAgent.autoBraking);
  179. agentInfo.Add("autoTraverseOffMeshLink", navigationAgent.autoTraverseOffMeshLink);
  180. agentInfo.Add("avoidancePriority", navigationAgent.avoidancePriority);
  181. agentInfo.Add("baseOffset", navigationAgent.baseOffset);
  182. agentInfo.Add("obstacleAvoidanceType", navigationAgent.obstacleAvoidanceType.ToString());
  183. agentInfo.Add("stoppingDistance", navigationAgent.stoppingDistance);
  184. metaData.navAgent = agentInfo;
  185. }
  186. // Navigation link
  187. metaData.meshLink = null;
  188. var navigationLink = gameObject.GetComponent<OffMeshLink>();
  189. if (navigationLink != null)
  190. {
  191. componentTags += " [MESHLINK]";
  192. Dictionary<string, object> linkInfo = new Dictionary<string, object>();
  193. linkInfo.Add("name", navigationLink.name);
  194. linkInfo.Add("activated", navigationLink.activated);
  195. linkInfo.Add("area", navigationLink.area);
  196. linkInfo.Add("autoUpdatePositions", navigationLink.autoUpdatePositions);
  197. linkInfo.Add("biDirectional", navigationLink.biDirectional);
  198. linkInfo.Add("costOverride", navigationLink.costOverride);
  199. linkInfo.Add("occupied", navigationLink.occupied);
  200. linkInfo.Add("start", GetTransformPropertyValue(navigationLink.startTransform));
  201. linkInfo.Add("end", GetTransformPropertyValue(navigationLink.endTransform));
  202. metaData.meshLink = linkInfo;
  203. }
  204. // Navigation obstacle
  205. metaData.meshObstacle = null;
  206. var navigationObstacle = gameObject.GetComponent<NavMeshObstacle>();
  207. if (navigationObstacle != null)
  208. {
  209. componentTags += " [MESHOBSTACLE]";
  210. Dictionary<string, object> obstacleInfo = new Dictionary<string, object>();
  211. obstacleInfo.Add("name", navigationObstacle.name);
  212. obstacleInfo.Add("carving", navigationObstacle.carving);
  213. obstacleInfo.Add("carveOnlyStationary", navigationObstacle.carveOnlyStationary);
  214. obstacleInfo.Add("carvingMoveThreshold", navigationObstacle.carvingMoveThreshold);
  215. obstacleInfo.Add("carvingTimeToStationary", navigationObstacle.carvingTimeToStationary);
  216. obstacleInfo.Add("shape", navigationObstacle.shape.ToString());
  217. obstacleInfo.Add("radius", navigationObstacle.radius);
  218. obstacleInfo.Add("center", navigationObstacle.center.ToFloat());
  219. obstacleInfo.Add("size", navigationObstacle.size.ToFloat());
  220. metaData.meshObstacle = obstacleInfo;
  221. }
  222. // Tags component
  223. var tagsComponent = gameObject.GetComponent<BabylonTagsComponent>();
  224. if (tagsComponent != null)
  225. {
  226. if (!String.IsNullOrEmpty(tagsComponent.babylonTags))
  227. {
  228. componentTags += (" " + tagsComponent.babylonTags);
  229. }
  230. }
  231. // Script components
  232. var gameComponents = gameObject.GetComponents<BabylonScriptComponent>();
  233. if (gameComponents != null)
  234. {
  235. var components = new List<object>();
  236. foreach (var gameComponent in gameComponents)
  237. {
  238. Type componentType = gameComponent.GetType();
  239. string componentName = componentType.FullName;
  240. var component = new UnityScriptComponent();
  241. MonoScript componentScript = MonoScript.FromMonoBehaviour(gameComponent);
  242. component.order = MonoImporter.GetExecutionOrder(componentScript);
  243. component.name = componentName;
  244. component.klass = gameComponent.babylonClass;
  245. component.update = (gameComponent.updateOption == BabylonTickOptions.EnableTick);
  246. component.controller = (gameComponent is BabylonSceneController);
  247. if (component.controller == true)
  248. {
  249. component.order = -1;
  250. if (foundController == false)
  251. {
  252. foundController = true;
  253. componentTags += " [CONTROLLER]";
  254. object userInterface = null;
  255. BabylonSceneController scx = (gameComponent as BabylonSceneController);
  256. EmbeddedAsset guiAsset = scx.sceneOptions.graphicUserInterface;
  257. if (guiAsset != null && scx.sceneOptions.userInterfaceMode != BabylonGuiMode.None)
  258. {
  259. userInterface = GetEmbeddedAssetPropertyValue(guiAsset);
  260. }
  261. SceneBuilder.Metadata.properties.Add("autoDraw", scx.sceneOptions.autoDrawInterface);
  262. SceneBuilder.Metadata.properties.Add("interfaceMode", scx.sceneOptions.userInterfaceMode.ToString());
  263. SceneBuilder.Metadata.properties.Add("userInterface", userInterface);
  264. SceneBuilder.Metadata.properties.Add("controllerPresent", true);
  265. SceneBuilder.Metadata.properties.Add("controllerObjectId", metaData.objectId);
  266. }
  267. else
  268. {
  269. Debug.LogError("Duplicate scene controller detected: " + component.name);
  270. }
  271. }
  272. FieldInfo[] componentFields = componentType.GetFields();
  273. if (componentFields != null)
  274. {
  275. foreach (var componentField in componentFields)
  276. {
  277. var componentAttribute = (BabylonPropertyAttribute)Attribute.GetCustomAttribute(componentField, typeof(BabylonPropertyAttribute));
  278. if (componentAttribute != null && componentField.Name != "babylonClass")
  279. {
  280. component.properties.Add(componentField.Name, GetComponentPropertyValue(componentField, gameComponent));
  281. }
  282. }
  283. }
  284. gameComponent.OnExportProperties(ref exportOptions, ref exportObject, ref component.properties, OutputPath);
  285. components.Add(component);
  286. }
  287. if (components.Count > 0)
  288. {
  289. metaData.components = components;
  290. }
  291. }
  292. // Format tags
  293. if (!String.IsNullOrEmpty(componentTags))
  294. {
  295. componentTags = componentTags.Trim();
  296. }
  297. // Audio sources
  298. var audioComponents = gameObject.GetComponents<BabylonAudioSource>();
  299. if (audioComponents != null)
  300. {
  301. foreach (var item in audioComponents)
  302. {
  303. if (item != null && item.exportAudio && item.sound != null)
  304. {
  305. string soundPath = AssetDatabase.GetAssetPath(item.sound);
  306. if (!String.IsNullOrEmpty(soundPath))
  307. {
  308. string soundName = Path.GetFileName(soundPath).Replace(" ", "");
  309. string outputFile = Path.Combine(OutputPath, soundName);
  310. if (File.Exists(soundPath))
  311. {
  312. File.Copy(soundPath, outputFile, true);
  313. var sound = new BabylonSound();
  314. sound.name = soundName;
  315. sound.volume = item.options.volume;
  316. sound.playbackRate = item.options.playbackRate;
  317. sound.autoplay = item.options.autoplay;
  318. sound.loop = item.options.loop;
  319. sound.soundTrackId = item.options.soundTrackId;
  320. sound.spatialSound = item.options.spatialSound;
  321. sound.position = item.options.position.ToFloat();
  322. sound.refDistance = item.options.refDistance;
  323. sound.rolloffFactor = item.options.rolloffFactor;
  324. sound.maxDistance = item.options.maxDistance;
  325. sound.distanceModel = item.options.distanceModel;
  326. sound.panningModel = item.options.panningModel;
  327. sound.isDirectional = item.options.isDirectional;
  328. sound.coneInnerAngle = item.options.coneInnerAngle;
  329. sound.coneOuterAngle = item.options.coneOuterAngle;
  330. sound.coneOuterGain = item.options.coneOuterGain;
  331. sound.localDirectionToMesh = item.options.directionToMesh.ToFloat();
  332. babylonScene.SoundsList.Add(sound);
  333. }
  334. else
  335. {
  336. Debug.LogError("Fail to locate audio file: " + soundPath);
  337. }
  338. }
  339. else
  340. {
  341. Debug.LogError("Null audio clip path for: " + item.sound.name);
  342. }
  343. }
  344. }
  345. }
  346. // Terrain meshes
  347. var terrainMesh = gameObject.GetComponent<Terrain>();
  348. if (terrainMesh != null)
  349. {
  350. ConvertUnityTerrainToBabylon(terrainMesh, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags);
  351. continue;
  352. }
  353. // Collision meshes
  354. BabylonMesh collisionMesh = null;
  355. var collider = gameObject.GetComponent<Collider>();
  356. if (collider != null)
  357. {
  358. if (collider.enabled)
  359. {
  360. int segments = 12;
  361. BabylonColliderDetail detail = (BabylonColliderDetail)exportationOptions.DefaultColliderDetail;
  362. var collisionData = new UnityMetaData();
  363. collisionData.objectId = Guid.NewGuid().ToString();
  364. collisionData.objectName = gameObject.name + "_Metadata";
  365. if (collider is MeshCollider)
  366. {
  367. var meshCollider = collider as MeshCollider;
  368. collisionMesh = new BabylonMesh();
  369. collisionMesh.tags = "[MESHCOLLIDER]";
  370. // Generate Mesh Collider Geometry
  371. Tools.GenerateBabylonMeshData(meshCollider.sharedMesh, collisionMesh);
  372. collisionMesh.position = Vector3.zero.ToFloat();
  373. collisionMesh.rotation = Vector3.zero.ToFloat();
  374. float factorX = 1f, factorY = 1f, factorZ = 1f;
  375. if (meshCollider.inflateMesh && meshCollider.skinWidth > 0f)
  376. {
  377. Vector3 localScale = gameObject.transform.localScale;
  378. factorX += (meshCollider.skinWidth / localScale.x);
  379. factorY += (meshCollider.skinWidth / localScale.y);
  380. factorZ += (meshCollider.skinWidth / localScale.z);
  381. }
  382. collisionMesh.scaling = new Vector3(factorX, factorY, factorZ).ToFloat();
  383. // Export Mesh Collider Metadata
  384. collisionData.tagName = "MeshCollider";
  385. collisionData.properties.Add("type", "Mesh");
  386. collisionData.properties.Add("convex", meshCollider.convex);
  387. collisionData.properties.Add("inflateMesh", meshCollider.inflateMesh);
  388. collisionData.properties.Add("skinWidth", meshCollider.skinWidth);
  389. }
  390. else if (collider is CapsuleCollider)
  391. {
  392. var capsuleCollider = collider as CapsuleCollider;
  393. collisionMesh = new BabylonMesh();
  394. collisionMesh.tags = "[CAPSULECOLLIDER]";
  395. switch (detail)
  396. {
  397. case BabylonColliderDetail.FullResolution:
  398. segments = 48;
  399. break;
  400. case BabylonColliderDetail.HighResolution:
  401. segments = 32;
  402. break;
  403. case BabylonColliderDetail.MediumResolution:
  404. segments = 24;
  405. break;
  406. case BabylonColliderDetail.LowResolution:
  407. segments = 12;
  408. break;
  409. case BabylonColliderDetail.VeryLowResolution:
  410. segments = 8;
  411. break;
  412. case BabylonColliderDetail.MinimumResolution:
  413. segments = 6;
  414. break;
  415. default:
  416. segments = 12;
  417. break;
  418. }
  419. // Generate Capsule Collider Geometry
  420. Mesh capsuleMesh = Tools.CreateCapsuleMesh(capsuleCollider.height, capsuleCollider.radius, segments);
  421. Tools.GenerateBabylonMeshData(capsuleMesh, collisionMesh);
  422. collisionMesh.position = new float[3];
  423. collisionMesh.position[0] = capsuleCollider.center.x;
  424. collisionMesh.position[1] = capsuleCollider.center.y;
  425. collisionMesh.position[2] = capsuleCollider.center.z;
  426. collisionMesh.rotation = new float[3];
  427. collisionMesh.rotation[0] = (capsuleCollider.direction == 2) ? 90f * (float)Math.PI / 180f : 0f;
  428. collisionMesh.rotation[1] = 0f;
  429. collisionMesh.rotation[2] = (capsuleCollider.direction == 0) ? 90f * (float)Math.PI / 180f : 0f;
  430. collisionMesh.scaling = new Vector3(1, 1, 1).ToFloat();
  431. // Export Capsule Collider Metadata
  432. collisionData.tagName = "CapsuleCollider";
  433. collisionData.properties.Add("type", "Capsule");
  434. collisionData.properties.Add("center", capsuleCollider.center.ToFloat());
  435. collisionData.properties.Add("radius", capsuleCollider.radius);
  436. collisionData.properties.Add("height", capsuleCollider.height);
  437. collisionData.properties.Add("direction", capsuleCollider.direction);
  438. }
  439. else if (collider is SphereCollider)
  440. {
  441. var sphereCollider = collider as SphereCollider;
  442. collisionMesh = new BabylonMesh();
  443. collisionMesh.tags = "[SPHERECOLLIDER]";
  444. switch (detail)
  445. {
  446. case BabylonColliderDetail.FullResolution:
  447. segments = 48;
  448. break;
  449. case BabylonColliderDetail.HighResolution:
  450. segments = 32;
  451. break;
  452. case BabylonColliderDetail.MediumResolution:
  453. segments = 24;
  454. break;
  455. case BabylonColliderDetail.LowResolution:
  456. segments = 12;
  457. break;
  458. case BabylonColliderDetail.VeryLowResolution:
  459. segments = 8;
  460. break;
  461. case BabylonColliderDetail.MinimumResolution:
  462. segments = 6;
  463. break;
  464. default:
  465. segments = 12;
  466. break;
  467. }
  468. // Generate Sphere Collider Geometry
  469. Mesh sphereMesh = Tools.CreateSphereMesh(sphereCollider.radius, segments);
  470. Tools.GenerateBabylonMeshData(sphereMesh, collisionMesh);
  471. collisionMesh.position = new float[3];
  472. collisionMesh.position[0] = sphereCollider.center.x;
  473. collisionMesh.position[1] = sphereCollider.center.y;
  474. collisionMesh.position[2] = sphereCollider.center.z;
  475. collisionMesh.rotation = Vector3.zero.ToFloat();
  476. collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat();
  477. // Export Sphere Collider Metadata
  478. collisionData.tagName = "SphereCollider";
  479. collisionData.properties.Add("type", "Sphere");
  480. collisionData.properties.Add("center", sphereCollider.center.ToFloat());
  481. collisionData.properties.Add("radius", sphereCollider.radius);
  482. }
  483. else if (collider is WheelCollider)
  484. {
  485. var wheelCollider = collider as WheelCollider;
  486. collisionMesh = new BabylonMesh();
  487. collisionMesh.tags = "[WHEELCOLLIDER]";
  488. switch (detail)
  489. {
  490. case BabylonColliderDetail.FullResolution:
  491. segments = 128;
  492. break;
  493. case BabylonColliderDetail.HighResolution:
  494. segments = 64;
  495. break;
  496. case BabylonColliderDetail.MediumResolution:
  497. segments = 48;
  498. break;
  499. case BabylonColliderDetail.LowResolution:
  500. segments = 32;
  501. break;
  502. case BabylonColliderDetail.VeryLowResolution:
  503. segments = 24;
  504. break;
  505. case BabylonColliderDetail.MinimumResolution:
  506. segments = 16;
  507. break;
  508. default:
  509. segments = 32;
  510. break;
  511. }
  512. // Generate Wheel Collider Geometry
  513. Mesh wheelMesh = Tools.CreateWheelMesh(wheelCollider.suspensionDistance, wheelCollider.radius, segments);
  514. Tools.GenerateBabylonMeshData(wheelMesh, collisionMesh);
  515. collisionMesh.position = new float[3];
  516. collisionMesh.position[0] = wheelCollider.center.x;
  517. collisionMesh.position[1] = wheelCollider.center.y;
  518. collisionMesh.position[2] = wheelCollider.center.z;
  519. collisionMesh.rotation = new float[3];
  520. collisionMesh.rotation[0] = 0f;
  521. collisionMesh.rotation[1] = 0f;
  522. collisionMesh.rotation[2] = 90f * (float)Math.PI / 180;
  523. collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat();
  524. // Export Wheel Collider Metadata
  525. collisionData.tagName = "WheelCollider";
  526. collisionData.properties.Add("type", "Wheel");
  527. collisionData.properties.Add("center", wheelCollider.center.ToFloat());
  528. collisionData.properties.Add("radius", wheelCollider.radius);
  529. }
  530. else if (collider is BoxCollider)
  531. {
  532. var boxCollider = collider as BoxCollider;
  533. collisionMesh = new BabylonMesh();
  534. collisionMesh.tags = "[BOXCOLLIDER]";
  535. // Generate Box Collider Geometry
  536. Mesh boxMesh = Tools.CreateBoxMesh(boxCollider.size.x, boxCollider.size.y, boxCollider.size.z);
  537. Tools.GenerateBabylonMeshData(boxMesh, collisionMesh);
  538. collisionMesh.position = new float[3];
  539. collisionMesh.position[0] = boxCollider.center.x;
  540. collisionMesh.position[1] = boxCollider.center.y;
  541. collisionMesh.position[2] = boxCollider.center.z;
  542. collisionMesh.rotation = Vector3.zero.ToFloat();
  543. collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat();
  544. // Export Box Collider Metadata
  545. collisionData.tagName = "BoxCollider";
  546. collisionData.properties.Add("type", "Box");
  547. collisionData.properties.Add("center", boxCollider.center.ToFloat());
  548. collisionData.properties.Add("size", boxCollider.size.ToFloat());
  549. }
  550. if (collisionMesh != null)
  551. {
  552. collisionMesh.id = Guid.NewGuid().ToString();
  553. collisionMesh.name = gameObject.name + "_Collider";
  554. // Default Check Collisions False
  555. collisionMesh.checkCollisions = false;
  556. collisionMesh.isVisible = false;
  557. collisionData.properties.Add("parrentId", metaData.objectId);
  558. collisionData.properties.Add("transform", GetTransformPropertyValue(gameObject.transform));
  559. collisionMesh.metadata = collisionData;
  560. babylonScene.MeshesList.Add(collisionMesh);
  561. SceneBuilder.Metadata.properties["hasCollisionMeshes"] = true;
  562. }
  563. }
  564. }
  565. // Static meshes
  566. var meshFilter = gameObject.GetComponent<MeshFilter>();
  567. if (meshFilter != null)
  568. {
  569. ConvertUnityMeshToBabylon(meshFilter.sharedMesh, meshFilter.transform, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider);
  570. continue;
  571. }
  572. // Skinned meshes
  573. var skinnedMesh = gameObject.GetComponent<SkinnedMeshRenderer>();
  574. if (skinnedMesh != null)
  575. {
  576. var babylonMesh = ConvertUnityMeshToBabylon(skinnedMesh.sharedMesh, skinnedMesh.transform, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider);
  577. var skeleton = ConvertUnitySkeletonToBabylon(skinnedMesh.bones, skinnedMesh.sharedMesh.bindposes, skinnedMesh.transform, gameObject, progress);
  578. babylonMesh.skeletonId = skeleton.id;
  579. ExportSkeletonAnimation(skinnedMesh, babylonMesh, skeleton);
  580. continue;
  581. }
  582. // Scene lights
  583. var light = gameObject.GetComponent<Light>();
  584. if (light != null)
  585. {
  586. ConvertUnityLightToBabylon(light, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags);
  587. continue;
  588. }
  589. // Scene cameras
  590. var camera = gameObject.GetComponent<Camera>();
  591. if (camera != null)
  592. {
  593. ConvertUnityCameraToBabylon(camera, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags);
  594. if (SceneController != null && SceneController.skyboxOptions.exportSkybox)
  595. {
  596. ConvertUnitySkyboxToBabylon(camera, progress);
  597. }
  598. continue;
  599. }
  600. // Empty objects
  601. ConvertUnityEmptyObjectToBabylon(gameObject, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider);
  602. }
  603. // Materials
  604. foreach (var mat in materialsDictionary)
  605. {
  606. babylonScene.MaterialsList.Add(mat.Value);
  607. }
  608. foreach (var multiMat in multiMatDictionary)
  609. {
  610. babylonScene.MultiMaterialsList.Add(multiMat.Value);
  611. }
  612. // Collisions
  613. if (exportationOptions.ExportCollisions)
  614. {
  615. babylonScene.gravity = exportationOptions.Gravity.ToFloat();
  616. babylonScene.workerCollisions = exportationOptions.WorkerCollisions;
  617. }
  618. // Babylon Physics
  619. if (exportationOptions.ExportPhysics)
  620. {
  621. babylonScene.physicsEnabled = true;
  622. babylonScene.physicsGravity = exportationOptions.Gravity.ToFloat();
  623. }
  624. // Scene Controller
  625. if (SceneController != null)
  626. {
  627. Color ambientColor = SceneController.sceneOptions.ambientColor;
  628. float ambientLevel = SceneController.lightingOptions.lightLevel;
  629. Color ambientSpecular = SceneController.lightingOptions.specularColor;
  630. babylonScene.autoClear = SceneController.sceneOptions.autoClear;
  631. int fogmode = 0;
  632. if (RenderSettings.fog)
  633. {
  634. switch (RenderSettings.fogMode)
  635. {
  636. case FogMode.Exponential:
  637. fogmode = 1;
  638. break;
  639. case FogMode.ExponentialSquared:
  640. fogmode = 2;
  641. break;
  642. case FogMode.Linear:
  643. fogmode = 3;
  644. break;
  645. }
  646. }
  647. babylonScene.fogMode = fogmode;
  648. babylonScene.fogDensity = RenderSettings.fogDensity;
  649. babylonScene.fogColor = RenderSettings.fogColor.ToFloat();
  650. babylonScene.fogStart = RenderSettings.fogStartDistance;
  651. babylonScene.fogEnd = RenderSettings.fogEndDistance;
  652. if (exportationOptions.DefaultLightmapMode != (int)BabylonLightmapMode.FullLightBaking && SceneController.lightingOptions.lightMode == BabylonAmbientLighting.UnityAmbientLighting)
  653. {
  654. var ambientLight = new BabylonLight
  655. {
  656. name = "Ambient Light",
  657. id = Guid.NewGuid().ToString(),
  658. parentId = null,
  659. metadata = null,
  660. position = null,
  661. exponent = 1.0f,
  662. angle = 0.0f,
  663. type = 3
  664. };
  665. var ambientDirection = new Vector3(0.0f, 1.0f, 0.0f);
  666. Color ambientDiffuse = (RenderSettings.ambientMode == UnityEngine.Rendering.AmbientMode.Skybox) ? RenderSettings.ambientSkyColor : RenderSettings.ambientLight;
  667. ambientLight.intensity = RenderSettings.ambientIntensity * ambientLevel;
  668. ambientLight.direction = ambientDirection.ToFloat(); ;
  669. ambientLight.diffuse = ambientDiffuse.ToFloat();
  670. ambientLight.specular = ambientSpecular.ToFloat();
  671. ambientLight.groundColor = RenderSettings.ambientGroundColor.ToFloat();
  672. babylonScene.ambientColor = ambientColor.ToFloat();
  673. babylonScene.LightsList.Add(ambientLight);
  674. ExporterWindow.ReportProgress(0, "Exporting ambient light intensity at: " + ambientLight.intensity.ToString());
  675. }
  676. if (SceneController.sceneOptions.navigationMesh == BabylonNavigationMesh.EnableNavigation)
  677. {
  678. ExporterWindow.ReportProgress(0, "Parsing scene navigation mesh...");
  679. NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation();
  680. if (triangulatedNavMesh.vertices != null && triangulatedNavMesh.vertices.Length > 0 && triangulatedNavMesh.indices != null && triangulatedNavMesh.indices.Length > 0)
  681. {
  682. int vertexCount = triangulatedNavMesh.vertices.Length;
  683. if (vertexCount <= SceneBuilder.MAX_VERTEX_COUNT)
  684. {
  685. ExporterWindow.ReportProgress(0, "Generating navigation mesh vertices: " + vertexCount.ToString());
  686. var navData = new UnityMetaData();
  687. navData.type = "NavMesh";
  688. navData.objectId = Guid.NewGuid().ToString();
  689. navData.objectName = "Navigation_Mesh";
  690. var areaTable = new List<object>();
  691. string[] areaNavigation = GameObjectUtility.GetNavMeshAreaNames();
  692. foreach (string areaName in areaNavigation)
  693. {
  694. var bag = new Dictionary<string, object>();
  695. int areaIndex = NavMesh.GetAreaFromName(areaName);
  696. float areaCost = NavMesh.GetAreaCost(areaIndex);
  697. bag.Add("index", areaIndex);
  698. bag.Add("area", areaName);
  699. bag.Add("cost", areaCost);
  700. areaTable.Add(bag);
  701. }
  702. navData.properties.Add("table", areaTable);
  703. navData.properties.Add("areas", triangulatedNavMesh.areas);
  704. Mesh mesh = new Mesh();
  705. mesh.name = "sceneNavigationMesh";
  706. mesh.vertices = triangulatedNavMesh.vertices;
  707. mesh.triangles = triangulatedNavMesh.indices;
  708. mesh.RecalculateNormals();
  709. BabylonMesh babylonMesh = new BabylonMesh();
  710. babylonMesh.tags = "[NAVMESH]";
  711. babylonMesh.metadata = navData;
  712. babylonMesh.name = mesh.name;
  713. babylonMesh.id = Guid.NewGuid().ToString();
  714. babylonMesh.parentId = null;
  715. babylonMesh.position = Vector3.zero.ToFloat();
  716. babylonMesh.rotation = Vector3.zero.ToFloat();
  717. babylonMesh.scaling = new Vector3(1, 1, 1).ToFloat();
  718. babylonMesh.isVisible = false;
  719. babylonMesh.visibility = 0.75f;
  720. babylonMesh.checkCollisions = false;
  721. Tools.GenerateBabylonMeshData(mesh, babylonMesh);
  722. babylonScene.MeshesList.Add(babylonMesh);
  723. SceneBuilder.Metadata.properties["hasNavigationMesh"] = true;
  724. }
  725. else
  726. {
  727. UnityEngine.Debug.LogError("Navigation mesh exceeds max (65000) vertex limit: " + vertexCount.ToString());
  728. }
  729. }
  730. }
  731. if (SceneController.sceneOptions.particleSystems)
  732. {
  733. if (particleSystems != null && particleSystems.Count > 0)
  734. {
  735. babylonScene.particleSystems = particleSystems.ToArray();
  736. }
  737. }
  738. if (SceneController.sceneOptions.lensFlareSystems)
  739. {
  740. if (lensFlareSystems != null && lensFlareSystems.Count > 0)
  741. {
  742. var lfs_buffer = new List<BabylonLensFlareSystem>();
  743. foreach (var ulfs in lensFlareSystems)
  744. {
  745. var lfs = new BabylonLensFlareSystem();
  746. lfs.borderLimit = ulfs.borderLimit;
  747. lfs.emitterId = ulfs.emitterId;
  748. var lfx = new List<BabylonLensFlare>();
  749. foreach (var ulf in ulfs.lensFlares)
  750. {
  751. var lf = new BabylonLensFlare();
  752. lf.textureName = ulf.textureName;
  753. lf.position = ulf.position;
  754. lf.color = ulf.color;
  755. lf.size = ulf.size;
  756. lfx.Add(lf);
  757. }
  758. lfs.flares = lfx.ToArray();
  759. lfs_buffer.Add(lfs);
  760. }
  761. babylonScene.lensFlareSystems = lfs_buffer.ToArray();
  762. }
  763. }
  764. }
  765. }
  766. catch (Exception ex)
  767. {
  768. Debug.LogException(ex);
  769. }
  770. finally
  771. {
  772. babylonScene.metadata = SceneBuilder.Metadata;
  773. }
  774. }
  775. private void ParseLensFlares(GameObject gameObject, string emitterId, ref List<UnityFlareSystem> lens)
  776. {
  777. var flare = gameObject.GetComponent<BabylonFlareSystem>();
  778. if (flare != null && flare.exportFlare && flare.lensFlares != null && flare.lensFlares.Length > 0)
  779. {
  780. var flareSystem = new UnityFlareSystem();
  781. flareSystem.name = (!String.IsNullOrEmpty(flare.flareName)) ? flare.flareName : String.Format("lensFlareSystem#" + Guid.NewGuid().ToString());
  782. flareSystem.emitterId = emitterId;
  783. flareSystem.borderLimit = flare.borderLimit;
  784. var flareBuffer = new List<UnityFlareItem>();
  785. foreach (var flareItem in flare.lensFlares)
  786. {
  787. var item = new UnityFlareItem();
  788. item.size = flareItem.size;
  789. item.position = flareItem.position;
  790. item.color = flareItem.color.ToFloat();
  791. if (flareItem.texture != null)
  792. {
  793. var babylonTexture = new BabylonTexture();
  794. var texturePath = AssetDatabase.GetAssetPath(flareItem.texture);
  795. CopyTexture(texturePath, flareItem.texture, babylonTexture);
  796. item.textureName = Path.GetFileName(texturePath);
  797. }
  798. flareBuffer.Add(item);
  799. }
  800. flareSystem.lensFlares = flareBuffer.ToArray();
  801. lens.Add(flareSystem);
  802. }
  803. }
  804. private void ParseParticleSystems(GameObject gameObject, string emitterId, ref List<BabylonExport.Entities.BabylonParticleSystem> particles)
  805. {
  806. var particle = gameObject.GetComponent<UnityEditor.BabylonParticleSystem>();
  807. if (particle != null && particle.exportParticle)
  808. {
  809. var particleSystem = new BabylonExport.Entities.BabylonParticleSystem();
  810. particleSystem.name = (!String.IsNullOrEmpty(particle.particleName)) ? particle.particleName : String.Format("particalSystem#" + Guid.NewGuid().ToString());
  811. particleSystem.emitterId = emitterId;
  812. particleSystem.linkToEmitter = true;
  813. particleSystem.preventAutoStart = !particle.autoStart;
  814. particleSystem.textureMask = particle.textureMask.ToFloat();
  815. particleSystem.updateSpeed = particle.updateSpeed;
  816. particleSystem.emitRate = particle.emitRate;
  817. particleSystem.gravity = particle.gravity.ToFloat();
  818. particleSystem.blendMode = (int)particle.blendMode;
  819. particleSystem.capacity = particle.capacity;
  820. particleSystem.color1 = particle.color1.ToFloat();
  821. particleSystem.color2 = particle.color2.ToFloat();
  822. particleSystem.colorDead = particle.colorDead.ToFloat();
  823. particleSystem.direction1 = particle.direction1.ToFloat();
  824. particleSystem.direction2 = particle.direction2.ToFloat();
  825. particleSystem.minEmitBox = particle.minEmitBox.ToFloat();
  826. particleSystem.maxEmitBox = particle.maxEmitBox.ToFloat();
  827. particleSystem.minEmitPower = particle.minEmitPower;
  828. particleSystem.maxEmitPower = particle.maxEmitPower;
  829. particleSystem.minLifeTime = particle.minLifeTime;
  830. particleSystem.maxLifeTime = particle.maxLifeTime;
  831. particleSystem.minSize = particle.minSize;
  832. particleSystem.maxSize = particle.maxSize;
  833. particleSystem.minAngularSpeed = particle.minAngularSpeed;
  834. particleSystem.maxAngularSpeed = particle.maxAngularSpeed;
  835. particleSystem.targetStopFrame = particle.targetStopFrame;
  836. particleSystem.deadAlpha = particle.deadAlpha;
  837. if (particle.texture != null)
  838. {
  839. var babylonTexture = new BabylonTexture();
  840. var texturePath = AssetDatabase.GetAssetPath(particle.texture);
  841. CopyTexture(texturePath, particle.texture, babylonTexture);
  842. particleSystem.textureName = Path.GetFileName(texturePath);
  843. }
  844. particles.Add(particleSystem);
  845. }
  846. }
  847. private object GetComponentPropertyValue(FieldInfo field, BabylonScriptComponent component)
  848. {
  849. object result = null;
  850. object fvalue = field.GetValue(component);
  851. if (fvalue != null)
  852. {
  853. Type ftype = fvalue.GetType();
  854. if (typeof(System.Enum).IsAssignableFrom(ftype))
  855. {
  856. result = Convert.ToInt32((System.Enum)fvalue);
  857. }
  858. else if (typeof(Boolean).IsAssignableFrom(ftype) || typeof(Byte).IsAssignableFrom(ftype) || typeof(SByte).IsAssignableFrom(ftype) || typeof(Int16).IsAssignableFrom(ftype) || typeof(UInt16).IsAssignableFrom(ftype) || typeof(Int32).IsAssignableFrom(ftype) || typeof(UInt32).IsAssignableFrom(ftype) || typeof(Int64).IsAssignableFrom(ftype) || typeof(UInt64).IsAssignableFrom(ftype) || typeof(IntPtr).IsAssignableFrom(ftype) || typeof(UIntPtr).IsAssignableFrom(ftype) || typeof(Char).IsAssignableFrom(ftype) || typeof(Double).IsAssignableFrom(ftype) || typeof(Single).IsAssignableFrom(ftype))
  859. {
  860. result = fvalue;
  861. }
  862. else if (typeof(System.String).IsAssignableFrom(ftype))
  863. {
  864. result = fvalue;
  865. }
  866. else if (typeof(Color).IsAssignableFrom(ftype))
  867. {
  868. var color = (Color)fvalue;
  869. result = new UnityBabylonColor { r = color.r, g = color.g, b = color.b, a = color.a };
  870. }
  871. else if (typeof(Vector2).IsAssignableFrom(ftype))
  872. {
  873. var vec2 = (Vector2)fvalue;
  874. result = new UnityBablylonVector2 { x = vec2.x, y = vec2.y };
  875. }
  876. else if (typeof(Vector3).IsAssignableFrom(ftype))
  877. {
  878. var vec3 = (Vector3)fvalue;
  879. result = new UnityBablylonVector3 { x = vec3.x, y = vec3.y, z = vec3.z };
  880. }
  881. else if (typeof(Vector4).IsAssignableFrom(ftype))
  882. {
  883. var vec4 = (Vector4)fvalue;
  884. result = new UnityBablylonVector4 { x = vec4.x, y = vec4.y, z = vec4.z, w = vec4.w };
  885. }
  886. else if (typeof(Transform).IsAssignableFrom(ftype))
  887. {
  888. var transform = (Transform)fvalue;
  889. result = GetTransformPropertyValue(transform);
  890. }
  891. else if (typeof(Texture2D).IsAssignableFrom(ftype))
  892. {
  893. var texture = (Texture2D)fvalue;
  894. result = GetTexturePropertyValue(texture);
  895. }
  896. else if (typeof(Cubemap).IsAssignableFrom(ftype))
  897. {
  898. var cubemap = (Cubemap)fvalue;
  899. result = GetCubemapPropertyValue(cubemap);
  900. }
  901. else if (typeof(Material).IsAssignableFrom(ftype))
  902. {
  903. var material = (Material)fvalue;
  904. result = GetMaterialPropertyValue(material);
  905. }
  906. else if (typeof(Shader).IsAssignableFrom(ftype))
  907. {
  908. var shader = (Shader)fvalue;
  909. result = GetShaderPropertyValue(shader);
  910. }
  911. else if (typeof(GameObject).IsAssignableFrom(ftype))
  912. {
  913. var gobject = (GameObject)fvalue;
  914. result = GetGamePropertyValue(gobject);
  915. }
  916. else if (typeof(AudioClip).IsAssignableFrom(ftype))
  917. {
  918. var aclip = (AudioClip)fvalue;
  919. result = GetAudioClipPropertyValue(aclip);
  920. }
  921. else if (typeof(EmbeddedAsset).IsAssignableFrom(ftype))
  922. {
  923. var easset = (EmbeddedAsset)fvalue;
  924. result = GetEmbeddedAssetPropertyValue(easset);
  925. }
  926. else if (typeof(TextAsset).IsAssignableFrom(ftype))
  927. {
  928. var tasset = (TextAsset)fvalue;
  929. result = GetTextAssetPropertyValue(tasset);
  930. }
  931. else if (typeof(DefaultAsset).IsAssignableFrom(ftype))
  932. {
  933. var dasset = (DefaultAsset)fvalue;
  934. result = GetDefaultAssetPropertyValue(dasset);
  935. }
  936. else if (ftype.IsArray)
  937. {
  938. if (typeof(Boolean[]).IsAssignableFrom(ftype) || typeof(Byte[]).IsAssignableFrom(ftype) || typeof(SByte[]).IsAssignableFrom(ftype) || typeof(Int16[]).IsAssignableFrom(ftype) || typeof(UInt16[]).IsAssignableFrom(ftype) || typeof(Int32[]).IsAssignableFrom(ftype) || typeof(UInt32[]).IsAssignableFrom(ftype) || typeof(Int64[]).IsAssignableFrom(ftype) || typeof(UInt64[]).IsAssignableFrom(ftype) || typeof(IntPtr[]).IsAssignableFrom(ftype) || typeof(UIntPtr[]).IsAssignableFrom(ftype) || typeof(Char[]).IsAssignableFrom(ftype) || typeof(Double[]).IsAssignableFrom(ftype) || typeof(Single[]).IsAssignableFrom(ftype))
  939. {
  940. result = fvalue;
  941. }
  942. else if (typeof(System.String[]).IsAssignableFrom(ftype))
  943. {
  944. result = fvalue;
  945. }
  946. else if (typeof(Color[]).IsAssignableFrom(ftype))
  947. {
  948. var colors = (Color[])fvalue;
  949. var colors_list = new List<UnityBabylonColor>();
  950. foreach (var color in colors)
  951. {
  952. colors_list.Add(new UnityBabylonColor { r = color.r, g = color.g, b = color.b, a = color.a });
  953. }
  954. result = colors_list.ToArray();
  955. }
  956. else if (typeof(Vector2[]).IsAssignableFrom(ftype))
  957. {
  958. var vecs2 = (Vector2[])fvalue;
  959. var vecs2_list = new List<UnityBablylonVector2>();
  960. foreach (var vec2 in vecs2)
  961. {
  962. vecs2_list.Add(new UnityBablylonVector2 { x = vec2.x, y = vec2.y });
  963. }
  964. result = vecs2_list.ToArray();
  965. }
  966. else if (typeof(Vector3[]).IsAssignableFrom(ftype))
  967. {
  968. var vecs3 = (Vector3[])fvalue;
  969. var vecs3_list = new List<UnityBablylonVector3>();
  970. foreach (var vec3 in vecs3)
  971. {
  972. vecs3_list.Add(new UnityBablylonVector3 { x = vec3.x, y = vec3.y, z = vec3.z });
  973. }
  974. result = vecs3_list.ToArray();
  975. }
  976. else if (typeof(Vector4[]).IsAssignableFrom(ftype))
  977. {
  978. var vecs4 = (Vector4[])fvalue;
  979. var vecs4_list = new List<UnityBablylonVector4>();
  980. foreach (var vec4 in vecs4)
  981. {
  982. vecs4_list.Add(new UnityBablylonVector4 { x = vec4.x, y = vec4.y, z = vec4.z, w = vec4.w });
  983. }
  984. result = vecs4_list.ToArray();
  985. }
  986. else if (typeof(Transform[]).IsAssignableFrom(ftype))
  987. {
  988. var transforms = (Transform[])fvalue;
  989. var transform_list = new List<object>();
  990. foreach (var transform in transforms)
  991. {
  992. transform_list.Add(GetTransformPropertyValue(transform));
  993. }
  994. result = transform_list.ToArray();
  995. }
  996. else if (typeof(Texture2D[]).IsAssignableFrom(ftype))
  997. {
  998. var textures = (Texture2D[])fvalue;
  999. var texture_list = new List<object>();
  1000. foreach (var texture in textures)
  1001. {
  1002. texture_list.Add(GetTexturePropertyValue(texture));
  1003. }
  1004. result = texture_list.ToArray();
  1005. }
  1006. else if (typeof(Cubemap[]).IsAssignableFrom(ftype))
  1007. {
  1008. var cubemaps = (Cubemap[])fvalue;
  1009. var cubemap_list = new List<object>();
  1010. foreach (var cubemap in cubemaps)
  1011. {
  1012. cubemap_list.Add(GetCubemapPropertyValue(cubemap));
  1013. }
  1014. result = cubemap_list.ToArray();
  1015. }
  1016. else if (typeof(Material[]).IsAssignableFrom(ftype))
  1017. {
  1018. var materials = (Material[])fvalue;
  1019. var material_list = new List<object>();
  1020. foreach (var material in materials)
  1021. {
  1022. material_list.Add(GetMaterialPropertyValue(material));
  1023. }
  1024. result = material_list.ToArray();
  1025. }
  1026. else if (typeof(Shader[]).IsAssignableFrom(ftype))
  1027. {
  1028. var shaders = (Shader[])fvalue;
  1029. var shader_list = new List<object>();
  1030. foreach (var shader in shaders)
  1031. {
  1032. shader_list.Add(GetShaderPropertyValue(shader));
  1033. }
  1034. result = shader_list.ToArray();
  1035. }
  1036. else if (typeof(GameObject[]).IsAssignableFrom(ftype))
  1037. {
  1038. var gobjects = (GameObject[])fvalue;
  1039. var gobject_list = new List<object>();
  1040. foreach (var gobject in gobjects)
  1041. {
  1042. gobject_list.Add(GetGamePropertyValue(gobject));
  1043. }
  1044. result = gobject_list.ToArray();
  1045. }
  1046. else if (typeof(AudioClip[]).IsAssignableFrom(ftype))
  1047. {
  1048. var aclips = (AudioClip[])fvalue;
  1049. var aclip_list = new List<object>();
  1050. foreach (var aclip in aclips)
  1051. {
  1052. aclip_list.Add(GetAudioClipPropertyValue(aclip));
  1053. }
  1054. result = aclip_list.ToArray();
  1055. }
  1056. else if (typeof(EmbeddedAsset[]).IsAssignableFrom(ftype))
  1057. {
  1058. var eassets = (EmbeddedAsset[])fvalue;
  1059. var easset_list = new List<object>();
  1060. foreach (var easset in eassets)
  1061. {
  1062. easset_list.Add(GetEmbeddedAssetPropertyValue(easset));
  1063. }
  1064. result = easset_list.ToArray();
  1065. }
  1066. else if (typeof(TextAsset[]).IsAssignableFrom(ftype))
  1067. {
  1068. var tassets = (TextAsset[])fvalue;
  1069. var tasset_list = new List<object>();
  1070. foreach (var tasset in tassets)
  1071. {
  1072. tasset_list.Add(GetTextAssetPropertyValue(tasset));
  1073. }
  1074. result = tasset_list.ToArray();
  1075. }
  1076. else if (typeof(DefaultAsset[]).IsAssignableFrom(ftype))
  1077. {
  1078. var dassets = (DefaultAsset[])fvalue;
  1079. var dasset_list = new List<object>();
  1080. foreach (var dasset in dassets)
  1081. {
  1082. dasset_list.Add(GetDefaultAssetPropertyValue(dasset));
  1083. }
  1084. result = dasset_list.ToArray();
  1085. }
  1086. }
  1087. }
  1088. return result;
  1089. }
  1090. private object GetGamePropertyValue(GameObject game)
  1091. {
  1092. if (game == null) return null;
  1093. Dictionary<string, object> objectInfo = new Dictionary<string, object>();
  1094. objectInfo.Add("type", game.GetType().FullName);
  1095. objectInfo.Add("id", GetID(game));
  1096. objectInfo.Add("tag", game.tag);
  1097. objectInfo.Add("name", game.name);
  1098. objectInfo.Add("layer", game.layer);
  1099. objectInfo.Add("isStatic", game.isStatic);
  1100. objectInfo.Add("hideFlags", game.hideFlags.ToString());
  1101. return objectInfo;
  1102. }
  1103. private object GetTransformPropertyValue(Transform transform)
  1104. {
  1105. if (transform == null) return null;
  1106. Dictionary<string, object> position = new Dictionary<string, object>();
  1107. position.Add("x", transform.localPosition.x);
  1108. position.Add("y", transform.localPosition.y);
  1109. position.Add("z", transform.localPosition.z);
  1110. Dictionary<string, object> rotation = new Dictionary<string, object>();
  1111. rotation.Add("x", transform.localRotation.x);
  1112. rotation.Add("y", transform.localRotation.y);
  1113. rotation.Add("z", transform.localRotation.z);
  1114. Dictionary<string, object> scale = new Dictionary<string, object>();
  1115. scale.Add("x", transform.localScale.x);
  1116. scale.Add("y", transform.localScale.y);
  1117. scale.Add("z", transform.localScale.z);
  1118. Dictionary<string, object> transformInfo = new Dictionary<string, object>();
  1119. transformInfo.Add("type", transform.GetType().FullName);
  1120. transformInfo.Add("id", GetID(transform.gameObject));
  1121. transformInfo.Add("position", position);
  1122. transformInfo.Add("rotation", rotation);
  1123. transformInfo.Add("scale", scale);
  1124. return transformInfo;
  1125. }
  1126. private object GetMaterialPropertyValue(Material material)
  1127. {
  1128. if (material == null) return null;
  1129. BabylonMaterial babylonMaterial = DumpMaterial(material);
  1130. Dictionary<string, object> materialInfo = new Dictionary<string, object>();
  1131. materialInfo.Add("type", material.GetType().FullName);
  1132. materialInfo.Add("id", babylonMaterial.id);
  1133. materialInfo.Add("name", babylonMaterial.name);
  1134. materialInfo.Add("alpha", babylonMaterial.alpha);
  1135. materialInfo.Add("wireframe", babylonMaterial.wireframe);
  1136. materialInfo.Add("backFaceCulling", babylonMaterial.backFaceCulling);
  1137. return materialInfo;
  1138. }
  1139. private object GetTexturePropertyValue(Texture2D texture)
  1140. {
  1141. if (texture == null) return null;
  1142. var texturePath = AssetDatabase.GetAssetPath(texture);
  1143. if (String.IsNullOrEmpty(texturePath)) return null;
  1144. var babylonTexture = new BabylonTexture();
  1145. CopyTexture(texturePath, texture, babylonTexture);
  1146. Dictionary<string, object> textureInfo = new Dictionary<string, object>();
  1147. textureInfo.Add("type", texture.GetType().FullName);
  1148. textureInfo.Add("name", babylonTexture.name);
  1149. textureInfo.Add("level", babylonTexture.level);
  1150. textureInfo.Add("isCube", babylonTexture.isCube);
  1151. textureInfo.Add("hasAlpha", babylonTexture.hasAlpha);
  1152. textureInfo.Add("coordinatesMode", babylonTexture.coordinatesMode);
  1153. textureInfo.Add("coordinatesIndex", babylonTexture.coordinatesIndex);
  1154. return textureInfo;
  1155. }
  1156. private object GetCubemapPropertyValue(Cubemap cubemap)
  1157. {
  1158. if (cubemap == null) return null;
  1159. var texturePath = AssetDatabase.GetAssetPath(cubemap);
  1160. if (String.IsNullOrEmpty(texturePath)) return null;
  1161. var textureName = Path.GetFileName(texturePath);
  1162. var outputPath = Path.Combine(babylonScene.OutputPath, textureName);
  1163. File.Copy(texturePath, outputPath, true);
  1164. Dictionary<string, object> textureInfo = new Dictionary<string, object>();
  1165. textureInfo.Add("type", cubemap.GetType().FullName);
  1166. textureInfo.Add("name", textureName);
  1167. textureInfo.Add("width", cubemap.width);
  1168. textureInfo.Add("height", cubemap.height);
  1169. textureInfo.Add("anisoLevel", cubemap.anisoLevel);
  1170. textureInfo.Add("texelSizeX", cubemap.texelSize.x);
  1171. textureInfo.Add("texelSizeY", cubemap.texelSize.y);
  1172. textureInfo.Add("dimension", cubemap.dimension.ToString());
  1173. textureInfo.Add("filterMode", cubemap.filterMode.ToString());
  1174. textureInfo.Add("format", cubemap.format.ToString());
  1175. textureInfo.Add("hideFlags", cubemap.hideFlags.ToString());
  1176. textureInfo.Add("mipMapBias", cubemap.mipMapBias.ToString());
  1177. textureInfo.Add("mipmapCount", cubemap.mipmapCount.ToString());
  1178. textureInfo.Add("wrapMode", cubemap.wrapMode.ToString());
  1179. return textureInfo;
  1180. }
  1181. private object GetEmbeddedAssetPropertyValue(EmbeddedAsset embedded)
  1182. {
  1183. if (embedded == null) return null;
  1184. var assetPath = AssetDatabase.GetAssetPath(embedded.textAsset);
  1185. if (String.IsNullOrEmpty(assetPath)) return null;
  1186. var assetName = Path.GetFileName(assetPath);
  1187. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1188. assetInfo.Add("type", embedded.GetType().FullName);
  1189. assetInfo.Add("filename", assetName);
  1190. assetInfo.Add("embedded", true);
  1191. if (embedded.encoding == BabylonTextEncoding.RawBytes)
  1192. {
  1193. assetInfo.Add("base64", Convert.ToBase64String(embedded.textAsset.bytes));
  1194. }
  1195. else
  1196. {
  1197. assetInfo.Add("base64", Tools.FormatBase64(embedded.textAsset.text));
  1198. }
  1199. return assetInfo;
  1200. }
  1201. private object GetTextAssetPropertyValue(TextAsset asset)
  1202. {
  1203. if (asset == null) return null;
  1204. var assetPath = AssetDatabase.GetAssetPath(asset);
  1205. if (String.IsNullOrEmpty(assetPath)) return null;
  1206. var assetName = Path.GetFileName(assetPath);
  1207. var outputPath = Path.Combine(babylonScene.OutputPath, assetName);
  1208. File.Copy(assetPath, outputPath, true);
  1209. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1210. assetInfo.Add("type", asset.GetType().FullName);
  1211. assetInfo.Add("filename", assetName);
  1212. assetInfo.Add("embedded", false);
  1213. assetInfo.Add("base64", null);
  1214. return assetInfo;
  1215. }
  1216. private object GetAudioClipPropertyValue(AudioClip clip)
  1217. {
  1218. if (clip == null) return null;
  1219. var assetPath = AssetDatabase.GetAssetPath(clip);
  1220. if (String.IsNullOrEmpty(assetPath)) return null;
  1221. var assetName = Path.GetFileName(assetPath);
  1222. var outputPath = Path.Combine(babylonScene.OutputPath, assetName);
  1223. File.Copy(assetPath, outputPath, true);
  1224. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1225. assetInfo.Add("type", clip.GetType().FullName);
  1226. assetInfo.Add("filename", assetName);
  1227. assetInfo.Add("length", clip.length);
  1228. assetInfo.Add("channels", clip.channels);
  1229. assetInfo.Add("frequency", clip.frequency);
  1230. assetInfo.Add("samples", clip.samples);
  1231. return assetInfo;
  1232. }
  1233. private object GetDefaultAssetPropertyValue(DefaultAsset asset)
  1234. {
  1235. if (asset == null) return null;
  1236. var assetPath = AssetDatabase.GetAssetPath(asset);
  1237. if (String.IsNullOrEmpty(assetPath)) return null;
  1238. var assetName = Path.GetFileName(assetPath);
  1239. var outputPath = Path.Combine(babylonScene.OutputPath, assetName);
  1240. File.Copy(assetPath, outputPath, true);
  1241. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1242. assetInfo.Add("type", asset.GetType().FullName);
  1243. assetInfo.Add("filename", assetName);
  1244. return assetInfo;
  1245. }
  1246. private object GetShaderPropertyValue(Shader shader)
  1247. {
  1248. if (shader == null || shader.name.Substring(0, 10) != "BabylonJS/") return null;
  1249. string filename = AssetDatabase.GetAssetPath(shader);
  1250. if (String.IsNullOrEmpty(filename)) return null;
  1251. List<string> attributeList = new List<string>();
  1252. List<string> uniformList = new List<string>();
  1253. List<string> samplerList = new List<string>();
  1254. List<string> defineList = new List<string>();
  1255. var result = new Dictionary<string, object>();
  1256. string program = Tools.LoadTextAsset(filename);
  1257. string basename = shader.name.Replace("BabylonJS/", "").Replace("/", "_").Replace(" ", "");
  1258. string babylonOptions = GetShaderProgramSection(basename, program, BabylonProgramSection.Babylon);
  1259. string[] babylonLines = babylonOptions.Split('\n');
  1260. foreach (string babylonLine in babylonLines)
  1261. {
  1262. if (babylonLine.IndexOf("attributes", StringComparison.OrdinalIgnoreCase) >= 0)
  1263. {
  1264. string[] attributes = babylonLine.Split(':');
  1265. if (attributes != null && attributes.Length > 1)
  1266. {
  1267. string abuffer = attributes[1].Replace("[", "").Replace("]", "");
  1268. if (!String.IsNullOrEmpty(abuffer))
  1269. {
  1270. abuffer = abuffer.Trim();
  1271. string[] adata = abuffer.Split(',');
  1272. if (adata != null && adata.Length > 0)
  1273. {
  1274. foreach (string aoption in adata)
  1275. {
  1276. string aoption_buffer = aoption.Trim().Replace("\"", "").Trim();
  1277. if (!String.IsNullOrEmpty(aoption_buffer))
  1278. {
  1279. attributeList.Add(aoption_buffer);
  1280. }
  1281. }
  1282. }
  1283. }
  1284. }
  1285. }
  1286. else if (babylonLine.IndexOf("uniforms", StringComparison.OrdinalIgnoreCase) >= 0)
  1287. {
  1288. string[] uniforms = babylonLine.Split(':');
  1289. if (uniforms != null && uniforms.Length > 1)
  1290. {
  1291. string ubuffer = uniforms[1].Replace("[", "").Replace("]", "");
  1292. if (!String.IsNullOrEmpty(ubuffer))
  1293. {
  1294. ubuffer = ubuffer.Trim();
  1295. string[] udata = ubuffer.Split(',');
  1296. if (udata != null && udata.Length > 0)
  1297. {
  1298. foreach (string uoption in udata)
  1299. {
  1300. string uoption_buffer = uoption.Trim().Replace("\"", "").Trim();
  1301. if (!String.IsNullOrEmpty(uoption_buffer))
  1302. {
  1303. uniformList.Add(uoption_buffer);
  1304. }
  1305. }
  1306. }
  1307. }
  1308. }
  1309. }
  1310. else if (babylonLine.IndexOf("samplers", StringComparison.OrdinalIgnoreCase) >= 0)
  1311. {
  1312. string[] samplers = babylonLine.Split(':');
  1313. if (samplers != null && samplers.Length > 1)
  1314. {
  1315. string sbuffer = samplers[1].Replace("[", "").Replace("]", "");
  1316. if (!String.IsNullOrEmpty(sbuffer))
  1317. {
  1318. sbuffer = sbuffer.Trim();
  1319. string[] sdata = sbuffer.Split(',');
  1320. if (sdata != null && sdata.Length > 0)
  1321. {
  1322. foreach (string soption in sdata)
  1323. {
  1324. string soption_buffer = soption.Trim().Replace("\"", "").Trim();
  1325. if (!String.IsNullOrEmpty(soption_buffer))
  1326. {
  1327. samplerList.Add(soption_buffer);
  1328. }
  1329. }
  1330. }
  1331. }
  1332. }
  1333. }
  1334. else if (babylonLine.IndexOf("defines", StringComparison.OrdinalIgnoreCase) >= 0)
  1335. {
  1336. string[] defines = babylonLine.Split(':');
  1337. if (defines != null && defines.Length > 1)
  1338. {
  1339. string dbuffer = defines[1].Replace("[", "").Replace("]", "");
  1340. if (!String.IsNullOrEmpty(dbuffer))
  1341. {
  1342. dbuffer = dbuffer.Trim();
  1343. string[] ddata = dbuffer.Split(',');
  1344. if (ddata != null && ddata.Length > 0)
  1345. {
  1346. foreach (string doption in ddata)
  1347. {
  1348. string doption_buffer = doption.Trim().Replace("\"", "").Trim();
  1349. if (!String.IsNullOrEmpty(doption_buffer))
  1350. {
  1351. defineList.Add(doption_buffer);
  1352. }
  1353. }
  1354. }
  1355. }
  1356. }
  1357. }
  1358. }
  1359. var shaderPath = new Dictionary<string, object>();
  1360. string vertexProgram = GetShaderProgramSection(basename, program, BabylonProgramSection.Vertex);
  1361. shaderPath.Add("vertexElement", ("base64:" + Tools.FormatBase64(vertexProgram)));
  1362. string fragmentProgram = GetShaderProgramSection(basename, program, BabylonProgramSection.Fragment);
  1363. shaderPath.Add("fragmentElement", ("base64:" + Tools.FormatBase64(fragmentProgram)));
  1364. result.Add("shaderPath", shaderPath);
  1365. var options = new BabylonShaderOptions();
  1366. options.attributes = attributeList.ToArray();
  1367. options.uniforms = uniformList.ToArray();
  1368. options.samplers = samplerList.ToArray();
  1369. options.defines = defineList.ToArray();
  1370. var shaderOptions = new Dictionary<string, object>();
  1371. shaderOptions.Add("attributes", options.attributes);
  1372. shaderOptions.Add("needAlphaBlending", false);
  1373. shaderOptions.Add("needAlphaTesting", false);
  1374. shaderOptions.Add("uniforms", options.uniforms);
  1375. shaderOptions.Add("samplers", options.samplers);
  1376. shaderOptions.Add("defines", options.defines);
  1377. result.Add("shaderOptions", shaderOptions);
  1378. return result;
  1379. }
  1380. private static void ExportSkeletonAnimation(SkinnedMeshRenderer skinnedMesh, BabylonMesh babylonMesh, BabylonSkeleton skeleton)
  1381. {
  1382. var animator = skinnedMesh.rootBone.gameObject.GetComponent<Animator>();
  1383. if (animator != null)
  1384. {
  1385. ExportSkeletonAnimationClips(animator, true, skeleton, skinnedMesh.bones, babylonMesh);
  1386. }
  1387. else
  1388. {
  1389. var parent = skinnedMesh.rootBone.parent;
  1390. while (parent != null)
  1391. {
  1392. animator = parent.gameObject.GetComponent<Animator>();
  1393. if (animator != null)
  1394. {
  1395. ExportSkeletonAnimationClips(animator, true, skeleton, skinnedMesh.bones, babylonMesh);
  1396. break;
  1397. }
  1398. parent = parent.parent;
  1399. }
  1400. }
  1401. }
  1402. }
  1403. }