public void MoveAndRotate(ref Vector3 moveIndicator, ref Vector2 rotationIndicator, bool canRotate)
        {
            var characterPhysics = Character.Physics;
            var characterProxy   = characterPhysics.CharacterProxy;

            ThrustComp.ControlThrust = Vector3.Zero;

            const MyCharacterMovementEnum newMovementState = MyCharacterMovementEnum.Flying;

            Character.SwitchAnimation(newMovementState);

            Character.SetCurrentMovementState(newMovementState);

            bool wantsFlyDown = (Character.MovementFlags & MyCharacterMovementFlags.FlyDown) == MyCharacterMovementFlags.FlyDown;
            bool wantsFlyUp   = (Character.MovementFlags & MyCharacterMovementFlags.FlyUp) == MyCharacterMovementFlags.FlyUp;

            IsFlying = moveIndicator.LengthSquared() != 0;

            var proxyState = characterProxy != null?characterProxy.GetState() : 0;

            if ((proxyState == HkCharacterStateType.HK_CHARACTER_IN_AIR || (int)proxyState == MyCharacter.HK_CHARACTER_FLYING))
            {
                Character.PlayCharacterAnimation("Jetpack", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f);

                Character.CanJump = true;
            }

            if (canRotate && rotationIndicator.X != 0)
            {
                MatrixD  rotationMatrix = Character.WorldMatrix.GetOrientation();
                Vector3D translation    = Character.WorldMatrix.Translation + Character.WorldMatrix.Up;

                if (Character.Definition.VerticalPositionFlyingOnly)
                {
                    Character.SetHeadLocalXAngle(MathHelper.Clamp(Character.HeadLocalXAngle - rotationIndicator.X * Character.RotationSpeed, MyCharacter.MIN_HEAD_LOCAL_X_ANGLE, MyCharacter.MAX_HEAD_LOCAL_X_ANGLE));
                }
                else
                {
                    rotationMatrix = rotationMatrix * MatrixD.CreateFromAxisAngle(Character.WorldMatrix.Right, rotationIndicator.X * -0.02 * Character.RotationSpeed);
                }

                rotationMatrix.Translation = translation - rotationMatrix.Up;

                //Enable if we want limit character rotation in collisions
                //if (m_shapeContactPoints.Count < 2)
                {
                    Character.WorldMatrix = rotationMatrix;
                    Character.ClearShapeContactPoints();
                }
            }

            Vector3 moveDirection = moveIndicator;

            if (Character.Definition.VerticalPositionFlyingOnly)
            {
                float  angleSign     = Math.Sign(Character.HeadLocalXAngle);
                double headAngle     = Math.Abs(MathHelper.ToRadians(Character.HeadLocalXAngle));
                double exponent      = 1.95;
                double smoothedAngle = Math.Pow(headAngle, exponent);
                smoothedAngle *= headAngle / Math.Pow(MathHelper.ToRadians(MyCharacter.MAX_HEAD_LOCAL_X_ANGLE), exponent);
                MatrixD rotationMatrix = MatrixD.CreateFromAxisAngle(Vector3D.Right, angleSign * smoothedAngle);
                moveDirection = Vector3D.Transform(moveDirection, rotationMatrix);
            }

            if (wantsFlyUp || wantsFlyDown)
            {
                moveDirection += (wantsFlyUp ? 1 : -1) * Vector3.Up;
            }

            if (!Vector3.IsZero(moveDirection))
            {
                moveDirection.Normalize();
            }

            ThrustComp.ControlThrust = moveDirection * ForceMagnitude;
        }
