コード例 #1
0
        private GLTFNode ExportLight(ref GLTFNode gltfNode, BabylonLight babylonLight, GLTF gltf, GLTFNode gltfParentNode, BabylonScene babylonScene)
        {
            if (exportParameters.enableKHRLightsPunctual)
            {
                if (babylonLight.type == 3) // ambient light
                {
                    RaiseMessage($"GLTFExporter.Light | Ambient light {babylonLight.name} is not supported in KHR_lights_punctual.");
                }
                else
                {
                    RaiseMessage("GLTFExporter.Light | Export light named: " + babylonLight.name, 2);

                    // new light in the node extensions
                    GLTFLight light = new GLTFLight
                    {
                        light = AddLightExtension(ref gltf, babylonLight)
                    };

                    if (gltfNode.extensions == null)
                    {
                        gltfNode.extensions = new GLTFExtensions();
                    }
                    gltfNode.extensions[KHR_lights_punctuals] = light;
                }
            }

            return(gltfNode);
        }
コード例 #2
0
        private GLTFNode ExportLight(ref GLTFNode gltfNode, BabylonLight babylonLight, GLTF gltf, GLTFNode gltfParentNode, BabylonScene babylonScene)
        {
            // Custom user properties
            if (babylonLight.metadata != null && babylonLight.metadata.Count != 0)
            {
                gltfNode.extras = babylonLight.metadata;
            }

            if (exportParameters.enableKHRLightsPunctual)
            {
                if (babylonLight.type == 3) // ambient light
                {
                    logger.RaiseMessage($"GLTFExporter.Light | Ambient light {babylonLight.name} is not supported in KHR_lights_punctual.");
                }
                else
                {
                    logger.RaiseMessage("GLTFExporter.Light | Export light named: " + babylonLight.name, 2);

                    // new light in the node extensions
                    GLTFLight light = new GLTFLight
                    {
                        light = AddLightExtension(ref gltf, babylonLight)
                    };

                    if (gltfNode.extensions == null)
                    {
                        gltfNode.extensions = new GLTFExtensions();
                    }
                    gltfNode.extensions[KHR_lights_punctuals] = light;
                }
            }
            ExportGLTFExtension(babylonLight, ref gltfNode, gltf);

            return(gltfNode);
        }
コード例 #3
0
        public const string KHR_lights = "KHR_lights";  // Name of the extension


        /// <summary>
        /// Add the light the global extensions
        /// </summary>
        /// <param name="gltf">The gltf data</param>
        /// <param name="babylonLight">The light to export</param>
        /// <returns>the index of the light</returns>
        private int AddLightExtension(ref GLTF gltf, BabylonLight babylonLight)
        {
            if (gltf.extensionsUsed.Contains(KHR_lights) == false)
            {
                gltf.extensionsUsed.Add(KHR_lights);
            }

            // new light in the gltf extensions
            GLTFLight light = new GLTFLight
            {
                color     = babylonLight.diffuse,
                type      = ((GLTFLight.LightType)babylonLight.type).ToString(),
                intensity = babylonLight.intensity,
            };

            switch (babylonLight.type)
            {
            case (0):     // point
                light.type  = GLTFLight.LightType.point.ToString();
                light.range = babylonLight.range;
                break;

            case (1):     // directional
                light.type = GLTFLight.LightType.directional.ToString();
                break;

            case (2):     // spot
                light.type  = GLTFLight.LightType.spot.ToString();
                light.range = babylonLight.range;
                light.spot  = new GLTFLight.Spot
                {
                    //innerConeAngle = 0, Babylon doesn't support the innerConeAngle
                    outerConeAngle = babylonLight.angle
                };
                break;

            case (3):     // ambient
                light.type = GLTFLight.LightType.ambient.ToString();
                break;
            }

            Dictionary <string, List <GLTFLight> > KHR_lightsExtension;

            if (gltf.extensions.ContainsKey(KHR_lights))
            {
                KHR_lightsExtension = (Dictionary <string, List <GLTFLight> >)gltf.extensions[KHR_lights];
                KHR_lightsExtension["lights"].Add(light);
            }
            else
            {
                KHR_lightsExtension           = new Dictionary <string, List <GLTFLight> >();
                KHR_lightsExtension["lights"] = new List <GLTFLight>();
                KHR_lightsExtension["lights"].Add(light);
                gltf.extensions[KHR_lights] = KHR_lightsExtension;
            }

            return(KHR_lightsExtension["lights"].Count - 1); // the index of the light
        }
コード例 #4
0
        private void ConvertUnityLightToBabylon(Light light, float progress)
        {
            if (!light.isActiveAndEnabled || light.alreadyLightmapped)
            {
                return;
            }

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

            BabylonLight babylonLight = new BabylonLight
            {
                name = light.name,
                id = GetID(light.gameObject),
                parentId = GetParentID(light.transform)
            };
            
            switch (light.type)
            {
                case LightType.Spot:
                    babylonLight.type = 2;
                    break;
                case LightType.Directional:
                    babylonLight.type = 1;
                    break;
                case LightType.Point:
                    babylonLight.type = 0;
                    babylonLight.range = light.range;
                    break;
                case LightType.Area:
                    // TODO
                    break;
            }

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

            var direction = new Vector3(0, 0, 1);
            var transformedDirection = light.transform.TransformDirection(direction);
            babylonLight.direction = transformedDirection.ToFloat();

            babylonLight.diffuse = light.color.ToFloat();

            babylonLight.intensity = light.intensity;

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

            babylonScene.LightsList.Add(babylonLight);

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

            // Shadows
            if ((light.type == LightType.Directional || light.type == LightType.Spot) && light.shadows != LightShadows.None)
            {
                GenerateShadowsGenerator(light);
            }
        }
コード例 #5
0
        private GLTFNode ExportLight(BabylonLight babylonLight, GLTF gltf, GLTFNode gltfParentNode)
        {
            RaiseMessage("GLTFExporter.Light | ExportLight babylonLight.name=" + babylonLight.name, 1);

            // --------------------------
            // ---------- Node ----------
            // --------------------------

            RaiseMessage("GLTFExporter.Light | Node", 2);
            // Node
            var gltfNode = new GLTFNode();

            gltfNode.name  = babylonLight.name;
            gltfNode.index = gltf.NodesList.Count;
            gltf.NodesList.Add(gltfNode);

            // Hierarchy
            if (gltfParentNode != null)
            {
                RaiseMessage("GLTFExporter.Light | Add " + babylonLight.name + " as child to " + gltfParentNode.name, 3);
                gltfParentNode.ChildrenList.Add(gltfNode.index);
                gltfNode.parent = gltfParentNode;
            }
            else
            {
                // It's a root node
                // Only root nodes are listed in a gltf scene
                RaiseMessage("GLTFExporter.Light | Add " + babylonLight.name + " as root node to scene", 3);
                gltf.scenes[0].NodesList.Add(gltfNode.index);
            }

            // Transform
            gltfNode.translation = babylonLight.position;
            // No rotation defined for babylon light. Use identity instead.
            gltfNode.rotation = new float[4] {
                0, 0, 0, 1
            };
            // No scaling defined for babylon light. Use identity instead.
            gltfNode.scale = new float[3] {
                1, 1, 1
            };

            // Switch coordinate system at object level
            gltfNode.translation[2] *= -1;
            gltfNode.rotation[0]    *= -1;
            gltfNode.rotation[1]    *= -1;

            // TODO - Animations
            //ExportNodeAnimation(babylonLight, gltf, gltfNode);

            return(gltfNode);
        }
コード例 #6
0
ファイル: NovaExporter.cs プロジェクト: yethusoe91/Babylon.js
        void DumpLights(NovaScene scene, BabylonScene babylonScene)
        {
            foreach (NovaLight light in scene.Lights)
            {
                if (light.Enabled)
                {
                    var babylonLight = new BabylonLight();
                    babylonScene.LightsList.Add(babylonLight);

                    babylonLight.name = light.Name;
                    babylonLight.id   = light.ID.ToString();
                    switch (light.Type)
                    {
                    case NovaLightType.Point:
                        babylonLight.type     = 0;
                        babylonLight.position = light.Position.ToArray();
                        break;

                    case NovaLightType.Spot:
                    case NovaLightType.Directional:
                        babylonLight.type      = 1;
                        babylonLight.position  = light.Position.ToArray();
                        babylonLight.direction = light.Direction.ToArray();
                        break;
                    }
                    babylonLight.diffuse   = light.Diffuse.ToArray();
                    babylonLight.specular  = light.Specular.ToArray();
                    babylonLight.intensity = light.Multiplicator;

                    if (light.ShadowMembers.Count > 0)
                    {
                        var shadowGenerator = new BabylonShadowGenerator
                        {
                            useVarianceShadowMap = true,
                            lightId    = light.ID.ToString(),
                            mapSize    = light.ShadowMapSize,
                            renderList = light.ShadowMembers.Select(m => m.ID.ToString()).ToArray()
                        };
                        babylonScene.ShadowGeneratorsList.Add(shadowGenerator);
                    }

                    if (light.LensFlares != null)
                    {
                        light.LensFlares.Tag = light;
                        lensFlareSystemToExport.Add(light.LensFlares);
                    }
                }
            }
        }
