예제 #1
0
        private void SpawnBlood(DamageInfo info)
        {
            if (AI.IsTurtle(this.m_AI.m_ID) || this.m_AI.m_ID == AI.AIID.ArmadilloThreeBanded)
            {
                return;
            }
            AIManager.BloodFXType key  = info.m_DamageItem ? info.m_DamageItem.m_Info.m_BloodFXType : AIManager.BloodFXType.Blunt;
            List <string>         list = AIManager.Get().m_BloodFXNames[(int)key];

            if (list.Count == 0)
            {
                DebugUtils.Assert("Missing blood fxes!", true, DebugUtils.AssertType.Info);
                return;
            }
            string text = list[UnityEngine.Random.Range(0, list.Count)];

            text += ((this.m_AI.m_Params.m_Human || this.m_AI.m_Params.m_BigAnimal) ? "_M" : "_S");
            Vector3     vector             = Vector3.zero;
            RagdollBone closestRagdollBone = this.m_AI.GetClosestRagdollBone(info.m_Position);

            if (closestRagdollBone)
            {
                vector = closestRagdollBone.transform.position;
            }
            else
            {
                vector = base.transform.position;
            }
            Vector3 forward = (info.m_Damager && info.m_Damager.IsPlayer()) ? (Camera.main.transform.position - Camera.main.transform.right - vector).normalized : (-info.m_HitDir);

            ParticlesManager.Get().Spawn(text, vector, Quaternion.LookRotation(forward), Vector3.zero, null, -1f, false);
        }
예제 #2
0
        RagdollBoneTargetBonePair[] CreateBonePairs(RagdollDefinitionBindings bindings, Transform targetParent)
        {
            List <RagdollBoneTargetBonePair> pairs = new List <RagdollBoneTargetBonePair>();

            CreateBonePairsRecursively(FindCorrespondingBone(bindings.Root.Transform, targetParent),
                                       pairs, bindings.transform);

            return(pairs.ToArray());


            void CreateBonePairsRecursively(Transform targetBoneTransform, List <RagdollBoneTargetBonePair> ragdollPairs, Transform ragdollParentTransform)
            {
                Transform ragdollBoneTransform = FindCorrespondingBone(targetBoneTransform, ragdollParentTransform);

                RagdollBone ragdollBone = null;

                if (ragdollBoneTransform)
                {
                    ragdollBone = GetRagdollBoneForRagdollBoneTransform(ragdollBoneTransform, bindings);
                }

                if (ragdollBone != null)
                {
                    ragdollPairs.Add(new RagdollBoneTargetBonePair(ragdollBone, targetBoneTransform));
                }

                //Recursively call all of its children
                for (int i = 0; i < targetBoneTransform.childCount; i++)
                {
                    CreateBonePairsRecursively(targetBoneTransform.GetChild(i), ragdollPairs, ragdollParentTransform);
                }
            }
        }
예제 #3
0
 private void SetBoneTo(RagdollBone ragdollBone, float weight, float dynamicChildrenWeight, float keyframedChildrenWeight, bool translationEnabled)
 {
     if ((this.Ragdoll != null) && (this.m_inicialized && this.IsActive))
     {
         int             index   = this.m_rigidBodiesToBonesIndices[ragdollBone.m_rigidBodyIndex][0];
         MyCharacterBone bone    = this.m_bones[index];
         Matrix          matrix  = (bone.Parent != null) ? bone.Parent.AbsoluteTransform : Matrix.Identity;
         Matrix          matrix3 = (this.m_bodyToBoneRigTransforms[ragdollBone.m_rigidBodyIndex] * this.Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex)) * Matrix.Invert(bone.BindTransform * matrix);
         if (!this.m_animationBlendingHelper.Initialized)
         {
             this.m_animationBlendingHelper.Init(this.m_bones, this.m_character.AnimationController.Controller);
         }
         this.m_animationBlendingHelper.BlendWeight(ref weight, bone, this.m_character.AnimationController.Variables);
         weight *= MyFakes.RAGDOLL_ANIMATION_WEIGHTING;
         float single1 = MathHelper.Clamp(weight, 0f, 1f);
         weight = single1;
         if (matrix3.IsValid() && (matrix3 != Matrix.Zero))
         {
             if (weight == 1f)
             {
                 bone.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.Normalize(matrix3.GetOrientation()));
                 if (translationEnabled)
                 {
                     bone.Translation = matrix3.Translation;
                 }
             }
             else
             {
                 bone.Rotation = Quaternion.Slerp(bone.Rotation, Quaternion.CreateFromRotationMatrix(Matrix.Normalize(matrix3.GetOrientation())), weight);
                 if (translationEnabled)
                 {
                     bone.Translation = Vector3.Lerp(bone.Translation, matrix3.Translation, weight);
                 }
             }
         }
         bone.ComputeAbsoluteTransform(true);
         foreach (RagdollBone bone2 in ragdollBone.m_children)
         {
             float num2 = dynamicChildrenWeight;
             if (this.m_keyframedBodies.Contains(bone2.m_rigidBodyIndex))
             {
                 num2 = keyframedChildrenWeight;
             }
             if (this.IsPartiallySimulated)
             {
                 this.SetBoneTo(bone2, num2, dynamicChildrenWeight, keyframedChildrenWeight, false);
             }
             else
             {
                 this.SetBoneTo(bone2, num2, dynamicChildrenWeight, keyframedChildrenWeight, !this.Ragdoll.IsRigidBodyPalmOrFoot(bone2.m_rigidBodyIndex) && MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION);
             }
         }
     }
 }
