public static CurveHandle GetCurve(IINode _node, int[] _frames, int _f, int _samplingRate)
        {
            CurveHandle result           = new CurveHandle(Vector2.Zero, Vector2.Zero);
            IIGameNode  _GNode           = maxGlobal.IGameInterface.GetIGameNode(_node);
            int         _ticks_per_frame = maxGlobal.TicksPerFrame;
            float       delta            = 0.0f;

            if (_f > 0)
            {
                List <Vector3> _samples     = new List <Vector3>();
                int            nb_of_frames = _frames[_f] - _frames[_f - 1];
                for (int i = _frames[_f - 1]; i <= _frames[_f]; i += _samplingRate)
                {
                    float          proportion     = 1.0f - ((_frames[_f] - i) / (float)(nb_of_frames));
                    IGMatrix       _node_LGmatrix = _GNode.GetLocalTM(i * _ticks_per_frame);
                    DualQuaternion _node_LDQ      = _node_LGmatrix.convertToDQ(Transformation.Rotation);
                    _samples.Add(new Vector3(proportion, Math.Abs(_node_LDQ.RollPitchYaw.X) + Math.Abs(_node_LDQ.RollPitchYaw.Y) + Math.Abs(_node_LDQ.RollPitchYaw.Z), 0));
                }
                List <BezierCurveFitting.BezierPoint> points = BezierCurveFitting.FitCurves.FitCurveBy(BezierCurveFitting.Method.Length, _samples.ToArray(), 0.01f, 2);
                delta = points[1].point.Y - points[0].point.Y;
                float val = points[1].foreHandle.Value.X;
                if (delta != 0)
                {
                    val = (points[1].point.Y - points[1].foreHandle.Value.Y) / delta;
                }

                result.easeIn = new Vector2(points[1].foreHandle.Value.X, val);
            }
            else if (_f == 0)
            {
                result.easeIn = new Vector2(0.0f, 0.0f);
            }
            if (_f < _frames.Length - 1)
            {
                List <Vector3> _samples     = new List <Vector3>();
                int            nb_of_frames = _frames[_f + 1] - _frames[_f];
                for (int i = _frames[_f]; i <= _frames[_f + 1]; i += _samplingRate)
                {
                    float          proportion     = 1.0f - ((_frames[_f + 1] - i) / (float)(nb_of_frames));
                    IGMatrix       _node_LGmatrix = _GNode.GetLocalTM(i * _ticks_per_frame);
                    DualQuaternion _node_LDQ      = _node_LGmatrix.convertToDQ(Transformation.Rotation);
                    _samples.Add(new Vector3(proportion, Math.Abs(_node_LDQ.RollPitchYaw.X) + Math.Abs(_node_LDQ.RollPitchYaw.Y) + Math.Abs(_node_LDQ.RollPitchYaw.Z), 0));
                }
                List <BezierCurveFitting.BezierPoint> points = BezierCurveFitting.FitCurves.FitCurveBy(BezierCurveFitting.Method.Length, _samples.ToArray(), 0.01f, 2);
                delta = points[1].point.Y - points[0].point.Y;
                float val = points[0].afterHandle.Value.X;
                if (delta != 0)
                {
                    val = (points[1].point.Y - points[0].afterHandle.Value.Y) / delta;
                }
                result.easeOut = new Vector2(points[0].afterHandle.Value.X, val);
            }
            else if (_f == _frames.Length - 1)
            {
                result.easeOut = new Vector2(1f, 1f);
            }
            return(result);
        }
        public void GenerateScalingAnimation(IIGameNode gameNode, List <BabylonAnimation> animations)
        {
            if (gameNode.IGameControl.IsAnimated(IGameControlType.Scale))
            {
                ExportVector3Animation("scaling", animations, key =>
                {
                    var localMatrix = gameNode.GetLocalTM(key);

                    if (float.IsNaN(localMatrix.Determinant))
                    {
                        RaiseError($"Determinant of {gameNode.Name} of scale animation at {key} localMatrix is NaN ");
                    }

                    var tm_babylon = new BabylonMatrix();
                    tm_babylon.m   = localMatrix.ToArray();

                    var s_babylon = new BabylonVector3();
                    var q_babylon = new BabylonQuaternion();
                    var t_babylon = new BabylonVector3();

                    tm_babylon.decompose(s_babylon, q_babylon, t_babylon);

                    return(new[] { s_babylon.X, s_babylon.Y, s_babylon.Z });
                });
            }
        }
        public void GenerateRotationAnimation(IIGameNode gameNode, List <BabylonAnimation> animations, bool force = false)
        {
            if (gameNode.IGameControl.IsAnimated(IGameControlType.Rot) ||
                gameNode.IGameControl.IsAnimated(IGameControlType.EulerX) ||
                gameNode.IGameControl.IsAnimated(IGameControlType.EulerY) ||
                gameNode.IGameControl.IsAnimated(IGameControlType.EulerZ) ||
                force)
            {
                ExportQuaternionAnimation("rotationQuaternion", animations, key =>
                {
                    var localMatrix = gameNode.GetLocalTM(key);
                    var tm_babylon  = new BabylonMatrix();
                    tm_babylon.m    = localMatrix.ToArray();

                    var s_babylon = new BabylonVector3();
                    var q_babylon = new BabylonQuaternion();
                    var t_babylon = new BabylonVector3();

                    tm_babylon.decompose(s_babylon, q_babylon, t_babylon);

                    // normalize
                    var q          = q_babylon;
                    float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W);

                    return(new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length });
                });
            }
        }