コード例 #7
0
        void ExportDefaultLight(BabylonScene babylonScene)
        {
            var babylonLight = new BabylonLight();

            babylonLight.name        = "Default light";
            babylonLight.id          = Guid.NewGuid().ToString();
            babylonLight.type        = 3;
            babylonLight.groundColor = new float[] { 0, 0, 0 };
            babylonLight.direction   = new[] { 0, 1.0f, 0 };

            babylonLight.intensity = 1;

            babylonLight.diffuse  = new[] { 1.0f, 1.0f, 1.0f };
            babylonLight.specular = new[] { 1.0f, 1.0f, 1.0f };

            babylonScene.LightsList.Add(babylonLight);
        }
コード例 #8
0
        private GLTFNode ExportLight(ref GLTFNode gltfNode, BabylonLight babylonLight, GLTF gltf, GLTFNode gltfParentNode, BabylonScene babylonScene)
        {
            RaiseMessage("GLTFExporter.Light | Export light named: " + babylonLight.name, 2);

            // new light in the node extensions
            GLTFLight light = new GLTFLight
            {
                light = AddLightExtension(ref gltf, babylonLight)
            };

            if (gltfNode.extensions == null)
            {
                gltfNode.extensions = new GLTFExtensions();
            }
            gltfNode.extensions[KHR_lights] = light;

            return(gltfNode);
        }
コード例 #9
0
        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);
                }
            }
        }
コード例 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mDagPath">DAG path to the transform above light</param>
        /// <param name="babylonScene"></param>
        /// <returns></returns>
        private BabylonNode ExportLight(MDagPath mDagPath, BabylonScene babylonScene)
        {
            RaiseMessage(mDagPath.partialPathName, 1);

            // Transform above light
            MFnTransform mFnTransform = new MFnTransform(mDagPath);

            // Light direct child of the transform
            MFnLight mFnLight = null;

            for (uint i = 0; i < mFnTransform.childCount; i++)
            {
                MObject childObject = mFnTransform.child(i);
                if (childObject.hasFn(MFn.Type.kLight))
                {
                    var _mFnLight = new MFnLight(childObject);
                    if (!_mFnLight.isIntermediateObject)
                    {
                        mFnLight = _mFnLight;
                    }
                }
            }
            if (mFnLight == null)
            {
                RaiseError("No light found has child of " + mDagPath.fullPathName);
                return(null);
            }

            RaiseMessage("mFnLight.fullPathName=" + mFnLight.fullPathName, 2);

            // --- prints ---
            #region prints

            // MFnLight
            RaiseVerbose("BabylonExporter.Light | mFnLight data", 2);
            RaiseVerbose("BabylonExporter.Light | mFnLight.color.toString()=" + mFnLight.color.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.intensity=" + mFnLight.intensity, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.useRayTraceShadows=" + mFnLight.useRayTraceShadows, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.shadowColor.toString()=" + mFnLight.shadowColor.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.centerOfIllumination=" + mFnLight.centerOfIllumination, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.numShadowSamples=" + mFnLight.numShadowSamples, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.rayDepthLimit=" + mFnLight.rayDepthLimit, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.opticalFXvisibility.toString()=" + mFnLight.opticalFXvisibility.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightIntensity.toString()=" + mFnLight.lightIntensity.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.instanceCount(true)=" + mFnLight.instanceCount(true), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightDirection(0).toString()=" + mFnLight.lightDirection(0).toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightAmbient=" + mFnLight.lightAmbient, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightDiffuse=" + mFnLight.lightDiffuse, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightSpecular=" + mFnLight.lightSpecular, 3);

            switch (mFnLight.objectProperty.apiType)
            {
            case MFn.Type.kSpotLight:
                MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty);
                // MFnNonAmbientLight
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.decayRate=" + mFnSpotLight.decayRate, 3);     // dropdown enum value
                // MFnNonExtendedLight
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.shadowRadius=" + mFnSpotLight.shadowRadius, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.castSoftShadows=" + mFnSpotLight.castSoftShadows, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDepthMapShadows=" + mFnSpotLight.useDepthMapShadows, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapFilterSize()=" + mFnSpotLight.depthMapFilterSize(), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapResolution()=" + mFnSpotLight.depthMapResolution(), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapBias()=" + mFnSpotLight.depthMapBias(), 3);
                // MFnSpotLight
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.coneAngle=" + mFnSpotLight.coneAngle, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.penumbraAngle=" + mFnSpotLight.penumbraAngle, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.dropOff=" + mFnSpotLight.dropOff, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.barnDoors=" + mFnSpotLight.barnDoors, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDecayRegions=" + mFnSpotLight.useDecayRegions, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird), 3);
                break;
            }

            Print(mFnTransform, 2, "Print ExportLight mFnTransform");

            Print(mFnLight, 2, "Print ExportLight mFnLight");

            #endregion

            if (IsLightExportable(mFnLight, mDagPath) == false)
            {
                return(null);
            }

            var babylonLight = new BabylonLight {
                name = mFnTransform.name, id = mFnTransform.uuid().asString()
            };

            // Hierarchy
            ExportHierarchy(babylonLight, mFnTransform);

            // User custom attributes
            babylonLight.metadata = ExportCustomAttributeFromTransform(mFnTransform);

            // Position
            //RaiseVerbose("BabylonExporter.Light | ExportTransform", 2);
            float[] position = null;
            GetTransform(mFnTransform, ref position);
            babylonLight.position = position;

            // Direction
            var vDir = new MVector(0, 0, -1);
            var transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix);
            vDir = vDir.multiply(transformationMatrix.asMatrixProperty);
            vDir.normalize();
            babylonLight.direction = new[] { (float)vDir.x, (float)vDir.y, -(float)vDir.z };

            // Common fields
            babylonLight.intensity = mFnLight.intensity;
            babylonLight.diffuse   = mFnLight.lightDiffuse ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 };
            babylonLight.specular  = mFnLight.lightSpecular ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 };

            // Type
            switch (mFnLight.objectProperty.apiType)
            {
            case MFn.Type.kPointLight:
                babylonLight.type = 0;
                break;

            case MFn.Type.kSpotLight:
                MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty);
                babylonLight.type     = 2;
                babylonLight.angle    = (float)mFnSpotLight.coneAngle;
                babylonLight.exponent = 1;

                if (mFnSpotLight.useDecayRegions)
                {
                    babylonLight.range = mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird);     // Max distance
                }
                break;

            case MFn.Type.kDirectionalLight:
                babylonLight.type = 1;
                break;

            case MFn.Type.kAmbientLight:
                babylonLight.type        = 3;
                babylonLight.groundColor = new float[] { 0, 0, 0 };

                // No emit diffuse /specular checkbox for ambient light
                babylonLight.diffuse  = mFnLight.color.toArrayRGB();
                babylonLight.specular = babylonLight.diffuse;

                // Direction
                vDir = new MVector(0, 1, 0);
                transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix);
                vDir = vDir.multiply(transformationMatrix.asMatrixProperty);
                vDir.normalize();
                babylonLight.direction = new[] { (float)vDir.x, (float)vDir.y, -(float)vDir.z };
                break;

            case MFn.Type.kAreaLight:
            case MFn.Type.kVolumeLight:
                RaiseError("Unsupported light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored. Supported light types are: ambient, directional, point and spot.", 1);
                return(null);

            default:
                RaiseWarning("Unknown light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored.", 1);
                return(null);
            }

            // TODO - Shadows

            //Variable declaration
            MStringArray  enlightedMeshesFullPathNames = new MStringArray();
            List <string> includeMeshesIds             = new List <string>();
            MStringArray  kTransMesh = new MStringArray();
            String        typeMesh   = null;
            MStringArray  UUIDMesh   = new MStringArray();

            //MEL Command that get the enlighted mesh for a given light
            MGlobal.executeCommand($@"lightlink -query -light {mFnTransform.fullPathName};", enlightedMeshesFullPathNames);

            //For each enlighted mesh
            foreach (String Mesh in enlightedMeshesFullPathNames)
            {
                //MEL Command use to get the type of each mesh
                typeMesh = MGlobal.executeCommandStringResult($@"nodeType -api {Mesh};");

                //We are targeting the type kMesh and not kTransform (for parenting)
                if (typeMesh == "kMesh")
                {
                    MGlobal.executeCommand($@"listRelatives -parent -fullPath {Mesh};", kTransMesh);

                    //And finally the MEL Command for the uuid of each mesh
                    MGlobal.executeCommand($@"ls -uuid {kTransMesh[0]};", UUIDMesh);
                    includeMeshesIds.Add(UUIDMesh[0]);
                }
            }

            babylonLight.includedOnlyMeshesIds = includeMeshesIds.ToArray();

            // Animations
            if (exportParameters.bakeAnimationFrames)
            {
                ExportNodeAnimationFrameByFrame(babylonLight, mFnTransform);
            }
            else
            {
                ExportNodeAnimation(babylonLight, mFnTransform);
            }

            babylonScene.LightsList.Add(babylonLight);

            return(babylonLight);
        }
