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; }
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; }