Exemple #4
0
        public void GenerateRotationAnimation(IIGameNode gameNode, List <BabylonAnimation> animations, bool force = false)
        {
            if (gameNode.IGameControl.IsAnimated(IGameControlType.Rot) ||
                gameNode.IGameControl.IsAnimated(IGameControlType.EulerX) ||
                gameNode.IGameControl.IsAnimated(IGameControlType.EulerY) ||
                gameNode.IGameControl.IsAnimated(IGameControlType.EulerZ) ||
                (gameNode.IGameObject.IGameType == Autodesk.Max.IGameObject.ObjectTypes.Light && gameNode.IGameObject.AsGameLight().LightTarget != null) || // Light with target are indirectly animated by their target
                force)
            {
                ExportQuaternionAnimation("rotationQuaternion", animations, key =>
                {
                    var localMatrix = gameNode.GetLocalTM(key);
                    var tm_babylon  = new BabylonMatrix();
                    tm_babylon.m    = localMatrix.ToArray();

                    var s_babylon = new BabylonVector3();
                    var q_babylon = new BabylonQuaternion();
                    var t_babylon = new BabylonVector3();

                    tm_babylon.decompose(s_babylon, q_babylon, t_babylon);

                    // normalize
                    var q          = q_babylon;
                    float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W);

                    return(new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length });
                });
            }
        }
        private void exportTransform(BabylonAbstractMesh babylonAbstractMesh, IIGameNode maxGameNode)
        {
            // Position / rotation / scaling
            var localTM = maxGameNode.GetLocalTM(0);

            var meshTrans    = localTM.Translation;
            var meshRotation = localTM.Rotation;
            var meshScale    = localTM.Scaling;

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

            var rotationQuaternion = new BabylonQuaternion {
                X = meshRotation.X, Y = meshRotation.Y, Z = meshRotation.Z, W = -meshRotation.W
            };

            if (ExportQuaternionsInsteadOfEulers)
            {
                babylonAbstractMesh.rotationQuaternion = rotationQuaternion.ToArray();
            }
            else
            {
                babylonAbstractMesh.rotation = rotationQuaternion.toEulerAngles().ToArray();
            }

            babylonAbstractMesh.scaling = new[] { meshScale.X, meshScale.Y, meshScale.Z };
        }
        public void GenerateRotationAnimation(IIGameNode gameNode, List <BabylonAnimation> animations, bool force = false)
        {
            if (isRotationAnimated(gameNode) || force)
            {
                ExportQuaternionAnimation("rotationQuaternion", animations, key =>
                {
                    var localMatrix = gameNode.GetLocalTM(key);

                    if (float.IsNaN(localMatrix.Determinant))
                    {
                        RaiseError($"Determinant of {gameNode.Name} of rotation animation at {key} localMatrix is NaN ");
                    }

                    var tm_babylon = new BabylonMatrix();
                    tm_babylon.m   = localMatrix.ToArray();

                    var s_babylon = new BabylonVector3();
                    var q_babylon = new BabylonQuaternion();
                    var t_babylon = new BabylonVector3();

                    tm_babylon.decompose(s_babylon, q_babylon, t_babylon);

                    // normalize
                    var q          = q_babylon;
                    float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W);

                    return(new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length });
                });
            }
        }
        private void exportTransform(BabylonAbstractMesh babylonAbstractMesh, IIGameNode maxGameNode)
        {
            // Position / rotation / scaling
            var localTM = maxGameNode.GetLocalTM(0);

            // use babylon decomposition, as 3ds max built-in values are no correct
            var tm_babylon = new BabylonMatrix();

            tm_babylon.m = localTM.ToArray();

            var s_babylon = new BabylonVector3();
            var q_babylon = new BabylonQuaternion();
            var t_babylon = new BabylonVector3();

            tm_babylon.decompose(s_babylon, q_babylon, t_babylon);

            if (ExportQuaternionsInsteadOfEulers)
            {
                babylonAbstractMesh.rotationQuaternion = q_babylon.ToArray();
            }
            else
            {
                babylonAbstractMesh.rotation = q_babylon.toEulerAngles().ToArray();
            }

            // normalize quaternion
            var   q        = q_babylon;
            float q_length = (float)Math.Sqrt(q.X * q.X + q.Y * q.Y + q.Z * q.Z + q.W * q.W);

            babylonAbstractMesh.rotationQuaternion = new[] { q_babylon.X / q_length, q_babylon.Y / q_length, q_babylon.Z / q_length, q_babylon.W / q_length };
            babylonAbstractMesh.scaling            = new[] { s_babylon.X, s_babylon.Y, s_babylon.Z };
            babylonAbstractMesh.position           = new[] { t_babylon.X, t_babylon.Y, t_babylon.Z };
        }