コード例 #11
0
        private BabylonNode ExportLight(IIGameScene scene, IIGameNode lightNode, BabylonScene babylonScene)
        {
            if (IsLightExportable(lightNode) == false)
            {
                return(null);
            }

            var gameLight    = lightNode.IGameObject.AsGameLight();
            var initialized  = gameLight.InitializeData;
            var babylonLight = new BabylonLight();

            RaiseMessage(lightNode.Name, 1);
            babylonLight.name = lightNode.Name;

            // Export the custom attributes of this light
            babylonLight.metadata = ExportExtraAttributes(lightNode, babylonScene);

            // To preserve the position/rotation and the hierarchy, we create a dummy that will contains as direct children the light and the light children
            // The light will have no children. The dummy will contains the position and rotation animations.
            bool        createDummy = lightNode.ChildCount > 0;
            BabylonNode dummy       = null;

            if (createDummy)
            {
                dummy                 = ExportDummy(scene, lightNode, babylonScene);
                dummy.name            = "_" + dummy.name + "_";
                babylonLight.id       = Guid.NewGuid().ToString();
                babylonLight.parentId = dummy.id;
                babylonLight.hasDummy = true;
            }
            else
            {
                babylonLight.id = lightNode.MaxNode.GetGuid().ToString();
                if (lightNode.NodeParent != null)
                {
                    babylonLight.parentId = lightNode.NodeParent.MaxNode.GetGuid().ToString();
                }
            }

            // Type
            var maxLight   = (lightNode.MaxNode.ObjectRef as ILightObject);
            var lightState = Loader.Global.LightState.Create();

            maxLight.EvalLightState(0, Tools.Forever, lightState);

            switch (lightState.Type)
            {
            case LightType.OmniLgt:
                babylonLight.type = 0;
                break;

            case LightType.SpotLgt:
                babylonLight.type     = 2;
                babylonLight.angle    = (float)(maxLight.GetFallsize(0, Tools.Forever) * Math.PI / 180.0f);
                babylonLight.exponent = 1;
                break;

            case LightType.DirectLgt:
                babylonLight.type = 1;
                break;

            case LightType.AmbientLgt:
                babylonLight.type        = 3;
                babylonLight.groundColor = new float[] { 0, 0, 0 };
                break;
            }


            // Shadows
            if (maxLight.ShadowMethod == 1)
            {
                if (lightState.Type == LightType.DirectLgt || lightState.Type == LightType.SpotLgt || lightState.Type == LightType.OmniLgt)
                {
                    ExportShadowGenerator(lightNode.MaxNode, babylonScene, babylonLight);
                }
                else
                {
                    RaiseWarning("Shadows maps are only supported for point, directional and spot lights", 2);
                }
            }

            // Position / rotation / scaling
            if (createDummy)
            {
                // The position is stored by the dummy parent and the default direction is downward and it is updated by the rotation of the parent dummy
                babylonLight.position  = new[] { 0f, 0f, 0f };
                babylonLight.direction = new[] { 0f, -1f, 0f };
            }
            else
            {
                exportTransform(babylonLight, lightNode);

                // Position
                var localMatrix = lightNode.GetLocalTM(0);
                var position    = localMatrix.Translation;

                // Direction
                var target = gameLight.LightTarget;
                if (target != null)
                {
                    var targetWm       = target.GetObjectTM(0);
                    var targetPosition = targetWm.Translation;

                    var direction = targetPosition.Subtract(position).Normalize;
                    babylonLight.direction = new[]   { direction.X, direction.Y, direction.Z };
                }
                else
                {
                    var vDir = Loader.Global.Point3.Create(0, -1, 0);
                    vDir = localMatrix.ExtractMatrix3().VectorTransform(vDir).Normalize;
                    babylonLight.direction = new[] { vDir.X, vDir.Y, vDir.Z };
                }
            }

            // The HemisphericLight simulates the ambient environment light, so the passed direction is the light reflection direction, not the incoming direction.
            // So we need the opposite direction
            if (babylonLight.type == 3)
            {
                var worldRotation            = lightNode.GetWorldTM(0).Rotation;
                BabylonQuaternion quaternion = new BabylonQuaternion(worldRotation.X, worldRotation.Y, worldRotation.Z, worldRotation.W);

                babylonLight.direction = quaternion.Rotate(new BabylonVector3(0f, 1f, 0f)).ToArray();
            }


            var maxScene = Loader.Core.RootNode;

            // Exclusion
            try
            {
                var inclusion          = maxLight.ExclList.TestFlag(1); //NT_INCLUDE
                var checkExclusionList = maxLight.ExclList.TestFlag(2); //NT_AFFECT_ILLUM

                if (checkExclusionList)
                {
                    var excllist = new List <string>();
                    var incllist = new List <string>();

                    foreach (var meshNode in maxScene.NodesListBySuperClass(SClass_ID.Geomobject))
                    {
#if MAX2017 || MAX2018 || MAX2019 || MAX2020
                        if (meshNode.CastShadows)
#else
                        if (meshNode.CastShadows == 1)
#endif
                        {
                            var inList = maxLight.ExclList.FindNode(meshNode) != -1;

                            if (inList)
                            {
                                if (inclusion)
                                {
                                    incllist.Add(meshNode.GetGuid().ToString());
                                }
                                else
                                {
                                    excllist.Add(meshNode.GetGuid().ToString());
                                }
                            }
                        }
                    }

                    babylonLight.includedOnlyMeshesIds = incllist.ToArray();
                    babylonLight.excludedMeshesIds     = excllist.ToArray();
                }
            }
            catch (Exception e)
            {
                RaiseMessage("Light exclusion not supported", 2);
            }

            // Other fields
            babylonLight.intensity = maxLight.GetIntensity(0, Tools.Forever);


            babylonLight.diffuse  = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Tools.Forever).ToArray() : new float[] { 0, 0, 0 };
            babylonLight.specular = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Tools.Forever).ToArray() : new float[] { 0, 0, 0 };


            if (maxLight.UseAtten)
            {
                babylonLight.range = maxLight.GetAtten(0, 3, Tools.Forever);
            }

            if (exportParameters.exportAnimations)
            {
                // Animations
                var animations = new List <BabylonAnimation>();

                if (createDummy)
                {
                    // Position and rotation animations are stored by the parent (the dummy). The direction result from the parent rotation except for the HemisphericLight.
                    if (babylonLight.type == 3)
                    {
                        BabylonVector3 direction = new BabylonVector3(0, 1, 0);
                        ExportVector3Animation("direction", animations, key =>
                        {
                            var worldRotation            = lightNode.GetWorldTM(key).Rotation;
                            BabylonQuaternion quaternion = new BabylonQuaternion(worldRotation.X, worldRotation.Y, worldRotation.Z, worldRotation.W);

                            return(quaternion.Rotate(direction).ToArray());
                        });
                    }
                }
                else
                {
                    GeneratePositionAnimation(lightNode, animations);

                    ExportVector3Animation("direction", animations, key =>
                    {
                        var localMatrixAnimDir = lightNode.GetLocalTM(key);

                        var positionLight = localMatrixAnimDir.Translation;
                        var lightTarget   = gameLight.LightTarget;
                        if (lightTarget != null)
                        {
                            var targetWm       = lightTarget.GetObjectTM(key);
                            var targetPosition = targetWm.Translation;

                            var direction = targetPosition.Subtract(positionLight).Normalize;
                            return(new[] { direction.X, direction.Y, direction.Z });
                        }
                        else
                        {
                            var vDir = Loader.Global.Point3.Create(0, -1, 0);
                            vDir     = localMatrixAnimDir.ExtractMatrix3().VectorTransform(vDir).Normalize;

                            // The HemisphericLight (type == 3) simulates the ambient environment light, so the passed direction is the light reflection direction, not the incoming direction.
                            // So we need the opposite direction
                            return(babylonLight.type != 3 ? new[] { vDir.X, vDir.Y, vDir.Z } : new[] { -vDir.X, -vDir.Y, -vDir.Z });
                        }
                    });

                    // Animation temporary stored for gltf but not exported for babylon
                    // TODO - Will cause an issue when externalizing the glTF export process
                    var extraAnimations = new List <BabylonAnimation>();
                    // Do not check if node rotation properties are animated
                    GenerateRotationAnimation(lightNode, extraAnimations, true);
                    babylonLight.extraAnimations = extraAnimations;
                }

                ExportFloatAnimation("intensity", animations, key => new[] { maxLight.GetIntensity(key, Tools.Forever) });

                ExportColor3Animation("diffuse", animations, key =>
                {
                    return(lightState.AffectDiffuse? maxLight.GetRGBColor(key, Tools.Forever).ToArray() : new float[] { 0, 0, 0 });
                });

                babylonLight.animations = animations.ToArray();

                if (lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimate"))
                {
                    babylonLight.autoAnimate     = true;
                    babylonLight.autoAnimateFrom = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_from");
                    babylonLight.autoAnimateTo   = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_to");
                    babylonLight.autoAnimateLoop = lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimateloop");
                }
            }

            babylonScene.LightsList.Add(babylonLight);

            return(createDummy ? dummy : babylonLight);
        }
