public void MoveToTargetPosition(bool lerp = true) { if (targetPosition == null) { return; } if (lerp) { if (Vector2.DistanceSquared((Vector2)targetPosition, body.Position) < 10.0f * 10.0f) { drawOffset = -((Vector2)targetPosition - (body.Position + drawOffset)); prevPosition = (Vector2)targetPosition; } else { drawOffset = Vector2.Zero; } if (targetRotation.HasValue) { rotationOffset = -MathUtils.GetShortestAngle(body.Rotation + rotationOffset, targetRotation.Value); } } SetTransform((Vector2)targetPosition, targetRotation == null ? body.Rotation : (float)targetRotation); targetPosition = null; targetRotation = null; }
public bool IsWithinSector(Vector2 worldPosition) { if (sectorRad >= MathHelper.TwoPi) { return(true); } Vector2 diff = worldPosition - WorldPosition; return(MathUtils.GetShortestAngle(MathUtils.VectorToAngle(diff), MathUtils.VectorToAngle(sectorDir)) <= sectorRad * 0.5f); }
/// <summary> /// rotate the body towards the target rotation in the "shortest direction" /// </summary> public void SmoothRotate(float targetRotation, float force = 10.0f) { float nextAngle = body.Rotation + body.AngularVelocity * (float)Timing.Step; float angle = MathUtils.GetShortestAngle(nextAngle, targetRotation); float torque = angle * 60.0f * (force / 100.0f); if (body.IsKinematic) { body.AngularVelocity = torque; } else { body.ApplyTorque(body.Mass * torque); } }
/// <summary> /// Rotate the body towards the target rotation in the "shortest direction", taking into account the current angular velocity to prevent overshooting. /// </summary> /// <param name="targetRotation">Desired rotation in radians</param> /// <param name="force">How fast the body should be rotated. Does not represent any real unit, you may want to experiment with different values to get the desired effect.</param> /// <param name="wrapAngle">Should the angles be wrapped. Set to false if it makes a difference whether the angle of the body is 0.0f or 360.0f.</param> public void SmoothRotate(float targetRotation, float force = 10.0f, bool wrapAngle = true) { float nextAngle = body.Rotation + body.AngularVelocity * (float)Timing.Step; float angle = wrapAngle ? MathUtils.GetShortestAngle(nextAngle, targetRotation) : MathHelper.Clamp(targetRotation - nextAngle, -MathHelper.Pi, MathHelper.Pi); float torque = angle * 60.0f * (force / 100.0f); if (body.IsKinematic) { if (!IsValidValue(torque, "torque")) return; body.AngularVelocity = torque; } else { ApplyTorque(body.Mass * torque); } }
public bool SectorHit(Vector2 armorSector, Vector2 simPosition) { if (armorSector == Vector2.Zero) { return(false); } float rot = body.Rotation; if (Dir == -1) { rot -= MathHelper.Pi; } Vector2 armorLimits = new Vector2(rot - armorSector.X * Dir, rot - armorSector.Y * Dir); float mid = (armorLimits.X + armorLimits.Y) / 2.0f; float angleDiff = MathUtils.GetShortestAngle(MathUtils.VectorToAngle(simPosition - SimPosition), mid); return(Math.Abs(angleDiff) < (armorSector.Y - armorSector.X) / 2.0f); }
public override void UpdateAnim(float deltaTime) { if (Frozen) { return; } if (MainLimb == null) { return; } if (!character.AllowInput) { levitatingCollider = false; Collider.FarseerBody.FixedRotation = false; if (GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient) { Collider.LinearVelocity = MainLimb.LinearVelocity; Collider.FarseerBody.FixedRotation = false; Collider.SetTransformIgnoreContacts(MainLimb.SimPosition, MainLimb.Rotation); } if (character.IsDead && deathAnimTimer < deathAnimDuration) { deathAnimTimer += deltaTime; UpdateDying(deltaTime); } return; } else { deathAnimTimer = 0.0f; } //re-enable collider if (!Collider.Enabled) { var lowestLimb = FindLowestLimb(); Collider.SetTransform(new Vector2( Collider.SimPosition.X, Math.Max(lowestLimb.SimPosition.Y + (Collider.radius + Collider.height / 2), Collider.SimPosition.Y)), 0.0f); Collider.Enabled = true; } ResetPullJoints(); if (strongestImpact > 0.0f) { character.Stun = MathHelper.Clamp(strongestImpact * 0.5f, character.Stun, 5.0f); strongestImpact = 0.0f; } if (inWater && !forceStanding) { Collider.FarseerBody.FixedRotation = false; UpdateSineAnim(deltaTime); } else if (CanEnterSubmarine && (currentHull != null || forceStanding) && CurrentGroundedParams != null) { //rotate collider back upright float standAngle = dir == Direction.Right ? CurrentGroundedParams.ColliderStandAngleInRadians : -CurrentGroundedParams.ColliderStandAngleInRadians; if (Math.Abs(MathUtils.GetShortestAngle(Collider.Rotation, standAngle)) > 0.001f) { Collider.AngularVelocity = MathUtils.GetShortestAngle(Collider.Rotation, standAngle) * 60.0f; Collider.FarseerBody.FixedRotation = false; } else { Collider.FarseerBody.FixedRotation = true; } UpdateWalkAnim(deltaTime); } //don't flip or drag when simply physics is enabled if (SimplePhysicsEnabled) { return; } if (!character.IsRemotePlayer && (character.AIController == null || character.AIController.CanFlip)) { if (!inWater || (CurrentSwimParams != null && CurrentSwimParams.Mirror)) { if (targetMovement.X > 0.1f && targetMovement.X > Math.Abs(targetMovement.Y) * 0.2f) { TargetDir = Direction.Right; } else if (targetMovement.X < -0.1f && targetMovement.X < -Math.Abs(targetMovement.Y) * 0.2f) { TargetDir = Direction.Left; } } else { float refAngle = 0.0f; Limb refLimb = GetLimb(LimbType.Head); if (refLimb == null) { refAngle = CurrentAnimationParams.TorsoAngleInRadians; refLimb = GetLimb(LimbType.Torso); } else { refAngle = CurrentAnimationParams.HeadAngleInRadians; } float rotation = refLimb.Rotation; if (!float.IsNaN(refAngle)) { rotation -= refAngle * Dir; } rotation = MathHelper.ToDegrees(MathUtils.WrapAngleTwoPi(rotation)); if (rotation < 0.0f) { rotation += 360; } if (rotation > 20 && rotation < 160) { TargetDir = Direction.Left; } else if (rotation > 200 && rotation < 340) { TargetDir = Direction.Right; } } } if (character.SelectedCharacter != null) { DragCharacter(character.SelectedCharacter, deltaTime); } if (!CurrentFishAnimation.Flip || IsStuck) { return; } if (character.AIController != null && !character.AIController.CanFlip) { return; } flipCooldown -= deltaTime; if (TargetDir != Direction.None && TargetDir != dir) { flipTimer += deltaTime; if ((flipTimer > 0.5f && flipCooldown <= 0.0f) || character.IsRemotePlayer) { Flip(); if (!inWater || (CurrentSwimParams != null && CurrentSwimParams.Mirror)) { Mirror(); } flipTimer = 0.0f; flipCooldown = 1.0f; } } else { flipTimer = 0.0f; } }
public override void UpdateAnim(float deltaTime) { if (Frozen) { return; } if (MainLimb == null) { return; } var mainLimb = MainLimb; levitatingCollider = true; if (!character.CanMove) { levitatingCollider = false; Collider.FarseerBody.FixedRotation = false; if (GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient) { Collider.Enabled = false; Collider.LinearVelocity = mainLimb.LinearVelocity; Collider.SetTransformIgnoreContacts(mainLimb.SimPosition, mainLimb.Rotation); //reset pull joints to prevent the character from "hanging" mid-air if pull joints had been active when the character was still moving //(except when dragging, then we need the pull joints) if (!character.CanBeDragged || character.SelectedBy == null) { ResetPullJoints(); } } if (character.IsDead && deathAnimTimer < deathAnimDuration) { deathAnimTimer += deltaTime; UpdateDying(deltaTime); } else if (!InWater && !CanWalk && character.AllowInput) { //cannot walk but on dry land -> wiggle around UpdateDying(deltaTime); } return; } else { deathAnimTimer = 0.0f; } //re-enable collider if (!Collider.Enabled) { var lowestLimb = FindLowestLimb(); Collider.SetTransform(new Vector2( Collider.SimPosition.X, Math.Max(lowestLimb.SimPosition.Y + (Collider.radius + Collider.height / 2), Collider.SimPosition.Y)), 0.0f); Collider.Enabled = true; } ResetPullJoints(); if (strongestImpact > 0.0f) { character.Stun = MathHelper.Clamp(strongestImpact * 0.5f, character.Stun, 5.0f); strongestImpact = 0.0f; } if (inWater && !forceStanding) { Collider.FarseerBody.FixedRotation = false; UpdateSineAnim(deltaTime); } else if (RagdollParams.CanWalk && (currentHull != null || forceStanding)) { if (CurrentGroundedParams != null) { //rotate collider back upright float standAngle = dir == Direction.Right ? CurrentGroundedParams.ColliderStandAngleInRadians : -CurrentGroundedParams.ColliderStandAngleInRadians; if (Math.Abs(MathUtils.GetShortestAngle(Collider.Rotation, standAngle)) > 0.001f) { Collider.AngularVelocity = MathUtils.GetShortestAngle(Collider.Rotation, standAngle) * 60.0f; Collider.FarseerBody.FixedRotation = false; } else { Collider.FarseerBody.FixedRotation = true; } } UpdateWalkAnim(deltaTime); } if (character.SelectedCharacter != null) { DragCharacter(character.SelectedCharacter, deltaTime); } //don't flip when simply physics is enabled if (SimplePhysicsEnabled) { return; } if (!character.IsRemotelyControlled && (character.AIController == null || character.AIController.CanFlip)) { if (!inWater || (CurrentSwimParams != null && CurrentSwimParams.Mirror)) { if (targetMovement.X > 0.1f && targetMovement.X > Math.Abs(targetMovement.Y) * 0.2f) { TargetDir = Direction.Right; } else if (targetMovement.X < -0.1f && targetMovement.X < -Math.Abs(targetMovement.Y) * 0.2f) { TargetDir = Direction.Left; } } else { float rotation = MathHelper.WrapAngle(Collider.Rotation); rotation = MathHelper.ToDegrees(rotation); if (rotation < 0.0f) { rotation += 360; } if (rotation > 20 && rotation < 160) { TargetDir = Direction.Left; } else if (rotation > 200 && rotation < 340) { TargetDir = Direction.Right; } } } if (!CurrentFishAnimation.Flip) { return; } if (IsStuck) { return; } if (character.AIController != null && !character.AIController.CanFlip) { return; } flipCooldown -= deltaTime; if (TargetDir != Direction.None && TargetDir != dir) { flipTimer += deltaTime; // Speed reductions are not taken into account here. It's intentional: an ai character cannot flip if it's heavily paralyzed (for example). float requiredSpeed = CurrentAnimationParams.MovementSpeed / 2; if (CurrentHull != null) { // Enemy movement speeds are halved inside submarines requiredSpeed /= 2; } bool isMovingFastEnough = Math.Abs(MainLimb.LinearVelocity.X) > requiredSpeed; bool isTryingToMoveHorizontally = Math.Abs(TargetMovement.X) > Math.Abs(TargetMovement.Y); if ((flipTimer > CurrentFishAnimation.FlipDelay && flipCooldown <= 0.0f && ((isMovingFastEnough && isTryingToMoveHorizontally) || IsMovingBackwards)) || character.IsRemotePlayer) { Flip(); if (!inWater || (CurrentSwimParams != null && CurrentSwimParams.Mirror)) { Mirror(CurrentSwimParams != null ? CurrentSwimParams.MirrorLerp : true); } flipTimer = 0.0f; flipCooldown = CurrentFishAnimation.FlipCooldown; } } else { flipTimer = 0.0f; } }
public static float InterpolateRotation(float previous, float current) { float angleDiff = MathUtils.GetShortestAngle(previous, current); return(previous + angleDiff * (float)alpha); }
public override void UpdateAnim(float deltaTime) { if (Frozen) { return; } if (character.IsDead || character.IsUnconscious || character.Stun > 0.0f) { Collider.FarseerBody.FixedRotation = false; if (character.IsRemotePlayer) { if (!SimplePhysicsEnabled) { MainLimb.PullJointWorldAnchorB = Collider.SimPosition; MainLimb.PullJointEnabled = true; } } else { Vector2 diff = (MainLimb.SimPosition - Collider.SimPosition); if (diff.LengthSquared() > 10.0f * 10.0f) { Collider.SetTransform(MainLimb.SimPosition, MainLimb.Rotation); } else { Collider.LinearVelocity = diff * 60.0f; Collider.SmoothRotate(MainLimb.Rotation); } } if (character.IsDead && deathAnimTimer < deathAnimDuration) { deathAnimTimer += deltaTime; UpdateDying(deltaTime); } return; } //re-enable collider if (!Collider.Enabled) { var lowestLimb = FindLowestLimb(); Collider.SetTransform(new Vector2( Collider.SimPosition.X, Math.Max(lowestLimb.SimPosition.Y + (Collider.radius + Collider.height / 2), Collider.SimPosition.Y)), 0.0f); Collider.Enabled = true; } ResetPullJoints(); if (strongestImpact > 0.0f) { character.Stun = MathHelper.Clamp(strongestImpact * 0.5f, character.Stun, 5.0f); strongestImpact = 0.0f; } if (inWater) { Collider.FarseerBody.FixedRotation = false; UpdateSineAnim(deltaTime); } else if (currentHull != null && CanEnterSubmarine) { if (Math.Abs(MathUtils.GetShortestAngle(Collider.Rotation, 0.0f)) > 0.001f) { //rotate collider back upright Collider.AngularVelocity = MathUtils.GetShortestAngle(Collider.Rotation, 0.0f) * 60.0f; Collider.FarseerBody.FixedRotation = false; } else { Collider.FarseerBody.FixedRotation = true; } UpdateWalkAnim(deltaTime); } //don't flip or drag when simply physics is enabled if (SimplePhysicsEnabled) { return; } if (!character.IsRemotePlayer) { if (mirror || !inWater) { if (targetMovement.X > 0.1f && targetMovement.X > Math.Abs(targetMovement.Y) * 0.5f) { TargetDir = Direction.Right; } else if (targetMovement.X < -0.1f && targetMovement.X < -Math.Abs(targetMovement.Y) * 0.5f) { TargetDir = Direction.Left; } } else { Limb head = GetLimb(LimbType.Head); if (head == null) { head = GetLimb(LimbType.Torso); } float rotation = MathUtils.WrapAngleTwoPi(head.Rotation); rotation = MathHelper.ToDegrees(rotation); if (rotation < 0.0f) { rotation += 360; } if (rotation > 20 && rotation < 160) { TargetDir = Direction.Left; } else if (rotation > 200 && rotation < 340) { TargetDir = Direction.Right; } } } if (character.SelectedCharacter != null) { DragCharacter(character.SelectedCharacter); } if (!flip) { return; } flipTimer += deltaTime; if (TargetDir != Direction.None && TargetDir != dir) { if (flipTimer > 1.0f || character.IsRemotePlayer) { Flip(); if (mirror || !inWater) { Mirror(); } flipTimer = 0.0f; } } }
public override void UpdateAnim(float deltaTime) { if (Frozen) { return; } levitatingCollider = true; ColliderIndex = Crouching ? 1 : 0; if (!Crouching && ColliderIndex == 1) { Crouching = true; } if (!character.AllowInput) { levitatingCollider = false; Collider.FarseerBody.FixedRotation = false; Collider.LinearVelocity = (GetLimb(LimbType.Waist).SimPosition - Collider.SimPosition) * 20.0f; Collider.SmoothRotate(GetLimb(LimbType.Torso).Rotation); return; } //stun (= disable the animations) if the ragdoll receives a large enough impact if (strongestImpact > 0.0f) { character.SetStun(MathHelper.Min(strongestImpact * 0.5f, 5.0f)); strongestImpact = 0.0f; return; } //re-enable collider if (!Collider.FarseerBody.Enabled) { var lowestLimb = FindLowestLimb(); Collider.SetTransform(new Vector2( Collider.SimPosition.X, Math.Max(lowestLimb.SimPosition.Y + (Collider.radius + Collider.height / 2), Collider.SimPosition.Y)), Collider.Rotation); Collider.FarseerBody.ResetDynamics(); Collider.FarseerBody.Enabled = true; } if (swimming) { Collider.FarseerBody.FixedRotation = false; } else if (!Collider.FarseerBody.FixedRotation) { if (Math.Abs(MathUtils.GetShortestAngle(Collider.Rotation, 0.0f)) > 0.001f) { //rotate collider back upright Collider.AngularVelocity = MathUtils.GetShortestAngle(Collider.Rotation, 0.0f) * 10.0f; Collider.FarseerBody.FixedRotation = false; } else { Collider.FarseerBody.FixedRotation = true; } } if (character.LockHands) { var leftHand = GetLimb(LimbType.LeftHand); var rightHand = GetLimb(LimbType.RightHand); var waist = GetLimb(LimbType.Waist); rightHand.Disabled = true; leftHand.Disabled = true; Vector2 midPos = waist.SimPosition; Matrix torsoTransform = Matrix.CreateRotationZ(waist.Rotation); midPos += Vector2.Transform(new Vector2(-0.3f * Dir, -0.2f), torsoTransform); if (rightHand.pullJoint.Enabled) { midPos = (midPos + rightHand.pullJoint.WorldAnchorB) / 2.0f; } HandIK(rightHand, midPos); HandIK(leftHand, midPos); } else { if (Anim != Animation.UsingConstruction) { ResetPullJoints(); } } if (SimplePhysicsEnabled) { UpdateStandingSimple(); return; } switch (Anim) { case Animation.Climbing: levitatingCollider = false; UpdateClimbing(); break; case Animation.CPR: UpdateCPR(deltaTime); break; case Animation.UsingConstruction: default: if (character.SelectedCharacter != null) { DragCharacter(character.SelectedCharacter); } //0.5 second delay for switching between swimming and walking //prevents rapid switches between swimming/walking if the water level is fluctuating around the minimum swimming depth if (inWater) { inWaterTimer = Math.Max(inWaterTimer + deltaTime, 0.5f); if (inWaterTimer >= 1.0f) { swimming = true; } } else { inWaterTimer = Math.Min(inWaterTimer - deltaTime, 0.5f); if (inWaterTimer <= 0.0f) { swimming = false; } } if (swimming) { UpdateSwimming(); } else { UpdateStanding(); } break; } if (TargetDir != dir) { Flip(); } foreach (Limb limb in Limbs) { limb.Disabled = false; } aiming = false; if (character.IsRemotePlayer && GameMain.Server == null) { Collider.LinearVelocity = Vector2.Zero; } }
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); } }