Exemple #8
0
        public void GeneratePositionAnimation(IIGameNode gameNode, List <BabylonAnimation> animations)
        {
            if (isPositionAnimated(gameNode))
            {
                ExportVector3Animation("position", animations, key =>
                {
                    var localMatrix = gameNode.GetLocalTM(key);

                    if (float.IsNaN(localMatrix.Determinant))
                    {
                        RaiseError($"Determinant of {gameNode.Name} of position animation at {key} localMatrix is NaN ");
                    }

                    var tm_babylon = new BabylonMatrix();
                    tm_babylon.m   = localMatrix.ToArray();

                    var s_babylon = new BabylonVector3();
                    var q_babylon = new BabylonQuaternion();
                    var t_babylon = new BabylonVector3();

                    tm_babylon.decompose(s_babylon, q_babylon, t_babylon);

                    // Apply unit conversion factor to meter
                    t_babylon *= scaleFactorToMeters;

                    return(new[] { t_babylon.X, t_babylon.Y, t_babylon.Z });
                });
            }
        }
        public static DualQuaternion GetBoneLocalDQ(IINode _node, int[] _frames, int _f)
        {
            IINode     _parent_node     = _node.ParentNode;
            IIGameNode _GNode           = maxGlobal.IGameInterface.GetIGameNode(_node);
            IIGameNode _parentGNode     = maxGlobal.IGameInterface.GetIGameNode(_parent_node);
            int        _ticks_per_frame = maxGlobal.TicksPerFrame;

            // node Local Transform
            IGMatrix       _node_LGmatrix = _GNode.GetLocalTM(_frames[_f] * _ticks_per_frame);
            DualQuaternion _node_LDQ      = _node_LGmatrix.convertToDQ(Transformation.Rotation);

            _node_LDQ.Normalize();
            IGMatrix       _node_BLGmatrix = _GNode.GetLocalTM(0);
            DualQuaternion _node_BLDQ      = _node_BLGmatrix.convertToDQ(Transformation.Rotation);

            _node_BLDQ.Normalize();
            DualQuaternion _node_LTDQL = _node_LDQ * DualQuaternion.Conjugate(_node_BLDQ);

            return(_node_LTDQL);
        }
 public void GenerateScalingAnimation(IIGameNode gameNode, List <BabylonAnimation> animations)
 {
     if (gameNode.IGameControl.IsAnimated(IGameControlType.Scale))
     {
         ExportVector3Animation("scaling", animations, key =>
         {
             var localMatrix = gameNode.GetLocalTM(key);
             var scale       = localMatrix.Scaling;
             return(new[] { scale.X, scale.Y, scale.Z });
         });
     }
 }
 public void GeneratePositionAnimation(IIGameNode gameNode, List <BabylonAnimation> animations)
 {
     if (gameNode.IGameControl.IsAnimated(IGameControlType.Pos) ||
         gameNode.IGameControl.IsAnimated(IGameControlType.PosX) ||
         gameNode.IGameControl.IsAnimated(IGameControlType.PosY) ||
         gameNode.IGameControl.IsAnimated(IGameControlType.PosZ))
     {
         ExportVector3Animation("position", animations, key =>
         {
             var localMatrix = gameNode.GetLocalTM(key);
             var trans       = localMatrix.Translation;
             return(new[] { trans.X, trans.Y, trans.Z });
         });
     }
 }
 public void GenerateRotationAnimation(IIGameNode gameNode, List <BabylonAnimation> animations, bool force = false)
 {
     if (gameNode.IGameControl.IsAnimated(IGameControlType.Rot) ||
         gameNode.IGameControl.IsAnimated(IGameControlType.EulerX) ||
         gameNode.IGameControl.IsAnimated(IGameControlType.EulerY) ||
         gameNode.IGameControl.IsAnimated(IGameControlType.EulerZ) ||
         force)
     {
         ExportQuaternionAnimation("rotationQuaternion", animations, key =>
         {
             var localMatrix = gameNode.GetLocalTM(key);
             var rot         = localMatrix.Rotation;
             return(new[] { rot.X, rot.Y, rot.Z, -rot.W });
         });
     }
 }