コード例 #12
0
        void DumpLights(NovaScene scene, BabylonScene babylonScene)
        {
            foreach (NovaLight light in scene.Lights)
            {
                if (light.Enabled)
                {
                    var babylonLight = new BabylonLight();
                    babylonScene.LightsList.Add(babylonLight);

                    babylonLight.name = light.Name;
                    babylonLight.id = light.ID.ToString();
                    switch (light.Type)
                    {
                        case NovaLightType.Point:
                            babylonLight.type = 0;
                            babylonLight.position = light.Position.ToArray();
                            break;
                        case NovaLightType.Spot:
                        case NovaLightType.Directional:
                            babylonLight.type = 1;
                            babylonLight.position = light.Position.ToArray();
                            babylonLight.direction = light.Direction.ToArray();
                            break;
                    }
                    babylonLight.diffuse = light.Diffuse.ToArray();
                    babylonLight.specular = light.Specular.ToArray();
                    babylonLight.intensity = light.Multiplicator;

                    if (light.ShadowMembers.Count > 0)
                    {
                        var shadowGenerator = new BabylonShadowGenerator
                        {
                            useVarianceShadowMap = true,
                            lightId = light.ID.ToString(),
                            mapSize = light.ShadowMapSize,
                            renderList = light.ShadowMembers.Select(m => m.ID.ToString()).ToArray()
                        };
                        babylonScene.ShadowGeneratorsList.Add(shadowGenerator);
                    }

                    if (light.LensFlares != null)
                    {
                        light.LensFlares.Tag = light;
                        lensFlareSystemToExport.Add(light.LensFlares);
                    }
                }
            }
        }
コード例 #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mDagPath">DAG path to the transform above light</param>
        /// <param name="babylonScene"></param>
        /// <returns></returns>
        private BabylonNode ExportLight(MDagPath mDagPath, BabylonScene babylonScene)
        {
            RaiseMessage(mDagPath.partialPathName, 1);

            // Transform above light
            MFnTransform mFnTransform = new MFnTransform(mDagPath);

            // Light direct child of the transform
            MFnLight mFnLight = null;

            for (uint i = 0; i < mFnTransform.childCount; i++)
            {
                MObject childObject = mFnTransform.child(i);
                if (childObject.hasFn(MFn.Type.kLight))
                {
                    mFnLight = new MFnLight(childObject);
                }
            }
            if (mFnLight == null)
            {
                RaiseError("No light found has child of " + mDagPath.fullPathName);
                return(null);
            }

            RaiseMessage("mFnLight.fullPathName=" + mFnLight.fullPathName, 2);


            // --- prints ---
            #region prints

            // MFnLight
            RaiseVerbose("BabylonExporter.Light | mFnLight data", 2);
            RaiseVerbose("BabylonExporter.Light | mFnLight.color.toString()=" + mFnLight.color.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.intensity=" + mFnLight.intensity, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.useRayTraceShadows=" + mFnLight.useRayTraceShadows, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.shadowColor.toString()=" + mFnLight.shadowColor.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.centerOfIllumination=" + mFnLight.centerOfIllumination, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.numShadowSamples=" + mFnLight.numShadowSamples, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.rayDepthLimit=" + mFnLight.rayDepthLimit, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.opticalFXvisibility.toString()=" + mFnLight.opticalFXvisibility.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightIntensity.toString()=" + mFnLight.lightIntensity.toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.instanceCount(true)=" + mFnLight.instanceCount(true), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightDirection(0).toString()=" + mFnLight.lightDirection(0).toString(), 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightAmbient=" + mFnLight.lightAmbient, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightDiffuse=" + mFnLight.lightDiffuse, 3);
            RaiseVerbose("BabylonExporter.Light | mFnLight.lightSpecular=" + mFnLight.lightSpecular, 3);

            switch (mFnLight.objectProperty.apiType)
            {
            case MFn.Type.kSpotLight:
                MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty);
                // MFnNonAmbientLight
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.decayRate=" + mFnSpotLight.decayRate, 3);     // dropdown enum value
                // MFnNonExtendedLight
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.shadowRadius=" + mFnSpotLight.shadowRadius, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.castSoftShadows=" + mFnSpotLight.castSoftShadows, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDepthMapShadows=" + mFnSpotLight.useDepthMapShadows, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapFilterSize()=" + mFnSpotLight.depthMapFilterSize(), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapResolution()=" + mFnSpotLight.depthMapResolution(), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.depthMapBias()=" + mFnSpotLight.depthMapBias(), 3);
                // MFnSpotLight
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.coneAngle=" + mFnSpotLight.coneAngle, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.penumbraAngle=" + mFnSpotLight.penumbraAngle, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.dropOff=" + mFnSpotLight.dropOff, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.barnDoors=" + mFnSpotLight.barnDoors, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.useDecayRegions=" + mFnSpotLight.useDecayRegions, 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kFirst), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kFirst), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kSecond), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kSecond), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.startDistance(MFnSpotLight.MDecayRegion.kThird), 3);
                RaiseVerbose("BabylonExporter.Light | mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird)=" + mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird), 3);
                break;
            }

            #endregion

            if (IsLightExportable(mFnLight, mDagPath) == false)
            {
                return(null);
            }

            var babylonLight = new BabylonLight {
                name = mFnTransform.name, id = mFnTransform.uuid().asString()
            };

            // Hierarchy
            ExportHierarchy(babylonLight, mFnTransform);

            // Position
            RaiseVerbose("BabylonExporter.Light | ExportTransform", 2);
            float[] position = null;
            GetTransform(mFnTransform, ref position);
            babylonLight.position = position;

            // Direction
            var vDir = new MVector(0, 0, -1);
            var transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix);
            vDir = vDir.multiply(transformationMatrix.asMatrixProperty);
            vDir.normalize();
            babylonLight.direction = new[] { (float)vDir.x, (float)vDir.y, -(float)vDir.z };

            // Common fields
            babylonLight.intensity = mFnLight.intensity;

            babylonLight.diffuse  = mFnLight.lightDiffuse ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 };
            babylonLight.specular = mFnLight.lightSpecular ? mFnLight.color.toArrayRGB() : new float[] { 0, 0, 0 };

            // Type
            switch (mFnLight.objectProperty.apiType)
            {
            case MFn.Type.kPointLight:
                babylonLight.type = 0;
                break;

            case MFn.Type.kSpotLight:
                MFnSpotLight mFnSpotLight = new MFnSpotLight(mFnLight.objectProperty);
                babylonLight.type     = 2;
                babylonLight.angle    = (float)mFnSpotLight.coneAngle;
                babylonLight.exponent = 1;

                if (mFnSpotLight.useDecayRegions)
                {
                    babylonLight.range = mFnSpotLight.endDistance(MFnSpotLight.MDecayRegion.kThird);     // Max distance
                }
                break;

            case MFn.Type.kDirectionalLight:
                babylonLight.type = 1;
                break;

            case MFn.Type.kAmbientLight:
                babylonLight.type        = 3;
                babylonLight.groundColor = new float[] { 0, 0, 0 };
                break;

            case MFn.Type.kAreaLight:
            case MFn.Type.kVolumeLight:
                RaiseError("Unsupported light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored. Supported light types are: ambient, directional, point and spot.");
                return(null);

            default:
                RaiseWarning("Unknown light type '" + mFnLight.objectProperty.apiType + "' for DAG path '" + mFnLight.fullPathName + "'. Light is ignored.");
                return(null);
            }

            // TODO - Shadows

            // TODO - Exclusion

            // TODO - Animations

            babylonScene.LightsList.Add(babylonLight);

            return(babylonLight);
        }