예제 #4
0
        void DoPoweredRotationMatching(AnimatedPair pair, BoneProfile boneProfile, float dt)
        {
            RagdollBone bone = pair.RagdollBone;

            Rigidbody rigidbody    = bone.Rigidbody;
            float     alpha        = boneProfile.rotationAlpha;
            float     dampingRatio = boneProfile.rotationDampingRatio;

            SetTargetRotation(pair);
            SetTargetAngularVelocityLocal(bone.Joint, pair.poseAngularVelocity, pair.RagdollBone.StartingJointRotation);
            bone.Joint.slerpDrive = AnimationMatching.GetRotationMatchingJointDrive(alpha, dampingRatio, rigidbody.mass, dt, boneProfile.maxAngularAcceleration);
        }
예제 #5
0
        private void SetBoneTo(RagdollBone ragdollBone, float weight, float dynamicChildrenWeight, float keyframedChildrenWeight)
        {
            int firstBoneIndex = m_rigidBodiesToBonesIndices[ragdollBone.m_rigidBodyIndex].First();

            MyCharacterBone bone = m_bones[firstBoneIndex];

            //Matrix localTransform = m_ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex);

            Matrix localTransform = m_bodyToBoneRigTransforms[ragdollBone.m_rigidBodyIndex] * m_ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex);

            Matrix parentMatrix = (bone.Parent != null) ? bone.Parent.AbsoluteTransform : Matrix.Identity;

            Matrix absoluteMatrixInverted = Matrix.Invert(bone.BindTransform * parentMatrix);

            Matrix finalTransform = localTransform * absoluteMatrixInverted;

            //finalTransform = rigidBodyToBoneTransform * finalTransform;

            if (weight == 1.0f)
            {
                bone.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation()));

                // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled on all bodies except the firs one
                if (MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION)
                {
                    bone.Translation = finalTransform.Translation;
                }
            }
            else
            {
                bone.Rotation = Quaternion.Slerp(bone.Rotation, Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation())), weight);

                // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled
                if (MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION)
                {
                    bone.Translation = Vector3.Lerp(bone.Translation, finalTransform.Translation, weight);
                }
            }

            bone.ComputeAbsoluteTransform();

            foreach (var childBone in ragdollBone.m_children)
            {
                float childWeight = dynamicChildrenWeight;
                if (m_keyframedBodies.Contains(childBone.m_rigidBodyIndex))
                {
                    childWeight = keyframedChildrenWeight;
                }
                SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight);
            }
        }
예제 #6
0
        private void SetupRagdollBones()
        {
            List <Rigidbody> componentsDeepChild = General.GetComponentsDeepChild <Rigidbody>(base.gameObject);

            for (int i = 0; i < componentsDeepChild.Count; i++)
            {
                componentsDeepChild[i].isKinematic = true;
                Collider    component   = componentsDeepChild[i].GetComponent <Collider>();
                RagdollBone ragdollBone = component.gameObject.AddComponent <RagdollBone>();
                ragdollBone.m_Parent = base.gameObject;
                component.enabled    = false;
                component.isTrigger  = true;
                this.m_RagdollBones.Add(component, componentsDeepChild[i]);
            }
        }
