private BabylonMesh ConvertUnityEmptyObjectToBabylon(GameObject gameObject, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags, BabylonMesh collisionMesh = null, Collider collider = null)
        {
            BabylonMesh babylonMesh = new BabylonMesh { name = gameObject.name, id = GetID(gameObject) };
            metaData.type = "Game";
            if (!String.IsNullOrEmpty(componentTags))
            {
                babylonMesh.tags = componentTags;
            }

            var transform = gameObject.transform;

            babylonMesh.parentId = GetParentID(transform);

            babylonMesh.position = transform.localPosition.ToFloat();

            babylonMesh.rotation = new float[3];
            babylonMesh.rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
            babylonMesh.rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
            babylonMesh.rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180;

            babylonMesh.scaling = transform.localScale.ToFloat();

            babylonMesh.isVisible = false;
            babylonMesh.visibility = 0;
            babylonMesh.checkCollisions = false;

            // Collision mesh (No detail mesh fallback)
            string collisionMeshId = null;
            if (collider != null && collisionMesh != null)
            {
                collisionMeshId = collisionMesh.id;
                collisionMesh.parentId = babylonMesh.id;
                collisionMesh.visibility = collider.isTrigger ? 0.25f : 0.5f;
                collisionMesh.checkCollisions = (exportationOptions.ExportCollisions && collider.isTrigger == false);
            }
            metaData.properties["collisionMeshId"] = collisionMeshId;

            babylonMesh.metadata = metaData;
            babylonScene.MeshesList.Add(babylonMesh);

            // Animations
            ExportAnimations(transform, babylonMesh);
            if (IsRotationQuaternionAnimated(babylonMesh))
            {
                babylonMesh.rotationQuaternion = transform.localRotation.ToFloat();
            }

            // Lens Flares
            ParseLensFlares(gameObject, babylonMesh.id, ref lensFlares);

            // Particles Systems
            ParseParticleSystems(gameObject, babylonMesh.id, ref particleSystems);

            return babylonMesh;
        }