コード例 #14
0
        private BabylonShadowGenerator ExportShadowGenerator(IINode lightNode, BabylonScene babylonScene, BabylonLight babylonLight)
        {
            var maxLight = (lightNode.ObjectRef as ILightObject);
            var babylonShadowGenerator = new BabylonShadowGenerator();

            RaiseMessage("Exporting shadow map", 2);

            babylonShadowGenerator.lightId = babylonLight.id;

            babylonShadowGenerator.mapSize = maxLight.GetMapSize(0, Tools.Forever);

            babylonShadowGenerator.bias = lightNode.GetFloatProperty("babylonjs_shadows_bias", 0.00005f);
            babylonShadowGenerator.forceBackFacesOnly = lightNode.GetBoolProperty("babylonjs_forcebackfaces");

            var shadowsType = lightNode.GetStringProperty("babylonjs_shadows_type", "Blurred ESM");

            switch (shadowsType)
            {
            case "Hard shadows":
                break;

            case "Poisson Sampling":
                babylonShadowGenerator.usePoissonSampling = true;
                break;

            case "ESM":
                babylonShadowGenerator.useExponentialShadowMap = true;
                break;

            case "Blurred ESM":
                babylonShadowGenerator.useBlurExponentialShadowMap = true;
                babylonShadowGenerator.blurScale     = lightNode.GetFloatProperty("babylonjs_shadows_blurScale", 2);
                babylonShadowGenerator.blurBoxOffset = lightNode.GetFloatProperty("babylonjs_shadows_blurBoxOffset", 1);
                break;
            }


            var list = new List <string>();

            var inclusion          = maxLight.ExclList.TestFlag(1); //NT_INCLUDE
            var checkExclusionList = maxLight.ExclList.TestFlag(4); //NT_AFFECT_SHADOWCAST

            foreach (var meshNode in Loader.Core.RootNode.NodesListBySuperClass(SClass_ID.Geomobject))
            {
#if MAX2017 || MAX2018 || MAX2019 || MAX2020
                if (meshNode.CastShadows)
#else
                if (meshNode.CastShadows == 1)
#endif
                {
                    var inList = maxLight.ExclList.FindNode(meshNode) != -1;

                    if (!checkExclusionList || (inList && inclusion) || (!inList && !inclusion))
                    {
                        list.Add(meshNode.GetGuid().ToString());
                    }
                }
            }
            babylonShadowGenerator.renderList = list.ToArray();

            babylonScene.ShadowGeneratorsList.Add(babylonShadowGenerator);
            return(babylonShadowGenerator);
        }
コード例 #15
0
        public const string KHR_lights_punctuals = "KHR_lights_punctual";  // Name of the extension


        /// <summary>
        /// Add the light the global extensions
        /// </summary>
        /// <param name="gltf">The gltf data</param>
        /// <param name="babylonLight">The light to export</param>
        /// <returns>the index of the light</returns>
        private int AddLightExtension(ref GLTF gltf, BabylonLight babylonLight)
        {
            if (gltf.extensionsUsed.Contains(KHR_lights_punctuals) == false)
            {
                gltf.extensionsUsed.Add(KHR_lights_punctuals);
            }

            // new light in the gltf extensions
            GLTFLight light = new GLTFLight
            {
                color     = babylonLight.diffuse,
                type      = ((GLTFLight.LightType)babylonLight.type).ToString(),
                intensity = babylonLight.intensity,
            };

            switch (babylonLight.type)
            {
            case (0):     // point
                light.type  = GLTFLight.LightType.point.ToString();
                light.range = babylonLight.range;
                break;

            case (1):     // directional
                light.type = GLTFLight.LightType.directional.ToString();
                break;

            case (2):     // spot
                light.type  = GLTFLight.LightType.spot.ToString();
                light.range = babylonLight.range;
                light.spot  = new GLTFLight.Spot
                {
                    //innerConeAngle = 0, Babylon doesn't support the innerConeAngle
                    outerConeAngle = babylonLight.angle
                };
                break;

            default:
                RaiseError($"Unsupported light type {light.type} for glTF");
                throw new System.Exception($"Unsupported light type {light.type} for glTF");
            }

            Dictionary <string, List <GLTFLight> > KHR_lightsExtension;

            if (gltf.extensions.ContainsKey(KHR_lights_punctuals))
            {
                KHR_lightsExtension = (Dictionary <string, List <GLTFLight> >)gltf.extensions[KHR_lights_punctuals];
                KHR_lightsExtension["lights"].Add(light);
            }
            else
            {
                KHR_lightsExtension           = new Dictionary <string, List <GLTFLight> >();
                KHR_lightsExtension["lights"] = new List <GLTFLight>();
                KHR_lightsExtension["lights"].Add(light);
                gltf.extensions[KHR_lights_punctuals] = KHR_lightsExtension;
                if (gltf.extensionsUsed == null)
                {
                    gltf.extensionsUsed = new List <string>();
                }
                if (!gltf.extensionsUsed.Contains(KHR_lights_punctuals))
                {
                    gltf.extensionsUsed.Add(KHR_lights_punctuals);
                }
            }

            return(KHR_lightsExtension["lights"].Count - 1); // the index of the light
        }
コード例 #16
0
        private void ConvertUnityLightToBabylon(Light light, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List <UnityFlareSystem> lensFlares, ref string componentTags)
        {
            if (light.isActiveAndEnabled == false)
            {
                return;
            }
            if (light.type != LightType.Area && light.lightmapBakeType == LightmapBakeType.Baked)
            {
                return;
            }
            if (light.type == LightType.Area && exportationOptions.BakedLightsMode == (int)BabylonAreaLights.ExcludeAreaBakingLights)
            {
                return;
            }

            ExporterWindow.ReportProgress(progress, "Exporting light: " + light.name);
            BabylonLight babylonLight = (light.type == LightType.Directional) ? new BabylonDirectionalLight() : new BabylonLight();

            babylonLight.name     = light.name;
            babylonLight.id       = GetID(light.gameObject);
            babylonLight.parentId = GetParentID(light.transform);

            metaData.type     = "Light";
            babylonLight.tags = componentTags;

            switch (light.type)
            {
            case LightType.Area:
            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);

            babylonLight.direction = transformedDirection.ToFloat();

            //light.intensityMode = BABYLON.Light.INTENSITYMODE_AUTOMATIC;
            // Lumen (lm)
            //light.intensityMode = BABYLON.Light.INTENSITYMODE_LUMINOUSPOWER;
            // Candela (lm/sr)
            //light.intensityMode = BABYLON.Light.INTENSITYMODE_LUMINOUSINTENSITY;
            // Lux (lm/m^2)
            //light.intensityMode = BABYLON.Light.INTENSITYMODE_ILLUMINANCE;
            // Nit (cd/m^2)
            //light.intensityMode = BABYLON.Light.INTENSITYMODE_LUMINANCE;

            babylonLight.intensity     = light.intensity;
            babylonLight.intensityMode = (int)BabylonLightIntensity.Automatic;
            var lightScale = gameObject.GetComponent <LightScale>();

            if (lightScale != null)
            {
                babylonLight.intensity    *= lightScale.lightIntensity;
                babylonLight.intensityMode = (int)lightScale.intensityMode;
            }
            babylonLight.diffuse  = light.color.ToFloat();
            babylonLight.specular = Color.white.ToFloat();
            babylonLight.exponent = 1.0f;
            babylonLight.angle    = light.spotAngle * (float)Math.PI / 180;

            // Animations
            ExportTransformAnimationClips(light.transform, babylonLight, ref metaData);

            // Tagging
            if (!String.IsNullOrEmpty(babylonLight.tags))
            {
                babylonLight.tags = babylonLight.tags.Trim();
            }

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

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

            // Realtime Shadows
            if (light.shadows != LightShadows.None)
            {
                GenerateShadowsGenerator(babylonLight, light, progress);
            }
            if (!exportationOptions.ExportMetadata)
            {
                babylonLight.metadata = null;
            }
        }