Exemple #13
0
        public void GenerateScalingAnimation(IIGameNode gameNode, List <BabylonAnimation> animations)
        {
            if (gameNode.IGameControl.IsAnimated(IGameControlType.Scale))
            {
                ExportVector3Animation("scaling", animations, key =>
                {
                    var localMatrix = gameNode.GetLocalTM(key);
                    var tm_babylon  = new BabylonMatrix();
                    tm_babylon.m    = localMatrix.ToArray();

                    var s_babylon = new BabylonVector3();
                    var q_babylon = new BabylonQuaternion();
                    var t_babylon = new BabylonVector3();

                    tm_babylon.decompose(s_babylon, q_babylon, t_babylon);

                    return(new[] { s_babylon.X, s_babylon.Y, s_babylon.Z });
                });
            }
        }
        private void ExportCamera(IIGameScene scene, IIGameNode cameraNode, BabylonScene babylonScene)
        {
            if (cameraNode.MaxNode.GetBoolProperty("babylonjs_noexport"))
            {
                return;
            }
            var gameCamera    = cameraNode.IGameObject.AsGameCamera();
            var maxCamera     = gameCamera.MaxObject as ICameraObject;
            var initialized   = gameCamera.InitializeData;
            var babylonCamera = new BabylonCamera();

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

            babylonCamera.fov = Tools.ConvertFov(maxCamera.GetFOV(0, Tools.Forever));

            if (maxCamera.ManualClip == 1)
            {
                babylonCamera.minZ = maxCamera.GetClipDist(0, 1, Tools.Forever);
                babylonCamera.maxZ = maxCamera.GetClipDist(0, 2, Tools.Forever);
            }
            else
            {
                babylonCamera.minZ = 0.1f;
                babylonCamera.maxZ = 10000.0f;
            }

            if (babylonCamera.minZ == 0.0f)
            {
                babylonCamera.minZ = 0.1f;
            }

            // Type
            babylonCamera.type = cameraNode.MaxNode.GetStringProperty("babylonjs_type", "FreeCamera");

            // Control
            babylonCamera.speed   = cameraNode.MaxNode.GetFloatProperty("babylonjs_speed", 1.0f);
            babylonCamera.inertia = cameraNode.MaxNode.GetFloatProperty("babylonjs_inertia", 0.9f);

            // Collisions
            babylonCamera.checkCollisions = cameraNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions");
            babylonCamera.applyGravity    = cameraNode.MaxNode.GetBoolProperty("babylonjs_applygravity");
            babylonCamera.ellipsoid       = cameraNode.MaxNode.GetVector3Property("babylonjs_ellipsoid");

            // Position / rotation
            var localTM = cameraNode.GetObjectTM(0);

            if (cameraNode.NodeParent != null)
            {
                var parentWorld = cameraNode.NodeParent.GetObjectTM(0);
                localTM.MultiplyBy(parentWorld.Inverse);
            }

            var position          = localTM.Translation;
            var rotation          = localTM.Rotation;
            var exportQuaternions = Loader.Core.RootNode.GetBoolProperty("babylonjs_exportquaternions");

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

            if (exportQuaternions)
            {
                babylonCamera.rotationQuaternion = new[] { rotation.X, rotation.Y, rotation.Z, -rotation.W };
            }
            else
            {
                babylonCamera.rotation = QuaternionToEulerAngles(rotation);
            }

            // Target
            var target = gameCamera.CameraTarget;

            if (target != null)
            {
                babylonCamera.lockedTargetId = target.MaxNode.GetGuid().ToString();
            }
            else
            {
                var dir = localTM.GetRow(3);
                babylonCamera.target = new [] { position.X - dir.X, position.Y - dir.Y, position.Z - dir.Z };
            }

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

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

            if (gameCamera.CameraTarget == null)
            {
                ExportVector3Animation("target", animations, key =>
                {
                    var tm = cameraNode.GetLocalTM(key);
                    if (cameraNode.NodeParent != null)
                    {
                        var parentWorld = cameraNode.NodeParent.GetObjectTM(key);
                        tm.MultiplyBy(parentWorld.Inverse);
                    }
                    var translation = tm.Translation;
                    var dir         = tm.GetRow(3);
                    return(new float[] { translation.X - dir.X, translation.Y - dir.Y, translation.Z - dir.Z });
                });
            }

            ExportFloatAnimation("fov", animations, key => new[] { Tools.ConvertFov((gameCamera.MaxObject as ICameraObject).GetFOV(key, Tools.Forever)) });

            babylonCamera.animations = animations.ToArray();

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

            babylonScene.CamerasList.Add(babylonCamera);
        }
        private void ExportCamera(IIGameScene scene,  IIGameNode cameraNode, BabylonScene babylonScene)
        {
            if (cameraNode.MaxNode.GetBoolProperty("babylonjs_noexport"))
            {
                return;
            }
            var gameCamera = cameraNode.IGameObject.AsGameCamera();
            var maxCamera = gameCamera.MaxObject as ICameraObject;
            var initialized = gameCamera.InitializeData;
            var babylonCamera = new BabylonCamera();

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

            babylonCamera.fov = Tools.ConvertFov(maxCamera.GetFOV(0, Tools.Forever));

            if (maxCamera.ManualClip == 1)
            {
                babylonCamera.minZ = maxCamera.GetClipDist(0, 1, Tools.Forever);
                babylonCamera.maxZ = maxCamera.GetClipDist(0, 2, Tools.Forever);
            }
            else
            {
                babylonCamera.minZ = 0.1f;
                babylonCamera.maxZ = 10000.0f;
            }

            if (babylonCamera.minZ == 0.0f)
            {
                babylonCamera.minZ = 0.1f;
            }

            // Type
            babylonCamera.type = cameraNode.MaxNode.GetStringProperty("babylonjs_type", "FreeCamera");

            // Control
            babylonCamera.speed = cameraNode.MaxNode.GetFloatProperty("babylonjs_speed", 1.0f);
            babylonCamera.inertia = cameraNode.MaxNode.GetFloatProperty("babylonjs_inertia", 0.9f);

            // Collisions
            babylonCamera.checkCollisions = cameraNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions");
            babylonCamera.applyGravity = cameraNode.MaxNode.GetBoolProperty("babylonjs_applygravity");
            babylonCamera.ellipsoid = cameraNode.MaxNode.GetVector3Property("babylonjs_ellipsoid");

            // Position
            var wm = cameraNode.GetLocalTM(0);
            if (cameraNode.NodeParent != null)
            {
                var parentWorld = cameraNode.NodeParent.GetObjectTM(0);
                wm.MultiplyBy(parentWorld.Inverse);
            }
            var position = wm.Translation;
            babylonCamera.position = new [] { position.X, position.Y, position.Z };

            // Target
            var target = gameCamera.CameraTarget;
            if (target != null)
            {
                babylonCamera.lockedTargetId = target.MaxNode.GetGuid().ToString();
            }
            else
            {
                var dir = wm.GetRow(3);
                babylonCamera.target = new [] { position.X - dir.X, position.Y - dir.Y, position.Z - dir.Z };
            }

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

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

            if (gameCamera.CameraTarget == null)
            {
                ExportVector3Animation("target", animations, key =>
                {
                    var tm = cameraNode.GetLocalTM(key);
                    if (cameraNode.NodeParent != null)
                    {
                        var parentWorld = cameraNode.NodeParent.GetObjectTM(key);
                        tm.MultiplyBy(parentWorld.Inverse);
                    }
                    var translation = tm.Translation;
                    var dir = tm.GetRow(3);
                    return new float[] { translation.X - dir.X, translation.Y - dir.Y, translation.Z - dir.Z };
                });
            }

            ExportFloatAnimation("fov", animations, key => new[] { Tools.ConvertFov((gameCamera.MaxObject as ICameraObject).GetFOV(key, Tools.Forever)) });

            babylonCamera.animations = animations.ToArray();

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

            babylonScene.CamerasList.Add(babylonCamera);
        }