예제 #7
0
        public override bool TakeDamage(DamageInfo info)
        {
            RagdollBone closestRagdollBone = this.GetClosestRagdollBone(info.m_Position);

            if (closestRagdollBone)
            {
                info.m_Damage *= closestRagdollBone.GetDamageMultiplier(false);
            }
            this.m_LastDamageInfo = info;
            bool flag = base.TakeDamage(info);

            if (flag && info.m_Damager && info.m_Damager.GetComponent <ReplicatedLogicalPlayer>())
            {
                PlayerStateModule.Get().OnGiveDamageToAI(this, info);
            }
            return(flag);
        }
        void HandleBoneDecayOnCollision(float collisionMagnitude2, RagdollBone bone, bool isCrushed, Collision collision)
        {
            if (isCrushed)
            {
                //Debug.LogWarning(bone + " / " + collision.transform.name + " CrUSHED");
                ragdollController.SetBoneDecay(bone.bone, 1, neighborDecayMultiplier);
            }
            // if the magnitude is above the minimum threshold for adding decay
            else if (collisionMagnitude2 >= decayMagnitudeRange.x * decayMagnitudeRange.x)
            {
                float magnitude = Mathf.Sqrt(collisionMagnitude2);

                //linearly interpolate decay between 0 and 1 base on collision magnitude
                float linearDecay = (magnitude - decayMagnitudeRange.x) / (decayMagnitudeRange.y - decayMagnitudeRange.x);
                //Debug.Log(bone + " / " + collision.transform.name + " mag: " + magnitude + " decay " + linearDecay);
                ragdollController.SetBoneDecay(bone.bone, linearDecay, neighborDecayMultiplier);
            }
        }
예제 #9
0
        public RagdollBone GetClosestRagdollBone(Vector3 point)
        {
            float       num    = float.MaxValue;
            RagdollBone result = null;

            foreach (RagdollBone ragdollBone in this.m_RagdollBones)
            {
                bool enabled = ragdollBone.m_Collider.enabled;
                ragdollBone.m_Collider.enabled = true;
                float sqrMagnitude = (ragdollBone.m_Collider.ClosestPoint(point) - point).sqrMagnitude;
                if (sqrMagnitude < num)
                {
                    result = ragdollBone;
                    num    = sqrMagnitude;
                }
                ragdollBone.m_Collider.enabled = enabled;
            }
            return(result);
        }
예제 #10
0
        IEnumerator CheckForCharacter(Ray ray)
        {
            yield return(new WaitForFixedUpdate());

            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, 100f, shooting.shootMask, QueryTriggerInteraction.Ignore))
            {
                //check if we hit a ragdoll bone
                RagdollBone ragdollBone = hit.transform.GetComponent <RagdollBone>();

                if (ragdollBone)
                {
                    // check if the ragdoll has a controller
                    if (ragdollBone.ragdoll.hasController)
                    {
                        AttachToCharacter(ragdollBone.ragdoll.controller.GetComponent <Character>());
                    }
                }
            }
        }
예제 #11
0
        IEnumerator ShootBullet(Ray ray)
        {
            yield return(new WaitForFixedUpdate());

            RaycastHit hit;

            if (Physics.Raycast(ray, out hit, 100f, shootMask, QueryTriggerInteraction.Ignore))
            {
                //check if we hit a ragdoll bone
                RagdollBone ragdollBone = hit.transform.GetComponent <RagdollBone>();

                if (ragdollBone)
                {
                    // check if the ragdoll has a controller
                    if (ragdollBone.ragdoll.hasController)
                    {
                        RagdollController controller = ragdollBone.ragdoll.controller;

                        // set bone decay for the hit bone, so the physics will affect it
                        // slightly lower for neighbor bones

                        float mainDecay          = 1;
                        float neighborMultiplier = .75f;
                        controller.SetBoneDecay(ragdollBone.bone, mainDecay, neighborMultiplier);

                        //make it go ragdoll
                        controller.GoRagdoll();
                    }
                }

                // shoot normally

                Rigidbody rb = hit.transform.GetComponent <Rigidbody>();

                if (rb)
                {
                    rb.AddForceAtPosition(ray.direction.normalized * modifiedBulletForce, hit.point, ForceMode.VelocityChange);
                }
            }
        }