Пример #2
0
        public void MoveAndRotate(ref Vector3 moveIndicator, ref Vector2 rotationIndicator, float roll, bool canRotate)
        {
            var characterPhysics = Character.Physics;
            var characterProxy   = characterPhysics.CharacterProxy;

            ThrustComp.ControlThrust = Vector3.Zero;

            const MyCharacterMovementEnum newMovementState = MyCharacterMovementEnum.Flying;

            Character.SwitchAnimation(newMovementState);

            Character.SetCurrentMovementState(newMovementState);

            bool wantsFlyDown = (Character.MovementFlags & MyCharacterMovementFlags.FlyDown) == MyCharacterMovementFlags.FlyDown;
            bool wantsFlyUp   = (Character.MovementFlags & MyCharacterMovementFlags.FlyUp) == MyCharacterMovementFlags.FlyUp;

            IsFlying = moveIndicator.LengthSquared() != 0;

            var proxyState = characterProxy != null?characterProxy.GetState() : 0;

            if ((proxyState == HkCharacterStateType.HK_CHARACTER_IN_AIR || (int)proxyState == MyCharacter.HK_CHARACTER_FLYING))
            {
                Character.PlayCharacterAnimation("Jetpack", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f);

                Character.CanJump = true;
            }

            MatrixD WorldMatrix    = Character.WorldMatrix;
            float   RotationSpeed  = Character.RotationSpeed;
            float   RotationFactor = 0.02f;

            if (canRotate)
            {
                MatrixD rotationXMatrix = MatrixD.Identity;
                MatrixD rotationYMatrix = MatrixD.Identity;
                MatrixD rotationZMatrix = MatrixD.Identity;

                if (Math.Abs(rotationIndicator.X) > float.Epsilon)
                {
                    if (Character.Definition.VerticalPositionFlyingOnly)
                    {
                        Character.SetHeadLocalXAngle(Character.HeadLocalXAngle - rotationIndicator.X * Character.RotationSpeed);
                    }
                    else
                    {
                        rotationXMatrix = MatrixD.CreateFromAxisAngle(WorldMatrix.Right, -rotationIndicator.X * RotationSpeed * RotationFactor);
                    }
                }

                if (Math.Abs(rotationIndicator.Y) > float.Epsilon)
                {
                    rotationYMatrix = MatrixD.CreateFromAxisAngle(WorldMatrix.Up, -rotationIndicator.Y * RotationSpeed * RotationFactor);
                }

                if (!Character.Definition.VerticalPositionFlyingOnly)
                {
                    if (Math.Abs(roll) > float.Epsilon)
                    {
                        rotationZMatrix = MatrixD.CreateFromAxisAngle(WorldMatrix.Forward, roll * RotationFactor);
                    }
                }

                // Rotation center is at the middle of the character, who is 2 meters high.
                float rotationHeight = Character.ModelCollision.BoundingBoxSizeHalf.Y;

                MatrixD  physicsMatrix = Character.Physics.GetWorldMatrix();
                Vector3D translation   = physicsMatrix.Translation + WorldMatrix.Up * rotationHeight;

                // Compute rotation
                MatrixD fullRotation  = rotationXMatrix * rotationYMatrix * rotationZMatrix;
                MatrixD rotatedMatrix = WorldMatrix.GetOrientation();
                rotatedMatrix             = rotatedMatrix * fullRotation;
                rotatedMatrix.Translation = translation - rotatedMatrix.Up * rotationHeight;

                // Update game character
                Character.WorldMatrix = rotatedMatrix;

                // Update physics character
                rotatedMatrix.Translation = physicsMatrix.Translation;
                Character.PositionComp.SetWorldMatrix(rotatedMatrix, Character.Physics);
                Character.ClearShapeContactPoints();
            }

            Vector3 moveDirection = moveIndicator;

            if (Character.Definition.VerticalPositionFlyingOnly)
            {
                float  angleSign     = Math.Sign(Character.HeadLocalXAngle);
                double headAngle     = Math.Abs(MathHelper.ToRadians(Character.HeadLocalXAngle));
                double exponent      = 1.95;
                double smoothedAngle = Math.Pow(headAngle, exponent);
                smoothedAngle *= headAngle / Math.Pow(MathHelper.ToRadians(MyCharacter.MAX_HEAD_LOCAL_X_ANGLE), exponent);
                MatrixD rotationMatrix = MatrixD.CreateFromAxisAngle(Vector3D.Right, angleSign * smoothedAngle);
                moveDirection = Vector3D.Transform(moveDirection, rotationMatrix);
            }

            if (!Vector3.IsZero(moveDirection))
            {
                moveDirection.Normalize();
            }

            ThrustComp.ControlThrust          += moveDirection * ForceMagnitude;
            ThrustComp.ControlThrustMagnitude += Vector3.One;
        }