示例#2
0
 public virtual void OnExportGameObject(ref Unity3D2Babylon.ExportationOptions exportOptions, ref GameObject unityGameObject, ref UnityMetaData metaData, ref BabylonScene sceneBuilder, string outputPath)
 {
 }
        private BabylonMesh ConvertUnityTerrainToBabylon(Terrain terrain, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags)
        {
            ExporterWindow.ReportProgress(progress, "Exporting terrain: " + gameObject.name);
            var transform = gameObject.transform;
            float[] position = transform.localPosition.ToFloat();
            float[] rotation = new float[3];
            rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
            rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
            rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180;
            float[] scaling = transform.localScale.ToFloat();

            BabylonMesh babylonMesh = new BabylonMesh { name = gameObject.name, id = GetID(gameObject) };
            metaData.type = "Terrain";
            if (!String.IsNullOrEmpty(componentTags))
            {
                babylonMesh.tags = componentTags;
            }
            babylonMesh.tags += " [TERRAIN]";
            if (!String.IsNullOrEmpty(babylonMesh.tags))
            {
                babylonMesh.tags = babylonMesh.tags.Trim();
            }
            babylonMesh.parentId = GetParentID(transform);
            babylonMesh.position = Vector3.zero.ToFloat();
            babylonMesh.rotation = rotation;
            babylonMesh.scaling = scaling;
            babylonMesh.isVisible = true;
            babylonMesh.visibility = 1;
            babylonMesh.checkCollisions = false;
            metaData.properties["collisionMeshId"] = null;

            var generator = gameObject.GetComponent<BabylonTerrainGenerator>();
            if (generator != null && terrain != null)
            {
                // TODO: Terrain tree information
                object treeInstances = null;
                object treePrototypes = null;

                // Terrain metadata infomation
                Vector3 terrainSize = terrain.terrainData.size;
                metaData.properties.Add("width", terrainSize.x);
                metaData.properties.Add("length", terrainSize.z);
                metaData.properties.Add("height", terrainSize.y);
                metaData.properties.Add("position", position);
                metaData.properties.Add("rotation", rotation);
                metaData.properties.Add("scaling", scaling);
                metaData.properties.Add("thickness", terrain.terrainData.thickness);
                metaData.properties.Add("detailWidth", terrain.terrainData.detailWidth);
                metaData.properties.Add("detailHeight", terrain.terrainData.detailHeight);
                metaData.properties.Add("heightmapWidth", terrain.terrainData.heightmapWidth);
                metaData.properties.Add("heightmapHeight", terrain.terrainData.heightmapHeight);
                metaData.properties.Add("wavingGrassAmount", terrain.terrainData.wavingGrassAmount);
                metaData.properties.Add("wavingGrassSpeed", terrain.terrainData.wavingGrassSpeed);
                metaData.properties.Add("wavingGrassStrength", terrain.terrainData.wavingGrassStrength);
                metaData.properties.Add("wavingGrassTint", terrain.terrainData.wavingGrassTint.ToFloat());
                metaData.properties.Add("treeInstanceCount", terrain.terrainData.treeInstanceCount);
                metaData.properties.Add("treeInstances", treeInstances);
                metaData.properties.Add("treePrototypes", treePrototypes);
                metaData.properties.Add("physicsState", generator.physicsActive);
                metaData.properties.Add("physicsMass", generator.physicsMass);
                metaData.properties.Add("physicsFriction", generator.physicsFriction);
                metaData.properties.Add("physicsRestitution", generator.physicsRestitution);
                metaData.properties.Add("physicsImpostor", (int)generator.physicsImpostor);
                metaData.properties.Add("groundTessellation", generator.groundTessellation);

                // Generate detailed mesh
                ExporterWindow.ReportProgress(progress, "Generating terrain mesh: " + gameObject.name);
                BabylonTerrainData terrainMeshData = Unity3D2Babylon.Tools.CreateTerrainData(terrain.terrainData, (int)generator.terrainResolution, transform.localPosition, true);
                Tools.GenerateBabylonMeshTerrainData(terrainMeshData, babylonMesh, false, babylonScene, transform);
                if (generator.surfaceMaterial != null)
                {
                    babylonMesh.materialId = DumpMaterial(generator.surfaceMaterial, terrain.lightmapIndex, terrain.lightmapScaleOffset, generator.coordinatesIndex).id;
                }

                // Generate collision heightmap
                var terrainCollider = gameObject.GetComponent<TerrainCollider>();
                if (terrainCollider != null && terrainCollider.enabled)
                {
                    ExporterWindow.ReportProgress(progress, "Generating terrain heightmap: " + gameObject.name);
                    float minheight = float.MaxValue;
                    float maxheight = float.MinValue;
                    int hwidth = terrain.terrainData.heightmapWidth;
                    int hheight = terrain.terrainData.heightmapHeight;
                    float[,] rawHeights = terrain.terrainData.GetHeights(0, 0, hwidth, hheight);
                    Texture2D heightMap = new Texture2D(hwidth, hheight, TextureFormat.ARGB32, false);
                    for (int y = 0; y < hheight; y++)
                    {
                        for (int x = 0; x < hwidth; x++)
                        {
                            float inverted = rawHeights[y, x];
                            minheight = Mathf.Min(minheight, inverted);
                            maxheight = Mathf.Max(maxheight, inverted);
                        }
                    }
                    List<Color32> pixels = new List<Color32>();
                    for (int y = 0; y < hheight; y++)
                    {
                        for (int x = 0; x < hwidth; x++)
                        {
                            float inverted = rawHeights[y, x];
                            if (generator.heightmapStrength > 0)
                            {
                                float threadhold = minheight + generator.floorThreashold;
                                if (inverted > threadhold)
                                {
                                    inverted += (generator.heightmapStrength / 10.0f);
                                }
                            }
                            byte[] packed = BitConverter.GetBytes(inverted);
                            if (packed != null && packed.Length >= 4)
                            {
                                pixels.Add(new Color32(packed[0], packed[1], packed[2], packed[3]));
                            }
                        }
                    }
                    heightMap.SetPixels32(pixels.ToArray());
                    heightMap.Apply();
                    byte[] heightmapBytes = heightMap.EncodeToPNG();
                    metaData.properties.Add("heightmapBase64", ("data:image/png;base64," + Convert.ToBase64String(heightmapBytes)));
                }
            }
            else
            {
                UnityEngine.Debug.LogWarning("No valid terrain or generator found for: " + gameObject.name);
            }

            babylonMesh.metadata = metaData;
            babylonScene.MeshesList.Add(babylonMesh);
            SceneBuilder.Metadata.properties["hasTerrainMeshes"] = true;

            // Animations
            ExportAnimations(transform, babylonMesh);
            if (IsRotationQuaternionAnimated(babylonMesh))
            {
                babylonMesh.rotationQuaternion = transform.localRotation.ToFloat();
            }

            // Lens Flares
            ParseLensFlares(gameObject, babylonMesh.id, ref lensFlares);

            // Particles Systems
            ParseParticleSystems(gameObject, babylonMesh.id, ref particleSystems);

            return babylonMesh;
        }
        private BabylonMesh ConvertUnityMeshToBabylon(Mesh mesh, Transform transform, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags, BabylonMesh collisionMesh = null, Collider collider = null)
        {
            BabylonMesh babylonMesh = new BabylonMesh();
            metaData.type = "Mesh";
            if (!String.IsNullOrEmpty(componentTags))
            {
                babylonMesh.tags = componentTags;
            }

            ExporterWindow.ReportProgress(progress, "Exporting mesh: " + gameObject.name);

            babylonMesh.name = gameObject.name;
            babylonMesh.id = GetID(transform.gameObject);

            var renderer = gameObject.GetComponent<Renderer>();
            if (renderer != null)
            {
                babylonMesh.receiveShadows = renderer.receiveShadows;
            }

            babylonMesh.parentId = GetParentID(transform);

            babylonMesh.position = transform.localPosition.ToFloat();

            babylonMesh.rotation = new float[3];
            babylonMesh.rotation[0] = transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
            babylonMesh.rotation[1] = transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
            babylonMesh.rotation[2] = transform.localRotation.eulerAngles.z * (float)Math.PI / 180;

            babylonMesh.scaling = transform.localScale.ToFloat();
            babylonMesh.checkCollisions = false;

            // Collision mesh (With detail mesh fallback)
            string collisionMeshId = null;
            if (collider != null)
            {
                if (collisionMesh != null)
                {
                    collisionMeshId = collisionMesh.id;
                    collisionMesh.parentId = babylonMesh.id;
                    collisionMesh.visibility = collider.isTrigger ? 0.25f : 0.5f;
                    collisionMesh.checkCollisions = (exportationOptions.ExportCollisions && collider.isTrigger == false);
                }
                else
                {
                    babylonMesh.checkCollisions = exportationOptions.ExportCollisions;
                }
            }
            metaData.properties["collisionMeshId"] = collisionMeshId;

            if (mesh != null)
            {
                Tools.GenerateBabylonMeshData(mesh, babylonMesh, babylonScene, transform);
                int index = 0;
                if (mesh.boneWeights.Length == mesh.vertexCount)
                {
                    babylonMesh.matricesIndices = new int[mesh.vertexCount];
                    babylonMesh.matricesWeights = new float[mesh.vertexCount * 4];
                    index = 0;
                    foreach (BoneWeight bw in mesh.boneWeights)
                    {
                        babylonMesh.matricesIndices[index] = (bw.boneIndex3 << 24) | (bw.boneIndex2 << 16) | (bw.boneIndex1 << 8) | bw.boneIndex0;
                        babylonMesh.matricesWeights[index * 4 + 0] = bw.weight0;
                        babylonMesh.matricesWeights[index * 4 + 1] = bw.weight1;
                        babylonMesh.matricesWeights[index * 4 + 2] = bw.weight2;
                        babylonMesh.matricesWeights[index * 4 + 3] = bw.weight3;
                        var totalWeight = bw.weight0 + bw.weight1 + bw.weight2 + bw.weight3;
                        if (Mathf.Abs(totalWeight - 1.0f) > 0.01f)
                        {
                            throw new Exception("Total bone weights is not normalized for: " + mesh);
                        }
                        index++;
                    }
                }
                index = 0;
                if (renderer != null && renderer.sharedMaterial != null)
                {
                    // Validate Multi Materials
                    if (mesh.subMeshCount > 1)
                    {
                        BabylonMultiMaterial bMultiMat;

                        string multiMatName = "";
                        for (int i = 0; i < renderer.sharedMaterials.Length; i++)
                        {
                            multiMatName += renderer.sharedMaterials[i].name;
                        }
                    

                        if (!multiMatDictionary.ContainsKey(multiMatName))
                        {
                            bMultiMat = new BabylonMultiMaterial
                            {
                                materials = new string[mesh.subMeshCount],
                                id = Guid.NewGuid().ToString(),
                                name = multiMatName
                            };

                            for (int i = 0; i < renderer.sharedMaterials.Length; i++)
                            {
                                var sharedMaterial = renderer.sharedMaterials[i];
                                BabylonMaterial babylonMaterial;

                                babylonMaterial = DumpMaterial(sharedMaterial, renderer.lightmapIndex, renderer.lightmapScaleOffset);

                                bMultiMat.materials[i] = babylonMaterial.id;
                            }
                            if (mesh.subMeshCount > 1)
                            {
                                multiMatDictionary.Add(bMultiMat.name, bMultiMat);
                            }
                        }
                        else
                        {
                            bMultiMat = multiMatDictionary[multiMatName];
                        }

                        babylonMesh.materialId = bMultiMat.id;
                        babylonMesh.subMeshes = new BabylonSubMesh[mesh.subMeshCount];

                        var offset = 0;
                        for (int materialIndex = 0; materialIndex < mesh.subMeshCount; materialIndex++)
                        {
                            var unityTriangles = mesh.GetTriangles(materialIndex);
                            babylonMesh.subMeshes[materialIndex] = new BabylonSubMesh
                            {
                                verticesStart = 0,
                                verticesCount = mesh.vertexCount,
                                materialIndex = materialIndex,
                                indexStart = offset,
                                indexCount = unityTriangles.Length
                            };
                            offset += unityTriangles.Length;
                        }
                    }
                    else
                    {
                        babylonMesh.materialId = DumpMaterial(renderer.sharedMaterial, renderer.lightmapIndex, renderer.lightmapScaleOffset).id;
                    }
                }

                babylonMesh.metadata = metaData;
                babylonScene.MeshesList.Add(babylonMesh);

                // Animations
                ExportAnimations(transform, babylonMesh);
                if (IsRotationQuaternionAnimated(babylonMesh))
                {
                    babylonMesh.rotationQuaternion = transform.localRotation.ToFloat();
                }

                // Lens Flares
                ParseLensFlares(gameObject, babylonMesh.id, ref lensFlares);

                // Particles Systems
                ParseParticleSystems(gameObject, babylonMesh.id, ref particleSystems);

                // Babylon Physics
                if (exportationOptions.ExportPhysics)
                {
                    var physics = gameObject.GetComponent<BabylonPhysicsState>();
                    if (physics != null)
                    {
                        babylonMesh.physicsMass = physics.mass;
                        babylonMesh.physicsFriction = physics.friction;
                        babylonMesh.physicsRestitution = physics.restitution;
                        babylonMesh.physicsImpostor = (int)physics.imposter;
                    }
                }
            }
            return babylonMesh;
        }