예제 #12
0
        IEnumerator CheckForRagdollGrab(Ray ray)
        {
            if (grabbedBone)
            {
                RagdollPhysics.DetachRigidbody(grabbedBone.GetComponent <Rigidbody>(), hangJoint, false);
                grabbedBone = null;
            }
            else
            {
                yield return(new WaitForFixedUpdate());

                RaycastHit hit;

                if (Physics.Raycast(ray, out hit, 100f, shootMask, QueryTriggerInteraction.Ignore))
                {
                    grabbedBone = hit.transform.GetComponent <RagdollBone>();
                    if (grabbedBone)
                    {
                        ragdollGrabberAnchor.transform.position = hit.point;
                        hangJoint = RagdollPhysics.GrabRigidbody(grabbedBone.rb, ragdollGrabberAnchor.childRigidbody, true);
                    }
                }
            }
        }
예제 #13
0
    private void Hit(CJObject cj_object, Collider coll, Vector3 hit_pos, Vector3 hit_dir)
    {
        Item currentItem = this.m_Player.GetCurrentItem(Hand.Right);

        if (cj_object)
        {
            HumanAI component = cj_object.GetComponent <HumanAI>();
            if (component)
            {
                if (component.m_Hallucination && component.m_HallucinationDisappearing)
                {
                    return;
                }
                this.HitHumanAI(component, hit_pos, hit_dir);
                this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID);
                this.m_AlreadyHit = true;
                return;
            }
            else
            {
                this.HitObject(cj_object, hit_pos, hit_dir);
            }
        }
        else
        {
            RagdollBone component2 = coll.gameObject.GetComponent <RagdollBone>();
            if (component2 && component2.m_Parent)
            {
                DeadBody component3 = component2.m_Parent.GetComponent <DeadBody>();
                if (component3)
                {
                    component3.OnTakeDamage(new DamageInfo
                    {
                        m_DamageItem = currentItem,
                        m_Damager    = base.gameObject,
                        m_Position   = hit_pos,
                        m_HitDir     = hit_dir,
                        m_Normal     = -hit_dir
                    });
                    return;
                }
            }
        }
        DamageInfo     damageInfo = new DamageInfo();
        ObjectMaterial component4;

        if (cj_object != null)
        {
            component4 = cj_object.gameObject.GetComponent <ObjectMaterial>();
        }
        else
        {
            component4 = coll.gameObject.GetComponent <ObjectMaterial>();
        }
        EObjectMaterial mat = (!(component4 == null)) ? component4.m_ObjectMaterial : EObjectMaterial.Unknown;

        damageInfo.m_Damage     = currentItem.m_Info.m_DamageSelf * ObjectMaterial.GetDamageSelfMul(mat);
        damageInfo.m_DamageItem = currentItem;
        this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID);
        currentItem.TakeDamage(damageInfo);
        this.OnHit();
    }
예제 #14
0
        private void SetBoneTo(RagdollBone ragdollBone, float weight, float dynamicChildrenWeight, float keyframedChildrenWeight, bool translationEnabled)
        {
            if (Ragdoll == null)
            {
                return;
            }
            if (!m_inicialized || !IsActive)
            {
                return;
            }

            int firstBoneIndex = m_rigidBodiesToBonesIndices[ragdollBone.m_rigidBodyIndex].First();

            MyCharacterBone bone = m_bones[firstBoneIndex];

            //Matrix localTransform = Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex);

            Matrix localTransform = m_bodyToBoneRigTransforms[ragdollBone.m_rigidBodyIndex] * Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex);

            Matrix parentMatrix = (bone.Parent != null) ? bone.Parent.AbsoluteTransform : Matrix.Identity;

            Matrix absoluteMatrixInverted = Matrix.Invert(bone.BindTransform * parentMatrix);

            Matrix finalTransform = localTransform * absoluteMatrixInverted;

            //finalTransform = rigidBodyToBoneTransform * finalTransform;

            Debug.Assert(finalTransform.IsValid() && finalTransform != Matrix.Zero, "Ragdoll - final bone transform is invalid!");

            if (finalTransform.IsValid() && finalTransform != Matrix.Zero)
            {
                if (weight == 1.0f)
                {
                    bone.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation()));

                    // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled on all bodies except the firs one
                    if (translationEnabled)// || m_character.IsDead)
                    {
                        bone.Translation = finalTransform.Translation;
                    }
                }
                else
                {
                    bone.Rotation = Quaternion.Slerp(bone.Rotation, Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation())), weight);

                    // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled
                    if (translationEnabled)// || m_character.IsDead)
                    {
                        bone.Translation = Vector3.Lerp(bone.Translation, finalTransform.Translation, weight);
                    }
                }
            }

            bone.ComputeAbsoluteTransform();

            foreach (var childBone in ragdollBone.m_children)
            {
                float childWeight = dynamicChildrenWeight;
                if (m_keyframedBodies.Contains(childBone.m_rigidBodyIndex))
                {
                    childWeight = keyframedChildrenWeight;
                }
                //SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight, MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION);

                if (IsPartiallySimulated)
                {
                    SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight, false);
                }
                else
                {
                    SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight, (Ragdoll.IsRigidBodyPalmOrFoot(childBone.m_rigidBodyIndex)) ? false : MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION);
                }
            }
        }
