Exemple #1
0
        void UpdateSwimming()
        {
            IgnorePlatforms = true;

            Vector2 footPos, handPos;

            float surfaceLimiter = 1.0f;

            Limb head  = GetLimb(LimbType.Head);
            Limb torso = GetLimb(LimbType.Torso);

            if (currentHull != null && (currentHull.Rect.Y - currentHull.Surface > 50.0f))
            {
                surfaceLimiter = (ConvertUnits.ToDisplayUnits(Collider.SimPosition.Y + 0.4f) - surfaceY);
                surfaceLimiter = Math.Max(1.0f, surfaceLimiter);
                if (surfaceLimiter > 50.0f)
                {
                    return;
                }
            }

            Limb leftHand  = GetLimb(LimbType.LeftHand);
            Limb rightHand = GetLimb(LimbType.RightHand);

            Limb leftFoot  = GetLimb(LimbType.LeftFoot);
            Limb rightFoot = GetLimb(LimbType.RightFoot);

            float rotation = MathHelper.WrapAngle(Collider.Rotation);

            rotation = MathHelper.ToDegrees(rotation);
            if (rotation < 0.0f)
            {
                rotation += 360;
            }

            if (!character.IsRemotePlayer && !aiming && Anim != Animation.UsingConstruction)
            {
                if (rotation > 20 && rotation < 170)
                {
                    TargetDir = Direction.Left;
                }
                else if (rotation > 190 && rotation < 340)
                {
                    TargetDir = Direction.Right;
                }
            }

            float targetSpeed = TargetMovement.Length();

            if (targetSpeed > 0.1f)
            {
                if (!aiming)
                {
                    float newRotation = MathUtils.VectorToAngle(TargetMovement) - MathHelper.PiOver2;
                    Collider.SmoothRotate(newRotation, 5.0f);
                    //torso.body.SmoothRotate(newRotation);
                }
            }
            else
            {
                if (aiming)
                {
                    Vector2 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition);
                    Vector2 diff     = (mousePos - torso.SimPosition) * Dir;

                    TargetMovement = new Vector2(0.0f, -0.1f);

                    float newRotation = MathUtils.VectorToAngle(diff);
                    Collider.SmoothRotate(newRotation, 5.0f);
                }
            }

            torso.body.SmoothRotate(Collider.Rotation);
            torso.body.MoveToPos(Collider.SimPosition + new Vector2((float)Math.Sin(-Collider.Rotation), (float)Math.Cos(-Collider.Rotation)) * 0.4f, 5.0f);

            if (TargetMovement == Vector2.Zero)
            {
                return;
            }

            movement = MathUtils.SmoothStep(movement, TargetMovement, 0.3f);

            //dont try to move upwards if head is already out of water
            if (surfaceLimiter > 1.0f && TargetMovement.Y > 0.0f)
            {
                if (TargetMovement.X == 0.0f)
                {
                    //pull head above water
                    head.body.SmoothRotate(0.0f, 5.0f);

                    walkPos += 0.05f;
                }
                else
                {
                    TargetMovement = new Vector2(
                        (float)Math.Sqrt(targetSpeed * targetSpeed - TargetMovement.Y * TargetMovement.Y)
                        * Math.Sign(TargetMovement.X),
                        Math.Max(TargetMovement.Y, TargetMovement.Y * 0.2f));

                    //turn head above the water
                    head.body.ApplyTorque(Dir);
                }

                movement.Y = movement.Y - (surfaceLimiter - 1.0f) * 0.01f;
            }

            if (!character.IsRemotePlayer || GameMain.Server != null)
            {
                Collider.LinearVelocity = Vector2.Lerp(Collider.LinearVelocity, movement * swimSpeed, movementLerp);
            }

            walkPos += movement.Length() * 0.2f;
            footPos  = Collider.SimPosition - new Vector2((float)Math.Sin(-Collider.Rotation), (float)Math.Cos(-Collider.Rotation)) * 0.4f;

            for (int i = -1; i < 2; i += 2)
            {
                var thigh = i == -1 ? GetLimb(LimbType.LeftThigh) : GetLimb(LimbType.RightThigh);
                var leg   = i == -1 ? GetLimb(LimbType.LeftLeg) : GetLimb(LimbType.RightLeg);

                float thighDiff = Math.Abs(MathUtils.GetShortestAngle(torso.Rotation, thigh.Rotation));
                if (thighDiff > MathHelper.PiOver2)
                {
                    //thigh bent too close to the torso -> force the leg to extend
                    float thighTorque = thighDiff * thigh.Mass * Math.Sign(torso.Rotation - thigh.Rotation) * 10.0f;
                    thigh.body.ApplyTorque(thighTorque);
                    leg.body.ApplyTorque(thighTorque);
                }
                else
                {
                    thigh.body.SmoothRotate(torso.Rotation + (float)Math.Sin(walkPos) * i * 0.3f, 2.0f);
                }
            }

            Vector2 transformedFootPos = new Vector2((float)Math.Sin(walkPos) * 0.5f, 0.0f);

            transformedFootPos = Vector2.Transform(
                transformedFootPos,
                Matrix.CreateRotationZ(Collider.Rotation));

            MoveLimb(rightFoot, footPos - transformedFootPos, 1.0f);
            MoveLimb(leftFoot, footPos + transformedFootPos, 1.0f);

            handPos = (torso.SimPosition + head.SimPosition) / 2.0f;

            //at the surface, not moving sideways -> hands just float around
            if (!headInWater && TargetMovement.X == 0.0f && TargetMovement.Y > 0)
            {
                handPos.X = handPos.X + Dir * 0.6f;

                float wobbleAmount = 0.1f;

                if (!rightHand.Disabled)
                {
                    MoveLimb(rightHand, new Vector2(
                                 handPos.X + (float)Math.Sin(walkPos / 1.5f) * wobbleAmount,
                                 handPos.Y + (float)Math.Sin(walkPos / 3.5f) * wobbleAmount - 0.25f), 1.5f);
                }

                if (!leftHand.Disabled)
                {
                    MoveLimb(leftHand, new Vector2(
                                 handPos.X + (float)Math.Sin(walkPos / 2.0f) * wobbleAmount,
                                 handPos.Y + (float)Math.Sin(walkPos / 3.0f) * wobbleAmount - 0.25f), 1.5f);
                }

                return;
            }

            handPos += head.LinearVelocity * 0.1f;

            float handCyclePos = walkPos / 2.0f * -Dir;
            float handPosX     = (float)Math.Cos(handCyclePos) * 0.4f;
            float handPosY     = (float)Math.Sin(handCyclePos) * 1.0f;

            handPosY = MathHelper.Clamp(handPosY, -0.8f, 0.8f);

            Matrix rotationMatrix = Matrix.CreateRotationZ(torso.Rotation);

            if (!rightHand.Disabled)
            {
                Vector2 rightHandPos = new Vector2(-handPosX, -handPosY);
                rightHandPos.X = (Dir == 1.0f) ? Math.Max(0.3f, rightHandPos.X) : Math.Min(-0.3f, rightHandPos.X);
                rightHandPos   = Vector2.Transform(rightHandPos, rotationMatrix);

                HandIK(rightHand, handPos + rightHandPos, 0.5f);
            }

            if (!leftHand.Disabled)
            {
                Vector2 leftHandPos = new Vector2(handPosX, handPosY);
                leftHandPos.X = (Dir == 1.0f) ? Math.Max(0.3f, leftHandPos.X) : Math.Min(-0.3f, leftHandPos.X);
                leftHandPos   = Vector2.Transform(leftHandPos, rotationMatrix);

                HandIK(leftHand, handPos + leftHandPos, 0.5f);
            }
        }