示例#5
0
 public virtual void OnExportGameObject(ref Unity3D2Babylon.ExportationOptions exportOptions, ref GameObject unityGameObject, ref UnityMetaData metaData, ref BabylonScene sceneBuilder, string outputPath) { }
示例#6
0
        public void ConvertFromUnity()
        {
            ExporterWindow.ReportProgress(0, "Starting exportation process...");
            gameObjects = Object.FindObjectsOfType(typeof(GameObject)) as GameObject[];
            if (gameObjects.Length == 0)
            {
                ExporterWindow.ShowMessage("No gameobject! - Please add at least a gameobject to export");
                return;
            }

            // Create scene metadata
            SceneBuilder.Metadata = new SceneMetaData();

            // Parse all scene game objects
            var index = 0;
            var itemsCount = gameObjects.Length;
            var particleSystems = new List<BabylonExport.Entities.BabylonParticleSystem>();
            var lensFlareSystems = new List<UnityFlareSystem>();
            ExporterWindow.ReportProgress(0, "Exporting game objects from scene...");
            babylonScene.physicsEngine = (exportationOptions.DefaultPhysicsEngine == 1) ? "oimo" : "cannon";
            try
            {
                bool foundController = false;
                foreach (var gameObject in gameObjects)
                {
                    var progress = ((float)index / itemsCount);
                    index++;

                    // Unity metadata
                    var metaData = new UnityMetaData();
                    metaData.objectId = GetID(gameObject);
                    metaData.objectName = gameObject.name;
                    metaData.tagName = gameObject.tag;
                    metaData.layerIndex = gameObject.layer;
                    metaData.layerName = LayerMask.LayerToName(gameObject.layer);

                    // Export hooking
                    var exportObject = gameObject;
                    var exportOptions = exportationOptions;
                    BabylonScene sceneBuilder = babylonScene;
                    if (SceneController != null)
                    {
                        SceneController.OnExportGameObject(ref exportOptions, ref exportObject, ref metaData, ref sceneBuilder, OutputPath);
                    }

                    // Components tags
                    string componentTags = String.Empty;
                    if (!String.IsNullOrEmpty(gameObject.tag) && !gameObject.tag.Equals("Untagged", StringComparison.OrdinalIgnoreCase))
                    {
                        componentTags = gameObject.tag;
                    }

                    // Navigation area
                    metaData.areaIndex = -1;
                    bool navigationStatic = GameObjectUtility.AreStaticEditorFlagsSet(gameObject, StaticEditorFlags.NavigationStatic);
                    if (navigationStatic)
                    {
                        metaData.areaIndex = GameObjectUtility.GetNavMeshArea(gameObject);
                    }

                    // Navigation agent
                    metaData.navAgent = null;
                    var navigationAgent = gameObject.GetComponent<NavMeshAgent>();
                    if (navigationAgent != null)
                    {
                        componentTags += " [NAVAGENT]";
                        Dictionary<string, object> agentInfo = new Dictionary<string, object>();
                        agentInfo.Add("name", navigationAgent.name);
                        agentInfo.Add("radius", navigationAgent.radius);
                        agentInfo.Add("height", navigationAgent.height);
                        agentInfo.Add("speed", navigationAgent.speed);
                        agentInfo.Add("acceleration", navigationAgent.acceleration);
                        agentInfo.Add("angularSpeed", navigationAgent.angularSpeed);
                        agentInfo.Add("areaMask", navigationAgent.areaMask);
                        agentInfo.Add("autoBraking", navigationAgent.autoBraking);
                        agentInfo.Add("autoTraverseOffMeshLink", navigationAgent.autoTraverseOffMeshLink);
                        agentInfo.Add("avoidancePriority", navigationAgent.avoidancePriority);
                        agentInfo.Add("baseOffset", navigationAgent.baseOffset);
                        agentInfo.Add("obstacleAvoidanceType", navigationAgent.obstacleAvoidanceType.ToString());
                        agentInfo.Add("stoppingDistance", navigationAgent.stoppingDistance);
                        metaData.navAgent = agentInfo;
                    }

                    // Navigation link
                    metaData.meshLink = null;
                    var navigationLink = gameObject.GetComponent<OffMeshLink>();
                    if (navigationLink != null)
                    {
                        componentTags += " [MESHLINK]";
                        Dictionary<string, object> linkInfo = new Dictionary<string, object>();
                        linkInfo.Add("name", navigationLink.name);
                        linkInfo.Add("activated", navigationLink.activated);
                        linkInfo.Add("area", navigationLink.area);
                        linkInfo.Add("autoUpdatePositions", navigationLink.autoUpdatePositions);
                        linkInfo.Add("biDirectional", navigationLink.biDirectional);
                        linkInfo.Add("costOverride", navigationLink.costOverride);
                        linkInfo.Add("occupied", navigationLink.occupied);
                        linkInfo.Add("start", GetTransformPropertyValue(navigationLink.startTransform));
                        linkInfo.Add("end", GetTransformPropertyValue(navigationLink.endTransform));
                        metaData.meshLink = linkInfo;
                    }

                    // Navigation obstacle
                    metaData.meshObstacle = null;
                    var navigationObstacle = gameObject.GetComponent<NavMeshObstacle>();
                    if (navigationObstacle != null)
                    {
                        componentTags += " [MESHOBSTACLE]";
                        Dictionary<string, object> obstacleInfo = new Dictionary<string, object>();
                        obstacleInfo.Add("name", navigationObstacle.name);
                        obstacleInfo.Add("carving", navigationObstacle.carving);
                        obstacleInfo.Add("carveOnlyStationary", navigationObstacle.carveOnlyStationary);
                        obstacleInfo.Add("carvingMoveThreshold", navigationObstacle.carvingMoveThreshold);
                        obstacleInfo.Add("carvingTimeToStationary", navigationObstacle.carvingTimeToStationary);
                        obstacleInfo.Add("shape", navigationObstacle.shape.ToString());
                        obstacleInfo.Add("radius", navigationObstacle.radius);
                        obstacleInfo.Add("center", navigationObstacle.center.ToFloat());
                        obstacleInfo.Add("size", navigationObstacle.size.ToFloat());
                        metaData.meshObstacle = obstacleInfo;
                    }

                    // Tags component
                    var tagsComponent = gameObject.GetComponent<BabylonTagsComponent>();
                    if (tagsComponent != null)
                    {
                        if (!String.IsNullOrEmpty(tagsComponent.babylonTags))
                        {
                            componentTags += (" " + tagsComponent.babylonTags);
                        }
                    }

                    // Script components
                    var gameComponents = gameObject.GetComponents<BabylonScriptComponent>();
                    if (gameComponents != null)
                    {
                        var components = new List<object>();
                        foreach (var gameComponent in gameComponents)
                        {
                            Type componentType = gameComponent.GetType();
                            string componentName = componentType.FullName;
                            var component = new UnityScriptComponent();
                            MonoScript componentScript = MonoScript.FromMonoBehaviour(gameComponent);
                            component.order = MonoImporter.GetExecutionOrder(componentScript);
                            component.name = componentName;
                            component.klass = gameComponent.babylonClass;
                            component.update = (gameComponent.updateOption == BabylonTickOptions.EnableTick);
                            component.controller = (gameComponent is BabylonSceneController);
                            if (component.controller == true)
                            {
                                component.order = -1;
                                if (foundController == false)
                                {
                                    foundController = true;
                                    componentTags += " [CONTROLLER]";
                                    object userInterface = null;
                                    BabylonSceneController scx = (gameComponent as BabylonSceneController);
                                    EmbeddedAsset guiAsset = scx.sceneOptions.graphicUserInterface;
                                    if (guiAsset != null && scx.sceneOptions.userInterfaceMode != BabylonGuiMode.None)
                                    {
                                        userInterface = GetEmbeddedAssetPropertyValue(guiAsset);
                                    }
                                    SceneBuilder.Metadata.properties.Add("autoDraw", scx.sceneOptions.autoDrawInterface);
                                    SceneBuilder.Metadata.properties.Add("interfaceMode", scx.sceneOptions.userInterfaceMode.ToString());
                                    SceneBuilder.Metadata.properties.Add("userInterface", userInterface);
                                    SceneBuilder.Metadata.properties.Add("controllerPresent", true);
                                    SceneBuilder.Metadata.properties.Add("controllerObjectId", metaData.objectId);
                                }
                                else
                                {
                                    Debug.LogError("Duplicate scene controller detected: " + component.name);
                                }
                            }
                            FieldInfo[] componentFields = componentType.GetFields();
                            if (componentFields != null)
                            {
                                foreach (var componentField in componentFields)
                                {
                                    var componentAttribute = (BabylonPropertyAttribute)Attribute.GetCustomAttribute(componentField, typeof(BabylonPropertyAttribute));
                                    if (componentAttribute != null && componentField.Name != "babylonClass")
                                    {
                                        component.properties.Add(componentField.Name, GetComponentPropertyValue(componentField, gameComponent));
                                    }
                                }
                            }
                            gameComponent.OnExportProperties(ref exportOptions, ref exportObject, ref component.properties, OutputPath);
                            components.Add(component);
                        }
                        if (components.Count > 0)
                        {
                            metaData.components = components;
                        }
                    }

                    // Format tags
                    if (!String.IsNullOrEmpty(componentTags))
                    {
                        componentTags = componentTags.Trim();
                    }

                    // Audio sources
                    var audioComponents = gameObject.GetComponents<BabylonAudioSource>();
                    if (audioComponents != null)
                    {
                        foreach (var item in audioComponents)
                        {
                            if (item != null && item.exportAudio && item.sound != null)
                            {
                                string soundPath = AssetDatabase.GetAssetPath(item.sound);
                                if (!String.IsNullOrEmpty(soundPath))
                                {
                                    string soundName = Path.GetFileName(soundPath).Replace(" ", "");
                                    string outputFile = Path.Combine(OutputPath, soundName);
                                    if (File.Exists(soundPath))
                                    {
                                        File.Copy(soundPath, outputFile, true);
                                        var sound = new BabylonSound();
                                        sound.name = soundName;
                                        sound.volume = item.options.volume;
                                        sound.playbackRate = item.options.playbackRate;
                                        sound.autoplay = item.options.autoplay;
                                        sound.loop = item.options.loop;
                                        sound.soundTrackId = item.options.soundTrackId;
                                        sound.spatialSound = item.options.spatialSound;
                                        sound.position = item.options.position.ToFloat();
                                        sound.refDistance = item.options.refDistance;
                                        sound.rolloffFactor = item.options.rolloffFactor;
                                        sound.maxDistance = item.options.maxDistance;
                                        sound.distanceModel = item.options.distanceModel;
                                        sound.panningModel = item.options.panningModel;
                                        sound.isDirectional = item.options.isDirectional;
                                        sound.coneInnerAngle = item.options.coneInnerAngle;
                                        sound.coneOuterAngle = item.options.coneOuterAngle;
                                        sound.coneOuterGain = item.options.coneOuterGain;
                                        sound.localDirectionToMesh = item.options.directionToMesh.ToFloat();
                                        babylonScene.SoundsList.Add(sound);
                                    }
                                    else
                                    {
                                        Debug.LogError("Fail to locate audio file: " + soundPath);
                                    }
                                }
                                else
                                {
                                    Debug.LogError("Null audio clip path for: " + item.sound.name);
                                }
                            }
                        }
                    }

                    // Terrain meshes
                    var terrainMesh = gameObject.GetComponent<Terrain>();
                    if (terrainMesh != null)
                    {
                        ConvertUnityTerrainToBabylon(terrainMesh, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags);
                        continue;
                    }

                    // Collision meshes
                    BabylonMesh collisionMesh = null;
                    var collider = gameObject.GetComponent<Collider>();
                    if (collider != null)
                    {
                        if (collider.enabled)
                        {
                            int segments = 12;
                            BabylonColliderDetail detail = (BabylonColliderDetail)exportationOptions.DefaultColliderDetail;
                            var collisionData = new UnityMetaData();
                            collisionData.objectId = Guid.NewGuid().ToString();
                            collisionData.objectName = gameObject.name + "_Metadata";
                            if (collider is MeshCollider)
                            {
                                var meshCollider = collider as MeshCollider;
                                collisionMesh = new BabylonMesh();
                                collisionMesh.tags = "[MESHCOLLIDER]";
                                // Generate Mesh Collider Geometry
                                if(!meshCollider.sharedMesh)
                                {
                                    UnityEngine.Debug.LogWarning(meshCollider.gameObject+" has a Mesh Collider component without a mesh");
                                }
                                else
                                {
                                    Tools.GenerateBabylonMeshData(meshCollider.sharedMesh, collisionMesh);
                                }
                                collisionMesh.position = Vector3.zero.ToFloat();
                                collisionMesh.rotation = Vector3.zero.ToFloat();
                                float factorX = 1f, factorY = 1f, factorZ = 1f;
                                if (meshCollider.inflateMesh && meshCollider.skinWidth > 0f)
                                {
                                    Vector3 localScale = gameObject.transform.localScale;
                                    factorX += (meshCollider.skinWidth / localScale.x);
                                    factorY += (meshCollider.skinWidth / localScale.y);
                                    factorZ += (meshCollider.skinWidth / localScale.z);
                                }
                                collisionMesh.scaling = new Vector3(factorX, factorY, factorZ).ToFloat();
                                // Export Mesh Collider Metadata
                                collisionData.tagName = "MeshCollider";
                                collisionData.properties.Add("type", "Mesh");
                                collisionData.properties.Add("convex", meshCollider.convex);
                                collisionData.properties.Add("inflateMesh", meshCollider.inflateMesh);
                                collisionData.properties.Add("skinWidth", meshCollider.skinWidth);
                            }
                            else if (collider is CapsuleCollider)
                            {
                                var capsuleCollider = collider as CapsuleCollider;
                                collisionMesh = new BabylonMesh();
                                collisionMesh.tags = "[CAPSULECOLLIDER]";
                                switch (detail)
                                {
                                    case BabylonColliderDetail.FullResolution:
                                        segments = 48;
                                        break;
                                    case BabylonColliderDetail.HighResolution:
                                        segments = 32;
                                        break;
                                    case BabylonColliderDetail.MediumResolution:
                                        segments = 24;
                                        break;
                                    case BabylonColliderDetail.LowResolution:
                                        segments = 12;
                                        break;
                                    case BabylonColliderDetail.VeryLowResolution:
                                        segments = 8;
                                        break;
                                    case BabylonColliderDetail.MinimumResolution:
                                        segments = 6;
                                        break;
                                    default:
                                        segments = 12;
                                        break;
                                }
                                // Generate Capsule Collider Geometry
                                Mesh capsuleMesh = Tools.CreateCapsuleMesh(capsuleCollider.height, capsuleCollider.radius, segments);
                                Tools.GenerateBabylonMeshData(capsuleMesh, collisionMesh);
                                collisionMesh.position = new float[3];
                                collisionMesh.position[0] = capsuleCollider.center.x;
                                collisionMesh.position[1] = capsuleCollider.center.y;
                                collisionMesh.position[2] = capsuleCollider.center.z;
                                collisionMesh.rotation = new float[3];
                                collisionMesh.rotation[0] = (capsuleCollider.direction == 2) ? 90f * (float)Math.PI / 180f : 0f;
                                collisionMesh.rotation[1] = 0f;
                                collisionMesh.rotation[2] = (capsuleCollider.direction == 0) ? 90f * (float)Math.PI / 180f : 0f;
                                collisionMesh.scaling = new Vector3(1, 1, 1).ToFloat();
                                // Export Capsule Collider Metadata
                                collisionData.tagName = "CapsuleCollider";
                                collisionData.properties.Add("type", "Capsule");
                                collisionData.properties.Add("center", capsuleCollider.center.ToFloat());
                                collisionData.properties.Add("radius", capsuleCollider.radius);
                                collisionData.properties.Add("height", capsuleCollider.height);
                                collisionData.properties.Add("direction", capsuleCollider.direction);
                            }
                            else if (collider is SphereCollider)
                            {
                                var sphereCollider = collider as SphereCollider;
                                collisionMesh = new BabylonMesh();
                                collisionMesh.tags = "[SPHERECOLLIDER]";
                                switch (detail)
                                {
                                    case BabylonColliderDetail.FullResolution:
                                        segments = 48;
                                        break;
                                    case BabylonColliderDetail.HighResolution:
                                        segments = 32;
                                        break;
                                    case BabylonColliderDetail.MediumResolution:
                                        segments = 24;
                                        break;
                                    case BabylonColliderDetail.LowResolution:
                                        segments = 12;
                                        break;
                                    case BabylonColliderDetail.VeryLowResolution:
                                        segments = 8;
                                        break;
                                    case BabylonColliderDetail.MinimumResolution:
                                        segments = 6;
                                        break;
                                    default:
                                        segments = 12;
                                        break;
                                }
                                // Generate Sphere Collider Geometry
                                Mesh sphereMesh = Tools.CreateSphereMesh(sphereCollider.radius, segments);
                                Tools.GenerateBabylonMeshData(sphereMesh, collisionMesh);
                                collisionMesh.position = new float[3];
                                collisionMesh.position[0] = sphereCollider.center.x;
                                collisionMesh.position[1] = sphereCollider.center.y;
                                collisionMesh.position[2] = sphereCollider.center.z;
                                collisionMesh.rotation = Vector3.zero.ToFloat();
                                collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat();
                                // Export Sphere Collider Metadata
                                collisionData.tagName = "SphereCollider";
                                collisionData.properties.Add("type", "Sphere");
                                collisionData.properties.Add("center", sphereCollider.center.ToFloat());
                                collisionData.properties.Add("radius", sphereCollider.radius);
                            }
                            else if (collider is WheelCollider)
                            {
                                var wheelCollider = collider as WheelCollider;
                                collisionMesh = new BabylonMesh();
                                collisionMesh.tags = "[WHEELCOLLIDER]";
                                switch (detail)
                                {
                                    case BabylonColliderDetail.FullResolution:
                                        segments = 128;
                                        break;
                                    case BabylonColliderDetail.HighResolution:
                                        segments = 64;
                                        break;
                                    case BabylonColliderDetail.MediumResolution:
                                        segments = 48;
                                        break;
                                    case BabylonColliderDetail.LowResolution:
                                        segments = 32;
                                        break;
                                    case BabylonColliderDetail.VeryLowResolution:
                                        segments = 24;
                                        break;
                                    case BabylonColliderDetail.MinimumResolution:
                                        segments = 16;
                                        break;
                                    default:
                                        segments = 32;
                                        break;
                                }
                                // Generate Wheel Collider Geometry
                                Mesh wheelMesh = Tools.CreateWheelMesh(wheelCollider.suspensionDistance, wheelCollider.radius, segments);
                                Tools.GenerateBabylonMeshData(wheelMesh, collisionMesh);
                                collisionMesh.position = new float[3];
                                collisionMesh.position[0] = wheelCollider.center.x;
                                collisionMesh.position[1] = wheelCollider.center.y;
                                collisionMesh.position[2] = wheelCollider.center.z;
                                collisionMesh.rotation = new float[3];
                                collisionMesh.rotation[0] = 0f;
                                collisionMesh.rotation[1] = 0f;
                                collisionMesh.rotation[2] = 90f * (float)Math.PI / 180;
                                collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat();
                                // Export Wheel Collider Metadata
                                collisionData.tagName = "WheelCollider";
                                collisionData.properties.Add("type", "Wheel");
                                collisionData.properties.Add("center", wheelCollider.center.ToFloat());
                                collisionData.properties.Add("radius", wheelCollider.radius);
                            }
                            else if (collider is BoxCollider)
                            {
                                var boxCollider = collider as BoxCollider;
                                collisionMesh = new BabylonMesh();
                                collisionMesh.tags = "[BOXCOLLIDER]";
                                // Generate Box Collider Geometry
                                Mesh boxMesh = Tools.CreateBoxMesh(boxCollider.size.x, boxCollider.size.y, boxCollider.size.z);
                                Tools.GenerateBabylonMeshData(boxMesh, collisionMesh);
                                collisionMesh.position = new float[3];
                                collisionMesh.position[0] = boxCollider.center.x;
                                collisionMesh.position[1] = boxCollider.center.y;
                                collisionMesh.position[2] = boxCollider.center.z;
                                collisionMesh.rotation = Vector3.zero.ToFloat();
                                collisionMesh.scaling = new Vector3(1f, 1f, 1f).ToFloat();
                                // Export Box Collider Metadata
                                collisionData.tagName = "BoxCollider";
                                collisionData.properties.Add("type", "Box");
                                collisionData.properties.Add("center", boxCollider.center.ToFloat());
                                collisionData.properties.Add("size", boxCollider.size.ToFloat());
                            }
                            if (collisionMesh != null)
                            {
                                collisionMesh.id = Guid.NewGuid().ToString();
                                collisionMesh.name = gameObject.name + "_Collider";
                                // Default Check Collisions False
                                collisionMesh.checkCollisions = false;
                                collisionMesh.isVisible = false;
                                collisionData.properties.Add("parrentId", metaData.objectId);
                                collisionData.properties.Add("transform", GetTransformPropertyValue(gameObject.transform));
                                collisionMesh.metadata = collisionData;
                                babylonScene.MeshesList.Add(collisionMesh);
                                SceneBuilder.Metadata.properties["hasCollisionMeshes"] = true;
                            }
                        }
                    }

                    // Static meshes
                    var meshFilter = gameObject.GetComponent<MeshFilter>();
                    if (meshFilter != null)
                    {
                        ConvertUnityMeshToBabylon(meshFilter.sharedMesh, meshFilter.transform, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider);
                        continue;
                    }

                    // Skinned meshes
                    var skinnedMesh = gameObject.GetComponent<SkinnedMeshRenderer>();
                    if (skinnedMesh != null)
                    {
                        var babylonMesh = ConvertUnityMeshToBabylon(skinnedMesh.sharedMesh, skinnedMesh.transform, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider);
                        var skeleton = ConvertUnitySkeletonToBabylon(skinnedMesh.bones, skinnedMesh.sharedMesh.bindposes, skinnedMesh.transform, gameObject, progress);
                        babylonMesh.skeletonId = skeleton.id;
                        ExportSkeletonAnimation(skinnedMesh, babylonMesh, skeleton);
                        continue;
                    }

                    // Scene lights
                    var light = gameObject.GetComponent<Light>();
                    if (light != null)
                    {
                        ConvertUnityLightToBabylon(light, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags);
                        continue;
                    }

                    // Scene cameras
                    var camera = gameObject.GetComponent<Camera>();
                    if (camera != null)
                    {
                        ConvertUnityCameraToBabylon(camera, gameObject, progress, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags);
                        if (SceneController != null && SceneController.skyboxOptions.exportSkybox)
                        {
                            ConvertUnitySkyboxToBabylon(camera, progress);
                        }
                        continue;
                    }

                    // Empty objects
                    ConvertUnityEmptyObjectToBabylon(gameObject, ref metaData, ref particleSystems, ref lensFlareSystems, ref componentTags, collisionMesh, collider);
                }

                // Materials
                foreach (var mat in materialsDictionary)
                {
                    babylonScene.MaterialsList.Add(mat.Value);
                }
                foreach (var multiMat in multiMatDictionary)
                {
                    babylonScene.MultiMaterialsList.Add(multiMat.Value);
                }

                // Collisions
                if (exportationOptions.ExportCollisions)
                {
                    babylonScene.workerCollisions = exportationOptions.WorkerCollisions;
                    if (SceneController != null) {
                        babylonScene.gravity = SceneController.sceneOptions.defaultGravity.ToFloat();
                    }
                }

                // Babylon Physics
                if (exportationOptions.ExportPhysics)
                {
                    babylonScene.physicsEnabled = true;
                    if (SceneController != null) {
                        babylonScene.physicsGravity = SceneController.sceneOptions.defaultGravity.ToFloat();
                    }
                }

                // Scene Controller
                if (SceneController != null)
                {
                    Color ambientColor = SceneController.sceneOptions.ambientColor;
                    float ambientLevel = SceneController.lightingOptions.lightLevel;
                    Color ambientSpecular = SceneController.lightingOptions.specularColor;
                    babylonScene.autoClear = SceneController.sceneOptions.autoClear;
                    int fogmode = 0;
                    if (RenderSettings.fog)
                    {
                        switch (RenderSettings.fogMode)
                        {
                            case FogMode.Exponential:
                                fogmode = 1;
                                break;
                            case FogMode.ExponentialSquared:
                                fogmode = 2;
                                break;
                            case FogMode.Linear:
                                fogmode = 3;
                                break;
                        }
                    }
                    babylonScene.fogMode = fogmode;
                    babylonScene.fogDensity = RenderSettings.fogDensity;
                    babylonScene.fogColor = RenderSettings.fogColor.ToFloat();
                    babylonScene.fogStart = RenderSettings.fogStartDistance;
                    babylonScene.fogEnd = RenderSettings.fogEndDistance;
                    if (exportationOptions.DefaultLightmapMode != (int)BabylonLightmapMode.FullLightBaking && SceneController.lightingOptions.lightMode == BabylonAmbientLighting.UnityAmbientLighting)
                    {
                        var ambientLight = new BabylonLight
                        {
                            name = "Ambient Light",
                            id = Guid.NewGuid().ToString(),
                            parentId = null,
                            metadata = null,
                            position = null,
                            exponent = 1.0f,
                            angle = 0.0f,
                            type = 3
                        };
                        var ambientDirection = new Vector3(0.0f, 1.0f, 0.0f);
                        Color ambientDiffuse = (RenderSettings.ambientMode == UnityEngine.Rendering.AmbientMode.Skybox) ? RenderSettings.ambientSkyColor : RenderSettings.ambientLight;
                        ambientLight.intensity = RenderSettings.ambientIntensity * ambientLevel;
                        ambientLight.direction = ambientDirection.ToFloat(); ;
                        ambientLight.diffuse = ambientDiffuse.ToFloat();
                        ambientLight.specular = ambientSpecular.ToFloat();
                        ambientLight.groundColor = RenderSettings.ambientGroundColor.ToFloat();
                        babylonScene.ambientColor = ambientColor.ToFloat();
                        babylonScene.LightsList.Add(ambientLight);
                        ExporterWindow.ReportProgress(0, "Exporting ambient light intensity at: " + ambientLight.intensity.ToString());
                    }
                    if (SceneController.sceneOptions.navigationMesh == BabylonNavigationMesh.EnableNavigation)
                    {
                        ExporterWindow.ReportProgress(0, "Parsing scene navigation mesh...");
                        NavMeshTriangulation triangulatedNavMesh = NavMesh.CalculateTriangulation();
                        if (triangulatedNavMesh.vertices != null && triangulatedNavMesh.vertices.Length > 0 && triangulatedNavMesh.indices != null && triangulatedNavMesh.indices.Length > 0)
                        {
                            int vertexCount = triangulatedNavMesh.vertices.Length;
                            if (vertexCount <= SceneBuilder.MAX_VERTEX_COUNT)
                            {
                                ExporterWindow.ReportProgress(0, "Generating navigation mesh vertices: " + vertexCount.ToString());
                                var navData = new UnityMetaData();
                                navData.type = "NavMesh";
                                navData.objectId = Guid.NewGuid().ToString();
                                navData.objectName = "Navigation_Mesh";
                                var areaTable = new List<object>();
                                string[] areaNavigation = GameObjectUtility.GetNavMeshAreaNames();
                                foreach (string areaName in areaNavigation)
                                {
                                    var bag = new Dictionary<string, object>();
                                    int areaIndex = NavMesh.GetAreaFromName(areaName);
                                    float areaCost = NavMesh.GetAreaCost(areaIndex);
                                    bag.Add("index", areaIndex);
                                    bag.Add("area", areaName);
                                    bag.Add("cost", areaCost);
                                    areaTable.Add(bag);
                                }
                                navData.properties.Add("table", areaTable);
                                navData.properties.Add("areas", triangulatedNavMesh.areas);

                                Mesh mesh = new Mesh();
                                mesh.name = "sceneNavigationMesh";
                                mesh.vertices = triangulatedNavMesh.vertices;
                                mesh.triangles = triangulatedNavMesh.indices;
                                mesh.RecalculateNormals();

                                BabylonMesh babylonMesh = new BabylonMesh();
                                babylonMesh.tags = "[NAVMESH]";
                                babylonMesh.metadata = navData;
                                babylonMesh.name = mesh.name;
                                babylonMesh.id = Guid.NewGuid().ToString();
                                babylonMesh.parentId = null;
                                babylonMesh.position = Vector3.zero.ToFloat();
                                babylonMesh.rotation = Vector3.zero.ToFloat();
                                babylonMesh.scaling = new Vector3(1, 1, 1).ToFloat();
                                babylonMesh.isVisible = false;
                                babylonMesh.visibility = 0.75f;
                                babylonMesh.checkCollisions = false;
                                Tools.GenerateBabylonMeshData(mesh, babylonMesh);
                                babylonScene.MeshesList.Add(babylonMesh);
                                SceneBuilder.Metadata.properties["hasNavigationMesh"] = true;
                            }
                            else
                            {
                                UnityEngine.Debug.LogError("Navigation mesh exceeds max (65000) vertex limit: " + vertexCount.ToString());
                            }
                        }
                    }
                    if (SceneController.sceneOptions.particleSystems)
                    {
                        if (particleSystems != null && particleSystems.Count > 0)
                        {
                            babylonScene.particleSystems = particleSystems.ToArray();
                        }
                    }
                    if (SceneController.sceneOptions.lensFlareSystems)
                    {
                        if (lensFlareSystems != null && lensFlareSystems.Count > 0)
                        {
                            var lfs_buffer = new List<BabylonLensFlareSystem>();
                            foreach (var ulfs in lensFlareSystems)
                            {
                                var lfs = new BabylonLensFlareSystem();
                                lfs.borderLimit = ulfs.borderLimit;
                                lfs.emitterId = ulfs.emitterId;
                                var lfx = new List<BabylonLensFlare>();
                                foreach (var ulf in ulfs.lensFlares)
                                {
                                    var lf = new BabylonLensFlare();
                                    lf.textureName = ulf.textureName;
                                    lf.position = ulf.position;
                                    lf.color = ulf.color;
                                    lf.size = ulf.size;
                                    lfx.Add(lf);
                                }
                                lfs.flares = lfx.ToArray();
                                lfs_buffer.Add(lfs);
                            }
                            babylonScene.lensFlareSystems = lfs_buffer.ToArray();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
            }
            finally
            {
                babylonScene.metadata = SceneBuilder.Metadata;
            }
        }
        private void ConvertUnityCameraToBabylon(Camera camera, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags)
        {
            ExporterWindow.ReportProgress(progress, "Exporting camera: " + camera.name);

            BabylonUniversalCamera babylonCamera = new BabylonUniversalCamera
            {
                name = camera.name,
                id = GetID(camera.gameObject),
                fov = camera.fieldOfView * (float)Math.PI / 180,
                minZ = camera.nearClipPlane,
                maxZ = camera.farClipPlane,
                parentId = GetParentID(camera.transform),
                position = camera.transform.localPosition.ToFloat()
            };
            metaData.type = "Camera";
            metaData.properties.Add("hdr", camera.hdr);
            metaData.properties.Add("clearFlags", camera.clearFlags.ToString());
            metaData.properties.Add("cullingMask", camera.cullingMask);
            metaData.properties.Add("stereoEnabled", camera.stereoEnabled);
            metaData.properties.Add("isOrthographic", camera.orthographic);
            metaData.properties.Add("useOcclusionCulling", camera.useOcclusionCulling);
            babylonCamera.tags = componentTags;

            var target = new Vector3(0, 0, 1);
            var transformedTarget = camera.transform.TransformDirection(target);
            babylonCamera.target = (camera.transform.position + transformedTarget).ToFloat();
            babylonCamera.isStereoscopicSideBySide = camera.stereoEnabled;
            if (camera.orthographic)
            {
                float vert = camera.orthographicSize;
                float horz = vert * exportationOptions.DefaultAspectRatio;
                babylonCamera.orthoTop = vert;
                babylonCamera.orthoBottom = -vert;
                babylonCamera.orthoLeft = -horz;
                babylonCamera.orthoRight = horz;
                babylonCamera.mode = 1;
            }
            else
            {
                babylonCamera.mode = 0;
            }

            babylonCamera.metadata = metaData;
            babylonScene.CamerasList.Add(babylonCamera);

            if (Camera.main == camera)
            {
                babylonScene.activeCameraID = babylonCamera.id;
                babylonScene.clearColor = camera.backgroundColor.ToFloat();
            }

            // Animations
            ExportAnimations(camera.transform, babylonCamera);

            // Collisions
            if (exportationOptions.ExportCollisions)
            {
                babylonCamera.checkCollisions = true;
                if (SceneController != null) {
                    babylonCamera.applyGravity = (SceneController.sceneOptions.defaultGravity.y == 0 && SceneController.sceneOptions.defaultGravity.y == 0 && SceneController.sceneOptions.defaultGravity.z == 0) ? false : true;
                    babylonCamera.ellipsoid = SceneController.sceneOptions.cameraEllipsoid.ToFloat();
                }
            }

            // Lens Flares
            ParseLensFlares(gameObject, babylonCamera.id, ref lensFlares);

            // Particles Systems
            ParseParticleSystems(gameObject, babylonCamera.id, ref particleSystems);
        }
        private void ConvertUnityLightToBabylon(Light light, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List<BabylonExport.Entities.BabylonParticleSystem> particleSystems, ref List<UnityFlareSystem> lensFlares, ref string componentTags)
        {
            // No Inactive Or Baking Lights
            if (light.isActiveAndEnabled == false || light.type == LightType.Area || light.lightmappingMode == LightmappingMode.Baked) return;

            ExporterWindow.ReportProgress(progress, "Exporting light: " + light.name);
            BabylonLight babylonLight = new BabylonLight
            {
                name = light.name,
                id = GetID(light.gameObject),
                parentId = GetParentID(light.transform)
            };
            metaData.type = "Light";
            babylonLight.tags = componentTags;

            switch (light.type)
            {
                case LightType.Point:
                    babylonLight.type = 0;
                    babylonLight.range = light.range;
                    break;
                case LightType.Directional:
                    babylonLight.type = 1;
                    break;
                case LightType.Spot:
                    babylonLight.type = 2;
                    break;
            }

            babylonLight.position = light.transform.localPosition.ToFloat();

            var direction = new Vector3(0, 0, 1);
            var transformedDirection = light.transform.TransformDirection(direction);
            transformedDirection[0] += exportationOptions.LightRotationOffset.X;
            transformedDirection[1] += exportationOptions.LightRotationOffset.Y;
            transformedDirection[2] += exportationOptions.LightRotationOffset.Z;
            babylonLight.direction = transformedDirection.ToFloat();
            
            babylonLight.diffuse = light.color.ToFloat();

            babylonLight.intensity = light.intensity * exportationOptions.LightIntensityFactor;

            babylonLight.angle = light.spotAngle * (float)Math.PI / 180;
            babylonLight.exponent = 1.0f;

            babylonLight.metadata = metaData;
            babylonScene.LightsList.Add(babylonLight);

            // Animations
            ExportAnimations(light.transform, babylonLight);

            // Lens Flares
            ParseLensFlares(gameObject, babylonLight.id, ref lensFlares);

            // Particles Systems
            ParseParticleSystems(gameObject, babylonLight.id, ref particleSystems);

            // Shadow Maps
            if (exportationOptions.ExportShadows)
            {
                if ((light.type == LightType.Directional || light.type == LightType.Spot) && light.shadows != LightShadows.None)
                {
                    GenerateShadowsGenerator(light, progress);
                }
            }
        }