コード例 #17
0
        private void ExportLight(IIGameScene scene, IIGameNode lightNode, BabylonScene babylonScene)
        {
            if (lightNode.MaxNode.GetBoolProperty("babylonjs_noexport"))
            {
                return;
            }

            var gameLight    = lightNode.IGameObject.AsGameLight();
            var initialized  = gameLight.InitializeData;
            var babylonLight = new BabylonLight();

            RaiseMessage(lightNode.Name, 1);
            babylonLight.name = lightNode.Name;
            babylonLight.id   = lightNode.MaxNode.GetGuid().ToString();
            if (lightNode.NodeParent != null)
            {
                babylonLight.parentId = GetParentID(lightNode.NodeParent, babylonScene, scene);
            }

            // Type

            var maxLight   = (lightNode.MaxNode.ObjectRef as ILightObject);
            var lightState = Loader.Global.LightState.Create();

            maxLight.EvalLightState(0, Tools.Forever, lightState);

            switch (lightState.Type)
            {
            case LightType.OmniLgt:
                babylonLight.type = 0;
                break;

            case LightType.SpotLgt:
                babylonLight.type     = 2;
                babylonLight.angle    = (float)(maxLight.GetFallsize(0, Tools.Forever) * Math.PI / 180.0f);
                babylonLight.exponent = 1;
                break;

            case LightType.DirectLgt:
                babylonLight.type = 1;
                break;

            case LightType.AmbientLgt:
                babylonLight.type        = 3;
                babylonLight.groundColor = new float[] { 0, 0, 0 };
                break;
            }


            // Shadows
            if (maxLight.ShadowMethod == 1)
            {
                if (lightState.Type == LightType.DirectLgt || lightState.Type == LightType.SpotLgt || lightState.Type == LightType.OmniLgt)
                {
                    ExportShadowGenerator(lightNode.MaxNode, babylonScene);
                }
                else
                {
                    RaiseWarning("Shadows maps are only supported for point, directional and spot lights", 2);
                }
            }

            // Position
            var wm = lightNode.GetObjectTM(0);

            if (lightNode.NodeParent != null)
            {
                var parentWorld = lightNode.NodeParent.GetObjectTM(0);
                wm.MultiplyBy(parentWorld.Inverse);
            }
            var position = wm.Translation;

            babylonLight.position = new[] { position.X, position.Y, position.Z };

            // Direction
            var target = gameLight.LightTarget;

            if (target != null)
            {
                var targetWm       = target.GetObjectTM(0);
                var targetPosition = targetWm.Translation;

                var direction = targetPosition.Subtract(position).Normalize;
                babylonLight.direction = new[] { direction.X, direction.Y, direction.Z };
            }
            else
            {
                var vDir = Loader.Global.Point3.Create(0, -1, 0);
                vDir = wm.ExtractMatrix3().VectorTransform(vDir).Normalize;
                babylonLight.direction = new[] { vDir.X, vDir.Y, vDir.Z };
            }

            var maxScene = Loader.Core.RootNode;

            // Exclusion
            var inclusion          = maxLight.ExclList.TestFlag(1); //NT_INCLUDE
            var checkExclusionList = maxLight.ExclList.TestFlag(2); //NT_AFFECT_ILLUM

            if (checkExclusionList)
            {
                var excllist = new List <string>();
                var incllist = new List <string>();

                foreach (var meshNode in maxScene.NodesListBySuperClass(SClass_ID.Geomobject))
                {
                    if (meshNode.CastShadows == 1)
                    {
                        var inList = maxLight.ExclList.FindNode(meshNode) != -1;

                        if (inList)
                        {
                            if (inclusion)
                            {
                                incllist.Add(meshNode.GetGuid().ToString());
                            }
                            else
                            {
                                excllist.Add(meshNode.GetGuid().ToString());
                            }
                        }
                    }
                }

                babylonLight.includedOnlyMeshesIds = incllist.ToArray();
                babylonLight.excludedMeshesIds     = excllist.ToArray();
            }

            // Other fields
            babylonLight.intensity = maxLight.GetIntensity(0, Tools.Forever);


            babylonLight.diffuse  = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Tools.Forever).ToArray() : new float[] { 0, 0, 0 };
            babylonLight.specular = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Tools.Forever).ToArray() : new float[] { 0, 0, 0 };


            if (maxLight.UseAtten)
            {
                babylonLight.range = maxLight.GetAtten(0, 3, Tools.Forever);
            }


            // Animations
            var animations = new List <BabylonAnimation>();

            ExportVector3Animation("position", animations, key =>
            {
                var mat = lightNode.GetObjectTM(key);
                if (lightNode.NodeParent != null)
                {
                    var parentWorld = lightNode.NodeParent.GetObjectTM(key);
                    mat.MultiplyBy(parentWorld.Inverse);
                }
                var pos = mat.Translation;
                return(new[] { pos.X, pos.Y, pos.Z });
            });

            ExportVector3Animation("direction", animations, key =>
            {
                var wmLight = lightNode.GetObjectTM(key);
                if (lightNode.NodeParent != null)
                {
                    var parentWorld = lightNode.NodeParent.GetObjectTM(key);
                    wmLight.MultiplyBy(parentWorld.Inverse);
                }
                var positionLight = wmLight.Translation;
                var lightTarget   = gameLight.LightTarget;
                if (lightTarget != null)
                {
                    var targetWm       = lightTarget.GetObjectTM(key);
                    var targetPosition = targetWm.Translation;

                    var direction = targetPosition.Subtract(positionLight).Normalize;
                    return(new[] { direction.X, direction.Y, direction.Z });
                }
                else
                {
                    var vDir = Loader.Global.Point3.Create(0, -1, 0);
                    vDir     = wmLight.ExtractMatrix3().VectorTransform(vDir).Normalize;
                    return(new[] { vDir.X, vDir.Y, vDir.Z });
                }
            });

            ExportFloatAnimation("intensity", animations, key => new[] { maxLight.GetIntensity(key, Tools.Forever) });

            ExportColor3Animation("diffuse", animations, key =>
            {
                return(lightState.AffectDiffuse? maxLight.GetRGBColor(key, Tools.Forever).ToArray() : new float[] { 0, 0, 0 });
            });

            babylonLight.animations = animations.ToArray();

            if (lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimate"))
            {
                babylonLight.autoAnimate     = true;
                babylonLight.autoAnimateFrom = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_from");
                babylonLight.autoAnimateTo   = (int)lightNode.MaxNode.GetFloatProperty("babylonjs_autoanimate_to");
                babylonLight.autoAnimateLoop = lightNode.MaxNode.GetBoolProperty("babylonjs_autoanimateloop");
            }

            babylonScene.LightsList.Add(babylonLight);
        }