Exemple #2
0
        void UpdateStanding()
        {
            Vector2 handPos;

            //if you're allergic to magic numbers, stop reading now

            Limb leftFoot  = GetLimb(LimbType.LeftFoot);
            Limb rightFoot = GetLimb(LimbType.RightFoot);
            Limb head      = GetLimb(LimbType.Head);
            Limb torso     = GetLimb(LimbType.Torso);

            Limb waist = GetLimb(LimbType.Waist);

            Limb leftHand  = GetLimb(LimbType.LeftHand);
            Limb rightHand = GetLimb(LimbType.RightHand);

            Limb leftLeg  = GetLimb(LimbType.LeftLeg);
            Limb rightLeg = GetLimb(LimbType.RightLeg);

            float getUpSpeed     = 0.3f;
            float walkCycleSpeed = movement.X * walkAnimSpeed;

            if (stairs != null)
            {
                TargetMovement = new Vector2(MathHelper.Clamp(TargetMovement.X, -1.5f, 1.5f), TargetMovement.Y);

                /*if ((TargetMovement.X > 0.0f && stairs.StairDirection == Direction.Right) ||
                 *  TargetMovement.X < 0.0f && stairs.StairDirection == Direction.Left)
                 * {
                 *  TargetMovement *= 1.7f;
                 *  //walkCycleSpeed *= 1.0f;
                 * }*/
            }

            Vector2 colliderPos = GetColliderBottom();

            if (Math.Abs(TargetMovement.X) > 1.0f)
            {
                float slowdownAmount = 0.0f;
                if (currentHull != null)
                {
                    //full slowdown (1.5f) when water is up to the torso
                    surfaceY       = ConvertUnits.ToSimUnits(currentHull.Surface);
                    slowdownAmount = MathHelper.Clamp((surfaceY - colliderPos.Y) / torsoPosition, 0.0f, 1.0f) * 1.5f;
                }

                float maxSpeed = Math.Max(TargetMovement.Length() - slowdownAmount, 1.0f);
                TargetMovement = Vector2.Normalize(TargetMovement) * maxSpeed;
            }

            float walkPosX        = (float)Math.Cos(walkPos);
            float walkPosY        = (float)Math.Sin(walkPos);
            float runningModifier = (float)Math.Max(Math.Min(Math.Abs(TargetMovement.X), 3.0f) / 1.5f, 1.0);

            Vector2 stepSize = new Vector2(
                this.stepSize.X * walkPosX * runningModifier,
                this.stepSize.Y * walkPosY * runningModifier * runningModifier);

            if (Crouching)
            {
                stepSize *= 0.5f;
            }

            float footMid = colliderPos.X;// (leftFoot.SimPosition.X + rightFoot.SimPosition.X) / 2.0f;

            movement = overrideTargetMovement == Vector2.Zero ?
                       MathUtils.SmoothStep(movement, TargetMovement * walkSpeed, movementLerp) :
                       overrideTargetMovement;

            if (Math.Abs(movement.X) < 0.005f)
            {
                movement.X = 0.0f;
            }

            movement.Y = 0.0f;

            for (int i = 0; i < 2; i++)
            {
                Limb leg = GetLimb((i == 0) ? LimbType.LeftThigh : LimbType.RightThigh);// : leftLeg;

                float shortestAngle = leg.Rotation - torso.Rotation;

                if (Math.Abs(shortestAngle) < 2.5f)
                {
                    continue;
                }

                if (Math.Abs(shortestAngle) > 5.0f)
                {
                    TargetDir = TargetDir == Direction.Right ? Direction.Left : Direction.Right;
                }
                else
                {
                    leg.body.ApplyTorque(shortestAngle * 10.0f);

                    leg = GetLimb((i == 0) ? LimbType.LeftLeg : LimbType.RightLeg);
                    leg.body.ApplyTorque(-shortestAngle * 10.0f);
                }
            }

            if (onGround && (!character.IsRemotePlayer || GameMain.Server != null))
            {
                //move slower if collider isn't upright
                float rotationFactor = (float)Math.Abs(Math.Cos(Collider.Rotation));

                Collider.LinearVelocity = new Vector2(
                    movement.X * rotationFactor,
                    Collider.LinearVelocity.Y > 0.0f ? Collider.LinearVelocity.Y * 0.5f : Collider.LinearVelocity.Y);
            }

            getUpSpeed = getUpSpeed * Math.Max(head.SimPosition.Y - colliderPos.Y, 0.5f);

            torso.pullJoint.Enabled = true;
            head.pullJoint.Enabled  = true;
            waist.pullJoint.Enabled = true;

            float floorPos = GetFloorY(colliderPos + new Vector2(Math.Sign(movement.X) * 0.5f, 1.0f));
            bool  onSlope  = floorPos > GetColliderBottom().Y + 0.05f;

            if (stairs != null || onSlope)
            {
                torso.pullJoint.WorldAnchorB = new Vector2(
                    MathHelper.SmoothStep(torso.SimPosition.X, footMid + movement.X * 0.25f, getUpSpeed * 0.8f),
                    MathHelper.SmoothStep(torso.SimPosition.Y, colliderPos.Y + TorsoPosition - Math.Abs(walkPosX * 0.05f), getUpSpeed * 2.0f));


                head.pullJoint.WorldAnchorB = new Vector2(
                    MathHelper.SmoothStep(head.SimPosition.X, footMid + movement.X * (Crouching ? 0.6f : 0.25f), getUpSpeed * 0.8f),
                    MathHelper.SmoothStep(head.SimPosition.Y, colliderPos.Y + HeadPosition - Math.Abs(walkPosX * 0.05f), getUpSpeed * 2.0f));

                waist.pullJoint.WorldAnchorB = waist.SimPosition;// +movement * 0.3f;
            }
            else
            {
                if (!onGround)
                {
                    movement = Vector2.Zero;
                }

                torso.pullJoint.WorldAnchorB =
                    MathUtils.SmoothStep(torso.SimPosition,
                                         new Vector2(footMid + movement.X * 0.2f, colliderPos.Y + TorsoPosition), getUpSpeed);

                head.pullJoint.WorldAnchorB =
                    MathUtils.SmoothStep(head.SimPosition,
                                         new Vector2(footMid + movement.X * (Crouching && Math.Sign(movement.X) == Math.Sign(Dir) ? 0.6f : 0.2f), colliderPos.Y + HeadPosition), getUpSpeed * 1.2f);

                waist.pullJoint.WorldAnchorB = waist.SimPosition + movement * 0.06f;
            }

            if (!onGround)
            {
                Vector2 move = torso.pullJoint.WorldAnchorB - torso.SimPosition;

                foreach (Limb limb in Limbs)
                {
                    MoveLimb(limb, limb.SimPosition + move, 15.0f, true);
                }

                return;
            }

            //moving horizontally
            if (TargetMovement.X != 0.0f)
            {
                //progress the walking animation
                walkPos -= (walkCycleSpeed / runningModifier) * 0.8f;

                for (int i = -1; i < 2; i += 2)
                {
                    Limb foot = i == -1 ? leftFoot : rightFoot;
                    Limb leg  = i == -1 ? leftLeg : rightLeg;

                    Vector2 footPos = stepSize * -i;
                    if (stepSize.Y < 0.0f)
                    {
                        stepSize.Y = -0.15f;
                    }

                    if (onSlope && stairs == null)
                    {
                        footPos.Y *= 2.0f;
                    }
                    footPos.Y = Math.Min(waist.SimPosition.Y - colliderPos.Y - 0.4f, footPos.Y);

                    MoveLimb(foot, footPos + colliderPos, 15.0f, true);
                    foot.body.SmoothRotate(leg.body.Rotation + MathHelper.PiOver2 * Dir * 1.6f, 20.0f * runningModifier);
                }

                if (runningModifier > 1.0f)
                {
                    if (walkPosY > 0.0f)
                    {
                        GetLimb(LimbType.LeftThigh).body.ApplyTorque(-walkPosY * Dir * Math.Abs(movement.X) * thighTorque);
                    }
                    else
                    {
                        GetLimb(LimbType.RightThigh).body.ApplyTorque(walkPosY * Dir * Math.Abs(movement.X) * thighTorque);
                    }
                }

                if (legTorque > 0.0f)
                {
                    if (Math.Sign(walkPosX) != Math.Sign(movement.X))
                    {
                        GetLimb(LimbType.LeftLeg).body.ApplyTorque(-walkPosY * Dir * Math.Abs(movement.X) * legTorque / runningModifier);
                    }
                    else
                    {
                        GetLimb(LimbType.RightLeg).body.ApplyTorque(walkPosY * Dir * Math.Abs(movement.X) * legTorque / runningModifier);
                    }
                }

                //calculate the positions of hands
                handPos   = torso.SimPosition;
                handPos.X = -walkPosX * 0.4f;

                float lowerY = -1.0f + (runningModifier - 1.0f) * 0.8f;

                handPos.Y = lowerY + (float)(Math.Abs(Math.Sin(walkPos - Math.PI * 1.5f) * 0.15 * runningModifier));

                Vector2 posAddition = new Vector2(-movement.X * 0.015f * runningModifier, 0.0f);

                if (!rightHand.Disabled)
                {
                    HandIK(rightHand, torso.SimPosition + posAddition +
                           new Vector2(
                               -handPos.X,
                               (Math.Sign(walkPosX) == Math.Sign(Dir)) ? handPos.Y : lowerY), 0.7f * runningModifier);
                }

                if (!leftHand.Disabled)
                {
                    HandIK(leftHand, torso.SimPosition + posAddition +
                           new Vector2(
                               handPos.X,
                               (Math.Sign(walkPosX) == Math.Sign(-Dir)) ? handPos.Y : lowerY), 0.7f * runningModifier);
                }
            }
            else
            {
                //float movementFactor = (movement.X / 4.0f) * movement.X * Math.Sign(movement.X);

                for (int i = -1; i < 2; i += 2)
                {
                    Vector2 footPos = colliderPos;

                    if (Crouching)
                    {
                        footPos = new Vector2(
                            waist.SimPosition.X + Math.Sign(stepSize.X * i) * Dir * 0.3f,
                            colliderPos.Y - 0.1f);
                    }
                    else
                    {
                        footPos = new Vector2(GetCenterOfMass().X + stepSize.X * i * 0.2f, colliderPos.Y - 0.1f);
                    }

                    if (stairs == null)
                    {
                        footPos.Y = Math.Max(Math.Min(floorPos, footPos.Y + 0.5f), footPos.Y);
                    }

                    var foot = i == -1 ? rightFoot : leftFoot;

                    MoveLimb(foot, footPos, Math.Abs(foot.SimPosition.X - footPos.X) * 100.0f, true);
                }

                leftFoot.body.SmoothRotate(Dir * MathHelper.PiOver2, 50.0f);
                rightFoot.body.SmoothRotate(Dir * MathHelper.PiOver2, 50.0f);

                if (!rightHand.Disabled)
                {
                    rightHand.body.SmoothRotate(0.0f, 5.0f);

                    var rightArm = GetLimb(LimbType.RightArm);
                    rightArm.body.SmoothRotate(0.0f, 20.0f);
                }

                if (!leftHand.Disabled)
                {
                    leftHand.body.SmoothRotate(0.0f, 5.0f);

                    var leftArm = GetLimb(LimbType.LeftArm);
                    leftArm.body.SmoothRotate(0.0f, 20.0f);
                }
            }
        }