Esempio n. 1
0
        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);
        }
Esempio n. 2
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);
                }
            }
        }
Esempio n. 3
0
        private static void ExportSkeletonAnimationClipData(GameObject source, BabylonSkeleton skeleton, SkinnedMeshRenderer skinnedMesh, BabylonMesh babylonMesh, UnityEditor.AnimationState animationState, ref List <AnimationClip> states, ref UnityMetaData metaData, Animator animator)
        {
            ExporterWindow.ReportProgress(1, "Exporting skeleton clips: " + skinnedMesh.name);
            //string sourceId = GetID(source);
            int frameRate       = 0;
            int firstClipEnd    = 0;
            int totalFrameCount = 0;

            Transform[]   bones          = skinnedMesh.bones;
            List <string> stateNameCache = new List <string>();

            if (!AnimationMode.InAnimationMode())
            {
                AnimationMode.StartAnimationMode();
            }
            //var anims = new List<BabylonAnimation>();
            //var pxkeys = new List<BabylonAnimationKey>();
            float playbackSpeed      = (animationState != null) ? animationState.playbackSpeed : 1.0f;
            float clampFeetPositions = (animationState != null) ? animationState.clampFeetPositions : 0.0f;
            BabylonAnimationBaking bakeRootTransforms = (animationState != null) ? animationState.bakeRootTransforms : BabylonAnimationBaking.GameBlend;

            foreach (var bone in skeleton.bones)
            {
                int       frameOffest = 0;
                var       keys        = new List <BabylonAnimationKey>();
                Transform transform   = bones.Single(b => b.name == bone.name);
                foreach (var state in states)
                {
                    if (state == null)
                    {
                        continue;
                    }
                    AnimationClip clip = state as AnimationClip;
                    if (frameRate <= 0)
                    {
                        frameRate = (int)clip.frameRate;
                    }
                    var frameTime      = 1.0f / frameRate;
                    int clipFrameCount = (int)(clip.length * frameRate);
                    if (firstClipEnd <= 0)
                    {
                        firstClipEnd = (clipFrameCount - 1);
                    }
                    var settings = AnimationUtility.GetAnimationClipSettings(clip);
                    BabylonLoopBehavior behavior = (settings.loopTime) ? BabylonLoopBehavior.Cycle : BabylonLoopBehavior.Constant;
                    if (settings.loopTime && settings.loopBlend)
                    {
                        behavior = BabylonLoopBehavior.Relative;
                    }
                    ExporterWindow.ReportProgress(1, "Sampling: " + babylonMesh.name + " - " + bone.name + " - " + clip.name);
                    // Set Animation State Meta Data
                    if (!stateNameCache.Contains(clip.name))
                    {
                        stateNameCache.Add(clip.name);
                        // Animation Clip Information
                        Dictionary <string, object> animStateInfo = new Dictionary <string, object>();
                        animStateInfo.Add("type", "skeleton");
                        animStateInfo.Add("name", clip.name);
                        animStateInfo.Add("start", frameOffest);
                        animStateInfo.Add("stop", (frameOffest + clipFrameCount - 1));
                        animStateInfo.Add("rate", frameRate);
                        animStateInfo.Add("behavior", (int)behavior);
                        animStateInfo.Add("playback", playbackSpeed);
                        metaData.animationClips.Add(animStateInfo);
                    }
                    AnimationMode.BeginSampling();
                    for (var i = 0; i < clipFrameCount; i++)
                    {
                        Matrix4x4 local;
                        int       frameIndex = (i + frameOffest);
                        float     originalPX = transform.localPosition.x;
                        float     originalPY = transform.localPosition.y;
                        float     originalPZ = transform.localPosition.z;
                        float     originalRY = transform.localRotation.eulerAngles.y;
                        clip.SampleAnimation(source, i * frameTime);
                        if (transform == skinnedMesh.rootBone)
                        {
                            float      positionX  = transform.localPosition.x;
                            float      positionY  = transform.localPosition.y;
                            float      positionZ  = transform.localPosition.z;
                            Quaternion rotationQT = transform.localRotation;
                            if (settings.loopBlendOrientation || settings.keepOriginalOrientation)
                            {
                                if (settings.keepOriginalOrientation)
                                {
                                    // Original Rotation - ???
                                    rotationQT = Quaternion.Euler(rotationQT.eulerAngles.x, originalRY, rotationQT.eulerAngles.z);
                                }
                                else
                                {
                                    // Body Orientation - ???
                                    rotationQT = Quaternion.Euler(rotationQT.eulerAngles.x, settings.orientationOffsetY, rotationQT.eulerAngles.z);
                                }
                            }
                            if (settings.loopBlendPositionY || settings.keepOriginalPositionY)
                            {
                                if (settings.keepOriginalPositionY)
                                {
                                    // Original Position Y
                                    positionY = originalPY;
                                }
                                else if (settings.heightFromFeet)
                                {
                                    // Feet Position Y
                                    positionY = (settings.level + clampFeetPositions);
                                }
                                else
                                {
                                    // Center Of Mass
                                    positionY = 0.0f;
                                }
                            }
                            if (settings.loopBlendPositionXZ || settings.keepOriginalPositionXZ)
                            {
                                if (settings.keepOriginalPositionXZ)
                                {
                                    // Original Position XZ
                                    positionX = originalPX;
                                    positionZ = originalPZ;
                                }
                                else
                                {
                                    // Center Of Mass
                                    positionX = 0.0f;
                                    positionZ = 0.0f;
                                }
                            }
                            if (bakeRootTransforms == BabylonAnimationBaking.GameBlend)
                            {
                                positionX = 0.0f;
                                positionZ = 0.0f;
                            }
                            local = Matrix4x4.TRS(new Vector3(positionX, positionY, positionZ), rotationQT, transform.localScale);
                        }
                        else
                        {
                            // DEPRECIATED: local = (transform.parent.localToWorldMatrix.inverse * transform.localToWorldMatrix);
                            local = Matrix4x4.TRS(transform.localPosition, transform.localRotation, transform.localScale);
                        }
                        float[] matrix = new[] {
                            local[0, 0], local[1, 0], local[2, 0], local[3, 0],
                            local[0, 1], local[1, 1], local[2, 1], local[3, 1],
                            local[0, 2], local[1, 2], local[2, 2], local[3, 2],
                            local[0, 3], local[1, 3], local[2, 3], local[3, 3]
                        };
                        var key = new BabylonAnimationKey
                        {
                            frame  = frameIndex,
                            values = matrix
                        };
                        keys.Add(key);
                    }
                    AnimationMode.EndSampling();
                    frameOffest     += clipFrameCount;
                    totalFrameCount += clipFrameCount;
                }
                var babylonAnimation = new BabylonAnimation
                {
                    name           = bone.name + "Animation",
                    property       = "_matrix",
                    dataType       = (int)BabylonAnimation.DataType.Matrix,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    framePerSecond = frameRate,
                    keys           = keys.ToArray()
                };
                bone.animation = babylonAnimation;
            }
            if (AnimationMode.InAnimationMode())
            {
                AnimationMode.StopAnimationMode();
            }

            /*
             * //
             * // TODO: Format Custom Curve Keys
             * //
             * string property = "none";
             * if (pxkeys.Count > 0)
             * {
             *  property = "metadata.state.animPosition.x";
             *  anims.Add(new BabylonAnimation
             *  {
             *      dataType = (int)BabylonAnimation.DataType.Float,
             *      name = property + " animation",
             *      keys = pxkeys.ToArray(),
             *      framePerSecond = frameRate,
             *      enableBlending = false,
             *      blendingSpeed = 0.0f,
             *      loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle,
             *      property = property
             *  });
             * }
             * //
             * // Cache Babylon Animation Keys
             * //
             * if (anims.Count > 0)
             * {
             *  List<BabylonAnimation> sourceAnimiamtions = null;
             *  if (SceneBuilder.AnimationCurveKeys.ContainsKey(sourceId)) {
             *      sourceAnimiamtions = SceneBuilder.AnimationCurveKeys[sourceId];
             *  } else {
             *      sourceAnimiamtions = new List<BabylonAnimation>();
             *      SceneBuilder.AnimationCurveKeys.Add(sourceId, sourceAnimiamtions);
             *  }
             *  foreach (var anim in anims) {
             *      sourceAnimiamtions.Add(anim);
             *  }
             * }
             */
        }