コード例 #18
0
        private void GenerateShadowsGenerator(BabylonLight babylonLight, Light light, float progress)
        {
            var shadows = light.gameObject.GetComponent <UnityEditor.ShadowGenerator>();

            if (shadows != null && shadows.isActiveAndEnabled)
            {
                if (babylonLight is BabylonDirectionalLight)
                {
                    ((BabylonDirectionalLight)babylonLight).shadowOrthoScale = shadows.shadowOrthoScale;
                }
                float strength  = light.shadowStrength * shadows.shadowStrengthScale;
                var   generator = new BabylonExport.Entities.BabylonShadowGenerator
                {
                    lightId            = GetID(light.gameObject),
                    bias               = shadows.shadowMapBias,
                    mapSize            = shadows.shadowMapSize,
                    darkness           = (1.0f - strength),
                    depthScale         = shadows.shadowDepthScale,
                    blurScale          = shadows.shadowBlurScale,
                    blurBoxOffset      = shadows.shadowBlurOffset,
                    forceBackFacesOnly = shadows.forceBackFacesOnly
                };
                switch (shadows.shadowMapFilter)
                {
                case BabylonLightingFilter.PoissonSampling:
                    generator.usePoissonSampling = true;
                    break;

                case BabylonLightingFilter.ExponentialShadowMap:
                    generator.useExponentialShadowMap = true;
                    break;

                case BabylonLightingFilter.BlurExponentialShadowMap:
                    generator.useBlurExponentialShadowMap = true;
                    break;
                }
                // Light Shadow Generator Render List
                var renderList = new List <string>();
                foreach (var gameObject in gameObjects)
                {
                    if (gameObject.layer != ExporterWindow.PrefabIndex)
                    {
                        if (!gameObject.IsLightapStatic())
                        {
                            var shadowmap = gameObject.GetComponent <ShadowMap>();
                            if (shadowmap != null && shadowmap.runtimeShadows == BabylonEnabled.Enabled)
                            {
                                var renderer   = gameObject.GetComponent <Renderer>();
                                var meshFilter = gameObject.GetComponent <MeshFilter>();
                                if (meshFilter != null && renderer != null && renderer.shadowCastingMode != ShadowCastingMode.Off)
                                {
                                    renderList.Add(GetID(gameObject));
                                    continue;
                                }
                                var skinnedMesh = gameObject.GetComponent <SkinnedMeshRenderer>();
                                if (skinnedMesh != null && renderer != null && renderer.shadowCastingMode != ShadowCastingMode.Off)
                                {
                                    renderList.Add(GetID(gameObject));
                                }
                            }
                        }
                    }
                }
                if (renderList.Count > 0)
                {
                    generator.renderList = renderList.ToArray();
                    babylonScene.ShadowGeneratorsList.Add(generator);
                }
            }
        }
コード例 #19
0
        public const string KHR_lights_punctuals = "KHR_lights_punctual";  // Name of the extension


        /// <summary>
        /// Add the light the global extensions
        /// </summary>
        /// <param name="gltf">The gltf data</param>
        /// <param name="babylonLight">The light to export</param>
        /// <returns>the index of the light</returns>
        private int AddLightExtension(ref GLTF gltf, BabylonLight babylonLight)
        {
            if (gltf.extensionsUsed.Contains(KHR_lights_punctuals) == false)
            {
                gltf.extensionsUsed.Add(KHR_lights_punctuals);
            }

            // new light in the gltf extensions
            GLTFLight light = new GLTFLight
            {
                color     = babylonLight.diffuse,
                type      = ((GLTFLight.LightType)babylonLight.type).ToString(),
                intensity = babylonLight.intensity,
            };

            // Custom user properties
            if (babylonLight.metadata != null && babylonLight.metadata.Count != 0)
            {
                light.extras = babylonLight.metadata;
            }

            switch (babylonLight.type)
            {
            case (0):     // point
                light.type  = GLTFLight.LightType.point.ToString();
                light.range = babylonLight.range;
                break;

            case (1):     // directional
                light.type = GLTFLight.LightType.directional.ToString();
                break;

            case (2):     // spot
                light.type  = GLTFLight.LightType.spot.ToString();
                light.range = babylonLight.range;
                light.spot  = new GLTFLight.Spot
                {
                    //innerConeAngle = 0, Babylon doesn't support the innerConeAngle
                    outerConeAngle = babylonLight.angle / 2     // divide by 2 as glTF measures light outer angle from the light's center, while Babylon's light angle measures the whole light's cone angle.
                };
                break;

            default:
                logger.RaiseError($"Unsupported light type {light.type} for glTF");
                throw new System.Exception($"Unsupported light type {light.type} for glTF");
            }

            Dictionary <string, List <GLTFLight> > KHR_lightsExtension;

            if (gltf.extensions.ContainsKey(KHR_lights_punctuals))
            {
                KHR_lightsExtension = (Dictionary <string, List <GLTFLight> >)gltf.extensions[KHR_lights_punctuals];
                KHR_lightsExtension["lights"].Add(light);
            }
            else
            {
                KHR_lightsExtension           = new Dictionary <string, List <GLTFLight> >();
                KHR_lightsExtension["lights"] = new List <GLTFLight>();
                KHR_lightsExtension["lights"].Add(light);
                gltf.extensions[KHR_lights_punctuals] = KHR_lightsExtension;
                if (gltf.extensionsUsed == null)
                {
                    gltf.extensionsUsed = new List <string>();
                }
                if (!gltf.extensionsUsed.Contains(KHR_lights_punctuals))
                {
                    gltf.extensionsUsed.Add(KHR_lights_punctuals);
                }
            }

            ExportGLTFExtension(babylonLight, ref light, gltf);

            return(KHR_lightsExtension["lights"].Count - 1); // the index of the light
        }
コード例 #20
0
        private void ConvertUnityLightToBabylon(Light light, GameObject gameObject, float progress, ref UnityMetaData metaData, ref List <UnityFlareSystem> lensFlares, ref string componentTags)
        {
            // Note: No Inactive Or Full Baking Lights Exported
            if (light.isActiveAndEnabled == false || light.type == LightType.Area || light.lightmapBakeType == LightmapBakeType.Baked)
            {
                return;
            }

            ExporterWindow.ReportProgress(progress, "Exporting light: " + light.name);
            BabylonLight babylonLight = (light.type == LightType.Directional) ? new BabylonDirectionalLight() : new BabylonLight();

            babylonLight.name     = light.name;
            babylonLight.id       = GetID(light.gameObject);
            babylonLight.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);
            var defaultRotationOffset = (SceneController != null) ? SceneController.lightingOptions.rotationOffset : ExporterWindow.DefaultRotationOffset;

            transformedDirection[0] += defaultRotationOffset.x;
            transformedDirection[1] += defaultRotationOffset.y;
            transformedDirection[2] += defaultRotationOffset.z;
            babylonLight.direction   = transformedDirection.ToFloat();

            babylonLight.diffuse = light.color.ToFloat();

            float defaultIntenistyFactor = (SceneController != null) ? SceneController.lightingOptions.intensityScale : ExporterWindow.DefaultIntensityScale;

            babylonLight.intensity = light.intensity * defaultIntenistyFactor;

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

            // Animations
            ExportTransformAnimationClips(light.transform, babylonLight, ref metaData);

            // Tagging
            if (!String.IsNullOrEmpty(babylonLight.tags))
            {
                babylonLight.tags = babylonLight.tags.Trim();
            }

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

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

            // Realtime Shadow Maps (Scene Controller Required)
            if ((light.type == LightType.Directional || light.type == LightType.Point || light.type == LightType.Spot) && light.shadows != LightShadows.None)
            {
                GenerateShadowsGenerator(babylonLight, light, progress);
            }
            if (!exportationOptions.ExportMetadata)
            {
                babylonLight.metadata = null;
            }
        }