Exemple #16
0
        private BabylonNode ExportLight(IIGameScene scene, IIGameNode lightNode, BabylonScene babylonScene)
        {
            if (IsLightExportable(lightNode) == false)
            {
                return(null);
            }

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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


            var maxScene = Loader.Core.RootNode;

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

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

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

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

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

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


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


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

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

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

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

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

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

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

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

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

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

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

                babylonLight.animations = animations.ToArray();

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

            babylonScene.LightsList.Add(babylonLight);

            return(createDummy ? dummy : babylonLight);
        }
Exemple #17
0
        private BabylonLight ExportLight(IIGameScene scene, IIGameNode lightNode, BabylonScene babylonScene)
        {
            if (IsLightExportable(lightNode) == false)
            {
                return(null);
            }

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

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

            // Type

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

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

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

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

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

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


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

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

            var position = localMatrix.Translation;

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

            // Direction
            var target = gameLight.LightTarget;

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

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

            var maxScene = Loader.Core.RootNode;

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

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

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

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

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

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


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


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


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

            GeneratePositionAnimation(lightNode, animations);

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

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

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

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

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

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

            babylonLight.animations = animations.ToArray();

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

            babylonScene.LightsList.Add(babylonLight);

            return(babylonLight);
        }
        private BabylonCamera ExportCamera(IIGameScene scene, IIGameNode cameraNode, BabylonScene babylonScene)
        {
            if (IsCameraExportable(cameraNode) == false)
            {
                return(null);
            }

            var gameCamera    = cameraNode.IGameObject.AsGameCamera();
            var maxCamera     = gameCamera.MaxObject as ICameraObject;
            var initialized   = gameCamera.InitializeData;
            var babylonCamera = new BabylonCamera();

            RaiseMessage(cameraNode.Name, 1);
            babylonCamera.name = cameraNode.Name;
            babylonCamera.id   = cameraNode.MaxNode.GetGuid().ToString();
            if (cameraNode.NodeParent != null)
            {
                babylonCamera.parentId = cameraNode.NodeParent.MaxNode.GetGuid().ToString();
            }

            babylonCamera.fov = Tools.ConvertFov(maxCamera.GetFOV(0, Tools.Forever));

            if (maxCamera.ManualClip == 1)
            {
                babylonCamera.minZ = maxCamera.GetClipDist(0, 1, Tools.Forever);
                babylonCamera.maxZ = maxCamera.GetClipDist(0, 2, Tools.Forever);
            }
            else
            {
                babylonCamera.minZ = 0.1f;
                babylonCamera.maxZ = 10000.0f;
            }

            if (babylonCamera.minZ == 0.0f)
            {
                babylonCamera.minZ = 0.1f;
            }

            // Type
            babylonCamera.type = cameraNode.MaxNode.GetStringProperty("babylonjs_type", "FreeCamera");

            // Control
            babylonCamera.speed   = cameraNode.MaxNode.GetFloatProperty("babylonjs_speed", 1.0f);
            babylonCamera.inertia = cameraNode.MaxNode.GetFloatProperty("babylonjs_inertia", 0.9f);

            // Collisions
            babylonCamera.checkCollisions = cameraNode.MaxNode.GetBoolProperty("babylonjs_checkcollisions");
            babylonCamera.applyGravity    = cameraNode.MaxNode.GetBoolProperty("babylonjs_applygravity");
            babylonCamera.ellipsoid       = cameraNode.MaxNode.GetVector3Property("babylonjs_ellipsoid");

            // Position / rotation
            var localMatrix = cameraNode.GetLocalTM(0);

            var position = localMatrix.Translation;
            var rotation = localMatrix.Rotation;

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

            var rotationQuaternion = new BabylonQuaternion {
                X = rotation.X, Y = rotation.Y, Z = rotation.Z, W = -rotation.W
            };

            if (ExportQuaternionsInsteadOfEulers)
            {
                babylonCamera.rotationQuaternion = rotationQuaternion.ToArray();
            }
            else
            {
                babylonCamera.rotation = rotationQuaternion.toEulerAngles().ToArray();
            }

            // Target
            var target = gameCamera.CameraTarget;

            if (target != null)
            {
                babylonCamera.lockedTargetId = target.MaxNode.GetGuid().ToString();
            }
            else
            {
                // TODO - Check if should be local or world
                var vDir = Loader.Global.Point3.Create(0, -1, 0);
                vDir = localMatrix.ExtractMatrix3().VectorTransform(vDir).Normalize;
                vDir = vDir.Add(position);
                babylonCamera.target = new[] { vDir.X, vDir.Y, vDir.Z };
            }

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

            GeneratePositionAnimation(cameraNode, animations);

            if (target == null)
            {
                // Export rotation animation
                //GenerateRotationAnimation(cameraNode, animations);

                ExportVector3Animation("target", animations, key =>
                {
                    var localMatrixAnimTarget = cameraNode.GetLocalTM(key);
                    var positionCam           = localMatrixAnimTarget.Translation;
                    var vDir = Loader.Global.Point3.Create(0, -1, 0);
                    vDir     = localMatrixAnimTarget.ExtractMatrix3().VectorTransform(vDir).Normalize;
                    vDir     = vDir.Add(positionCam);
                    return(new[] { vDir.X, vDir.Y, vDir.Z });
                });
            }

            // Animation temporary stored for gltf but not exported for babylon
            // TODO - Will cause an issue when externalizing the glTF export process
            var extraAnimations = new List <BabylonAnimation>();

            // Do not check if node rotation properties are animated
            GenerateRotationAnimation(cameraNode, extraAnimations, true);
            babylonCamera.extraAnimations = extraAnimations;

            ExportFloatAnimation("fov", animations, key => new[] { Tools.ConvertFov((gameCamera.MaxObject as ICameraObject).GetFOV(key, Tools.Forever)) });

            babylonCamera.animations = animations.ToArray();

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

            babylonScene.CamerasList.Add(babylonCamera);

            return(babylonCamera);
        }