SceneBuilder.cs 81 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477
  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.gravity = exportationOptions.Gravity.ToFloat();
  623. babylonScene.workerCollisions = exportationOptions.WorkerCollisions;
  624. }
  625. // Babylon Physics
  626. if (exportationOptions.ExportPhysics)
  627. {
  628. babylonScene.physicsEnabled = true;
  629. babylonScene.physicsGravity = exportationOptions.Gravity.ToFloat();
  630. }
  631. // Scene Controller
  632. if (SceneController != null)
  633. {
  634. Color ambientColor = SceneController.sceneOptions.ambientColor;
  635. float ambientLevel = SceneController.lightingOptions.lightLevel;
  636. Color ambientSpecular = SceneController.lightingOptions.specularColor;
  637. babylonScene.autoClear = SceneController.sceneOptions.autoClear;
  638. int fogmode = 0;
  639. if (RenderSettings.fog)
  640. {
  641. switch (RenderSettings.fogMode)
  642. {
  643. case FogMode.Exponential:
  644. fogmode = 1;
  645. break;
  646. case FogMode.ExponentialSquared:
  647. fogmode = 2;
  648. break;
  649. case FogMode.Linear:
  650. fogmode = 3;
  651. break;
  652. }
  653. }
  654. babylonScene.fogMode = fogmode;
  655. babylonScene.fogDensity = RenderSettings.fogDensity;
  656. babylonScene.fogColor = RenderSettings.fogColor.ToFloat();
  657. babylonScene.fogStart = RenderSettings.fogStartDistance;
  658. babylonScene.fogEnd = RenderSettings.fogEndDistance;
  659. if (exportationOptions.DefaultLightmapMode != (int)BabylonLightmapMode.FullLightBaking && SceneController.lightingOptions.lightMode == BabylonAmbientLighting.UnityAmbientLighting)
  660. {
  661. var ambientLight = new BabylonLight
  662. {
  663. name = "Ambient Light",
  664. id = Guid.NewGuid().ToString(),
  665. parentId = null,
  666. metadata = null,
  667. position = null,
  668. exponent = 1.0f,
  669. angle = 0.0f,
  670. type = 3
  671. };
  672. var ambientDirection = new Vector3(0.0f, 1.0f, 0.0f);
  673. Color ambientDiffuse = (RenderSettings.ambientMode == UnityEngine.Rendering.AmbientMode.Skybox) ? RenderSettings.ambientSkyColor : RenderSettings.ambientLight;
  674. ambientLight.intensity = RenderSettings.ambientIntensity * ambientLevel;
  675. ambientLight.direction = ambientDirection.ToFloat(); ;
  676. ambientLight.diffuse = ambientDiffuse.ToFloat();
  677. ambientLight.specular = ambientSpecular.ToFloat();
  678. ambientLight.groundColor = RenderSettings.ambientGroundColor.ToFloat();
  679. babylonScene.ambientColor = ambientColor.ToFloat();
  680. babylonScene.LightsList.Add(ambientLight);
  681. ExporterWindow.ReportProgress(0, "Exporting ambient light intensity at: " + ambientLight.intensity.ToString());
  682. }
  683. if (SceneController.sceneOptions.navigationMesh == BabylonNavigationMesh.EnableNavigation)
  684. {
  685. ExporterWindow.ReportProgress(0, "Parsing scene navigation mesh...");
  686. NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation();
  687. if (triangulatedNavMesh.vertices != null && triangulatedNavMesh.vertices.Length > 0 && triangulatedNavMesh.indices != null && triangulatedNavMesh.indices.Length > 0)
  688. {
  689. int vertexCount = triangulatedNavMesh.vertices.Length;
  690. if (vertexCount <= SceneBuilder.MAX_VERTEX_COUNT)
  691. {
  692. ExporterWindow.ReportProgress(0, "Generating navigation mesh vertices: " + vertexCount.ToString());
  693. var navData = new UnityMetaData();
  694. navData.type = "NavMesh";
  695. navData.objectId = Guid.NewGuid().ToString();
  696. navData.objectName = "Navigation_Mesh";
  697. var areaTable = new List<object>();
  698. string[] areaNavigation = GameObjectUtility.GetNavMeshAreaNames();
  699. foreach (string areaName in areaNavigation)
  700. {
  701. var bag = new Dictionary<string, object>();
  702. int areaIndex = NavMesh.GetAreaFromName(areaName);
  703. float areaCost = NavMesh.GetAreaCost(areaIndex);
  704. bag.Add("index", areaIndex);
  705. bag.Add("area", areaName);
  706. bag.Add("cost", areaCost);
  707. areaTable.Add(bag);
  708. }
  709. navData.properties.Add("table", areaTable);
  710. navData.properties.Add("areas", triangulatedNavMesh.areas);
  711. Mesh mesh = new Mesh();
  712. mesh.name = "sceneNavigationMesh";
  713. mesh.vertices = triangulatedNavMesh.vertices;
  714. mesh.triangles = triangulatedNavMesh.indices;
  715. mesh.RecalculateNormals();
  716. BabylonMesh babylonMesh = new BabylonMesh();
  717. babylonMesh.tags = "[NAVMESH]";
  718. babylonMesh.metadata = navData;
  719. babylonMesh.name = mesh.name;
  720. babylonMesh.id = Guid.NewGuid().ToString();
  721. babylonMesh.parentId = null;
  722. babylonMesh.position = Vector3.zero.ToFloat();
  723. babylonMesh.rotation = Vector3.zero.ToFloat();
  724. babylonMesh.scaling = new Vector3(1, 1, 1).ToFloat();
  725. babylonMesh.isVisible = false;
  726. babylonMesh.visibility = 0.75f;
  727. babylonMesh.checkCollisions = false;
  728. Tools.GenerateBabylonMeshData(mesh, babylonMesh);
  729. babylonScene.MeshesList.Add(babylonMesh);
  730. SceneBuilder.Metadata.properties["hasNavigationMesh"] = true;
  731. }
  732. else
  733. {
  734. UnityEngine.Debug.LogError("Navigation mesh exceeds max (65000) vertex limit: " + vertexCount.ToString());
  735. }
  736. }
  737. }
  738. if (SceneController.sceneOptions.particleSystems)
  739. {
  740. if (particleSystems != null && particleSystems.Count > 0)
  741. {
  742. babylonScene.particleSystems = particleSystems.ToArray();
  743. }
  744. }
  745. if (SceneController.sceneOptions.lensFlareSystems)
  746. {
  747. if (lensFlareSystems != null && lensFlareSystems.Count > 0)
  748. {
  749. var lfs_buffer = new List<BabylonLensFlareSystem>();
  750. foreach (var ulfs in lensFlareSystems)
  751. {
  752. var lfs = new BabylonLensFlareSystem();
  753. lfs.borderLimit = ulfs.borderLimit;
  754. lfs.emitterId = ulfs.emitterId;
  755. var lfx = new List<BabylonLensFlare>();
  756. foreach (var ulf in ulfs.lensFlares)
  757. {
  758. var lf = new BabylonLensFlare();
  759. lf.textureName = ulf.textureName;
  760. lf.position = ulf.position;
  761. lf.color = ulf.color;
  762. lf.size = ulf.size;
  763. lfx.Add(lf);
  764. }
  765. lfs.flares = lfx.ToArray();
  766. lfs_buffer.Add(lfs);
  767. }
  768. babylonScene.lensFlareSystems = lfs_buffer.ToArray();
  769. }
  770. }
  771. }
  772. }
  773. catch (Exception ex)
  774. {
  775. Debug.LogException(ex);
  776. }
  777. finally
  778. {
  779. babylonScene.metadata = SceneBuilder.Metadata;
  780. }
  781. }
  782. private void ParseLensFlares(GameObject gameObject, string emitterId, ref List<UnityFlareSystem> lens)
  783. {
  784. var flare = gameObject.GetComponent<BabylonFlareSystem>();
  785. if (flare != null && flare.exportFlare && flare.lensFlares != null && flare.lensFlares.Length > 0)
  786. {
  787. var flareSystem = new UnityFlareSystem();
  788. flareSystem.name = (!String.IsNullOrEmpty(flare.flareName)) ? flare.flareName : String.Format("lensFlareSystem#" + Guid.NewGuid().ToString());
  789. flareSystem.emitterId = emitterId;
  790. flareSystem.borderLimit = flare.borderLimit;
  791. var flareBuffer = new List<UnityFlareItem>();
  792. foreach (var flareItem in flare.lensFlares)
  793. {
  794. var item = new UnityFlareItem();
  795. item.size = flareItem.size;
  796. item.position = flareItem.position;
  797. item.color = flareItem.color.ToFloat();
  798. if (flareItem.texture != null)
  799. {
  800. var babylonTexture = new BabylonTexture();
  801. var texturePath = AssetDatabase.GetAssetPath(flareItem.texture);
  802. CopyTexture(texturePath, flareItem.texture, babylonTexture);
  803. item.textureName = Path.GetFileName(texturePath);
  804. }
  805. flareBuffer.Add(item);
  806. }
  807. flareSystem.lensFlares = flareBuffer.ToArray();
  808. lens.Add(flareSystem);
  809. }
  810. }
  811. private void ParseParticleSystems(GameObject gameObject, string emitterId, ref List<BabylonExport.Entities.BabylonParticleSystem> particles)
  812. {
  813. var particle = gameObject.GetComponent<UnityEditor.BabylonParticleSystem>();
  814. if (particle != null && particle.exportParticle)
  815. {
  816. var particleSystem = new BabylonExport.Entities.BabylonParticleSystem();
  817. particleSystem.name = (!String.IsNullOrEmpty(particle.particleName)) ? particle.particleName : String.Format("particalSystem#" + Guid.NewGuid().ToString());
  818. particleSystem.emitterId = emitterId;
  819. particleSystem.linkToEmitter = true;
  820. particleSystem.preventAutoStart = !particle.autoStart;
  821. particleSystem.textureMask = particle.textureMask.ToFloat();
  822. particleSystem.updateSpeed = particle.updateSpeed;
  823. particleSystem.emitRate = particle.emitRate;
  824. particleSystem.gravity = particle.gravity.ToFloat();
  825. particleSystem.blendMode = (int)particle.blendMode;
  826. particleSystem.capacity = particle.capacity;
  827. particleSystem.color1 = particle.color1.ToFloat();
  828. particleSystem.color2 = particle.color2.ToFloat();
  829. particleSystem.colorDead = particle.colorDead.ToFloat();
  830. particleSystem.direction1 = particle.direction1.ToFloat();
  831. particleSystem.direction2 = particle.direction2.ToFloat();
  832. particleSystem.minEmitBox = particle.minEmitBox.ToFloat();
  833. particleSystem.maxEmitBox = particle.maxEmitBox.ToFloat();
  834. particleSystem.minEmitPower = particle.minEmitPower;
  835. particleSystem.maxEmitPower = particle.maxEmitPower;
  836. particleSystem.minLifeTime = particle.minLifeTime;
  837. particleSystem.maxLifeTime = particle.maxLifeTime;
  838. particleSystem.minSize = particle.minSize;
  839. particleSystem.maxSize = particle.maxSize;
  840. particleSystem.minAngularSpeed = particle.minAngularSpeed;
  841. particleSystem.maxAngularSpeed = particle.maxAngularSpeed;
  842. particleSystem.targetStopFrame = particle.targetStopFrame;
  843. particleSystem.deadAlpha = particle.deadAlpha;
  844. if (particle.texture != null)
  845. {
  846. var babylonTexture = new BabylonTexture();
  847. var texturePath = AssetDatabase.GetAssetPath(particle.texture);
  848. CopyTexture(texturePath, particle.texture, babylonTexture);
  849. particleSystem.textureName = Path.GetFileName(texturePath);
  850. }
  851. particles.Add(particleSystem);
  852. }
  853. }
  854. private object GetComponentPropertyValue(FieldInfo field, BabylonScriptComponent component)
  855. {
  856. object result = null;
  857. object fvalue = field.GetValue(component);
  858. if (fvalue != null)
  859. {
  860. Type ftype = fvalue.GetType();
  861. if (typeof(System.Enum).IsAssignableFrom(ftype))
  862. {
  863. result = Convert.ToInt32((System.Enum)fvalue);
  864. }
  865. 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))
  866. {
  867. result = fvalue;
  868. }
  869. else if (typeof(System.String).IsAssignableFrom(ftype))
  870. {
  871. result = fvalue;
  872. }
  873. else if (typeof(Color).IsAssignableFrom(ftype))
  874. {
  875. var color = (Color)fvalue;
  876. result = new UnityBabylonColor { r = color.r, g = color.g, b = color.b, a = color.a };
  877. }
  878. else if (typeof(Vector2).IsAssignableFrom(ftype))
  879. {
  880. var vec2 = (Vector2)fvalue;
  881. result = new UnityBablylonVector2 { x = vec2.x, y = vec2.y };
  882. }
  883. else if (typeof(Vector3).IsAssignableFrom(ftype))
  884. {
  885. var vec3 = (Vector3)fvalue;
  886. result = new UnityBablylonVector3 { x = vec3.x, y = vec3.y, z = vec3.z };
  887. }
  888. else if (typeof(Vector4).IsAssignableFrom(ftype))
  889. {
  890. var vec4 = (Vector4)fvalue;
  891. result = new UnityBablylonVector4 { x = vec4.x, y = vec4.y, z = vec4.z, w = vec4.w };
  892. }
  893. else if (typeof(Transform).IsAssignableFrom(ftype))
  894. {
  895. var transform = (Transform)fvalue;
  896. result = GetTransformPropertyValue(transform);
  897. }
  898. else if (typeof(Texture2D).IsAssignableFrom(ftype))
  899. {
  900. var texture = (Texture2D)fvalue;
  901. result = GetTexturePropertyValue(texture);
  902. }
  903. else if (typeof(Cubemap).IsAssignableFrom(ftype))
  904. {
  905. var cubemap = (Cubemap)fvalue;
  906. result = GetCubemapPropertyValue(cubemap);
  907. }
  908. else if (typeof(Material).IsAssignableFrom(ftype))
  909. {
  910. var material = (Material)fvalue;
  911. result = GetMaterialPropertyValue(material);
  912. }
  913. else if (typeof(Shader).IsAssignableFrom(ftype))
  914. {
  915. var shader = (Shader)fvalue;
  916. result = GetShaderPropertyValue(shader);
  917. }
  918. else if (typeof(GameObject).IsAssignableFrom(ftype))
  919. {
  920. var gobject = (GameObject)fvalue;
  921. result = GetGamePropertyValue(gobject);
  922. }
  923. else if (typeof(AudioClip).IsAssignableFrom(ftype))
  924. {
  925. var aclip = (AudioClip)fvalue;
  926. result = GetAudioClipPropertyValue(aclip);
  927. }
  928. else if (typeof(EmbeddedAsset).IsAssignableFrom(ftype))
  929. {
  930. var easset = (EmbeddedAsset)fvalue;
  931. result = GetEmbeddedAssetPropertyValue(easset);
  932. }
  933. else if (typeof(TextAsset).IsAssignableFrom(ftype))
  934. {
  935. var tasset = (TextAsset)fvalue;
  936. result = GetTextAssetPropertyValue(tasset);
  937. }
  938. else if (typeof(DefaultAsset).IsAssignableFrom(ftype))
  939. {
  940. var dasset = (DefaultAsset)fvalue;
  941. result = GetDefaultAssetPropertyValue(dasset);
  942. }
  943. else if (ftype.IsArray)
  944. {
  945. 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))
  946. {
  947. result = fvalue;
  948. }
  949. else if (typeof(System.String[]).IsAssignableFrom(ftype))
  950. {
  951. result = fvalue;
  952. }
  953. else if (typeof(Color[]).IsAssignableFrom(ftype))
  954. {
  955. var colors = (Color[])fvalue;
  956. var colors_list = new List<UnityBabylonColor>();
  957. foreach (var color in colors)
  958. {
  959. colors_list.Add(new UnityBabylonColor { r = color.r, g = color.g, b = color.b, a = color.a });
  960. }
  961. result = colors_list.ToArray();
  962. }
  963. else if (typeof(Vector2[]).IsAssignableFrom(ftype))
  964. {
  965. var vecs2 = (Vector2[])fvalue;
  966. var vecs2_list = new List<UnityBablylonVector2>();
  967. foreach (var vec2 in vecs2)
  968. {
  969. vecs2_list.Add(new UnityBablylonVector2 { x = vec2.x, y = vec2.y });
  970. }
  971. result = vecs2_list.ToArray();
  972. }
  973. else if (typeof(Vector3[]).IsAssignableFrom(ftype))
  974. {
  975. var vecs3 = (Vector3[])fvalue;
  976. var vecs3_list = new List<UnityBablylonVector3>();
  977. foreach (var vec3 in vecs3)
  978. {
  979. vecs3_list.Add(new UnityBablylonVector3 { x = vec3.x, y = vec3.y, z = vec3.z });
  980. }
  981. result = vecs3_list.ToArray();
  982. }
  983. else if (typeof(Vector4[]).IsAssignableFrom(ftype))
  984. {
  985. var vecs4 = (Vector4[])fvalue;
  986. var vecs4_list = new List<UnityBablylonVector4>();
  987. foreach (var vec4 in vecs4)
  988. {
  989. vecs4_list.Add(new UnityBablylonVector4 { x = vec4.x, y = vec4.y, z = vec4.z, w = vec4.w });
  990. }
  991. result = vecs4_list.ToArray();
  992. }
  993. else if (typeof(Transform[]).IsAssignableFrom(ftype))
  994. {
  995. var transforms = (Transform[])fvalue;
  996. var transform_list = new List<object>();
  997. foreach (var transform in transforms)
  998. {
  999. transform_list.Add(GetTransformPropertyValue(transform));
  1000. }
  1001. result = transform_list.ToArray();
  1002. }
  1003. else if (typeof(Texture2D[]).IsAssignableFrom(ftype))
  1004. {
  1005. var textures = (Texture2D[])fvalue;
  1006. var texture_list = new List<object>();
  1007. foreach (var texture in textures)
  1008. {
  1009. texture_list.Add(GetTexturePropertyValue(texture));
  1010. }
  1011. result = texture_list.ToArray();
  1012. }
  1013. else if (typeof(Cubemap[]).IsAssignableFrom(ftype))
  1014. {
  1015. var cubemaps = (Cubemap[])fvalue;
  1016. var cubemap_list = new List<object>();
  1017. foreach (var cubemap in cubemaps)
  1018. {
  1019. cubemap_list.Add(GetCubemapPropertyValue(cubemap));
  1020. }
  1021. result = cubemap_list.ToArray();
  1022. }
  1023. else if (typeof(Material[]).IsAssignableFrom(ftype))
  1024. {
  1025. var materials = (Material[])fvalue;
  1026. var material_list = new List<object>();
  1027. foreach (var material in materials)
  1028. {
  1029. material_list.Add(GetMaterialPropertyValue(material));
  1030. }
  1031. result = material_list.ToArray();
  1032. }
  1033. else if (typeof(Shader[]).IsAssignableFrom(ftype))
  1034. {
  1035. var shaders = (Shader[])fvalue;
  1036. var shader_list = new List<object>();
  1037. foreach (var shader in shaders)
  1038. {
  1039. shader_list.Add(GetShaderPropertyValue(shader));
  1040. }
  1041. result = shader_list.ToArray();
  1042. }
  1043. else if (typeof(GameObject[]).IsAssignableFrom(ftype))
  1044. {
  1045. var gobjects = (GameObject[])fvalue;
  1046. var gobject_list = new List<object>();
  1047. foreach (var gobject in gobjects)
  1048. {
  1049. gobject_list.Add(GetGamePropertyValue(gobject));
  1050. }
  1051. result = gobject_list.ToArray();
  1052. }
  1053. else if (typeof(AudioClip[]).IsAssignableFrom(ftype))
  1054. {
  1055. var aclips = (AudioClip[])fvalue;
  1056. var aclip_list = new List<object>();
  1057. foreach (var aclip in aclips)
  1058. {
  1059. aclip_list.Add(GetAudioClipPropertyValue(aclip));
  1060. }
  1061. result = aclip_list.ToArray();
  1062. }
  1063. else if (typeof(EmbeddedAsset[]).IsAssignableFrom(ftype))
  1064. {
  1065. var eassets = (EmbeddedAsset[])fvalue;
  1066. var easset_list = new List<object>();
  1067. foreach (var easset in eassets)
  1068. {
  1069. easset_list.Add(GetEmbeddedAssetPropertyValue(easset));
  1070. }
  1071. result = easset_list.ToArray();
  1072. }
  1073. else if (typeof(TextAsset[]).IsAssignableFrom(ftype))
  1074. {
  1075. var tassets = (TextAsset[])fvalue;
  1076. var tasset_list = new List<object>();
  1077. foreach (var tasset in tassets)
  1078. {
  1079. tasset_list.Add(GetTextAssetPropertyValue(tasset));
  1080. }
  1081. result = tasset_list.ToArray();
  1082. }
  1083. else if (typeof(DefaultAsset[]).IsAssignableFrom(ftype))
  1084. {
  1085. var dassets = (DefaultAsset[])fvalue;
  1086. var dasset_list = new List<object>();
  1087. foreach (var dasset in dassets)
  1088. {
  1089. dasset_list.Add(GetDefaultAssetPropertyValue(dasset));
  1090. }
  1091. result = dasset_list.ToArray();
  1092. }
  1093. }
  1094. }
  1095. return result;
  1096. }
  1097. private object GetGamePropertyValue(GameObject game)
  1098. {
  1099. if (game == null) return null;
  1100. Dictionary<string, object> objectInfo = new Dictionary<string, object>();
  1101. objectInfo.Add("type", game.GetType().FullName);
  1102. objectInfo.Add("id", GetID(game));
  1103. objectInfo.Add("tag", game.tag);
  1104. objectInfo.Add("name", game.name);
  1105. objectInfo.Add("layer", game.layer);
  1106. objectInfo.Add("isStatic", game.isStatic);
  1107. objectInfo.Add("hideFlags", game.hideFlags.ToString());
  1108. return objectInfo;
  1109. }
  1110. private object GetTransformPropertyValue(Transform transform)
  1111. {
  1112. if (transform == null) return null;
  1113. Dictionary<string, object> position = new Dictionary<string, object>();
  1114. position.Add("x", transform.localPosition.x);
  1115. position.Add("y", transform.localPosition.y);
  1116. position.Add("z", transform.localPosition.z);
  1117. Dictionary<string, object> rotation = new Dictionary<string, object>();
  1118. rotation.Add("x", transform.localRotation.x);
  1119. rotation.Add("y", transform.localRotation.y);
  1120. rotation.Add("z", transform.localRotation.z);
  1121. Dictionary<string, object> scale = new Dictionary<string, object>();
  1122. scale.Add("x", transform.localScale.x);
  1123. scale.Add("y", transform.localScale.y);
  1124. scale.Add("z", transform.localScale.z);
  1125. Dictionary<string, object> transformInfo = new Dictionary<string, object>();
  1126. transformInfo.Add("type", transform.GetType().FullName);
  1127. transformInfo.Add("id", GetID(transform.gameObject));
  1128. transformInfo.Add("position", position);
  1129. transformInfo.Add("rotation", rotation);
  1130. transformInfo.Add("scale", scale);
  1131. return transformInfo;
  1132. }
  1133. private object GetMaterialPropertyValue(Material material)
  1134. {
  1135. if (material == null) return null;
  1136. BabylonMaterial babylonMaterial = DumpMaterial(material);
  1137. Dictionary<string, object> materialInfo = new Dictionary<string, object>();
  1138. materialInfo.Add("type", material.GetType().FullName);
  1139. materialInfo.Add("id", babylonMaterial.id);
  1140. materialInfo.Add("name", babylonMaterial.name);
  1141. materialInfo.Add("alpha", babylonMaterial.alpha);
  1142. materialInfo.Add("wireframe", babylonMaterial.wireframe);
  1143. materialInfo.Add("backFaceCulling", babylonMaterial.backFaceCulling);
  1144. return materialInfo;
  1145. }
  1146. private object GetTexturePropertyValue(Texture2D texture)
  1147. {
  1148. if (texture == null) return null;
  1149. var texturePath = AssetDatabase.GetAssetPath(texture);
  1150. if (String.IsNullOrEmpty(texturePath)) return null;
  1151. var babylonTexture = new BabylonTexture();
  1152. CopyTexture(texturePath, texture, babylonTexture);
  1153. Dictionary<string, object> textureInfo = new Dictionary<string, object>();
  1154. textureInfo.Add("type", texture.GetType().FullName);
  1155. textureInfo.Add("name", babylonTexture.name);
  1156. textureInfo.Add("level", babylonTexture.level);
  1157. textureInfo.Add("isCube", babylonTexture.isCube);
  1158. textureInfo.Add("hasAlpha", babylonTexture.hasAlpha);
  1159. textureInfo.Add("coordinatesMode", babylonTexture.coordinatesMode);
  1160. textureInfo.Add("coordinatesIndex", babylonTexture.coordinatesIndex);
  1161. return textureInfo;
  1162. }
  1163. private object GetCubemapPropertyValue(Cubemap cubemap)
  1164. {
  1165. if (cubemap == null) return null;
  1166. var texturePath = AssetDatabase.GetAssetPath(cubemap);
  1167. if (String.IsNullOrEmpty(texturePath)) return null;
  1168. var textureName = Path.GetFileName(texturePath);
  1169. var outputPath = Path.Combine(babylonScene.OutputPath, textureName);
  1170. File.Copy(texturePath, outputPath, true);
  1171. Dictionary<string, object> textureInfo = new Dictionary<string, object>();
  1172. textureInfo.Add("type", cubemap.GetType().FullName);
  1173. textureInfo.Add("name", textureName);
  1174. textureInfo.Add("width", cubemap.width);
  1175. textureInfo.Add("height", cubemap.height);
  1176. textureInfo.Add("anisoLevel", cubemap.anisoLevel);
  1177. textureInfo.Add("texelSizeX", cubemap.texelSize.x);
  1178. textureInfo.Add("texelSizeY", cubemap.texelSize.y);
  1179. textureInfo.Add("dimension", cubemap.dimension.ToString());
  1180. textureInfo.Add("filterMode", cubemap.filterMode.ToString());
  1181. textureInfo.Add("format", cubemap.format.ToString());
  1182. textureInfo.Add("hideFlags", cubemap.hideFlags.ToString());
  1183. textureInfo.Add("mipMapBias", cubemap.mipMapBias.ToString());
  1184. textureInfo.Add("mipmapCount", cubemap.mipmapCount.ToString());
  1185. textureInfo.Add("wrapMode", cubemap.wrapMode.ToString());
  1186. return textureInfo;
  1187. }
  1188. private object GetEmbeddedAssetPropertyValue(EmbeddedAsset embedded)
  1189. {
  1190. if (embedded == null) return null;
  1191. var assetPath = AssetDatabase.GetAssetPath(embedded.textAsset);
  1192. if (String.IsNullOrEmpty(assetPath)) return null;
  1193. var assetName = Path.GetFileName(assetPath);
  1194. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1195. assetInfo.Add("type", embedded.GetType().FullName);
  1196. assetInfo.Add("filename", assetName);
  1197. assetInfo.Add("embedded", true);
  1198. if (embedded.encoding == BabylonTextEncoding.RawBytes)
  1199. {
  1200. assetInfo.Add("base64", Convert.ToBase64String(embedded.textAsset.bytes));
  1201. }
  1202. else
  1203. {
  1204. assetInfo.Add("base64", Tools.FormatBase64(embedded.textAsset.text));
  1205. }
  1206. return assetInfo;
  1207. }
  1208. private object GetTextAssetPropertyValue(TextAsset asset)
  1209. {
  1210. if (asset == null) return null;
  1211. var assetPath = AssetDatabase.GetAssetPath(asset);
  1212. if (String.IsNullOrEmpty(assetPath)) return null;
  1213. var assetName = Path.GetFileName(assetPath);
  1214. var outputPath = Path.Combine(babylonScene.OutputPath, assetName);
  1215. File.Copy(assetPath, outputPath, true);
  1216. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1217. assetInfo.Add("type", asset.GetType().FullName);
  1218. assetInfo.Add("filename", assetName);
  1219. assetInfo.Add("embedded", false);
  1220. assetInfo.Add("base64", null);
  1221. return assetInfo;
  1222. }
  1223. private object GetAudioClipPropertyValue(AudioClip clip)
  1224. {
  1225. if (clip == null) return null;
  1226. var assetPath = AssetDatabase.GetAssetPath(clip);
  1227. if (String.IsNullOrEmpty(assetPath)) return null;
  1228. var assetName = Path.GetFileName(assetPath);
  1229. var outputPath = Path.Combine(babylonScene.OutputPath, assetName);
  1230. File.Copy(assetPath, outputPath, true);
  1231. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1232. assetInfo.Add("type", clip.GetType().FullName);
  1233. assetInfo.Add("filename", assetName);
  1234. assetInfo.Add("length", clip.length);
  1235. assetInfo.Add("channels", clip.channels);
  1236. assetInfo.Add("frequency", clip.frequency);
  1237. assetInfo.Add("samples", clip.samples);
  1238. return assetInfo;
  1239. }
  1240. private object GetDefaultAssetPropertyValue(DefaultAsset asset)
  1241. {
  1242. if (asset == null) return null;
  1243. var assetPath = AssetDatabase.GetAssetPath(asset);
  1244. if (String.IsNullOrEmpty(assetPath)) return null;
  1245. var assetName = Path.GetFileName(assetPath);
  1246. var outputPath = Path.Combine(babylonScene.OutputPath, assetName);
  1247. File.Copy(assetPath, outputPath, true);
  1248. Dictionary<string, object> assetInfo = new Dictionary<string, object>();
  1249. assetInfo.Add("type", asset.GetType().FullName);
  1250. assetInfo.Add("filename", assetName);
  1251. return assetInfo;
  1252. }
  1253. private object GetShaderPropertyValue(Shader shader)
  1254. {
  1255. if (shader == null || shader.name.Substring(0, 10) != "BabylonJS/") return null;
  1256. string filename = AssetDatabase.GetAssetPath(shader);
  1257. if (String.IsNullOrEmpty(filename)) return null;
  1258. List<string> attributeList = new List<string>();
  1259. List<string> uniformList = new List<string>();
  1260. List<string> samplerList = new List<string>();
  1261. List<string> defineList = new List<string>();
  1262. var result = new Dictionary<string, object>();
  1263. string program = Tools.LoadTextAsset(filename);
  1264. string basename = shader.name.Replace("BabylonJS/", "").Replace("/", "_").Replace(" ", "");
  1265. string babylonOptions = GetShaderProgramSection(basename, program, BabylonProgramSection.Babylon);
  1266. string[] babylonLines = babylonOptions.Split('\n');
  1267. foreach (string babylonLine in babylonLines)
  1268. {
  1269. if (babylonLine.IndexOf("attributes", StringComparison.OrdinalIgnoreCase) >= 0)
  1270. {
  1271. string[] attributes = babylonLine.Split(':');
  1272. if (attributes != null && attributes.Length > 1)
  1273. {
  1274. string abuffer = attributes[1].Replace("[", "").Replace("]", "");
  1275. if (!String.IsNullOrEmpty(abuffer))
  1276. {
  1277. abuffer = abuffer.Trim();
  1278. string[] adata = abuffer.Split(',');
  1279. if (adata != null && adata.Length > 0)
  1280. {
  1281. foreach (string aoption in adata)
  1282. {
  1283. string aoption_buffer = aoption.Trim().Replace("\"", "").Trim();
  1284. if (!String.IsNullOrEmpty(aoption_buffer))
  1285. {
  1286. attributeList.Add(aoption_buffer);
  1287. }
  1288. }
  1289. }
  1290. }
  1291. }
  1292. }
  1293. else if (babylonLine.IndexOf("uniforms", StringComparison.OrdinalIgnoreCase) >= 0)
  1294. {
  1295. string[] uniforms = babylonLine.Split(':');
  1296. if (uniforms != null && uniforms.Length > 1)
  1297. {
  1298. string ubuffer = uniforms[1].Replace("[", "").Replace("]", "");
  1299. if (!String.IsNullOrEmpty(ubuffer))
  1300. {
  1301. ubuffer = ubuffer.Trim();
  1302. string[] udata = ubuffer.Split(',');
  1303. if (udata != null && udata.Length > 0)
  1304. {
  1305. foreach (string uoption in udata)
  1306. {
  1307. string uoption_buffer = uoption.Trim().Replace("\"", "").Trim();
  1308. if (!String.IsNullOrEmpty(uoption_buffer))
  1309. {
  1310. uniformList.Add(uoption_buffer);
  1311. }
  1312. }
  1313. }
  1314. }
  1315. }
  1316. }
  1317. else if (babylonLine.IndexOf("samplers", StringComparison.OrdinalIgnoreCase) >= 0)
  1318. {
  1319. string[] samplers = babylonLine.Split(':');
  1320. if (samplers != null && samplers.Length > 1)
  1321. {
  1322. string sbuffer = samplers[1].Replace("[", "").Replace("]", "");
  1323. if (!String.IsNullOrEmpty(sbuffer))
  1324. {
  1325. sbuffer = sbuffer.Trim();
  1326. string[] sdata = sbuffer.Split(',');
  1327. if (sdata != null && sdata.Length > 0)
  1328. {
  1329. foreach (string soption in sdata)
  1330. {
  1331. string soption_buffer = soption.Trim().Replace("\"", "").Trim();
  1332. if (!String.IsNullOrEmpty(soption_buffer))
  1333. {
  1334. samplerList.Add(soption_buffer);
  1335. }
  1336. }
  1337. }
  1338. }
  1339. }
  1340. }
  1341. else if (babylonLine.IndexOf("defines", StringComparison.OrdinalIgnoreCase) >= 0)
  1342. {
  1343. string[] defines = babylonLine.Split(':');
  1344. if (defines != null && defines.Length > 1)
  1345. {
  1346. string dbuffer = defines[1].Replace("[", "").Replace("]", "");
  1347. if (!String.IsNullOrEmpty(dbuffer))
  1348. {
  1349. dbuffer = dbuffer.Trim();
  1350. string[] ddata = dbuffer.Split(',');
  1351. if (ddata != null && ddata.Length > 0)
  1352. {
  1353. foreach (string doption in ddata)
  1354. {
  1355. string doption_buffer = doption.Trim().Replace("\"", "").Trim();
  1356. if (!String.IsNullOrEmpty(doption_buffer))
  1357. {
  1358. defineList.Add(doption_buffer);
  1359. }
  1360. }
  1361. }
  1362. }
  1363. }
  1364. }
  1365. }
  1366. var shaderPath = new Dictionary<string, object>();
  1367. string vertexProgram = GetShaderProgramSection(basename, program, BabylonProgramSection.Vertex);
  1368. shaderPath.Add("vertexElement", ("base64:" + Tools.FormatBase64(vertexProgram)));
  1369. string fragmentProgram = GetShaderProgramSection(basename, program, BabylonProgramSection.Fragment);
  1370. shaderPath.Add("fragmentElement", ("base64:" + Tools.FormatBase64(fragmentProgram)));
  1371. result.Add("shaderPath", shaderPath);
  1372. var options = new BabylonShaderOptions();
  1373. options.attributes = attributeList.ToArray();
  1374. options.uniforms = uniformList.ToArray();
  1375. options.samplers = samplerList.ToArray();
  1376. options.defines = defineList.ToArray();
  1377. var shaderOptions = new Dictionary<string, object>();
  1378. shaderOptions.Add("attributes", options.attributes);
  1379. shaderOptions.Add("needAlphaBlending", false);
  1380. shaderOptions.Add("needAlphaTesting", false);
  1381. shaderOptions.Add("uniforms", options.uniforms);
  1382. shaderOptions.Add("samplers", options.samplers);
  1383. shaderOptions.Add("defines", options.defines);
  1384. result.Add("shaderOptions", shaderOptions);
  1385. return result;
  1386. }
  1387. private static void ExportSkeletonAnimation(SkinnedMeshRenderer skinnedMesh, BabylonMesh babylonMesh, BabylonSkeleton skeleton)
  1388. {
  1389. var animator = skinnedMesh.rootBone.gameObject.GetComponent<Animator>();
  1390. if (animator != null)
  1391. {
  1392. ExportSkeletonAnimationClips(animator, true, skeleton, skinnedMesh.bones, babylonMesh);
  1393. }
  1394. else
  1395. {
  1396. var parent = skinnedMesh.rootBone.parent;
  1397. while (parent != null)
  1398. {
  1399. animator = parent.gameObject.GetComponent<Animator>();
  1400. if (animator != null)
  1401. {
  1402. ExportSkeletonAnimationClips(animator, true, skeleton, skinnedMesh.bones, babylonMesh);
  1403. break;
  1404. }
  1405. parent = parent.parent;
  1406. }
  1407. }
  1408. }
  1409. }
  1410. }