コード例 #21
0
        private BabylonLight ExportLight(Node lightNode, BabylonScene babylonScene)
        {
            var maxLight     = (lightNode.Object as Light);
            var babylonLight = new BabylonLight();

            RaiseMessage(maxLight.Name, true);
            babylonLight.name = lightNode.Name;
            babylonLight.id   = lightNode.GetGuid().ToString();

            // Type
            var lightState = Loader.Global.LightState.Create();

            maxLight._Light.EvalLightState(0, Interval.Forever._IInterval, lightState);
            var directionScale = -1;

            switch (lightState.Type)
            {
            case LightType.OmniLgt:
                babylonLight.type = 0;
                break;

            case LightType.SpotLgt:
                babylonLight.type     = 2;
                babylonLight.angle    = (float)(maxLight.GetFallOffSize(0, Interval.Forever) * Math.PI / 180.0f);
                babylonLight.exponent = 1;
                break;

            case LightType.DirectLgt:
                babylonLight.type = 1;

                // Shadows
                if (maxLight.ShadowMethod == 1)
                {
                    ExportShadowGenerator(lightNode, babylonScene);
                }

                break;

            case LightType.AmbientLgt:
                babylonLight.type        = 3;
                babylonLight.groundColor = new float[] { 0, 0, 0 };
                directionScale           = 1;
                break;
            }

            // Position
            var wm       = lightNode.GetWorldMatrix(0, false);
            var position = wm.Trans;

            babylonLight.position = position.ToArraySwitched();

            // Direction
            var target = lightNode._Node.Target;

            if (target != null)
            {
                var targetWm       = target.GetObjTMBeforeWSM(0, Interval.Forever._IInterval);
                var targetPosition = targetWm.Trans;

                var direction = targetPosition.Subtract(position);
                babylonLight.direction = direction.ToArraySwitched();
            }
            else
            {
                var dir = wm.GetRow(2).MultiplyBy(directionScale);
                babylonLight.direction = dir.ToArraySwitched();
            }

            // Exclusion
            var maxScene           = Kernel.Scene;
            var inclusion          = maxLight._Light.ExclList.TestFlag(1); //NT_INCLUDE
            var checkExclusionList = maxLight._Light.ExclList.TestFlag(2); //NT_AFFECT_ILLUM

            if (checkExclusionList)
            {
                var list = new List <string>();

                foreach (var meshNode in maxScene.NodesListBySuperClass(SuperClassID.GeometricObject))
                {
                    if (meshNode._Node.CastShadows == 1)
                    {
                        var inList = maxLight._Light.ExclList.FindNode(meshNode._Node) != -1;

                        if ((!inList && inclusion) || (inList && !inclusion))
                        {
                            list.Add(meshNode.GetGuid().ToString());
                        }
                    }
                }

                babylonLight.excludedMeshesIds = list.ToArray();
            }

            // Other fields
            babylonLight.intensity = maxLight.GetIntensity(0, Interval.Forever);

            babylonLight.diffuse  = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Interval.Forever).ToArray() : new float[] { 0, 0, 0 };
            babylonLight.specular = lightState.AffectDiffuse ? maxLight.GetRGBColor(0, Interval.Forever).ToArray() : new float[] { 0, 0, 0 };

            if (maxLight.UseAttenuation)
            {
                babylonLight.range = maxLight.GetAttenuation(0, 1, Interval.Forever);
            }

            // Animations
            var animations = new List <BabylonAnimation>();

            ExportVector3Animation("position", animations, key =>
            {
                var worldMatrix = lightNode.GetWorldMatrix(key, lightNode.HasParent());
                return(worldMatrix.Trans.ToArraySwitched());
            });

            ExportVector3Animation("direction", animations, key =>
            {
                var targetNode = lightNode._Node.Target;
                if (targetNode != null)
                {
                    var targetWm       = target.GetObjTMBeforeWSM(0, Interval.Forever._IInterval);
                    var targetPosition = targetWm.Trans;

                    var direction = targetPosition.Subtract(position);
                    return(direction.ToArraySwitched());
                }

                var dir = wm.GetRow(2).MultiplyBy(directionScale);
                return(dir.ToArraySwitched());
            });

            ExportFloatAnimation("intensity", animations, key => new[] { maxLight.GetIntensity(key, Interval.Forever) });


            babylonLight.animations = animations.ToArray();

            if (lightNode._Node.GetBoolProperty("babylonjs_autoanimate"))
            {
                babylonLight.autoAnimate     = true;
                babylonLight.autoAnimateFrom = (int)lightNode._Node.GetFloatProperty("babylonjs_autoanimate_from");
                babylonLight.autoAnimateTo   = (int)lightNode._Node.GetFloatProperty("babylonjs_autoanimate_to");
                babylonLight.autoAnimateLoop = lightNode._Node.GetBoolProperty("babylonjs_autoanimateloop");
            }

            babylonScene.LightsList.Add(babylonLight);
            return(babylonLight);
        }
コード例 #22
0
        private void GenerateShadowsGenerator(BabylonLight babylonLight, Light light, float progress)
        {
            BabylonLightingFilter shadowMapFilter = BabylonLightingFilter.BlurCloseExponentialShadowMap;
            int   shadowMapSize       = 1024;
            float shadowMapBias       = 0.00005f;
            float normalMapBias       = 0.0f;
            float shadowNearPlane     = 0.1f;
            float shadowFarPlane      = 100.0f;
            bool  shadowKernelBlur    = false;
            float shadowBlurKernel    = 1.0f;
            float shadowBlurScale     = 2.0f;
            float shadowBlurOffset    = 0.0f;
            float shadowOrthoScale    = 0.1f;
            float shadowStrengthScale = 1.0f;
            float shadowDepthScale    = 50.0f;
            float frustumEdgeFalloff  = 0.0f;
            bool  forceBackFacesOnly  = true;
            bool  transparencyShadow  = false;
            float contactHardening    = 0.1f;
            var   shadows             = light.gameObject.GetComponent <UnityEditor.ShadowGenerator>();

            if (shadows != null && shadows.isActiveAndEnabled)
            {
                shadowMapSize       = shadows.shadowMapSize;
                shadowMapBias       = shadows.shadowMapBias;
                normalMapBias       = shadows.shadowNormBias;
                shadowNearPlane     = shadows.shadowNearPlane;
                shadowFarPlane      = shadows.shadowFarPlane;
                shadowMapFilter     = shadows.shadowMapFilter;
                shadowKernelBlur    = shadows.shadowKernelBlur;
                shadowBlurKernel    = shadows.shadowBlurKernel;
                shadowBlurScale     = shadows.shadowBlurScale;
                shadowBlurOffset    = shadows.shadowBlurOffset;
                shadowOrthoScale    = shadows.shadowOrthoScale;
                shadowStrengthScale = shadows.shadowStrengthScale;
                shadowDepthScale    = shadows.shadowDepthScale;
                forceBackFacesOnly  = shadows.forceBackFacesOnly;
                transparencyShadow  = shadows.transparencyShadow;
                contactHardening    = shadows.contactHardening;
                frustumEdgeFalloff  = shadows.frustumEdgeFalloff;
            }
            babylonLight.shadowMinZ = shadowNearPlane;
            babylonLight.shadowMaxZ = shadowFarPlane;
            if (babylonLight is BabylonDirectionalLight)
            {
                ((BabylonDirectionalLight)babylonLight).shadowOrthoScale = shadowOrthoScale;
            }
            float strength  = light.shadowStrength * shadowStrengthScale;
            var   generator = new BabylonExport.Entities.BabylonShadowGenerator
            {
                lightId            = GetID(light.gameObject),
                bias               = shadowMapBias,
                normalBias         = normalMapBias,
                mapSize            = shadowMapSize,
                darkness           = (1.0f - strength),
                depthScale         = shadowDepthScale,
                blurScale          = shadowBlurScale,
                blurKernel         = shadowBlurKernel,
                blurBoxOffset      = shadowBlurOffset,
                useKernelBlur      = shadowKernelBlur,
                forceBackFacesOnly = forceBackFacesOnly,
                transparencyShadow = transparencyShadow,
                frustumEdgeFalloff = frustumEdgeFalloff,
                contactHardeningLightSizeUVRatio = contactHardening
            };

            switch (shadowMapFilter)
            {
            case BabylonLightingFilter.PoissonSampling:
                generator.usePoissonSampling = true;
                break;

            case BabylonLightingFilter.ExponentialShadowMap:
                generator.useExponentialShadowMap = true;
                break;

            case BabylonLightingFilter.BlurExponentialShadowMap:
                generator.useBlurExponentialShadowMap = true;
                break;

            case BabylonLightingFilter.CloseExponentialShadowMap:
                generator.useCloseExponentialShadowMap = true;
                break;

            case BabylonLightingFilter.BlurCloseExponentialShadowMap:
                generator.useBlurCloseExponentialShadowMap = true;
                break;

            case BabylonLightingFilter.PercentageCloserFiltering:
                generator.usePercentageCloserFiltering = true;
                break;

            case BabylonLightingFilter.ContactHardeningShadowMap:
                generator.useContactHardeningShadow = true;
                break;
            }
            // ..
            // Light Shadow Generator Render List (TODO: Support Specific Meshes Or Layers Or Tags)
            // ..
            var renderList = new List <string>();

            renderList.Add(rootInstance.id);
            foreach (var gameObject in gameObjects)
            {
                if (gameObject.layer != ExporterWindow.PrefabIndex)
                {
                    if (!gameObject.IsLightapStatic())
                    {
                        var meshFilter = gameObject.GetComponent <MeshFilter>();
                        var meshRender = gameObject.GetComponent <MeshRenderer>();
                        if (meshFilter != null && meshRender != null && meshRender.enabled == true && meshRender.shadowCastingMode != ShadowCastingMode.Off)
                        {
                            renderList.Add(GetID(gameObject));
                            continue;
                        }
                        var skinnedMesh = gameObject.GetComponent <SkinnedMeshRenderer>();
                        if (skinnedMesh != null && skinnedMesh.enabled == true && skinnedMesh.shadowCastingMode != ShadowCastingMode.Off)
                        {
                            renderList.Add(GetID(gameObject));
                        }
                    }
                }
            }
            generator.renderList = renderList.ToArray();
            babylonScene.ShadowGeneratorsList.Add(generator);
        }