예제 #15
0
    private void Hit(CJObject cj_object, Collider coll, Vector3 hit_pos, Vector3 hit_dir)
    {
        Item currentItem = this.m_Player.GetCurrentItem(Hand.Right);

        if (cj_object)
        {
            HumanAI humanAI   = null;
            AI      component = cj_object.GetComponent <AI>();
            if (component && component.IsHuman())
            {
                humanAI = (HumanAI)component;
            }
            if (humanAI)
            {
                if (humanAI.m_Hallucination && humanAI.m_HallucinationDisappearing)
                {
                    return;
                }
                this.HitHumanAI(humanAI, hit_pos, hit_dir);
                this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID);
                this.m_AlreadyHit = true;
            }
            else
            {
                Fish component2 = cj_object.GetComponent <Fish>();
                if (component2 && component2.m_ID != AI.AIID.AngelFish && component2.m_ID != AI.AIID.DiscusFish && UnityEngine.Random.Range(0f, 1f) < 0.5f)
                {
                    this.m_AlreadyHit = true;
                }
                else if (base.m_ControllerType == PlayerControllerType.WeaponMelee && component2 && component2.m_ID != AI.AIID.AngelFish && component2.m_ID != AI.AIID.DiscusFish)
                {
                    component2.OnHitByItem(null, hit_pos);
                    this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID);
                    this.m_AlreadyHit = true;
                }
            }
            if (component)
            {
                PlayerConditionModule.Get().GetDirtinessAdd(GetDirtyReason.Combat, null);
            }
            if (!this.m_AlreadyHit)
            {
                this.HitObject(cj_object, hit_pos, hit_dir);
            }
        }
        else
        {
            RagdollBone component3 = coll.gameObject.GetComponent <RagdollBone>();
            if (component3 && component3.m_ParentObject)
            {
                DeadBody component4 = component3.m_ParentObject.GetComponent <DeadBody>();
                if (component4)
                {
                    component4.OnTakeDamage(new DamageInfo
                    {
                        m_DamageItem = currentItem,
                        m_Damager    = base.gameObject,
                        m_Position   = hit_pos,
                        m_HitDir     = hit_dir,
                        m_Normal     = -hit_dir
                    });
                    this.m_AlreadyHit = true;
                }
            }
        }
        DamageInfo     damageInfo = new DamageInfo();
        ObjectMaterial component5;

        if (cj_object != null)
        {
            component5 = cj_object.gameObject.GetComponent <ObjectMaterial>();
        }
        else
        {
            component5 = coll.gameObject.GetComponent <ObjectMaterial>();
        }
        EObjectMaterial mat = (component5 == null) ? EObjectMaterial.Unknown : component5.m_ObjectMaterial;

        damageInfo.m_Damage     = currentItem.m_Info.m_DamageSelf * ObjectMaterial.GetDamageSelfMul(mat);
        damageInfo.m_DamageItem = currentItem;
        this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID);
        currentItem.TakeDamage(damageInfo);
        this.OnHit();
    }
