private void AttachToBody(PhysicsBody collider, Limb attachLimb, Body targetBody, Vector2 attachPos) { //already attached to something if (attachJoints.Count > 0) { //already attached to the target body, no need to do anything if (attachJoints[0].BodyB == targetBody) { return; } DeattachFromBody(); } jointDir = attachLimb.Dir; Vector2 transformedLocalAttachPos = localAttachPos * attachLimb.character.AnimController.RagdollParams.LimbScale; if (jointDir < 0.0f) { transformedLocalAttachPos.X = -transformedLocalAttachPos.X; } //transformedLocalAttachPos = Vector2.Transform(transformedLocalAttachPos, Matrix.CreateRotationZ(attachLimb.Rotation)); float angle = MathUtils.VectorToAngle(-attachSurfaceNormal) - MathHelper.PiOver2 + attachLimbRotation * attachLimb.Dir; attachLimb.body.SetTransform(attachPos + attachSurfaceNormal * transformedLocalAttachPos.Length(), angle); var limbJoint = new WeldJoint(attachLimb.body.FarseerBody, targetBody, transformedLocalAttachPos, targetBody.GetLocalPoint(attachPos), false) { FrequencyHz = 10.0f, DampingRatio = 0.5f, KinematicBodyB = true, CollideConnected = false, }; GameMain.World.AddJoint(limbJoint); attachJoints.Add(limbJoint); // Limb scale is already taken into account when creating the collider. Vector2 colliderFront = collider.GetLocalFront(); if (jointDir < 0.0f) { colliderFront.X = -colliderFront.X; } collider.SetTransform(attachPos + attachSurfaceNormal * colliderFront.Length(), MathUtils.VectorToAngle(-attachSurfaceNormal) - MathHelper.PiOver2); var colliderJoint = new WeldJoint(collider.FarseerBody, targetBody, colliderFront, targetBody.GetLocalPoint(attachPos), false) { FrequencyHz = 10.0f, DampingRatio = 0.5f, KinematicBodyB = true, CollideConnected = false, //Length = 0.1f }; GameMain.World.AddJoint(colliderJoint); attachJoints.Add(colliderJoint); }