SceneBuilder.cs 81 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478
  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. if(!meshCollider.sharedMesh)
  372. {
  373. UnityEngine.Debug.LogWarning(meshCollider.gameObject+" has a Mesh Collider component without a mesh");
  374. }
  375. else
  376. {
  377. Tools.GenerateBabylonMeshData(meshCollider.sharedMesh, collisionMesh);
  378. }
  379. collisionMesh.position = Vector3.zero.ToFloat();
  380. collisionMesh.rotation = Vector3.zero.ToFloat();
  381. float factorX = 1f, factorY = 1f, factorZ = 1f;
  382. if (meshCollider.inflateMesh && meshCollider.skinWidth > 0f)
  383. {
  384. Vector3 localScale = gameObject.transform.localScale;
  385. factorX += (meshCollider.skinWidth / localScale.x);
  386. factorY += (meshCollider.skinWidth / localScale.y);
  387. factorZ += (meshCollider.skinWidth / localScale.z);
  388. }
  389. collisionMesh.scaling = new Vector3(factorX, factorY, factorZ).ToFloat();
  390. // Export Mesh Collider Metadata
  391. collisionData.tagName = "MeshCollider";
  392. collisionData.properties.Add("type", "Mesh");
  393. collisionData.properties.Add("convex", meshCollider.convex);
  394. collisionData.properties.Add("inflateMesh", meshCollider.inflateMesh);
  395. collisionData.properties.Add("skinWidth", meshCollider.skinWidth);
  396. }
  397. else if (collider is CapsuleCollider)
  398. {
  399. var capsuleCollider = collider as CapsuleCollider;
  400. collisionMesh = new BabylonMesh();
  401. collisionMesh.tags = "[CAPSULECOLLIDER]";
  402. switch (detail)
  403. {
  404. case BabylonColliderDetail.FullResolution:
  405. segments = 48;
  406. break;
  407. case BabylonColliderDetail.HighResolution:
  408. segments = 32;
  409. break;
  410. case BabylonColliderDetail.MediumResolution:
  411. segments = 24;
  412. break;
  413. case BabylonColliderDetail.LowResolution:
  414. segments = 12;
  415. break;
  416. case BabylonColliderDetail.VeryLowResolution:
  417. segments = 8;
  418. break;
  419. case BabylonColliderDetail.MinimumResolution:
  420. segments = 6;
  421. break;
  422. default:
  423. segments = 12;
  424. break;
  425. }
  426. // Generate Capsule Collider Geometry
  427. Mesh capsuleMesh = Tools.CreateCapsuleMesh(capsuleCollider.height, capsuleCollider.radius, segments);
  428. Tools.GenerateBabylonMeshData(capsuleMesh, collisionMesh);
  429. collisionMesh.position = new float[3];
  430. collisionMesh.position[0] = capsuleCollider.center.x;
  431. collisionMesh.position[1] = capsuleCollider.center.y;
  432. collisionMesh.position[2] = capsuleCollider.center.z;
  433. collisionMesh.rotation = new float[3];
  434. collisionMesh.rotation[0] = (capsuleCollider.direction == 2) ? 90f * (float)Math.PI / 180f : 0f;
  435. collisionMesh.rotation[1] = 0f;
  436. collisionMesh.rotation[2] = (capsuleCollider.direction == 0) ? 90f * (float)Math.PI / 180f : 0f;
  437. collisionMesh.scaling = new Vector3(1, 1, 1).ToFloat();
  438. // Export Capsule Collider Metadata
  439. collisionData.tagName = "CapsuleCollider";
  440. collisionData.properties.Add("type", "Capsule");
  441. collisionData.properties.Add("center", capsuleCollider.center.ToFloat());
  442. collisionData.properties.Add("radius", capsuleCollider.radius);
  443. collisionData.properties.Add("height", capsuleCollider.height);
  444. collisionData.properties.Add("direction", capsuleCollider.direction);
  445. }
  446. else if (collider is SphereCollider)
  447. {
  448. var sphereCollider = collider as SphereCollider;
  449. collisionMesh = new BabylonMesh();
  450. collisionMesh.tags = "[SPHERECOLLIDER]";
  451. switch (detail)
  452. {
  453. case BabylonColliderDetail.FullResolution:
  454. segments = 48;
  455. break;
  456. case BabylonColliderDetail.HighResolution:
  457. segments = 32;
  458. break;
  459. case BabylonColliderDetail.MediumResolution:
  460. segments = 24;
  461. break;
  462. case BabylonColliderDetail.LowResolution:
  463. segments = 12;
  464. break;
  465. case BabylonColliderDetail.VeryLowResolution:
  466. segments = 8;
  467. break;
  468. case BabylonColliderDetail.MinimumResolution:
  469. segments = 6;
  470. break;
  471. default:
  472. segments = 12;
  473. break;
  474. }
  475. // Generate Sphere Collider Geometry
  476. Mesh sphereMesh = Tools.CreateSphereMesh(sphereCollider.radius, segments);
  477. Tools.GenerateBabylonMeshData(sphereMesh, collisionMesh);
  478. collisionMesh.position = new float[3];
  479. collisionMesh.position[0] = sphereCollider.center.x;
  480. collisionMesh.position[1] = sphereCollider.center.y;
  481. collisionMesh.position[2] = sphereCollider.center.z;
  482. collisionMesh.rotation = Vector3.zero.ToFloat();
  483. collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat();
  484. // Export Sphere Collider Metadata
  485. collisionData.tagName = "SphereCollider";
  486. collisionData.properties.Add("type", "Sphere");
  487. collisionData.properties.Add("center", sphereCollider.center.ToFloat());
  488. collisionData.properties.Add("radius", sphereCollider.radius);
  489. }
  490. else if (collider is WheelCollider)
  491. {
  492. var wheelCollider = collider as WheelCollider;
  493. collisionMesh = new BabylonMesh();
  494. collisionMesh.tags = "[WHEELCOLLIDER]";
  495. switch (detail)
  496. {
  497. case BabylonColliderDetail.FullResolution:
  498. segments = 128;
  499. break;
  500. case BabylonColliderDetail.HighResolution:
  501. segments = 64;
  502. break;
  503. case BabylonColliderDetail.MediumResolution:
  504. segments = 48;
  505. break;
  506. case BabylonColliderDetail.LowResolution:
  507. segments = 32;
  508. break;
  509. case BabylonColliderDetail.VeryLowResolution:
  510. segments = 24;
  511. break;
  512. case BabylonColliderDetail.MinimumResolution:
  513. segments = 16;
  514. break;
  515. default:
  516. segments = 32;
  517. break;
  518. }
  519. // Generate Wheel Collider Geometry
  520. Mesh wheelMesh = Tools.CreateWheelMesh(wheelCollider.suspensionDistance, wheelCollider.radius, segments);
  521. Tools.GenerateBabylonMeshData(wheelMesh, collisionMesh);
  522. collisionMesh.position = new float[3];
  523. collisionMesh.position[0] = wheelCollider.center.x;
  524. collisionMesh.position[1] = wheelCollider.center.y;
  525. collisionMesh.position[2] = wheelCollider.center.z;
  526. collisionMesh.rotation = new float[3];
  527. collisionMesh.rotation[0] = 0f;
  528. collisionMesh.rotation[1] = 0f;
  529. collisionMesh.rotation[2] = 90f * (float)Math.PI / 180;
  530. collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat();
  531. // Export Wheel Collider Metadata
  532. collisionData.tagName = "WheelCollider";
  533. collisionData.properties.Add("type", "Wheel");
  534. collisionData.properties.Add("center", wheelCollider.center.ToFloat());
  535. collisionData.properties.Add("radius", wheelCollider.radius);
  536. }
  537. else if (collider is BoxCollider)
  538. {
  539. var boxCollider = collider as BoxCollider;
  540. collisionMesh = new BabylonMesh();
  541. collisionMesh.tags = "[BOXCOLLIDER]";
  542. // Generate Box Collider Geometry
  543. Mesh boxMesh = Tools.CreateBoxMesh(boxCollider.size.x, boxCollider.size.y, boxCollider.size.z);
  544. Tools.GenerateBabylonMeshData(boxMesh, collisionMesh);
  545. collisionMesh.position = new float[3];
  546. collisionMesh.position[0] = boxCollider.center.x;
  547. collisionMesh.position[1] = boxCollider.center.y;
  548. collisionMesh.position[2] = boxCollider.center.z;
  549. collisionMesh.rotation = Vector3.zero.ToFloat();
  550. collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat();
  551. // Export Box Collider Metadata
  552. collisionData.tagName = "BoxCollider";
  553. collisionData.properties.Add("type", "Box");
  554. collisionData.properties.Add("center", boxCollider.center.ToFloat());
  555. collisionData.properties.Add("size", boxCollider.size.ToFloat());
  556. }
  557. if (collisionMesh != null)
  558. {
  559. collisionMesh.id = Guid.NewGuid().ToString();
  560. collisionMesh.name = gameObject.name + "_Collider";
  561. // Default Check Collisions False
  562. collisionMesh.checkCollisions = false;
  563. collisionMesh.isVisible = false;
  564. collisionData.properties.Add("parrentId", metaData.objectId);
  565. collisionData.properties.Add("transform", GetTransformPropertyValue(gameObject.transform));
  566. collisionMesh.metadata = collisionData;
  567. babylonScene.MeshesList.Add(collisionMesh);
  568. SceneBuilder.Metadata.properties["hasCollisionMeshes"] = true;
  569. }
  570. }
  571. }
  572. // Static meshes
  573. var meshFilter = gameObject.GetComponent<MeshFilter>();
  574. if (meshFilter != null)
  575. {
  576. ConvertUnityMeshToBabylon(meshFilter.sharedMesh, meshFilter.transform, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider);
  577. continue;
  578. }
  579. // Skinned meshes
  580. var skinnedMesh = gameObject.GetComponent<SkinnedMeshRenderer>();
  581. if (skinnedMesh != null)
  582. {
  583. var babylonMesh = ConvertUnityMeshToBabylon(skinnedMesh.sharedMesh, skinnedMesh.transform, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider);
  584. var skeleton = ConvertUnitySkeletonToBabylon(skinnedMesh.bones, skinnedMesh.sharedMesh.bindposes, skinnedMesh.transform, gameObject, progress);
  585. babylonMesh.skeletonId = skeleton.id;
  586. ExportSkeletonAnimation(skinnedMesh, babylonMesh, skeleton);
  587. continue;
  588. }
  589. // Scene lights
  590. var light = gameObject.GetComponent<Light>();
  591. if (light != null)
  592. {
  593. ConvertUnityLightToBabylon(light, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags);
  594. continue;
  595. }
  596. // Scene cameras
  597. var camera = gameObject.GetComponent<Camera>();
  598. if (camera != null)
  599. {
  600. ConvertUnityCameraToBabylon(camera, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags);
  601. if (SceneController != null && SceneController.skyboxOptions.exportSkybox)
  602. {
  603. ConvertUnitySkyboxToBabylon(camera, progress);
  604. }
  605. continue;
  606. }
  607. // Empty objects
  608. ConvertUnityEmptyObjectToBabylon(gameObject, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider);
  609. }
  610. // Materials
  611. foreach (var mat in materialsDictionary)
  612. {
  613. babylonScene.MaterialsList.Add(mat.Value);
  614. }
  615. foreach (var multiMat in multiMatDictionary)
  616. {
  617. babylonScene.MultiMaterialsList.Add(multiMat.Value);
  618. }
  619. // Collisions
  620. if (exportationOptions.ExportCollisions)
  621. {
  622. babylonScene.workerCollisions = exportationOptions.WorkerCollisions;
  623. if (SceneController != null) {
  624. babylonScene.gravity = SceneController.sceneOptions.defaultGravity.ToFloat();
  625. }
  626. }
  627. // Babylon Physics
  628. if (exportationOptions.ExportPhysics)
  629. {
  630. babylonScene.physicsEnabled = true;
  631. if (SceneController != null) {
  632. babylonScene.physicsGravity = SceneController.sceneOptions.defaultGravity.ToFloat();
  633. }
  634. }
  635. // Scene Controller
  636. if (SceneController != null)
  637. {
  638. Color ambientColor = SceneController.sceneOptions.ambientColor;
  639. float ambientLevel = SceneController.lightingOptions.lightLevel;
  640. Color ambientSpecular = SceneController.lightingOptions.specularColor;
  641. babylonScene.autoClear = SceneController.sceneOptions.autoClear;
  642. int fogmode = 0;
  643. if (RenderSettings.fog)
  644. {
  645. switch (RenderSettings.fogMode)
  646. {
  647. case FogMode.Exponential:
  648. fogmode = 1;
  649. break;
  650. case FogMode.ExponentialSquared:
  651. fogmode = 2;
  652. break;
  653. case FogMode.Linear:
  654. fogmode = 3;
  655. break;
  656. }
  657. }
  658. babylonScene.fogMode = fogmode;
  659. babylonScene.fogDensity = RenderSettings.fogDensity;
  660. babylonScene.fogColor = RenderSettings.fogColor.ToFloat();
  661. babylonScene.fogStart = RenderSettings.fogStartDistance;
  662. babylonScene.fogEnd = RenderSettings.fogEndDistance;
  663. if (exportationOptions.DefaultLightmapMode != (int)BabylonLightmapMode.FullLightBaking && SceneController.lightingOptions.lightMode == BabylonAmbientLighting.UnityAmbientLighting)
  664. {
  665. var ambientLight = new BabylonLight
  666. {
  667. name = "Ambient Light",
  668. id = Guid.NewGuid().ToString(),
  669. parentId = null,
  670. metadata = null,
  671. position = null,
  672. exponent = 1.0f,
  673. angle = 0.0f,
  674. type = 3
  675. };
  676. var ambientDirection = new Vector3(0.0f, 1.0f, 0.0f);
  677. Color ambientDiffuse = (RenderSettings.ambientMode == UnityEngine.Rendering.AmbientMode.Skybox) ? RenderSettings.ambientSkyColor : RenderSettings.ambientLight;
  678. ambientLight.intensity = RenderSettings.ambientIntensity * ambientLevel;
  679. ambientLight.direction = ambientDirection.ToFloat(); ;
  680. ambientLight.diffuse = ambientDiffuse.ToFloat();
  681. ambientLight.specular = ambientSpecular.ToFloat();
  682. ambientLight.groundColor = RenderSettings.ambientGroundColor.ToFloat();
  683. babylonScene.ambientColor = ambientColor.ToFloat();
  684. babylonScene.LightsList.Add(ambientLight);
  685. ExporterWindow.ReportProgress(0, "Exporting ambient light intensity at: " + ambientLight.intensity.ToString());
  686. }
  687. if (SceneController.sceneOptions.navigationMesh == BabylonNavigationMesh.EnableNavigation)
  688. {
  689. ExporterWindow.ReportProgress(0, "Parsing scene navigation mesh...");
  690. NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation();
  691. if (triangulatedNavMesh.vertices != null && triangulatedNavMesh.vertices.Length > 0 && triangulatedNavMesh.indices != null && triangulatedNavMesh.indices.Length > 0)
  692. {
  693. int vertexCount = triangulatedNavMesh.vertices.Length;
  694. if (vertexCount <= SceneBuilder.MAX_VERTEX_COUNT)
  695. {
  696. ExporterWindow.ReportProgress(0, "Generating navigation mesh vertices: " + vertexCount.ToString());
  697. var navData = new UnityMetaData();
  698. navData.type = "NavMesh";
  699. navData.objectId = Guid.NewGuid().ToString();
  700. navData.objectName = "Navigation_Mesh";
  701. var areaTable = new List<object>();
  702. string[] areaNavigation = GameObjectUtility.GetNavMeshAreaNames();
  703. foreach (string areaName in areaNavigation)
  704. {
  705. var bag = new Dictionary<string, object>();
  706. int areaIndex = NavMesh.GetAreaFromName(areaName);
  707. float areaCost = NavMesh.GetAreaCost(areaIndex);
  708. bag.Add("index", areaIndex);
  709. bag.Add("area", areaName);
  710. bag.Add("cost", areaCost);
  711. areaTable.Add(bag);
  712. }
  713. navData.properties.Add("table", areaTable);
  714. navData.properties.Add("areas", triangulatedNavMesh.areas);
  715. Mesh mesh = new Mesh();
  716. mesh.name = "sceneNavigationMesh";
  717. mesh.vertices = triangulatedNavMesh.vertices;
  718. mesh.triangles = triangulatedNavMesh.indices;
  719. mesh.RecalculateNormals();
  720. BabylonMesh babylonMesh = new BabylonMesh();
  721. babylonMesh.tags = "[NAVMESH]";
  722. babylonMesh.metadata = navData;
  723. babylonMesh.name = mesh.name;
  724. babylonMesh.id = Guid.NewGuid().ToString();
  725. babylonMesh.parentId = null;
  726. babylonMesh.position = Vector3.zero.ToFloat();
  727. babylonMesh.rotation = Vector3.zero.ToFloat();
  728. babylonMesh.scaling = new Vector3(1, 1, 1).ToFloat();
  729. babylonMesh.isVisible = false;
  730. babylonMesh.visibility = 0.75f;
  731. babylonMesh.checkCollisions = false;
  732. Tools.GenerateBabylonMeshData(mesh, babylonMesh);
  733. babylonScene.MeshesList.Add(babylonMesh);
  734. SceneBuilder.Metadata.properties["hasNavigationMesh"] = true;
  735. }
  736. else
  737. {
  738. UnityEngine.Debug.LogError("Navigation mesh exceeds max (65000) vertex limit: " + vertexCount.ToString());
  739. }
  740. }
  741. }
  742. if (SceneController.sceneOptions.particleSystems)
  743. {
  744. if (particleSystems != null && particleSystems.Count > 0)
  745. {
  746. babylonScene.particleSystems = particleSystems.ToArray();
  747. }
  748. }
  749. if (SceneController.sceneOptions.lensFlareSystems)
  750. {
  751. if (lensFlareSystems != null && lensFlareSystems.Count > 0)
  752. {
  753. var lfs_buffer = new List<BabylonLensFlareSystem>();
  754. foreach (var ulfs in lensFlareSystems)
  755. {
  756. var lfs = new BabylonLensFlareSystem();
  757. lfs.borderLimit = ulfs.borderLimit;
  758. lfs.emitterId = ulfs.emitterId;
  759. var lfx = new List<BabylonLensFlare>();
  760. foreach (var ulf in ulfs.lensFlares)
  761. {
  762. var lf = new BabylonLensFlare();
  763. lf.textureName = ulf.textureName;
  764. lf.position = ulf.position;
  765. lf.color = ulf.color;
  766. lf.size = ulf.size;
  767. lfx.Add(lf);
  768. }
  769. lfs.flares = lfx.ToArray();
  770. lfs_buffer.Add(lfs);
  771. }
  772. babylonScene.lensFlareSystems = lfs_buffer.ToArray();
  773. }
  774. }
  775. }
  776. }
  777. catch (Exception ex)
  778. {
  779. Debug.LogException(ex);
  780. }
  781. finally
  782. {
  783. babylonScene.metadata = SceneBuilder.Metadata;
  784. }
  785. }
  786. private void ParseLensFlares(GameObject gameObject, string emitterId, ref List<UnityFlareSystem> lens)
  787. {
  788. var flare = gameObject.GetComponent<BabylonFlareSystem>();
  789. if (flare != null && flare.exportFlare && flare.lensFlares != null && flare.lensFlares.Length > 0)
  790. {
  791. var flareSystem = new UnityFlareSystem();
  792. flareSystem.name = (!String.IsNullOrEmpty(flare.flareName)) ? flare.flareName : String.Format("lensFlareSystem#" + Guid.NewGuid().ToString());
  793. flareSystem.emitterId = emitterId;
  794. flareSystem.borderLimit = flare.borderLimit;
  795. var flareBuffer = new List<UnityFlareItem>();
  796. foreach (var flareItem in flare.lensFlares)
  797. {
  798. var item = new UnityFlareItem();
  799. item.size = flareItem.size;
  800. item.position = flareItem.position;
  801. item.color = flareItem.color.ToFloat();
  802. if (flareItem.texture != null)
  803. {
  804. var babylonTexture = new BabylonTexture();
  805. var texturePath = AssetDatabase.GetAssetPath(flareItem.texture);
  806. CopyTexture(texturePath, flareItem.texture, babylonTexture);
  807. item.textureName = Path.GetFileName(texturePath);
  808. }
  809. flareBuffer.Add(item);
  810. }
  811. flareSystem.lensFlares = flareBuffer.ToArray();
  812. lens.Add(flareSystem);
  813. }
  814. }
  815. private void ParseParticleSystems(GameObject gameObject, string emitterId, ref List<BabylonExport.Entities.BabylonParticleSystem> particles)
  816. {
  817. var particle = gameObject.GetComponent<UnityEditor.BabylonParticleSystem>();
  818. if (particle != null && particle.exportParticle)
  819. {
  820. var particleSystem = new BabylonExport.Entities.BabylonParticleSystem();
  821. particleSystem.name = (!String.IsNullOrEmpty(particle.particleName)) ? particle.particleName : String.Format("particalSystem#" + Guid.NewGuid().ToString());
  822. particleSystem.emitterId = emitterId;
  823. particleSystem.linkToEmitter = true;
  824. particleSystem.preventAutoStart = !particle.autoStart;
  825. particleSystem.textureMask = particle.textureMask.ToFloat();
  826. particleSystem.updateSpeed = particle.updateSpeed;
  827. particleSystem.emitRate = particle.emitRate;
  828. particleSystem.gravity = particle.gravity.ToFloat();
  829. particleSystem.blendMode = (int)particle.blendMode;
  830. particleSystem.capacity = particle.capacity;
  831. particleSystem.color1 = particle.color1.ToFloat();
  832. particleSystem.color2 = particle.color2.ToFloat();
  833. particleSystem.colorDead = particle.colorDead.ToFloat();
  834. particleSystem.direction1 = particle.direction1.ToFloat();
  835. particleSystem.direction2 = particle.direction2.ToFloat();
  836. particleSystem.minEmitBox = particle.minEmitBox.ToFloat();
  837. particleSystem.maxEmitBox = particle.maxEmitBox.ToFloat();
  838. particleSystem.minEmitPower = particle.minEmitPower;
  839. particleSystem.maxEmitPower = particle.maxEmitPower;
  840. particleSystem.minLifeTime = particle.minLifeTime;
  841. particleSystem.maxLifeTime = particle.maxLifeTime;
  842. particleSystem.minSize = particle.minSize;
  843. particleSystem.maxSize = particle.maxSize;
  844. particleSystem.minAngularSpeed = particle.minAngularSpeed;
  845. particleSystem.maxAngularSpeed = particle.maxAngularSpeed;
  846. particleSystem.targetStopFrame = particle.targetStopFrame;
  847. particleSystem.deadAlpha = particle.deadAlpha;
  848. if (particle.texture != null)
  849. {
  850. var babylonTexture = new BabylonTexture();
  851. var texturePath = AssetDatabase.GetAssetPath(particle.texture);
  852. CopyTexture(texturePath, particle.texture, babylonTexture);
  853. particleSystem.textureName = Path.GetFileName(texturePath);
  854. }
  855. particles.Add(particleSystem);
  856. }
  857. }
  858. private object GetComponentPropertyValue(FieldInfo field, BabylonScriptComponent component)
  859. {
  860. object result = null;
  861. object fvalue = field.GetValue(component);
  862. if (fvalue != null)
  863. {
  864. Type ftype = fvalue.GetType();
  865. if (typeof(System.Enum).IsAssignableFrom(ftype))
  866. {
  867. result = Convert.ToInt32((System.Enum)fvalue);
  868. }
  869. 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))
  870. {
  871. result = fvalue;
  872. }
  873. else if (typeof(System.String).IsAssignableFrom(ftype))
  874. {
  875. result = fvalue;
  876. }
  877. else if (typeof(Color).IsAssignableFrom(ftype))
  878. {
  879. var color = (Color)fvalue;
  880. result = new UnityBabylonColor { r = color.r, g = color.g, b = color.b, a = color.a };
  881. }
  882. else if (typeof(Vector2).IsAssignableFrom(ftype))
  883. {
  884. var vec2 = (Vector2)fvalue;
  885. result = new UnityBablylonVector2 { x = vec2.x, y = vec2.y };
  886. }
  887. else if (typeof(Vector3).IsAssignableFrom(ftype))
  888. {
  889. var vec3 = (Vector3)fvalue;
  890. result = new UnityBablylonVector3 { x = vec3.x, y = vec3.y, z = vec3.z };
  891. }
  892. else if (typeof(Vector4).IsAssignableFrom(ftype))
  893. {
  894. var vec4 = (Vector4)fvalue;
  895. result = new UnityBablylonVector4 { x = vec4.x, y = vec4.y, z = vec4.z, w = vec4.w };
  896. }
  897. else if (typeof(Transform).IsAssignableFrom(ftype))
  898. {
  899. var transform = (Transform)fvalue;
  900. result = GetTransformPropertyValue(transform);
  901. }
  902. else if (typeof(Texture2D).IsAssignableFrom(ftype))
  903. {
  904. var texture = (Texture2D)fvalue;
  905. result = GetTexturePropertyValue(texture);
  906. }
  907. else if (typeof(Cubemap).IsAssignableFrom(ftype))
  908. {
  909. var cubemap = (Cubemap)fvalue;
  910. result = GetCubemapPropertyValue(cubemap);
  911. }
  912. else if (typeof(Material).IsAssignableFrom(ftype))
  913. {
  914. var material = (Material)fvalue;
  915. result = GetMaterialPropertyValue(material);
  916. }
  917. else if (typeof(Shader).IsAssignableFrom(ftype))
  918. {
  919. var shader = (Shader)fvalue;
  920. result = GetShaderPropertyValue(shader);
  921. }
  922. else if (typeof(GameObject).IsAssignableFrom(ftype))
  923. {
  924. var gobject = (GameObject)fvalue;
  925. result = GetGamePropertyValue(gobject);
  926. }
  927. else if (typeof(AudioClip).IsAssignableFrom(ftype))
  928. {
  929. var aclip = (AudioClip)fvalue;
  930. result = GetAudioClipPropertyValue(aclip);
  931. }
  932. else if (typeof(EmbeddedAsset).IsAssignableFrom(ftype))
  933. {
  934. var easset = (EmbeddedAsset)fvalue;
  935. result = GetEmbeddedAssetPropertyValue(easset);
  936. }
  937. else if (typeof(TextAsset).IsAssignableFrom(ftype))
  938. {
  939. var tasset = (TextAsset)fvalue;
  940. result = GetTextAssetPropertyValue(tasset);
  941. }
  942. else if (typeof(DefaultAsset).IsAssignableFrom(ftype))
  943. {
  944. var dasset = (DefaultAsset)fvalue;
  945. result = GetDefaultAssetPropertyValue(dasset);
  946. }
  947. else if (ftype.IsArray)
  948. {
  949. 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))
  950. {
  951. result = fvalue;
  952. }
  953. else if (typeof(System.String[]).IsAssignableFrom(ftype))
  954. {
  955. result = fvalue;
  956. }
  957. else if (typeof(Color[]).IsAssignableFrom(ftype))
  958. {
  959. var colors = (Color[])fvalue;
  960. var colors_list = new List<UnityBabylonColor>();
  961. foreach (var color in colors)
  962. {
  963. colors_list.Add(new UnityBabylonColor { r = color.r, g = color.g, b = color.b, a = color.a });
  964. }
  965. result = colors_list.ToArray();
  966. }
  967. else if (typeof(Vector2[]).IsAssignableFrom(ftype))
  968. {
  969. var vecs2 = (Vector2[])fvalue;
  970. var vecs2_list = new List<UnityBablylonVector2>();
  971. foreach (var vec2 in vecs2)
  972. {
  973. vecs2_list.Add(new UnityBablylonVector2 { x = vec2.x, y = vec2.y });
  974. }
  975. result = vecs2_list.ToArray();
  976. }
  977. else if (typeof(Vector3[]).IsAssignableFrom(ftype))
  978. {
  979. var vecs3 = (Vector3[])fvalue;
  980. var vecs3_list = new List<UnityBablylonVector3>();
  981. foreach (var vec3 in vecs3)
  982. {
  983. vecs3_list.Add(new UnityBablylonVector3 { x = vec3.x, y = vec3.y, z = vec3.z });
  984. }
  985. result = vecs3_list.ToArray();
  986. }
  987. else if (typeof(Vector4[]).IsAssignableFrom(ftype))
  988. {
  989. var vecs4 = (Vector4[])fvalue;
  990. var vecs4_list = new List<UnityBablylonVector4>();
  991. foreach (var vec4 in vecs4)
  992. {
  993. vecs4_list.Add(new UnityBablylonVector4 { x = vec4.x, y = vec4.y, z = vec4.z, w = vec4.w });
  994. }
  995. result = vecs4_list.ToArray();
  996. }
  997. else if (typeof(Transform[]).IsAssignableFrom(ftype))
  998. {
  999. var transforms = (Transform[])fvalue;
  1000. var transform_list = new List<object>();
  1001. foreach (var transform in transforms)
  1002. {
  1003. transform_list.Add(GetTransformPropertyValue(transform));
  1004. }
  1005. result = transform_list.ToArray();
  1006. }
  1007. else if (typeof(Texture2D[]).IsAssignableFrom(ftype))
  1008. {
  1009. var textures = (Texture2D[])fvalue;
  1010. var texture_list = new List<object>();
  1011. foreach (var texture in textures)
  1012. {
  1013. texture_list.Add(GetTexturePropertyValue(texture));
  1014. }
  1015. result = texture_list.ToArray();
  1016. }
  1017. else if (typeof(Cubemap[]).IsAssignableFrom(ftype))
  1018. {
  1019. var cubemaps = (Cubemap[])fvalue;
  1020. var cubemap_list = new List<object>();
  1021. foreach (var cubemap in cubemaps)
  1022. {
  1023. cubemap_list.Add(GetCubemapPropertyValue(cubemap));
  1024. }
  1025. result = cubemap_list.ToArray();
  1026. }
  1027. else if (typeof(Material[]).IsAssignableFrom(ftype))
  1028. {
  1029. var materials = (Material[])fvalue;
  1030. var material_list = new List<object>();
  1031. foreach (var material in materials)
  1032. {
  1033. material_list.Add(GetMaterialPropertyValue(material));
  1034. }
  1035. result = material_list.ToArray();
  1036. }
  1037. else if (typeof(Shader[]).IsAssignableFrom(ftype))
  1038. {
  1039. var shaders = (Shader[])fvalue;
  1040. var shader_list = new List<object>();
  1041. foreach (var shader in shaders)
  1042. {
  1043. shader_list.Add(GetShaderPropertyValue(shader));
  1044. }
  1045. result = shader_list.ToArray();
  1046. }
  1047. else if (typeof(GameObject[]).IsAssignableFrom(ftype))
  1048. {
  1049. var gobjects = (GameObject[])fvalue;
  1050. var gobject_list = new List<object>();
  1051. foreach (var gobject in gobjects)
  1052. {
  1053. gobject_list.Add(GetGamePropertyValue(gobject));
  1054. }
  1055. result = gobject_list.ToArray();
  1056. }
  1057. else if (typeof(AudioClip[]).IsAssignableFrom(ftype))
  1058. {
  1059. var aclips = (AudioClip[])fvalue;
  1060. var aclip_list = new List<object>();
  1061. foreach (var aclip in aclips)
  1062. {
  1063. aclip_list.Add(GetAudioClipPropertyValue(aclip));
  1064. }
  1065. result = aclip_list.ToArray();
  1066. }
  1067. else if (typeof(EmbeddedAsset[]).IsAssignableFrom(ftype))
  1068. {
  1069. var eassets = (EmbeddedAsset[])fvalue;
  1070. var easset_list = new List<object>();
  1071. foreach (var easset in eassets)
  1072. {
  1073. easset_list.Add(GetEmbeddedAssetPropertyValue(easset));
  1074. }
  1075. result = easset_list.ToArray();
  1076. }
  1077. else if (typeof(TextAsset[]).IsAssignableFrom(ftype))
  1078. {
  1079. var tassets = (TextAsset[])fvalue;
  1080. var tasset_list = new List<object>();
  1081. foreach (var tasset in tassets)
  1082. {
  1083. tasset_list.Add(GetTextAssetPropertyValue(tasset));
  1084. }
  1085. result = tasset_list.ToArray();
  1086. }
  1087. else if (typeof(DefaultAsset[]).IsAssignableFrom(ftype))
  1088. {
  1089. var dassets = (DefaultAsset[])fvalue;
  1090. var dasset_list = new List<object>();
  1091. foreach (var dasset in dassets)
  1092. {
  1093. dasset_list.Add(GetDefaultAssetPropertyValue(dasset));
  1094. }
  1095. result = dasset_list.ToArray();
  1096. }
  1097. }
  1098. }
  1099. return result;
  1100. }
  1101. private object GetGamePropertyValue(GameObject game)
  1102. {
  1103. if (game == null) return null;
  1104. Dictionary<string, object> objectInfo = new Dictionary<string, object>();
  1105. objectInfo.Add("type", game.GetType().FullName);
  1106. objectInfo.Add("id", GetID(game));
  1107. objectInfo.Add("tag", game.tag);
  1108. objectInfo.Add("name", game.name);
  1109. objectInfo.Add("layer", game.layer);
  1110. objectInfo.Add("isStatic", game.isStatic);
  1111. objectInfo.Add("hideFlags", game.hideFlags.ToString());
  1112. return objectInfo;
  1113. }
  1114. private object GetTransformPropertyValue(Transform transform)
  1115. {
  1116. if (transform == null) return null;
  1117. Dictionary<string, object> position = new Dictionary<string, object>();
  1118. position.Add("x", transform.localPosition.x);
  1119. position.Add("y", transform.localPosition.y);
  1120. position.Add("z", transform.localPosition.z);
  1121. Dictionary<string, object> rotation = new Dictionary<string, object>();
  1122. rotation.Add("x", transform.localRotation.x);
  1123. rotation.Add("y", transform.localRotation.y);
  1124. rotation.Add("z", transform.localRotation.z);
  1125. Dictionary<string, object> scale = new Dictionary<string, object>();
  1126. scale.Add("x", transform.localScale.x);
  1127. scale.Add("y", transform.localScale.y);
  1128. scale.Add("z", transform.localScale.z);
  1129. Dictionary<string, object> transformInfo = new Dictionary<string, object>();
  1130. transformInfo.Add("type", transform.GetType().FullName);
  1131. transformInfo.Add("id", GetID(transform.gameObject));
  1132. transformInfo.Add("position", position);
  1133. transformInfo.Add("rotation", rotation);
  1134. transformInfo.Add("scale", scale);
  1135. return transformInfo;
  1136. }
  1137. private object GetMaterialPropertyValue(Material material)
  1138. {
  1139. if (material == null) return null;
  1140. BabylonMaterial babylonMaterial = DumpMaterial(material);
  1141. Dictionary<string, object> materialInfo = new Dictionary<string, object>();
  1142. materialInfo.Add("type", material.GetType().FullName);
  1143. materialInfo.Add("id", babylonMaterial.id);
  1144. materialInfo.Add("name", babylonMaterial.name);
  1145. materialInfo.Add("alpha", babylonMaterial.alpha);
  1146. materialInfo.Add("wireframe", babylonMaterial.wireframe);
  1147. materialInfo.Add("backFaceCulling", babylonMaterial.backFaceCulling);
  1148. return materialInfo;
  1149. }
  1150. private object GetTexturePropertyValue(Texture2D texture)
  1151. {
  1152. if (texture == null) return null;
  1153. var texturePath = AssetDatabase.GetAssetPath(texture);
  1154. if (String.IsNullOrEmpty(texturePath)) return null;
  1155. var babylonTexture = new BabylonTexture();
  1156. CopyTexture(texturePath, texture, babylonTexture);
  1157. Dictionary<string, object> textureInfo = new Dictionary<string, object>();
  1158. textureInfo.Add("type", texture.GetType().FullName);
  1159. textureInfo.Add("name", babylonTexture.name);
  1160. textureInfo.Add("level", babylonTexture.level);
  1161. textureInfo.Add("isCube", babylonTexture.isCube);
  1162. textureInfo.Add("hasAlpha", babylonTexture.hasAlpha);
  1163. textureInfo.Add("coordinatesMode", babylonTexture.coordinatesMode);
  1164. textureInfo.Add("coordinatesIndex", babylonTexture.coordinatesIndex);
  1165. return textureInfo;
  1166. }
  1167. private object GetCubemapPropertyValue(Cubemap cubemap)
  1168. {
  1169. if (cubemap == null) return null;
  1170. var texturePath = AssetDatabase.GetAssetPath(cubemap);
  1171. if (String.IsNullOrEmpty(texturePath)) return null;
  1172. var textureName = Path.GetFileName(texturePath);
  1173. var outputPath = Path.Combine(babylonScene.OutputPath, textureName);
  1174. File.Copy(texturePath, outputPath, true);
  1175. Dictionary<string, object> textureInfo = new Dictionary<string, object>();
  1176. textureInfo.Add("type", cubemap.GetType().FullName);
  1177. textureInfo.Add("name", textureName);
  1178. textureInfo.Add("width", cubemap.width);
  1179. textureInfo.Add("height", cubemap.height);
  1180. textureInfo.Add("anisoLevel", cubemap.anisoLevel);
  1181. textureInfo.Add("texelSizeX", cubemap.texelSize.x);
  1182. textureInfo.Add("texelSizeY", cubemap.texelSize.y);
  1183. textureInfo.Add("dimension", cubemap.dimension.ToString());
  1184. textureInfo.Add("filterMode", cubemap.filterMode.ToString());
  1185. textureInfo.Add("format", cubemap.format.ToString());
  1186. textureInfo.Add("hideFlags", cubemap.hideFlags.ToString());
  1187. textureInfo.Add("mipMapBias", cubemap.mipMapBias.ToString());
  1188. textureInfo.Add("mipmapCount", cubemap.mipmapCount.ToString());
  1189. textureInfo.Add("wrapMode", cubemap.wrapMode.ToString());
  1190. return textureInfo;
  1191. }
  1192. private object GetEmbeddedAssetPropertyValue(EmbeddedAsset embedded)
  1193. {
  1194. if (embedded == null) return null;
  1195. var assetPath = AssetDatabase.GetAssetPath(embedded.textAsset);
  1196. if (String.IsNullOrEmpty(assetPath)) return null;
  1197. var assetName = Path.GetFileName(assetPath);
  1198. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1199. assetInfo.Add("type", embedded.GetType().FullName);
  1200. assetInfo.Add("filename", assetName);
  1201. assetInfo.Add("embedded", true);
  1202. if (embedded.encoding == BabylonTextEncoding.RawBytes)
  1203. {
  1204. assetInfo.Add("base64", Convert.ToBase64String(embedded.textAsset.bytes));
  1205. }
  1206. else
  1207. {
  1208. assetInfo.Add("base64", Tools.FormatBase64(embedded.textAsset.text));
  1209. }
  1210. return assetInfo;
  1211. }
  1212. private object GetTextAssetPropertyValue(TextAsset asset)
  1213. {
  1214. if (asset == null) return null;
  1215. var assetPath = AssetDatabase.GetAssetPath(asset);
  1216. if (String.IsNullOrEmpty(assetPath)) return null;
  1217. var assetName = Path.GetFileName(assetPath);
  1218. var outputPath = Path.Combine(babylonScene.OutputPath, assetName);
  1219. File.Copy(assetPath, outputPath, true);
  1220. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1221. assetInfo.Add("type", asset.GetType().FullName);
  1222. assetInfo.Add("filename", assetName);
  1223. assetInfo.Add("embedded", false);
  1224. assetInfo.Add("base64", null);
  1225. return assetInfo;
  1226. }
  1227. private object GetAudioClipPropertyValue(AudioClip clip)
  1228. {
  1229. if (clip == null) return null;
  1230. var assetPath = AssetDatabase.GetAssetPath(clip);
  1231. if (String.IsNullOrEmpty(assetPath)) return null;
  1232. var assetName = Path.GetFileName(assetPath);
  1233. var outputPath = Path.Combine(babylonScene.OutputPath, assetName);
  1234. File.Copy(assetPath, outputPath, true);
  1235. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1236. assetInfo.Add("type", clip.GetType().FullName);
  1237. assetInfo.Add("filename", assetName);
  1238. assetInfo.Add("length", clip.length);
  1239. assetInfo.Add("channels", clip.channels);
  1240. assetInfo.Add("frequency", clip.frequency);
  1241. assetInfo.Add("samples", clip.samples);
  1242. return assetInfo;
  1243. }
  1244. private object GetDefaultAssetPropertyValue(DefaultAsset asset)
  1245. {
  1246. if (asset == null) return null;
  1247. var assetPath = AssetDatabase.GetAssetPath(asset);
  1248. if (String.IsNullOrEmpty(assetPath)) return null;
  1249. var assetName = Path.GetFileName(assetPath);
  1250. var outputPath = Path.Combine(babylonScene.OutputPath, assetName);
  1251. File.Copy(assetPath, outputPath, true);
  1252. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1253. assetInfo.Add("type", asset.GetType().FullName);
  1254. assetInfo.Add("filename", assetName);
  1255. return assetInfo;
  1256. }
  1257. private object GetShaderPropertyValue(Shader shader)
  1258. {
  1259. if (shader == null || shader.name.Substring(0, 10) != "BabylonJS/") return null;
  1260. string filename = AssetDatabase.GetAssetPath(shader);
  1261. if (String.IsNullOrEmpty(filename)) return null;
  1262. List<string> attributeList = new List<string>();
  1263. List<string> uniformList = new List<string>();
  1264. List<string> samplerList = new List<string>();
  1265. List<string> defineList = new List<string>();
  1266. var result = new Dictionary<string, object>();
  1267. string program = Tools.LoadTextAsset(filename);
  1268. string basename = shader.name.Replace("BabylonJS/", "").Replace("/", "_").Replace(" ", "");
  1269. string babylonOptions = GetShaderProgramSection(basename, program, BabylonProgramSection.Babylon);
  1270. string[] babylonLines = babylonOptions.Split('\n');
  1271. foreach (string babylonLine in babylonLines)
  1272. {
  1273. if (babylonLine.IndexOf("attributes", StringComparison.OrdinalIgnoreCase) >= 0)
  1274. {
  1275. string[] attributes = babylonLine.Split(':');
  1276. if (attributes != null && attributes.Length > 1)
  1277. {
  1278. string abuffer = attributes[1].Replace("[", "").Replace("]", "").Replace("\"", "");
  1279. if (!String.IsNullOrEmpty(abuffer))
  1280. {
  1281. abuffer = abuffer.Trim();
  1282. string[] adata = abuffer.Split(',');
  1283. if (adata != null && adata.Length > 0)
  1284. {
  1285. foreach (string aoption in adata)
  1286. {
  1287. string aoption_buffer = aoption.Trim();
  1288. if (!String.IsNullOrEmpty(aoption_buffer))
  1289. {
  1290. attributeList.Add(aoption_buffer);
  1291. }
  1292. }
  1293. }
  1294. }
  1295. }
  1296. }
  1297. else if (babylonLine.IndexOf("uniforms", StringComparison.OrdinalIgnoreCase) >= 0)
  1298. {
  1299. string[] uniforms = babylonLine.Split(':');
  1300. if (uniforms != null && uniforms.Length > 1)
  1301. {
  1302. string ubuffer = uniforms[1].Replace("[", "").Replace("]", "").Replace("\"", "");
  1303. if (!String.IsNullOrEmpty(ubuffer))
  1304. {
  1305. ubuffer = ubuffer.Trim();
  1306. string[] udata = ubuffer.Split(',');
  1307. if (udata != null && udata.Length > 0)
  1308. {
  1309. foreach (string uoption in udata)
  1310. {
  1311. string uoption_buffer = uoption.Trim();
  1312. if (!String.IsNullOrEmpty(uoption_buffer))
  1313. {
  1314. uniformList.Add(uoption_buffer);
  1315. }
  1316. }
  1317. }
  1318. }
  1319. }
  1320. }
  1321. else if (babylonLine.IndexOf("samplers", StringComparison.OrdinalIgnoreCase) >= 0)
  1322. {
  1323. string[] samplers = babylonLine.Split(':');
  1324. if (samplers != null && samplers.Length > 1)
  1325. {
  1326. string sbuffer = samplers[1].Replace("[", "").Replace("]", "").Replace("\"", "");
  1327. if (!String.IsNullOrEmpty(sbuffer))
  1328. {
  1329. sbuffer = sbuffer.Trim();
  1330. string[] sdata = sbuffer.Split(',');
  1331. if (sdata != null && sdata.Length > 0)
  1332. {
  1333. foreach (string soption in sdata)
  1334. {
  1335. string soption_buffer = soption.Trim();
  1336. if (!String.IsNullOrEmpty(soption_buffer))
  1337. {
  1338. samplerList.Add(soption_buffer);
  1339. }
  1340. }
  1341. }
  1342. }
  1343. }
  1344. }
  1345. else if (babylonLine.IndexOf("defines", StringComparison.OrdinalIgnoreCase) >= 0)
  1346. {
  1347. string[] defines = babylonLine.Split(':');
  1348. if (defines != null && defines.Length > 1)
  1349. {
  1350. string dbuffer = defines[1].Replace("[", "").Replace("]", "").Replace("\"", "");
  1351. if (!String.IsNullOrEmpty(dbuffer))
  1352. {
  1353. dbuffer = dbuffer.Trim();
  1354. string[] ddata = dbuffer.Split(',');
  1355. if (ddata != null && ddata.Length > 0)
  1356. {
  1357. foreach (string doption in ddata)
  1358. {
  1359. string doption_buffer = doption.Trim();
  1360. if (!String.IsNullOrEmpty(doption_buffer))
  1361. {
  1362. defineList.Add(doption_buffer);
  1363. }
  1364. }
  1365. }
  1366. }
  1367. }
  1368. }
  1369. }
  1370. var shaderPath = new Dictionary<string, object>();
  1371. string vertexProgram = GetShaderProgramSection(basename, program, BabylonProgramSection.Vertex);
  1372. shaderPath.Add("vertexElement", ("base64:" + Tools.FormatBase64(vertexProgram)));
  1373. string fragmentProgram = GetShaderProgramSection(basename, program, BabylonProgramSection.Fragment);
  1374. shaderPath.Add("fragmentElement", ("base64:" + Tools.FormatBase64(fragmentProgram)));
  1375. result.Add("shaderPath", shaderPath);
  1376. var options = new BabylonShaderOptions();
  1377. options.attributes = attributeList.ToArray();
  1378. options.uniforms = uniformList.ToArray();
  1379. options.samplers = samplerList.ToArray();
  1380. options.defines = defineList.ToArray();
  1381. var shaderOptions = new Dictionary<string, object>();
  1382. shaderOptions.Add("attributes", options.attributes);
  1383. shaderOptions.Add("needAlphaBlending", false);
  1384. shaderOptions.Add("needAlphaTesting", false);
  1385. shaderOptions.Add("uniforms", options.uniforms);
  1386. shaderOptions.Add("samplers", options.samplers);
  1387. shaderOptions.Add("defines", options.defines);
  1388. result.Add("shaderOptions", shaderOptions);
  1389. return result;
  1390. }
  1391. private static void ExportSkeletonAnimation(SkinnedMeshRenderer skinnedMesh, BabylonMesh babylonMesh, BabylonSkeleton skeleton)
  1392. {
  1393. var animator = skinnedMesh.rootBone.gameObject.GetComponent<Animator>();
  1394. if (animator != null)
  1395. {
  1396. ExportSkeletonAnimationClips(animator, true, skeleton, skinnedMesh.bones, babylonMesh);
  1397. }
  1398. else
  1399. {
  1400. var parent = skinnedMesh.rootBone.parent;
  1401. while (parent != null)
  1402. {
  1403. animator = parent.gameObject.GetComponent<Animator>();
  1404. if (animator != null)
  1405. {
  1406. ExportSkeletonAnimationClips(animator, true, skeleton, skinnedMesh.bones, babylonMesh);
  1407. break;
  1408. }
  1409. parent = parent.parent;
  1410. }
  1411. }
  1412. }
  1413. }
  1414. }