예제 #16
0
        private void SetBoneTo(RagdollBone ragdollBone, float weight, float dynamicChildrenWeight, float keyframedChildrenWeight, bool translationEnabled)
        {
            if (Ragdoll == null) return;
            if (!m_inicialized || !IsActive) return;

            int firstBoneIndex = m_rigidBodiesToBonesIndices[ragdollBone.m_rigidBodyIndex].First();

            MyCharacterBone bone = m_bones[firstBoneIndex];

            //Matrix localTransform = Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex);

            Matrix localTransform = m_bodyToBoneRigTransforms[ragdollBone.m_rigidBodyIndex] * Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex);

            Matrix parentMatrix = (bone.Parent != null) ? bone.Parent.AbsoluteTransform : Matrix.Identity;

            Matrix absoluteMatrixInverted = Matrix.Invert(bone.BindTransform * parentMatrix);

            Matrix finalTransform = localTransform * absoluteMatrixInverted;

            //finalTransform = rigidBodyToBoneTransform * finalTransform;

            Debug.Assert(finalTransform.IsValid() && finalTransform != Matrix.Zero, "Ragdoll - final bone transform is invalid!");

            if (finalTransform.IsValid() && finalTransform != Matrix.Zero)
            {

                if (weight == 1.0f)
                {
                    bone.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation()));

                    // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled on all bodies except the firs one                    
                    if (translationEnabled)// || m_character.IsDead) 
                    {
                        bone.Translation = finalTransform.Translation;
                    }
                }
                else
                {
                    bone.Rotation = Quaternion.Slerp(bone.Rotation, Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation())), weight);

                    // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled
                    if (translationEnabled)// || m_character.IsDead) 
                    {
                        bone.Translation = Vector3.Lerp(bone.Translation, finalTransform.Translation, weight);
                    }
                }
            }

            bone.ComputeAbsoluteTransform();

            foreach (var childBone in ragdollBone.m_children)
            {
                float childWeight = dynamicChildrenWeight;
                if (m_keyframedBodies.Contains(childBone.m_rigidBodyIndex))
                {
                    childWeight = keyframedChildrenWeight;
                }
                SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight, MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION);
            }
        }
        /*
         *              callback called when ragdoll bone gets a collision
         *  then apply bone decay to those bones
         */
        void OnRagdollCollisionEnter(RagdollBone bone, Collision collision)
        {
            float stepOffset = characterController.stepOffset;
            float charHeight = characterController.height;


            //maybe add warp to master state for ragdoll check

            bool checkForRagdoll = ragdollController.state == RagdollControllerState.Animated || ragdollController.state == RagdollControllerState.BlendToAnimated;

            bool isFalling = ragdollController.state == RagdollControllerState.Falling;

            if (!isFalling && !checkForRagdoll)
            {
                return;
            }

            //check for and ignore self ragdoll collsion (only happens when falling)
            if (ragdollController.ragdoll.ColliderIsPartOfRagdoll(collision.collider))
            {
                return;
            }

            if (checkForRagdoll)
            {
                //if we're getting up, knock us out regardless of where the collision takes place
                if (!ragdollController.isGettingUp)
                {
                    // if it's below our step offset (plus a buffer)
                    // ignore it... we can just step on top of it
                    if (!CollisionIsAboveStepOffset(collision, stepOffset, .1f))
                    {
                        return;
                    }
                }
            }


            bool  isCrushed           = CollisionHasCrushMass(collision) && CollisionIsAboveCrushOffset(collision, charHeight);
            float collisionMagnitude2 = collision.relativeVelocity.sqrMagnitude;

            if (checkForRagdoll)
            {
                // string message = "crush";
                // check if we're being crushed
                bool goRagdoll = isCrushed;

                // else check if the collision is above our incoming threhsold, (something being thrown at us)
                if (!goRagdoll)
                {
                    // message = "incoming";
                    goRagdoll = collisionMagnitude2 >= incomingMagnitudeThreshold * incomingMagnitudeThreshold;
                }

                // else check if we're travelling fast enough to go ragdoll (we ran into a wall or something...)
                if (!goRagdoll)
                {
                    // message = "outgoing";
                    collisionMagnitude2 = controllerVelocity.sqrMagnitude;
                    goRagdoll           = collisionMagnitude2 >= outgoingMagnitudeThreshold * outgoingMagnitudeThreshold;
                }

                if (!goRagdoll)
                {
                    return;
                }

                //Debug.Log( message + "/" + bone.name + " went ragdoll cuae of " + collision.collider.name + "/" + Mathf.Sqrt(collisionMagnitude2));
                ragdollController.GoRagdoll();
            }


            HandleBoneDecayOnCollision(collisionMagnitude2, bone, isCrushed, collision);
        }
 internal RagdollBoneTargetBonePair(RagdollBone ragdollBone, Transform targetBone)
 {
     RagdollBone = ragdollBone;
     TargetBone  = targetBone;
 }