Esempio n. 4
0
        private static void ExportTransformAnimationClipData(GameObject source, Transform transform, BabylonIAnimatable animatable, UnityEditor.AnimationState animationState, ref List <AnimationClip> states, ref UnityMetaData metaData, Animator animator)
        {
            ExporterWindow.ReportProgress(1, "Exporting transform clips: " + transform.gameObject.name);
            int                     frameRate       = 0;
            int                     firstClipEnd    = 0;
            int                     totalFrameCount = 0;
            List <string>           stateNameCache  = new List <string>();
            List <BabylonAnimation> animations      = new List <BabylonAnimation>();

            var positionX = new List <BabylonAnimationKey>();
            var positionY = new List <BabylonAnimationKey>();
            var positionZ = new List <BabylonAnimationKey>();

            var rotationX = new List <BabylonAnimationKey>();
            var rotationY = new List <BabylonAnimationKey>();
            var rotationZ = new List <BabylonAnimationKey>();
            var rotationW = new List <BabylonAnimationKey>();

            var scaleX = new List <BabylonAnimationKey>();
            var scaleY = new List <BabylonAnimationKey>();
            var scaleZ = new List <BabylonAnimationKey>();

            int   frameOffest   = 0;
            float playbackSpeed = (animationState != null) ? animationState.playbackSpeed : 1.0f;

            foreach (var state in states)
            {
                if (state == null)
                {
                    continue;
                }
                AnimationClip clip = state as AnimationClip;
                if (frameRate <= 0)
                {
                    frameRate = (int)clip.frameRate;
                }
                //var frameTime = 1.0f / frameRate;
                int clipFrameCount = (int)(clip.length * frameRate);
                if (firstClipEnd <= 0)
                {
                    firstClipEnd = (clipFrameCount - 1);
                }
                var settings = AnimationUtility.GetAnimationClipSettings(clip);
                BabylonLoopBehavior behavior = (settings.loopTime) ? BabylonLoopBehavior.Cycle : BabylonLoopBehavior.Constant;
                if (settings.loopTime && settings.loopBlend)
                {
                    behavior = BabylonLoopBehavior.Relative;
                }
                ExporterWindow.ReportProgress(1, "Transforming: " + transform.gameObject.name + " - " + clip.name);
                // Set Animation State Meta Data
                if (!stateNameCache.Contains(clip.name))
                {
                    stateNameCache.Add(clip.name);
                    // Animation Clip Information
                    Dictionary <string, object> animStateInfo = new Dictionary <string, object>();
                    animStateInfo.Add("type", "transform");
                    animStateInfo.Add("name", clip.name);
                    animStateInfo.Add("start", frameOffest);
                    animStateInfo.Add("stop", (frameOffest + clipFrameCount - 1));
                    animStateInfo.Add("rate", frameRate);
                    animStateInfo.Add("behavior", (int)behavior);
                    animStateInfo.Add("playback", playbackSpeed);
                    metaData.animationClips.Add(animStateInfo);
                }

                // Animation Curve Bindings
                var curveBindings = AnimationUtility.GetCurveBindings(clip);
                foreach (var binding in curveBindings)
                {
                    var curve = AnimationUtility.GetEditorCurve(clip, binding);
                    switch (binding.propertyName)
                    {
                    //Position
                    case "m_LocalPosition.x":
                        IEnumerable <BabylonAnimationKey> px_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionX.AddRange(px_keys);
                        break;

                    case "m_LocalPosition.y":
                        IEnumerable <BabylonAnimationKey> py_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionY.AddRange(py_keys);
                        break;

                    case "m_LocalPosition.z":
                        IEnumerable <BabylonAnimationKey> pz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionZ.AddRange(pz_keys);
                        break;

                    // Rotation
                    case "localEulerAnglesRaw.x":
                        IEnumerable <BabylonAnimationKey> rx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationX.AddRange(rx_keys);
                        break;

                    case "localEulerAnglesRaw.y":
                        IEnumerable <BabylonAnimationKey> ry_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationY.AddRange(ry_keys);
                        break;

                    case "localEulerAnglesRaw.z":
                        IEnumerable <BabylonAnimationKey> rz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationZ.AddRange(rz_keys);
                        break;

                    case "localEulerAnglesRaw.w":
                        IEnumerable <BabylonAnimationKey> rw_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationW.AddRange(rw_keys);
                        break;

                    // Scaling
                    case "m_LocalScale.x":
                        IEnumerable <BabylonAnimationKey> sx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scaleX.AddRange(sx_keys);
                        break;

                    case "m_LocalScale.y":
                        IEnumerable <BabylonAnimationKey> sy_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scaleY.AddRange(sy_keys);
                        break;

                    case "m_LocalScale.z":
                        IEnumerable <BabylonAnimationKey> sz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scaleZ.AddRange(sz_keys);
                        break;

                    default:
                        continue;
                    }
                }
                frameOffest     += clipFrameCount;
                totalFrameCount += clipFrameCount;
            }

            // Position properties
            string property = "none";

            if (positionX.Count > 0)
            {
                property = "position.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = positionX.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (positionY.Count > 0)
            {
                property = "position.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = positionY.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (positionZ.Count > 0)
            {
                property = "position.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = positionZ.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }

            // Rotation properties
            property = "none";
            if (rotationX.Count > 0)
            {
                property = "rotation.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = rotationX.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (rotationY.Count > 0)
            {
                property = "rotation.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = rotationY.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (rotationZ.Count > 0)
            {
                property = "rotation.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = rotationZ.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (rotationW.Count > 0)
            {
                property = "rotation.w";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = rotationW.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }

            // Scale properties
            property = "none";
            if (scaleX.Count > 0)
            {
                property = "scaling.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = scaleX.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (scaleY.Count > 0)
            {
                property = "scaling.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = scaleY.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            property = "none";
            if (scaleZ.Count > 0)
            {
                property = "scaling.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = property + " animation",
                    keys           = scaleZ.ToArray(),
                    framePerSecond = frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Relative,
                    property       = property
                });
            }
            if (animations.Count > 0)
            {
                animatable.animations = animations.ToArray();
            }
        }
Esempio n. 5
0
        private static void ExportTransformAnimationClips(Transform transform, BabylonIAnimatable animatable, ref UnityMetaData metaData)
        {
            Animator  animator = transform.gameObject.GetComponent <Animator>();
            Animation legacy   = transform.gameObject.GetComponent <Animation>();

            if (legacy != null)
            {
                UnityEngine.Debug.LogWarning("Legacy animation component not supported for game object: " + transform.gameObject.name);
            }
            if (animator != null && animator.runtimeAnimatorController != null && animator.runtimeAnimatorController.animationClips != null && animator.runtimeAnimatorController.animationClips.Length > 0)
            {
                UnityEditor.AnimationState astate = transform.gameObject.GetComponent <UnityEditor.AnimationState>();
                if (astate == null)
                {
                    UnityEngine.Debug.LogWarning("AnimationState component not found for game object: " + transform.gameObject.name);
                }
                if (astate != null && astate.isActiveAndEnabled == true && astate.controlType == BabylonAnimationMode.Transform)
                {
                    if (animator != null)
                    {
                        animator.enabled = true;
                    }
                    List <AnimationClip> states = Tools.GetAnimationClips(animator);
                    if (states != null && states.Count > 0)
                    {
                        ExportTransformAnimationClipData(animator.gameObject, transform, animatable, astate, ref states, ref metaData, animator);
                    }
                }
            }
        }
Esempio n. 6
0
        private static void ExportSkeletonAnimationClips(Animator animator, BabylonSkeleton skeleton, SkinnedMeshRenderer skinnedMesh, BabylonMesh babylonMesh, UnityEditor.AnimationState animationState, ref UnityMetaData metaData)
        {
            List <AnimationClip> states = Tools.GetAnimationClips(animator);

            if (states != null && states.Count > 0)
            {
                ExportSkeletonAnimationClipData(animator.gameObject, skeleton, skinnedMesh, babylonMesh, animationState, ref states, ref metaData, animator);
            }
        }
Esempio n. 7
0
        private void ConvertUnityCameraToBabylon(Camera camera, GameObject gameObject, float progress, ref UnityMetaData metaData, 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()
            };

            if (camera.transform.parent != null)
            {
                babylonCamera.rotation    = new float[3];
                babylonCamera.rotation[0] = camera.transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
                babylonCamera.rotation[1] = camera.transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
                babylonCamera.rotation[2] = camera.transform.localRotation.eulerAngles.z * (float)Math.PI / 180;
            }
            else
            {
                var target            = new Vector3(0, 0, 1);
                var transformedTarget = camera.transform.TransformDirection(target);
                babylonCamera.target = (camera.transform.position + transformedTarget).ToFloat();
            }

            if (camera.orthographic)
            {
                babylonCamera.tags += " [ORTHOGRAPHIC]";
                babylonCamera.mode  = 1;
            }
            else
            {
                babylonCamera.mode = 0;
            }

            bool preventDefault  = false;
            bool virtualJoystick = false;

            bool   trackPosition = false;
            float  positionScale = 1.0f;
            string displayName   = "";

            int   horizontalRes        = 1280;
            int   verticalRes          = 800;
            float horizontalScreen     = 0.1497f;
            float verticalScreen       = 0.0935f;
            float screenCenter         = 0.0468f;
            float cameraBridge         = 0.005f;
            float eyeToScreen          = 0.0410f;
            float interpupillary       = 0.0640f;
            float lensSeparation       = 0.0635f;
            float lensCenterOffset     = 0.1520f;
            float postProcessScale     = 1.7146f;
            bool  compensateDistortion = true;

            float  ratio             = 1.0f;
            float  exposure          = 1.0f;
            float  gaussCoeff        = 0.3f;
            float  gaussMean         = 1.0f;
            float  gaussStandDev     = 0.8f;
            float  gaussMultiplier   = 4.0f;
            float  brightThreshold   = 0.8f;
            float  minimumLuminance  = 1.0f;
            float  maximumLuminance  = 1e20f;
            float  luminanceIncrease = 0.5f;
            float  luminanceDecrease = 0.5f;
            bool   stereoSideBySide  = false;
            int    cameraRigInput    = 0;
            float  cameraMoveSpeed   = 1.0f;
            float  cameraRotateSpeed = 0.005f;
            string cameraRigType     = "UniversalCamera";
            var    rigger            = gameObject.GetComponent <CameraRig>();

            if (rigger != null && rigger.isActiveAndEnabled)
            {
                cameraRigType                    = rigger.cameraType.ToString();
                cameraRigInput                   = (int)rigger.cameraInput;
                cameraMoveSpeed                  = rigger.inputMoveSpeed;
                cameraRotateSpeed                = rigger.inputRotateSpeed;
                babylonCamera.speed              = rigger.cameraSpeed;
                babylonCamera.inertia            = rigger.inertiaScaleFactor;
                babylonCamera.interaxialDistance = rigger.interaxialDistance;
                preventDefault                   = rigger.preventDefaultEvents;
                stereoSideBySide                 = rigger.stereoscopicSideBySide;
                virtualJoystick                  = (rigger.cameraType == BabylonCameraOptions.VirtualJoysticksCamera);

                trackPosition = rigger.virtualRealityWebPlatform.trackPosition;
                positionScale = rigger.virtualRealityWebPlatform.positionScale;
                displayName   = rigger.virtualRealityWebPlatform.displayName;;

                horizontalRes        = rigger.virtualRealityHeadsetOptions.horizontalResolution;
                verticalRes          = rigger.virtualRealityHeadsetOptions.verticalResolution;
                horizontalScreen     = rigger.virtualRealityHeadsetOptions.horizontalScreen;
                verticalScreen       = rigger.virtualRealityHeadsetOptions.verticalScreen;
                screenCenter         = rigger.virtualRealityHeadsetOptions.screenCenter;
                cameraBridge         = rigger.virtualRealityHeadsetOptions.cameraBridge;
                eyeToScreen          = rigger.virtualRealityHeadsetOptions.eyeToScreen;
                interpupillary       = rigger.virtualRealityHeadsetOptions.interpupillary;
                lensSeparation       = rigger.virtualRealityHeadsetOptions.lensSeparation;
                lensCenterOffset     = rigger.virtualRealityHeadsetOptions.lensCenterOffset;
                postProcessScale     = rigger.virtualRealityHeadsetOptions.postProcessScale;
                compensateDistortion = rigger.virtualRealityHeadsetOptions.compensateDistortion;

                ratio             = rigger.highDynamicRenderingPipeline.ratio;
                exposure          = rigger.highDynamicRenderingPipeline.exposure;
                gaussCoeff        = rigger.highDynamicRenderingPipeline.gaussCoeff;
                gaussMean         = rigger.highDynamicRenderingPipeline.gaussMean;
                gaussStandDev     = rigger.highDynamicRenderingPipeline.gaussStandDev;
                gaussMultiplier   = rigger.highDynamicRenderingPipeline.gaussMultiplier;
                brightThreshold   = rigger.highDynamicRenderingPipeline.brightThreshold;
                minimumLuminance  = rigger.highDynamicRenderingPipeline.minimumLuminance;
                maximumLuminance  = rigger.highDynamicRenderingPipeline.maximumLuminance;
                luminanceIncrease = rigger.highDynamicRenderingPipeline.luminanceIncrease;
                luminanceDecrease = rigger.highDynamicRenderingPipeline.luminanceDecrease;
            }
            SceneBuilder.Metadata.properties["virtualJoystickAttached"] = virtualJoystick;

            metaData.type = "Camera";
            metaData.properties.Add("cameraType", cameraRigType);
            metaData.properties.Add("cameraInput", cameraRigInput);
            metaData.properties.Add("clearFlags", camera.clearFlags.ToString());
            metaData.properties.Add("clearColor", camera.backgroundColor.ToFloat());
            metaData.properties.Add("cullingMask", camera.cullingMask);
            metaData.properties.Add("isOrthographic", camera.orthographic);
            metaData.properties.Add("orthographicSize", camera.orthographicSize);
            metaData.properties.Add("cameraMoveSpeed", cameraMoveSpeed);
            metaData.properties.Add("cameraRotateSpeed", cameraRotateSpeed);
            metaData.properties.Add("useOcclusionCulling", camera.useOcclusionCulling);
            metaData.properties.Add("preventDefaultEvents", preventDefault);
            metaData.properties.Add("stereoscopicSideBySide", stereoSideBySide);

            metaData.properties.Add("wvrTrackPosition", trackPosition);
            metaData.properties.Add("wvrPositionScale", positionScale);
            metaData.properties.Add("wvrDisplayName", displayName);

            metaData.properties.Add("vrHorizontalRes", horizontalRes);
            metaData.properties.Add("vrVerticalRes", verticalRes);
            metaData.properties.Add("vrHorizontalScreen", horizontalScreen);
            metaData.properties.Add("vrVerticalScreen", verticalScreen);
            metaData.properties.Add("vrScreenCenter", screenCenter);
            metaData.properties.Add("vrCameraBridge", cameraBridge);
            metaData.properties.Add("vrEyeToScreen", eyeToScreen);
            metaData.properties.Add("vrInterpupillary", interpupillary);
            metaData.properties.Add("vrLensSeparation", lensSeparation);
            metaData.properties.Add("vrLensCenterOffset", lensCenterOffset);
            metaData.properties.Add("vrPostProcessScale", postProcessScale);
            metaData.properties.Add("vrCompensateDistortion", compensateDistortion);

            metaData.properties.Add("hdr", camera.allowHDR);
            metaData.properties.Add("hdrPipeline", null);
            metaData.properties.Add("hdrRatio", ratio);
            metaData.properties.Add("hdrExposure", exposure);
            metaData.properties.Add("hdrGaussCoeff", gaussCoeff);
            metaData.properties.Add("hdrGaussMean", gaussMean);
            metaData.properties.Add("hdrGaussStandDev", gaussStandDev);
            metaData.properties.Add("hdrGaussMultiplier", gaussMultiplier);
            metaData.properties.Add("hdrBrightThreshold", brightThreshold);
            metaData.properties.Add("hdrMinimumLuminance", minimumLuminance);
            metaData.properties.Add("hdrMaximumLuminance", maximumLuminance);
            metaData.properties.Add("hdrLuminanceIncrease", luminanceIncrease);
            metaData.properties.Add("hdrLuminanceDecrease", luminanceDecrease);

            babylonCamera.isStereoscopicSideBySide = stereoSideBySide;
            babylonCamera.type = cameraRigType;
            babylonCamera.tags = componentTags;

            // Animations
            ExportTransformAnimationClips(camera.transform, babylonCamera, ref metaData);

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

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

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

            // Collisions
            if (exportationOptions.ExportCollisions)
            {
                // TODO: Move To Camera Rig Options and Otherwise defaults
                babylonCamera.checkCollisions = true;
                if (SceneController != null)
                {
                    babylonCamera.applyGravity = (SceneController.sceneOptions.defaultGravity.y == 0.0f && SceneController.sceneOptions.defaultGravity.y == 0.0f && SceneController.sceneOptions.defaultGravity.z == 0.0f) ? false : true;
                    babylonCamera.ellipsoid    = SceneController.sceneOptions.defaultEllipsoid.ToFloat();
                }
            }

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

            // Particles Systems
            if (!exportationOptions.ExportMetadata)
            {
                babylonCamera.metadata = null;
            }
        }
        private static void ExportTransformAnimationClipData(GameObject source, Transform transform, BabylonIAnimatable animatable, ref List <AnimationClip> clips, ref UnityMetaData metaData, List <UnityEditor.AnimationParameters> aparams)
        {
            ExporterWindow.ReportProgress(1, "Baking " + transform.gameObject.name.ToLower() + " transform... This may take a while.");
            string sourceId  = GetID(source);
            int    frameRate = 0;
            var    anims     = new List <BabylonAnimation>();
            List <BabylonRange>     ranges         = new List <BabylonRange>();
            List <string>           stateNameCache = new List <string>();
            List <BabylonAnimation> animations     = new List <BabylonAnimation>();

            var positionX = new List <BabylonAnimationKey>();
            var positionY = new List <BabylonAnimationKey>();
            var positionZ = new List <BabylonAnimationKey>();

            var rotationX = new List <BabylonAnimationKey>();
            var rotationY = new List <BabylonAnimationKey>();
            var rotationZ = new List <BabylonAnimationKey>();

            var quaternionX = new List <BabylonAnimationKey>();
            var quaternionY = new List <BabylonAnimationKey>();
            var quaternionZ = new List <BabylonAnimationKey>();
            var quaternionW = new List <BabylonAnimationKey>();

            var scalingX = new List <BabylonAnimationKey>();
            var scalingY = new List <BabylonAnimationKey>();
            var scalingZ = new List <BabylonAnimationKey>();

            int frameOffest = 0;

            foreach (var clip in clips)
            {
                if (clip == null)
                {
                    continue;
                }
                string clipName = FormatSafeClipName(clip.name);
                BabylonLoopBehavior behavior = (clip.wrapMode == WrapMode.Loop) ? BabylonLoopBehavior.Cycle : BabylonLoopBehavior.Constant;
                if (clip.wrapMode == WrapMode.PingPong)
                {
                    UnityEngine.Debug.LogWarning("PingPong transform animation wrap mode not supported for clip: " + clip.name);
                }
                // ..
                // Sample Animation Frame
                // ..
                if (frameRate <= 0)
                {
                    frameRate = (int)clip.frameRate;
                }
                int clipFrameCount = (int)(clip.length * clip.frameRate);
                int lastFrameCount = clipFrameCount - 1;
                // ..
                // Animation Curve Bindings
                // ..
                var curveBindings = AnimationUtility.GetCurveBindings(clip);
                foreach (var binding in curveBindings)
                {
                    var curve = AnimationUtility.GetEditorCurve(clip, binding);
                    switch (binding.propertyName)
                    {
                    //Positions
                    case "m_LocalPosition.x":
                        IEnumerable <BabylonAnimationKey> px_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionX.AddRange(px_keys);
                        break;

                    case "m_LocalPosition.y":
                        IEnumerable <BabylonAnimationKey> py_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionY.AddRange(py_keys);
                        break;

                    case "m_LocalPosition.z":
                        IEnumerable <BabylonAnimationKey> pz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        positionZ.AddRange(pz_keys);
                        break;

                    // Rotations
                    case "localEuler.x":
                    case "localEulerAnglesRaw.x":
                    case "localEulerAnglesBaked.x":
                        IEnumerable <BabylonAnimationKey> rx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationX.AddRange(rx_keys);
                        break;

                    case "localEuler.y":
                    case "localEulerAnglesRaw.y":
                    case "localEulerAnglesBaked.y":
                        IEnumerable <BabylonAnimationKey> ry_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationY.AddRange(ry_keys);
                        break;

                    case "localEuler.z":
                    case "localEulerAnglesRaw.z":
                    case "localEulerAnglesBaked.z":
                        IEnumerable <BabylonAnimationKey> rz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value *(float)Math.PI / 180 }
                        });
                        rotationZ.AddRange(rz_keys);
                        break;

                    // Quaternions
                    case "localRotation.x":
                    case "m_LocalRotation.x":
                        IEnumerable <BabylonAnimationKey> qx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        quaternionX.AddRange(qx_keys);
                        break;

                    case "localRotation.y":
                    case "m_LocalRotation.y":
                        IEnumerable <BabylonAnimationKey> qy_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        quaternionY.AddRange(qy_keys);
                        break;

                    case "localRotation.z":
                    case "m_LocalRotation.z":
                        IEnumerable <BabylonAnimationKey> qz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        quaternionZ.AddRange(qz_keys);
                        break;

                    case "localRotation.w":
                    case "m_LocalRotation.w":
                        IEnumerable <BabylonAnimationKey> qw_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        quaternionW.AddRange(qw_keys);
                        break;

                    // Scaling
                    case "m_LocalScale.x":
                        IEnumerable <BabylonAnimationKey> sx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scalingX.AddRange(sx_keys);
                        break;

                    case "m_LocalScale.y":
                        IEnumerable <BabylonAnimationKey> sy_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scalingY.AddRange(sy_keys);
                        break;

                    case "m_LocalScale.z":
                        IEnumerable <BabylonAnimationKey> sz_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                            frame  = (int)((keyFrame.time * frameRate) + frameOffest),
                            values = new[] { keyFrame.value }
                        });
                        scalingZ.AddRange(sz_keys);
                        break;

                    default:
                        continue;
                    }
                }
                // ..
                // Set Animation State Meta Data
                // ..
                if (!stateNameCache.Contains(clipName))
                {
                    stateNameCache.Add(clipName);
                    // Animation Clip Information
                    int fromFrame = frameOffest, toFrame = frameOffest + lastFrameCount;
                    Dictionary <string, object> animStateInfo = new Dictionary <string, object>();
                    animStateInfo.Add("type", "transform");
                    animStateInfo.Add("wrap", clip.wrapMode);
                    animStateInfo.Add("name", clipName);
                    animStateInfo.Add("start", fromFrame);
                    animStateInfo.Add("stop", toFrame);
                    animStateInfo.Add("rate", clip.frameRate);
                    animStateInfo.Add("frames", clipFrameCount);
                    animStateInfo.Add("weight", 1.0f);
                    animStateInfo.Add("behavior", (int)behavior);
                    animStateInfo.Add("apparentSpeed", clip.apparentSpeed);
                    animStateInfo.Add("averageSpeed", clip.averageSpeed.ToFloat());
                    animStateInfo.Add("averageDuration", clip.averageDuration);
                    animStateInfo.Add("averageAngularSpeed", clip.averageAngularSpeed);
                    List <string> customCurveKeyNames = new List <string>();
                    // ..
                    // UnityEditor.AnimationParameters;
                    // ..
                    if (aparams != null && aparams.Count > 0)
                    {
                        foreach (var aparam in aparams)
                        {
                            if (aparam.curve == true)
                            {
                                var curve = Tools.GetAnimationCurve(clip, aparam.name);
                                if (curve != null)
                                {
                                    IEnumerable <BabylonAnimationKey> cx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                                        frame  = (int)(keyFrame.time * frameRate),
                                        values = new[] { keyFrame.value }
                                    });
                                    BabylonAnimationKey[] xkeys = (cx_keys != null && cx_keys.Count() > 0) ? cx_keys.ToArray() : null;
                                    if (xkeys != null && xkeys.Length > 0)
                                    {
                                        string xkey  = aparam.name;
                                        string xprop = "metadata.state.floats." + xkey;
                                        string xname = "custom:" + clipName.Replace(" ", "") + ":" + System.Guid.NewGuid().ToString();
                                        customCurveKeyNames.Add(xname);
                                        anims.Add(new BabylonAnimation
                                        {
                                            dataType       = (int)BabylonAnimation.DataType.Float,
                                            name           = xname,
                                            keys           = xkeys,
                                            framePerSecond = frameRate,
                                            enableBlending = false,
                                            blendingSpeed  = 0.0f,
                                            loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                                            property       = xprop
                                        });
                                    }
                                }
                            }
                        }
                    }
                    animStateInfo.Add("customCurveKeyNames", (customCurveKeyNames.Count > 0) ? customCurveKeyNames.ToArray() : null);
                    metaData.animationClips.Add(animStateInfo);
                    ranges.Add(new BabylonRange {
                        name = clipName, from = fromFrame, to = toFrame
                    });
                }
                // ..
                frameOffest += clipFrameCount;
            }

            // Position properties
            string prefix   = "transform:";
            string suffix   = ":animation";
            string property = "none";

            if (positionX.Count > 0)
            {
                property = "position.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = positionX.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (positionY.Count > 0)
            {
                property = "position.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = positionY.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (positionZ.Count > 0)
            {
                property = "position.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = positionZ.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }

            // Rotation properties
            property = "none";
            if (rotationX.Count > 0)
            {
                property = "rotation.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = rotationX.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (rotationY.Count > 0)
            {
                property = "rotation.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = rotationY.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (rotationZ.Count > 0)
            {
                property = "rotation.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = rotationZ.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }

            // Quaternion properties
            property = "none";
            if (quaternionX.Count > 0)
            {
                property = "rotationQuaternion.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = quaternionX.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (quaternionY.Count > 0)
            {
                property = "rotationQuaternion.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = quaternionY.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (quaternionZ.Count > 0)
            {
                property = "rotationQuaternion.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = quaternionZ.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (quaternionW.Count > 0)
            {
                property = "rotationQuaternion.w";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = quaternionW.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }

            // Scaling properties
            property = "none";
            if (scalingX.Count > 0)
            {
                property = "scaling.x";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = scalingX.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (scalingY.Count > 0)
            {
                property = "scaling.y";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = scalingY.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            property = "none";
            if (scalingZ.Count > 0)
            {
                property = "scaling.z";
                animations.Add(new BabylonAnimation
                {
                    dataType       = (int)BabylonAnimation.DataType.Float,
                    name           = prefix + property.ToLower() + suffix,
                    keys           = scalingZ.ToArray(),
                    framePerSecond = (int)frameRate,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    property       = property
                });
            }
            // Serialize animations
            if (animations.Count > 0)
            {
                animatable.animations = animations.ToArray();
            }
            //
            // Cache Babylon Animation Keys
            //
            if (anims.Count > 0)
            {
                List <BabylonAnimation> sourceAnimiamtions = null;
                if (SceneBuilder.AnimationCurveKeys.ContainsKey(sourceId))
                {
                    sourceAnimiamtions = SceneBuilder.AnimationCurveKeys[sourceId];
                }
                else
                {
                    sourceAnimiamtions = new List <BabylonAnimation>();
                    SceneBuilder.AnimationCurveKeys.Add(sourceId, sourceAnimiamtions);
                }
                foreach (var anim in anims)
                {
                    sourceAnimiamtions.Add(anim);
                }
            }
        }
        private void ConvertUnityCameraToBabylon(Camera camera, GameObject gameObject, float progress, ref UnityMetaData metaData, 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()
            };

            if (camera.transform.parent != null)
            {
                babylonCamera.rotation    = new float[3];
                babylonCamera.rotation[0] = camera.transform.localRotation.eulerAngles.x * (float)Math.PI / 180;
                babylonCamera.rotation[1] = camera.transform.localRotation.eulerAngles.y * (float)Math.PI / 180;
                babylonCamera.rotation[2] = camera.transform.localRotation.eulerAngles.z * (float)Math.PI / 180;
            }
            else
            {
                var target            = new Vector3(0, 0, 1);
                var transformedTarget = camera.transform.TransformDirection(target);
                babylonCamera.target = (camera.transform.position + transformedTarget).ToFloat();
            }

            if (camera.orthographic)
            {
                babylonCamera.tags += " [ORTHOGRAPHIC]";
                babylonCamera.mode  = 1;
            }
            else
            {
                babylonCamera.mode = 0;
            }

            bool preventDefault  = false;
            bool virtualJoystick = false;

            string followTarget             = null;
            float  followRadius             = 20.0f;
            float  followHeightOffset       = 4.0f;
            float  followRotationOffset     = 0.0f;
            float  followCameraAcceleration = 0.5f;
            float  followMaxCameraSpeed     = 50.0f;

            float arcRotateAlpha  = (float)Math.PI / 2.0f;
            float arcRotateBeta   = (float)Math.PI / 4.0f;
            float arcRotateRadius = 3.0f;

            float[] arcRotateTarget           = new float[] { 0.0f, 1.0f, 0.0f };
            float   arcRotateLowerRadiusLimit = 1;
            float   arcRotateUpperRadiusLimit = 10;

            float[] arcRotateCollisionRadius      = new float[] { 1.0f, 1.0f, 1.0f };
            float   arcRotateWheelDeltaPercentage = 0.01f;

            bool   enableVirtualReality    = false;
            bool   displayGazeIcon         = false;
            bool   displayLaserBeam        = true;
            bool   enableInteractions      = false;
            bool   enableTeleportation     = false;
            bool   useControllerPrefabs    = false;
            int    initialController       = 0;
            string leftControllerPrefab    = "LeftController";
            string rightControllerPrefab   = "RightController";
            bool   deviceOrientationCamera = false;
            bool   fallbackFreeCamera      = true;
            bool   useCustomButton         = false;
            string buttonElementID         = null;
            float  rayCastLength           = 100f;
            float  defaultHeight           = 1.7f;
            float  positionScale           = 1.0f;
            string floorMeshesTags         = "Navigation";

            bool   stereoSideBySide  = false;
            int    cameraRigInput    = 0;
            float  cameraMoveSpeed   = 1.0f;
            float  cameraRotateSpeed = 0.005f;
            string cameraRigType     = "UniversalCamera";
            bool   localMultiPlayer  = false;
            bool   cameraCollisions  = true;
            bool   useMovementKeys   = true;
            bool   applyCamerGravity = true;
            var    rigger            = gameObject.GetComponent <CameraRig>();

            if (rigger != null && rigger.isActiveAndEnabled)
            {
                localMultiPlayer                 = (rigger.cameraType == BabylonCameraOptions.LocalMultiPlayerViewCamera);
                cameraRigType                    = (localMultiPlayer == true) ? "UniversalCamera" : rigger.cameraType.ToString();
                cameraRigInput                   = (int)rigger.cameraInput;
                cameraMoveSpeed                  = rigger.inputMoveSpeed;
                cameraRotateSpeed                = rigger.inputRotateSpeed;
                babylonCamera.speed              = rigger.cameraSpeed;
                babylonCamera.inertia            = rigger.inertiaScaleFactor;
                babylonCamera.interaxialDistance = rigger.interaxialDistance;
                preventDefault                   = rigger.preventDefaultEvents;
                stereoSideBySide                 = rigger.stereoSideBySide;
                virtualJoystick                  = (rigger.cameraType == BabylonCameraOptions.VirtualJoysticksCamera);
                cameraCollisions                 = rigger.checkCameraCollision;
                useMovementKeys                  = rigger.useMovementKeys;
                applyCamerGravity                = rigger.applyCameraGravity;

                if (rigger.followCameraOptions.target != null)
                {
                    followTarget = GetID(rigger.followCameraOptions.target);
                }
                followRadius             = rigger.followCameraOptions.radius;
                followHeightOffset       = rigger.followCameraOptions.heightOffset;
                followRotationOffset     = rigger.followCameraOptions.rotationOffset;
                followCameraAcceleration = rigger.followCameraOptions.cameraAcceleration;
                followMaxCameraSpeed     = rigger.followCameraOptions.maxCameraSpeed;

                arcRotateAlpha                = rigger.arcRotateCameraOptions.rotateAlpha;
                arcRotateBeta                 = rigger.arcRotateCameraOptions.rotateBeta;
                arcRotateRadius               = rigger.arcRotateCameraOptions.rotateRadius;
                arcRotateTarget               = rigger.arcRotateCameraOptions.rotateTarget.ToFloat();
                arcRotateLowerRadiusLimit     = rigger.arcRotateCameraOptions.lowerRadiusLimit;
                arcRotateUpperRadiusLimit     = rigger.arcRotateCameraOptions.upperRadiusLimit;
                arcRotateCollisionRadius      = rigger.arcRotateCameraOptions.collisionRadius.ToFloat();
                arcRotateWheelDeltaPercentage = rigger.arcRotateCameraOptions.wheelDeltaPercentage;

                enableVirtualReality    = rigger.virtualRealityWebPlatform.experienceHelper;
                displayGazeIcon         = rigger.virtualRealityWebPlatform.displayGazeIcon;
                displayLaserBeam        = rigger.virtualRealityWebPlatform.displayLaserBeam;
                enableInteractions      = rigger.virtualRealityWebPlatform.enableInteractions;
                enableTeleportation     = rigger.virtualRealityWebPlatform.enableTeleportation;
                useControllerPrefabs    = rigger.virtualRealityWebPlatform.customControllerPrefabs.enablePrefabs;
                initialController       = (int)rigger.virtualRealityWebPlatform.customControllerPrefabs.initialController;
                leftControllerPrefab    = rigger.virtualRealityWebPlatform.customControllerPrefabs.leftPrefabName;
                rightControllerPrefab   = rigger.virtualRealityWebPlatform.customControllerPrefabs.rightPrefabName;
                deviceOrientationCamera = (rigger.virtualRealityWebPlatform.experienceHelperOptions.defaultCamera == VirtualRealityCamera.DeviceOrientationCamera);
                fallbackFreeCamera      = rigger.virtualRealityWebPlatform.experienceHelperOptions.fallbackCamera;
                useCustomButton         = rigger.virtualRealityWebPlatform.experienceHelperOptions.useCustomButton;
                buttonElementID         = rigger.virtualRealityWebPlatform.experienceHelperOptions.buttonElementID;
                rayCastLength           = rigger.virtualRealityWebPlatform.experienceHelperOptions.rayCastLength;
                defaultHeight           = rigger.virtualRealityWebPlatform.experienceHelperOptions.defaultHeight;
                positionScale           = rigger.virtualRealityWebPlatform.experienceHelperOptions.positionScale;
                floorMeshesTags         = rigger.virtualRealityWebPlatform.experienceHelperOptions.floorMeshesTags;
            }
            SceneBuilder.Metadata.properties["virtualJoystickAttached"] = virtualJoystick;

            metaData.type = "Camera";
            metaData.properties.Add("mainCamera", (Camera.main == camera));
            metaData.properties.Add("cameraType", cameraRigType);
            metaData.properties.Add("cameraInput", cameraRigInput);
            metaData.properties.Add("clearFlags", camera.clearFlags.ToString());
            metaData.properties.Add("clearColor", babylonScene.clearColor);
            metaData.properties.Add("cullingMask", camera.cullingMask);
            metaData.properties.Add("movementKeys", useMovementKeys);
            metaData.properties.Add("isOrthographic", camera.orthographic);
            metaData.properties.Add("orthographicSize", camera.orthographicSize);
            metaData.properties.Add("cameraMoveSpeed", cameraMoveSpeed);
            metaData.properties.Add("cameraRotateSpeed", cameraRotateSpeed);
            metaData.properties.Add("useOcclusionCulling", camera.useOcclusionCulling);
            metaData.properties.Add("preventDefaultEvents", preventDefault);
            metaData.properties.Add("stereoscopicSideBySide", stereoSideBySide);
            metaData.properties.Add("localMultiPlayerViewCamera", localMultiPlayer);

            metaData.properties.Add("followTarget", followTarget);
            metaData.properties.Add("followRadius", followRadius);
            metaData.properties.Add("followHeightOffset", followHeightOffset);
            metaData.properties.Add("followRotationOffset", followRotationOffset);
            metaData.properties.Add("followCameraAcceleration", followCameraAcceleration);
            metaData.properties.Add("followMaxCameraSpeed", followMaxCameraSpeed);

            metaData.properties.Add("arcRotateAlpha", arcRotateAlpha);
            metaData.properties.Add("arcRotateBeta", arcRotateBeta);
            metaData.properties.Add("arcRotateRadius", arcRotateRadius);
            metaData.properties.Add("arcRotateTarget", arcRotateTarget);
            metaData.properties.Add("arcRotateLowerRadiusLimit", arcRotateLowerRadiusLimit);
            metaData.properties.Add("arcRotateUpperRadiusLimit", arcRotateUpperRadiusLimit);
            metaData.properties.Add("arcRotateCollisionRadius", arcRotateCollisionRadius);
            metaData.properties.Add("arcRotateWheelDeltaPercentage", arcRotateWheelDeltaPercentage);

            metaData.properties.Add("webvrUniversalCamera", enableVirtualReality);
            metaData.properties.Add("webvrDisplayGazeIcon", displayGazeIcon);
            metaData.properties.Add("webvrDisplayLaserBeam", displayLaserBeam);
            metaData.properties.Add("webvrEnableInteractions", enableInteractions);
            metaData.properties.Add("webvrEnableTeleportation", enableTeleportation);
            metaData.properties.Add("webvrControllerPrefabs", useControllerPrefabs);
            metaData.properties.Add("webvrInitialController", initialController);
            metaData.properties.Add("webvrLeftControllerPrefab", leftControllerPrefab);
            metaData.properties.Add("webvrRightControllerPrefab", rightControllerPrefab);
            metaData.properties.Add("webvrDeviceOrientationCamera", deviceOrientationCamera);
            metaData.properties.Add("webvrFallbackFreeCamera", fallbackFreeCamera);
            metaData.properties.Add("webvrUseCustomButton", useCustomButton);
            metaData.properties.Add("webvrButtonElementID", buttonElementID);
            metaData.properties.Add("webvrRayCastLength", rayCastLength);
            metaData.properties.Add("webvrDefaultHeight", defaultHeight);
            metaData.properties.Add("webvrPositionScale", positionScale);
            metaData.properties.Add("webvrFloorMeshesTags", floorMeshesTags);

            babylonCamera.isStereoscopicSideBySide = stereoSideBySide;
            babylonCamera.applyGravity             = applyCamerGravity;
            babylonCamera.type = cameraRigType;
            babylonCamera.tags = componentTags;

            // Animations
            ExportTransformAnimationClips(camera.transform, babylonCamera, ref metaData);

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

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

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

            // Collisions
            if (exportationOptions.ExportCollisions)
            {
                if (camera.transform.parent != null)
                {
                    babylonCamera.checkCollisions = false;
                }
                else
                {
                    babylonCamera.checkCollisions = cameraCollisions;
                }
            }

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

            // Greavity Ellispoid
            if (SceneController != null)
            {
                babylonCamera.ellipsoid = SceneController.sceneOptions.defaultEllipsoid.ToFloat();
            }

            // Particles Systems
            if (!exportationOptions.ExportMetadata)
            {
                babylonCamera.metadata = null;
            }
        }
Esempio n. 10
0
        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("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 size = camera.orthographicSize;
                babylonCamera.orthoTop    = size;
                babylonCamera.orthoBottom = -size;
                babylonCamera.orthoLeft   = -size;
                babylonCamera.orthoRight  = size;
                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;
                babylonCamera.applyGravity    = (exportationOptions.Gravity.X == 0 && exportationOptions.Gravity.Y == 0 && exportationOptions.Gravity.Z == 0) ? false : true;
                babylonCamera.ellipsoid       = exportationOptions.CameraEllipsoid.ToFloat();
            }

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

            // Particles Systems
            ParseParticleSystems(gameObject, babylonCamera.id, ref particleSystems);
        }
Esempio n. 11
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;
            }
        }
        private static void ExportSkeletonAnimationClipData(GameObject source, BabylonSkeleton skeleton, SkinnedMeshRenderer skinnedMesh, BabylonMesh babylonMesh, ref List <AnimationClip> clips, ref UnityMetaData metaData, List <UnityEditor.AnimationParameters> aparams)
        {
            ExporterWindow.ReportProgress(1, "Baking " + skinnedMesh.name.ToLower() + " skeleton... This may take a while.");
            string sourceId  = GetID(source);
            int    frameRate = 0;

            Transform[]         bones          = skinnedMesh.bones;
            var                 anims          = new List <BabylonAnimation>();
            List <BabylonRange> ranges         = new List <BabylonRange>();
            List <string>       stateNameCache = new List <string>();

            if (!AnimationMode.InAnimationMode())
            {
                AnimationMode.StartAnimationMode();
            }
            foreach (var bone in skeleton.bones)
            {
                int       frameOffest = 0;
                var       keys        = new List <BabylonAnimationKey>();
                Transform transform   = bones.Single(b => b.name == bone.name);
                foreach (var clip in clips)
                {
                    if (clip == null)
                    {
                        continue;
                    }
                    string clipName = FormatSafeClipName(clip.name);
                    var    settings = AnimationUtility.GetAnimationClipSettings(clip);
                    BabylonLoopBehavior behavior = (settings.loopTime) ? BabylonLoopBehavior.Relative : BabylonLoopBehavior.Constant;
                    if (settings.loopTime && settings.loopBlend)
                    {
                        behavior = BabylonLoopBehavior.Cycle;
                    }
                    // ..
                    int   framePadding = 1;
                    float deltaTime    = 1.0f / clip.frameRate;
                    if (frameRate <= 0)
                    {
                        frameRate = (int)clip.frameRate;
                    }
                    float clipFrameTotal = clip.length * clip.frameRate;
                    int   clipFrameCount = (int)clipFrameTotal + framePadding;
                    int   lastFrameCount = clipFrameCount - 1;
                    // ..
                    AnimationMode.BeginSampling();
                    for (int i = 0; i < clipFrameCount; i++)
                    {
                        Matrix4x4 local;
                        int       frameIndex = (int)(i + frameOffest);
                        float     sampleTime = (i < lastFrameCount) ? (i * deltaTime) : clip.length;
                        clip.SampleAnimation(source, sampleTime);
                        if (transform == skinnedMesh.rootBone)
                        {
                            float      positionX  = transform.localPosition.x;
                            float      positionY  = transform.localPosition.y;
                            float      positionZ  = transform.localPosition.z;
                            Quaternion rotationQT = transform.localRotation;
                            if (settings.loopBlendOrientation)
                            {
                                if (settings.keepOriginalOrientation)
                                {
                                    rotationQT = Quaternion.Euler(rotationQT.eulerAngles.x, (rotationQT.eulerAngles.y + settings.orientationOffsetY), rotationQT.eulerAngles.z);
                                }
                                else
                                {
                                    rotationQT = Quaternion.Euler(rotationQT.eulerAngles.x, settings.orientationOffsetY, rotationQT.eulerAngles.z);
                                }
                            }
                            if (settings.loopBlendPositionY)
                            {
                                if (settings.keepOriginalPositionY || settings.heightFromFeet)
                                {
                                    positionY += settings.level;
                                }
                                else
                                {
                                    positionY = settings.level;
                                }
                            }
                            if (settings.loopBlendPositionXZ)
                            {
                                positionX = 0.0f;
                                positionZ = 0.0f;
                            }
                            local = Matrix4x4.TRS(new Vector3(positionX, positionY, positionZ), rotationQT, transform.localScale);
                        }
                        else
                        {
                            local = Matrix4x4.TRS(transform.localPosition, transform.localRotation, transform.localScale);
                        }
                        float[] matrix = new[] {
                            local[0, 0], local[1, 0], local[2, 0], local[3, 0],
                            local[0, 1], local[1, 1], local[2, 1], local[3, 1],
                            local[0, 2], local[1, 2], local[2, 2], local[3, 2],
                            local[0, 3], local[1, 3], local[2, 3], local[3, 3]
                        };
                        var key = new BabylonAnimationKey
                        {
                            frame  = frameIndex,
                            values = matrix
                        };
                        keys.Add(key);
                    }
                    AnimationMode.EndSampling();
                    // ..
                    // Set Animation State Meta Data
                    // ..
                    if (!stateNameCache.Contains(clipName))
                    {
                        stateNameCache.Add(clipName);
                        // Animation Clip Information
                        int fromFrame = frameOffest, toFrame = frameOffest + lastFrameCount;
                        Dictionary <string, object> animStateInfo = new Dictionary <string, object>();
                        animStateInfo.Add("type", "skeleton");
                        animStateInfo.Add("wrap", clip.wrapMode);
                        animStateInfo.Add("name", clipName);
                        animStateInfo.Add("start", fromFrame);
                        animStateInfo.Add("stop", toFrame);
                        animStateInfo.Add("rate", clip.frameRate);
                        animStateInfo.Add("frames", clipFrameCount);
                        animStateInfo.Add("weight", 1.0f);
                        animStateInfo.Add("behavior", (int)behavior);
                        animStateInfo.Add("apparentSpeed", clip.apparentSpeed);
                        animStateInfo.Add("averageSpeed", clip.averageSpeed.ToFloat());
                        animStateInfo.Add("averageDuration", clip.averageDuration);
                        animStateInfo.Add("averageAngularSpeed", clip.averageAngularSpeed);
                        List <string> customCurveKeyNames = new List <string>();
                        // ..
                        // UnityEditor.AnimationParameters;
                        // ..
                        if (aparams != null && aparams.Count > 0)
                        {
                            foreach (var aparam in aparams)
                            {
                                if (aparam.curve == true)
                                {
                                    var curve = Tools.GetAnimationCurve(clip, aparam.name);
                                    if (curve != null)
                                    {
                                        IEnumerable <BabylonAnimationKey> cx_keys = curve.keys.Select(keyFrame => new BabylonAnimationKey {
                                            frame  = (int)(keyFrame.time * frameRate),
                                            values = new[] { keyFrame.value }
                                        });
                                        BabylonAnimationKey[] xkeys = (cx_keys != null && cx_keys.Count() > 0) ? cx_keys.ToArray() : null;
                                        if (xkeys != null && xkeys.Length > 0)
                                        {
                                            string xkey  = aparam.name;
                                            string xprop = "metadata.state.floats." + xkey;
                                            string xname = "curve:" + clipName.Replace(" ", "") + ":" + System.Guid.NewGuid().ToString();
                                            customCurveKeyNames.Add(xname);
                                            anims.Add(new BabylonAnimation
                                            {
                                                dataType       = (int)BabylonAnimation.DataType.Float,
                                                name           = xname,
                                                keys           = xkeys,
                                                framePerSecond = frameRate,
                                                enableBlending = false,
                                                blendingSpeed  = 0.0f,
                                                loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                                                property       = xprop
                                            });
                                        }
                                    }
                                }
                            }
                        }
                        animStateInfo.Add("customCurveKeyNames", (customCurveKeyNames.Count > 0) ? customCurveKeyNames.ToArray() : null);
                        metaData.animationClips.Add(animStateInfo);
                        ranges.Add(new BabylonRange {
                            name = clipName, from = fromFrame, to = toFrame
                        });
                    }
                    // ..
                    frameOffest += clipFrameCount;
                }
                var babylonAnimation = new BabylonAnimation
                {
                    name           = "skeleton:" + bone.name.ToLower() + ":animation",
                    property       = "_matrix",
                    dataType       = (int)BabylonAnimation.DataType.Matrix,
                    loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                    enableBlending = false,
                    blendingSpeed  = 0.0f,
                    framePerSecond = frameRate,
                    keys           = keys.ToArray()
                };
                bone.animation = babylonAnimation;
            }
            if (AnimationMode.InAnimationMode())
            {
                AnimationMode.StopAnimationMode();
            }
            //
            // Serialize Skeleton Clip Ranges
            //
            skeleton.ranges = (ranges.Count > 0) ? ranges.ToArray() : null;
            //
            // Cache Babylon Animation Keys
            //
            if (anims.Count > 0)
            {
                List <BabylonAnimation> sourceAnimiamtions = null;
                if (SceneBuilder.AnimationCurveKeys.ContainsKey(sourceId))
                {
                    sourceAnimiamtions = SceneBuilder.AnimationCurveKeys[sourceId];
                }
                else
                {
                    sourceAnimiamtions = new List <BabylonAnimation>();
                    SceneBuilder.AnimationCurveKeys.Add(sourceId, sourceAnimiamtions);
                }
                foreach (var anim in anims)
                {
                    sourceAnimiamtions.Add(anim);
                }
            }
        }
        private static void ExportSkeletonAnimationClips(Animator animator, BabylonSkeleton skeleton, SkinnedMeshRenderer skinnedMesh, BabylonMesh babylonMesh, UnityEditor.AnimationState animationState, ref UnityMetaData metaData)
        {
            List <UnityEditor.AnimationParameters> aparams = Tools.GetAnimationParameters(animator);
            List <AnimationClip> clips = Tools.GetAnimationClips(animator);

            if (clips != null && clips.Count > 0)
            {
                ExportSkeletonAnimationClipData(animator.gameObject, skeleton, skinnedMesh, babylonMesh, ref clips, ref metaData, aparams);
            }
        }
Esempio n. 14
0
        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);
        }
Esempio n. 15
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;
            }
        }
Esempio n. 16
0
        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 static void ExportTransformAnimationClips(Transform transform, BabylonIAnimatable animatable, ref UnityMetaData metaData)
        {
            Animator  animator = transform.gameObject.GetComponent <Animator>();
            Animation legacy   = transform.gameObject.GetComponent <Animation>();

            if (animator != null && animator.runtimeAnimatorController != null && animator.runtimeAnimatorController.animationClips != null && animator.runtimeAnimatorController.animationClips.Length > 0)
            {
                UnityEditor.AnimationState astate = transform.gameObject.GetComponent <UnityEditor.AnimationState>();
                if (astate == null)
                {
                    UnityEngine.Debug.LogWarning("AnimationState component not found for game object: " + transform.gameObject.name);
                }
                if (astate != null && astate.isActiveAndEnabled == true && astate.controlType == BabylonAnimationMode.TransformAnimation)
                {
                    animator.enabled = true;
                    List <UnityEditor.AnimationParameters> aparams = Tools.GetAnimationParameters(animator);
                    List <AnimationClip> clips = Tools.GetAnimationClips(animator);
                    if (clips != null && clips.Count > 0)
                    {
                        ExportTransformAnimationClipData(animator.gameObject, transform, animatable, ref clips, ref metaData, aparams);
                    }
                }
            }
            else if (legacy != null && legacy.GetClipCount() > 0)
            {
                UnityEditor.AnimationState astate = transform.gameObject.GetComponent <UnityEditor.AnimationState>();
                if (astate == null)
                {
                    UnityEngine.Debug.LogWarning("AnimationState component not found for game object: " + transform.gameObject.name);
                }
                if (astate != null && astate.isActiveAndEnabled == true && astate.controlType == BabylonAnimationMode.TransformAnimation)
                {
                    legacy.enabled = true;
                    List <UnityEditor.AnimationParameters> aparams = Tools.GetAnimationParameters(legacy);
                    List <AnimationClip> clips = Tools.GetAnimationClips(legacy);
                    if (clips != null && clips.Count > 0)
                    {
                        ExportTransformAnimationClipData(legacy.gameObject, transform, animatable, ref clips, ref metaData, aparams);
                    }
                }
            }
        }