示例#1
0
            public virtual void Init(MyDebrisBaseDescription desc)
            {
                HkShape shape;

                base.Init(null, desc.Model, null, 1f, null);
                this.LifespanInMiliseconds = MyUtils.GetRandomInt(desc.LifespanMinInMiliseconds, desc.LifespanMaxInMiliseconds);
                MyDebrisBase.MyDebrisPhysics physics = (MyDebrisBase.MyDebrisPhysics) this.GetPhysics(RigidBodyFlag.RBF_DEBRIS);
                base.Container.Entity.Physics = physics;
                float mass = this.CalculateMass(((MyEntity)base.Entity).Render.GetModel().BoundingSphere.Radius);

                physics.CreatePhysicsShape(out shape, out this.m_massProperties, mass);
                physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, new HkMassProperties?(this.m_massProperties), 20);
                HkMassChangerUtil.Create(physics.RigidBody, -21, 1f, 0f);
                new HkEasePenetrationAction(physics.RigidBody, 3f)
                {
                    InitialAllowedPenetrationDepthMultiplier = 10f
                }.RemoveReference();
                base.Container.Entity.Physics.Enabled = false;
                shape.RemoveReference();
                base.m_entity.Save = false;
                base.Container.Entity.Physics.PlayCollisionCueEnabled = true;
                base.NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
                base.Container.Entity.NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
                this.m_onCloseCallback            = desc.OnCloseAction;
            }
示例#2
0
        public void StopManipulation()
        {
            if (m_state != MyState.NONE && Owner != null)
            {
                var characterMovementState = Owner.GetCurrentMovementState();
                switch (characterMovementState)
                {
                case MyCharacterMovementEnum.Walking:
                case MyCharacterMovementEnum.BackWalking:
                case MyCharacterMovementEnum.WalkingLeftFront:
                case MyCharacterMovementEnum.WalkingRightFront:
                case MyCharacterMovementEnum.WalkingLeftBack:
                case MyCharacterMovementEnum.WalkingRightBack:
                case MyCharacterMovementEnum.WalkStrafingLeft:
                case MyCharacterMovementEnum.WalkStrafingRight:
                case MyCharacterMovementEnum.Running:
                case MyCharacterMovementEnum.Backrunning:
                case MyCharacterMovementEnum.RunStrafingLeft:
                case MyCharacterMovementEnum.RunStrafingRight:
                case MyCharacterMovementEnum.RunningRightFront:
                case MyCharacterMovementEnum.RunningRightBack:
                case MyCharacterMovementEnum.RunningLeftFront:
                case MyCharacterMovementEnum.RunningLeftBack:
                    Owner.PlayCharacterAnimation("WalkBack", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f, 1f);
                    break;

                case MyCharacterMovementEnum.Standing:
                case MyCharacterMovementEnum.RotatingLeft:
                case MyCharacterMovementEnum.RotatingRight:
                case MyCharacterMovementEnum.Flying:
                    Owner.PlayCharacterAnimation("Idle", MyBlendOption.Immediate, MyFrameOption.Loop, 0.2f, 1f);
                    break;
                }
            }


            if (m_constraint != null)
            {
                if (OwnerVirtualPhysics != null)
                {
                    OwnerVirtualPhysics.RemoveConstraint(m_constraint);
                }

                m_constraint.Dispose();
                m_constraint = null;
            }

            if (m_fixedConstraintData != null)
            {
                if (!m_fixedConstraintData.IsDisposed)
                {
                    m_fixedConstraintData.Dispose();
                }

                m_fixedConstraintData = null;
            }

            m_headLocalPivotMatrix  = Matrix.Zero;
            m_otherLocalPivotMatrix = Matrix.Zero;
            if (m_otherEntity != null)
            {
                SetTransparent(m_otherEntity);

                if (m_state == MyState.HOLD)
                {
                    SetMotionOnClient(m_otherEntity, HkMotionType.Dynamic);

                    // Do not send when disconnecting
                    if (IsOwnerLocalPlayer() && !MyEntities.CloseAllowed && !(m_otherEntity is MyCharacter))
                    {
                        Sync.Players.RemoveControlledEntity(m_otherEntity);
                    }
                }

                m_manipulatedEntitites.Remove(m_otherEntity);
                var handler = ManipulationStopped;
                if (handler != null)
                {
                    handler(m_otherEntity);
                }

                m_otherEntity.SyncFlag = true;

                if (m_otherEntity.Physics != null && m_otherRigidBody != null && !m_otherRigidBody.IsDisposed)
                {
                    SetManipulated(m_otherEntity, false);
                    //m_otherRigidBody.AngularDamping = m_otherAngularDamping;
                    //m_otherRigidBody.LinearDamping = m_otherLinearDamping;
                    if (m_otherEntity is MyCharacter)
                    {
                        m_otherEntity.Physics.SetRagdollDefaults();
                    }
                    else
                    {
                        m_otherRigidBody.Restitution        = m_otherRestitution;
                        m_otherRigidBody.MaxLinearVelocity  = m_otherMaxLinearVelocity;
                        m_otherRigidBody.MaxAngularVelocity = m_otherMaxAngularVelocity;
                        if (m_massChange != null)
                        {
                            m_massChange.Remove();
                        }
                        m_massChange = null;
                        // Clamp output velocity
                        m_otherRigidBody.LinearVelocity  = Vector3.Clamp(m_otherRigidBody.LinearVelocity, -2 * Vector3.One, 2 * Vector3.One);
                        m_otherRigidBody.AngularVelocity = Vector3.Clamp(m_otherRigidBody.AngularVelocity, -Vector3.One * (float)Math.PI, Vector3.One * (float)Math.PI);
                        if (!m_otherRigidBody.IsActive)
                        {
                            m_otherRigidBody.Activate();
                        }
                        m_otherRigidBody.EnableDeactivation = false;
                        m_otherRigidBody.EnableDeactivation = true; //resets deactivation counter
                    }
                    m_otherRigidBody = null;
                }

                m_otherEntity.OnClosing -= OtherEntity_OnClosing;
                m_otherEntity            = null;
            }

            m_constraintInitialized = false;

            RemoveOwnerVirtualPhysics();

            if (Owner != null)
            {
                Owner.ManipulatedEntity = null;
            }
            m_state = MyState.NONE;
        }
示例#3
0
        public void StartManipulation(MyState state, MyEntity otherEntity, Vector3D hitPosition, ref MatrixD ownerWorldHeadMatrix, bool fromServer = false)
        {
            Debug.Assert(m_constraintInitialized == false);

            // Commenting this out to allow picking up dead bodies and characters
            if (otherEntity is MyCharacter)
            {
                return;
            }

            if (Owner == null)
            {
                Debug.Assert(!fromServer, "Desync!");
                return;
            }

            if (otherEntity.Physics == null)
            {
                return;
            }

            m_otherRigidBody   = otherEntity.Physics.RigidBody;
            m_otherPhysicsBody = otherEntity.Physics;

            if (otherEntity is MyCharacter)
            {
                if (!(otherEntity as MyCharacter).IsDead || !((otherEntity as MyCharacter).Components.Has <MyCharacterRagdollComponent>() && (otherEntity as MyCharacter).Components.Get <MyCharacterRagdollComponent>().IsRagdollActivated))
                {
                    Debug.Assert(!fromServer, "Desync!");
                    return;
                }

                m_otherRigidBody = (otherEntity as MyCharacter).Physics.Ragdoll.GetRootRigidBody();
            }
            // else (!otherEntity.Physics.RigidBody.InWorld) // Do we need to check if the body is in the world when this was returned byt RayCast ? Commenting this out for now..

            var characterMovementState = Owner.GetCurrentMovementState();

            if (!CanManipulate(characterMovementState))
            {
                Debug.Assert(!fromServer, "Desync!");
                return;
            }

            if (!CanManipulateEntity(otherEntity))
            {
                Debug.Assert(!fromServer, "Desync!");
                return;
            }

            m_otherRigidBody.Activate();

            Vector3D hitUp = Vector3D.Up;
            Vector3D hitRight;
            double   dot = Vector3D.Dot(ownerWorldHeadMatrix.Forward, hitUp);

            if (dot == 1 || dot == -1)
            {
                hitRight = ownerWorldHeadMatrix.Right;
            }
            else
            {
                hitRight = Vector3D.Cross(ownerWorldHeadMatrix.Forward, hitUp);
                hitRight.Normalize();
            }

            Vector3D hitForward = Vector3D.Cross(hitUp, hitRight);

            hitForward.Normalize();

            // Matrix of constraint for other body in world
            MatrixD otherWorldMatrix = MatrixD.Identity;

            otherWorldMatrix.Forward     = hitForward;
            otherWorldMatrix.Right       = hitRight;
            otherWorldMatrix.Up          = hitUp;
            otherWorldMatrix.Translation = hitPosition;

            const float headPivotOffset = 1.5f;

            MatrixD headPivotWorldMatrix = ownerWorldHeadMatrix;

            headPivotWorldMatrix.Translation = ownerWorldHeadMatrix.Translation + headPivotOffset * ownerWorldHeadMatrix.Forward;
            //float distanceToHead = (float)(headPivotWorldMatrix.Translation - otherWorldMatrix.Translation).Length();
            //distanceToHead = MathHelper.Clamp(distanceToHead, 0.6f, 2.5f);

            // Matrix of constraint for other body in local
            m_otherLocalPivotMatrix = (Matrix)(otherWorldMatrix * otherEntity.PositionComp.WorldMatrixNormalizedInv);
            m_otherWorldPivotOrigin = otherWorldMatrix.Translation;

            MatrixD ownerWorldMatrixInverse = MatrixD.Normalize(MatrixD.Invert(ownerWorldHeadMatrix));

            m_headLocalPivotMatrix             = Matrix.Identity;
            m_headLocalPivotMatrix.Translation = Vector3D.Transform(headPivotWorldMatrix.Translation, ownerWorldMatrixInverse);

            HkConstraintData data;

            if (state == MyState.HOLD)
            {
                if (!fromServer)
                {
                    float mass = 0;
                    if (otherEntity is MyCubeGrid)
                    {
                        var group = MyCubeGridGroups.Static.Physical.GetGroup((otherEntity as MyCubeGrid));
                        foreach (var node in group.Nodes)
                        {
                            if (node.NodeData.IsStatic) //fixed constraint on part connected to static grid isnt good idea
                            {
                                return;
                            }
                            mass += node.NodeData.Physics.Mass;
                        }
                        mass = GetRealMass(mass);
                    }
                    else if (otherEntity is MyCharacter)
                    {
                        mass = (otherEntity as MyCharacter).Definition.Mass;
                    }
                    else
                    {
                        mass = GetRealMass(m_otherRigidBody.Mass);
                    }

                    // Player can hold large projectile (~222kg)
                    if ((mass > 210) || ((otherEntity is MyCharacter) && (otherEntity.Physics.Mass > 210)))
                    {
                        return;
                    }
                }

                if (!CreateOwnerVirtualPhysics())
                {
                    return;
                }

                if (IsOwnerLocalPlayer())
                {
                    var controllingPlayer = Sync.Players.GetControllingPlayer(otherEntity);
                    if (controllingPlayer != null)
                    {
                        RemoveOwnerVirtualPhysics();
                        return;
                    }

                    if (!(otherEntity is MyCharacter)) // this would cause to start controlling the dead body..
                    {
                        Sync.Players.TrySetControlledEntity(Owner.ControllerInfo.Controller.Player.Id, otherEntity);
                    }
                }

                SetMotionOnClient(otherEntity, HkMotionType.Dynamic);

                data = CreateFixedConstraintData(ref m_otherLocalPivotMatrix, headPivotOffset);
                if (otherEntity is MyCharacter)
                {
                    if (MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT)
                    {
                        HkMalleableConstraintData mcData = data as HkMalleableConstraintData;
                        mcData.Strength = 0.005f;
                    }
                    else
                    {
                        HkFixedConstraintData fcData = data as HkFixedConstraintData;
                        fcData.MaximumAngularImpulse = 0.0005f;
                        fcData.MaximumLinearImpulse  = 0.0005f;
                        fcData.BreachImpulse         = 0.0004f;
                    }
                }
            }
            else
            {
                if (!CreateOwnerVirtualPhysics())
                {
                    return;
                }

                data = CreateBallAndSocketConstraintData(ref m_otherLocalPivotMatrix, ref m_headLocalPivotMatrix);
                if (otherEntity is MyCharacter)
                {
                    HkMalleableConstraintData mcData = data as HkMalleableConstraintData;
                    mcData.Strength = 0.005f;
                }
            }

            m_otherEntity            = otherEntity;
            m_otherEntity.OnClosing += OtherEntity_OnClosing;

            //m_otherAngularDamping = m_otherRigidBody.AngularDamping;
            //m_otherLinearDamping = m_otherRigidBody.LinearDamping;
            m_otherRestitution        = m_otherRigidBody.Restitution;
            m_otherMaxLinearVelocity  = m_otherRigidBody.MaxLinearVelocity;
            m_otherMaxAngularVelocity = m_otherRigidBody.MaxAngularVelocity;

            SetManipulated(m_otherEntity, true);
            if (state == MyState.HOLD)
            {
                if (m_otherEntity is MyCharacter)
                {
                    foreach (var body in m_otherEntity.Physics.Ragdoll.RigidBodies)
                    {
                        //body.AngularDamping = TARGET_ANGULAR_DAMPING;
                        //body.LinearDamping = TARGET_LINEAR_DAMPING;
                        //body.Mass = 5;
                        body.Restitution        = TARGET_RESTITUTION;
                        body.MaxLinearVelocity  = m_limitingLinearVelocity;
                        body.MaxAngularVelocity = (float)Math.PI * 0.1f;
                    }
                }
                else
                {
                    m_massChange = HkMassChangerUtil.Create(m_otherRigidBody, int.MaxValue, 1, 0.001f);
                    //m_otherRigidBody.AngularDamping = TARGET_ANGULAR_DAMPING;
                    //m_otherRigidBody.LinearDamping = TARGET_LINEAR_DAMPING;
                    m_otherRigidBody.Restitution        = TARGET_RESTITUTION;
                    m_otherRigidBody.MaxLinearVelocity  = m_limitingLinearVelocity;
                    m_otherRigidBody.MaxAngularVelocity = (float)Math.PI;
                }

                const float holdingTransparency = 0.4f;
                SetTransparent(otherEntity, holdingTransparency);
            }

            m_constraint = new HkConstraint(m_otherRigidBody, OwnerVirtualPhysics.RigidBody, data);

            OwnerVirtualPhysics.AddConstraint(m_constraint);

            m_constraintCreationTime = MySandboxGame.Static.UpdateTime;

            m_state = state;

            m_previousCharacterMovementState = Owner.GetCurrentMovementState();

            if (m_state == MyState.HOLD)
            {
                Owner.PlayCharacterAnimation("PickLumber", MyBlendOption.Immediate, MyFrameOption.PlayOnce, 0.2f, 1f);
            }
            else
            {
                Owner.PlayCharacterAnimation("PullLumber", MyBlendOption.Immediate, MyFrameOption.PlayOnce, 0.2f, 1f);
            }

            m_manipulatedEntitites.Add(m_otherEntity);

            Owner.ManipulatedEntity = m_otherEntity;

            var handler = ManipulationStarted;

            if (handler != null)
            {
                handler(m_otherEntity);
            }
        }
示例#4
0
        public void StopManipulation()
        {
            if (m_state != MyState.NONE && Owner != null)
            {
                var characterMovementState = Owner.GetCurrentMovementState();
                switch (characterMovementState)
                {
                case MyCharacterMovementEnum.Walking:
                case MyCharacterMovementEnum.BackWalking:
                case MyCharacterMovementEnum.WalkingLeftFront:
                case MyCharacterMovementEnum.WalkingRightFront:
                case MyCharacterMovementEnum.WalkingLeftBack:
                case MyCharacterMovementEnum.WalkingRightBack:
                case MyCharacterMovementEnum.WalkStrafingLeft:
                case MyCharacterMovementEnum.WalkStrafingRight:
                case MyCharacterMovementEnum.Running:
                case MyCharacterMovementEnum.Backrunning:
                case MyCharacterMovementEnum.RunStrafingLeft:
                case MyCharacterMovementEnum.RunStrafingRight:
                case MyCharacterMovementEnum.RunningRightFront:
                case MyCharacterMovementEnum.RunningRightBack:
                case MyCharacterMovementEnum.RunningLeftFront:
                case MyCharacterMovementEnum.RunningLeftBack:
                    Owner.PlayCharacterAnimation("WalkBack", true, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f);
                    break;

                case MyCharacterMovementEnum.Standing:
                case MyCharacterMovementEnum.RotatingLeft:
                case MyCharacterMovementEnum.RotatingRight:
                case MyCharacterMovementEnum.Flying:
                    Owner.PlayCharacterAnimation("Idle", true, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f);
                    break;
                }
            }


            if (m_constraint != null)
            {
                if (Owner != null && Owner.VirtualPhysics != null)
                {
                    Owner.VirtualPhysics.RemoveConstraint(m_constraint);
                }

                m_constraint.Dispose();
                m_constraint = null;
            }

            if (m_fixedConstraintData != null)
            {
                if (!m_fixedConstraintData.IsDisposed)
                {
                    m_fixedConstraintData.Dispose();
                }

                m_fixedConstraintData = null;
            }

            m_headLocalPivotMatrix  = Matrix.Zero;
            m_otherLocalPivotMatrix = Matrix.Zero;
            if (m_otherEntity != null)
            {
                SetTransparent(m_otherEntity);
                SetTransparent(m_otherEntity);

                if (m_state == MyState.HOLD)
                {
                    SetMotionOnClient(m_otherEntity, HkMotionType.Keyframed);
                }

                m_manipulatedEntitites.Remove(m_otherEntity);

                m_otherEntity.SyncFlag = true;

                if (m_otherEntity.Physics != null && m_otherRigidBody != null && !m_otherRigidBody.IsDisposed)
                {
                    SetManipulated(m_otherEntity, false);
                    //m_otherRigidBody.AngularDamping = m_otherAngularDamping;
                    //m_otherRigidBody.LinearDamping = m_otherLinearDamping;
                    m_otherRigidBody.Restitution        = m_otherRestitution;
                    m_otherRigidBody.MaxLinearVelocity  = m_otherMaxLinearVelocity;
                    m_otherRigidBody.MaxAngularVelocity = m_otherMaxAngularVelocity;
                    if (m_massChange != null)
                    {
                        m_massChange.Remove();
                    }
                    m_massChange = null;
                    // Clamp output velocity
                    m_otherRigidBody.LinearVelocity  = Vector3.Clamp(m_otherRigidBody.LinearVelocity, -2 * Vector3.One, 2 * Vector3.One);
                    m_otherRigidBody.AngularVelocity = Vector3.Clamp(m_otherRigidBody.AngularVelocity, -Vector3.One * (float)Math.PI, Vector3.One * (float)Math.PI);
                    if (!m_otherRigidBody.IsActive)
                    {
                        m_otherRigidBody.Activate();
                    }
                    m_otherRigidBody.EnableDeactivation = false;
                    m_otherRigidBody.EnableDeactivation = true; //resets deactivation counter
                    m_otherRigidBody = null;
                }

                m_otherEntity.OnClosing -= OtherEntity_OnClosing;
                m_otherEntity            = null;
            }

            m_constraintInitialized = false;

            if (Owner != null)
            {
                Owner.ManipulatedEntity = null;
            }
            m_state = MyState.NONE;
        }
示例#5
0
        private void InitInternal()
        {
            MyPhysicalItemDefinition physicalItemDefinition = MyDefinitionManager.Static.GetPhysicalItemDefinition(this.Item.Content);

            this.m_health      = physicalItemDefinition.Health;
            this.VoxelMaterial = null;
            if (physicalItemDefinition.VoxelMaterial != MyStringHash.NullOrEmpty)
            {
                this.VoxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(physicalItemDefinition.VoxelMaterial.String);
            }
            else if (this.Item.Content is MyObjectBuilder_Ore)
            {
                string subtypeName  = physicalItemDefinition.Id.SubtypeName;
                string materialName = (this.Item.Content as MyObjectBuilder_Ore).GetMaterialName();
                bool   flag         = (this.Item.Content as MyObjectBuilder_Ore).HasMaterialName();
                foreach (MyVoxelMaterialDefinition definition2 in MyDefinitionManager.Static.GetVoxelMaterialDefinitions())
                {
                    if ((flag && (materialName == definition2.Id.SubtypeName)) || (!flag && (subtypeName == definition2.MinedOre)))
                    {
                        this.VoxelMaterial = definition2;
                        break;
                    }
                }
            }
            if ((this.VoxelMaterial != null) && (this.VoxelMaterial.DamagedMaterial != MyStringHash.NullOrEmpty))
            {
                this.VoxelMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(this.VoxelMaterial.DamagedMaterial.ToString());
            }
            string model = physicalItemDefinition.Model;

            if (physicalItemDefinition.HasModelVariants)
            {
                int length = physicalItemDefinition.Models.Length;
                this.m_modelVariant = this.m_modelVariant % length;
                model = physicalItemDefinition.Models[this.m_modelVariant];
            }
            else if ((this.Item.Content is MyObjectBuilder_Ore) && (this.VoxelMaterial != null))
            {
                float num5 = 50f;
                model = MyDebris.GetAmountBasedDebrisVoxel(Math.Max((float)this.Item.Amount, num5));
            }
            float scale = 0.7f;

            this.FormatDisplayName(this.m_displayedText, this.Item);
            float?nullable = null;

            this.Init(this.m_displayedText, model, null, nullable, null);
            HkMassProperties massProperties = new HkMassProperties();
            float            mass           = MathHelper.Clamp((float)((MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(physicalItemDefinition.Mass) : physicalItemDefinition.Mass) * ((float)this.Item.Amount)), (float)3f, (float)100000f);
            HkShape          shape          = this.GetPhysicsShape(mass, scale, out massProperties);

            massProperties.Mass = mass;
            Matrix identity = Matrix.Identity;

            if (this.Physics != null)
            {
                this.Physics.Close();
            }
            this.Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);
            int collisionFilter = (mass > MyPerGameSettings.MinimumLargeShipCollidableMass) ? 0x17 : 10;

            this.Physics.LinearDamping  = 0.1f;
            this.Physics.AngularDamping = 2f;
            if (!shape.IsConvex || (shape.ShapeType == HkShapeType.Sphere))
            {
                this.Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, new HkMassProperties?(massProperties), collisionFilter);
                this.Physics.Enabled = true;
            }
            else
            {
                HkConvexTransformShape shape2 = new HkConvexTransformShape((HkConvexShape)shape, ref identity, HkReferencePolicy.None);
                this.Physics.CreateFromCollisionObject((HkShape)shape2, Vector3.Zero, MatrixD.Identity, new HkMassProperties?(massProperties), collisionFilter);
                this.Physics.Enabled = true;
                shape2.Base.RemoveReference();
            }
            this.Physics.Friction                = 2f;
            this.Physics.MaterialType            = this.EvaluatePhysicsMaterial(physicalItemDefinition.PhysicalMaterial);
            this.Physics.PlayCollisionCueEnabled = true;
            this.Physics.RigidBody.ContactSoundCallbackEnabled = true;
            base.NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
            this.Physics.RigidBody.SetProperty(HkCharacterRigidBody.FLOATING_OBJECT, 0f);
            this.Physics.RigidBody.CenterOfMassLocal = Vector3.Zero;
            HkMassChangerUtil.Create(this.Physics.RigidBody, 0x10200, 1f, 0f);
        }
示例#6
0
        public void StartManipulation(MyState state, MyEntity otherEntity, Vector3D hitPosition, ref MatrixD ownerWorldHeadMatrix)
        {
            Debug.Assert(m_constraintInitialized == false);

            // Commenting this out to allow picking up dead bodies and characters
            //if (otherEntity is MyCharacter)
            //    return;

            if (Owner == null || Owner.VirtualPhysics == null || !Owner.VirtualPhysics.RigidBody.InWorld)
            {
                return;
            }

            var ownerRigidBody = Owner.VirtualPhysics.RigidBody;

            if (otherEntity.Physics == null)
            {
                return;
            }

            m_otherRigidBody = otherEntity.Physics.RigidBody;

            if (otherEntity is MyCharacter)
            {
                if (!(otherEntity as MyCharacter).IsDead || !(otherEntity as MyCharacter).IsRagdollActivated)
                {
                    return;
                }

                m_otherRigidBody = (otherEntity as MyCharacter).Physics.Ragdoll.GetRootRigidBody();
            }
            // else (!otherEntity.Physics.RigidBody.InWorld) // Do we need to check if the body is in the world when this was returned byt RayCast ? Commenting this out for now..

            var characterMovementState = Owner.GetCurrentMovementState();

            if (!CanManipulate(characterMovementState))
            {
                return;
            }

            if (!CanManipulateEntity(otherEntity))
            {
                return;
            }

            // PetrM:TODO: Make all client grids dynamic.
            if (!(otherEntity is MyCharacter && (otherEntity as MyCharacter).IsRagdollActivated) && state == MyState.HOLD)  // In case of picking up a ragdoll don't turn off and on the physics
            {
                otherEntity.Physics.Enabled = false;
                otherEntity.SyncFlag        = false;
                m_otherRigidBody.UpdateMotionType(HkMotionType.Dynamic);
                otherEntity.Physics.Enabled = true;

                // HACK: This is here only because disabling and enabling physics puts constraints into inconsistent state.
                otherEntity.RaisePhysicsChanged();
            }

            Owner.VirtualPhysics.RigidBody.Activate();
            m_otherRigidBody.Activate();

            Vector3D hitUp = Vector3D.Up;
            Vector3D hitRight;
            double   dot = Vector3D.Dot(ownerWorldHeadMatrix.Forward, hitUp);

            if (dot == 1 || dot == -1)
            {
                hitRight = ownerWorldHeadMatrix.Right;
            }
            else
            {
                hitRight = Vector3D.Cross(ownerWorldHeadMatrix.Forward, hitUp);
                hitRight.Normalize();
            }

            Vector3D hitForward = Vector3D.Cross(hitUp, hitRight);

            hitForward.Normalize();

            // Matrix of constraint for other body in world
            MatrixD otherWorldMatrix = MatrixD.Identity;

            otherWorldMatrix.Forward     = hitForward;
            otherWorldMatrix.Right       = hitRight;
            otherWorldMatrix.Up          = hitUp;
            otherWorldMatrix.Translation = hitPosition;

            const float headPivotOffset = 1.5f;

            MatrixD headPivotWorldMatrix = ownerWorldHeadMatrix;

            headPivotWorldMatrix.Translation = ownerWorldHeadMatrix.Translation + headPivotOffset * ownerWorldHeadMatrix.Forward;
            //float distanceToHead = (float)(headPivotWorldMatrix.Translation - otherWorldMatrix.Translation).Length();
            //distanceToHead = MathHelper.Clamp(distanceToHead, 0.6f, 2.5f);

            // Matrix of constraint for other body in local
            m_otherLocalPivotMatrix = (Matrix)(otherWorldMatrix * otherEntity.PositionComp.WorldMatrixNormalizedInv);
            m_otherWorldPivotOrigin = otherWorldMatrix.Translation;

            MatrixD ownerWorldMatrixInverse = MatrixD.Normalize(MatrixD.Invert(ownerWorldHeadMatrix));

            m_headLocalPivotMatrix             = Matrix.Identity;
            m_headLocalPivotMatrix.Translation = Vector3D.Transform(headPivotWorldMatrix.Translation, ownerWorldMatrixInverse);

            HkConstraintData data;

            if (state == MyState.HOLD)
            {
                float mass = 0;
                if (otherEntity is MyCubeGrid)
                {
                    var group = MyCubeGridGroups.Static.Physical.GetGroup((otherEntity as MyCubeGrid));
                    foreach (var node in group.Nodes)
                    {
                        mass += node.NodeData.Physics.Mass;
                    }
                    mass = GetRealMass(mass);
                }
                else
                {
                    mass = GetRealMass(otherEntity.Physics.Mass);
                }

                // Player can hold large projectile (~222kg)
                if ((mass <= 210) || ((otherEntity is MyCharacter) && (otherEntity.Physics.Mass < 210)))
                {
                    data = CreateFixedConstraintData(ref m_otherLocalPivotMatrix, headPivotOffset);
                }
                else
                {
                    return;
                }

                if (otherEntity is MyCharacter)
                {
                    if (MyFakes.MANIPULATION_TOOL_VELOCITY_LIMIT)
                    {
                        HkMalleableConstraintData mcData = data as HkMalleableConstraintData;
                        mcData.Strength = 0.005f;
                    }
                    else
                    {
                        HkFixedConstraintData fcData = data as HkFixedConstraintData;
                        fcData.MaximumAngularImpulse = 2.0f;
                        fcData.MaximumLinearImpulse  = 2.0f;
                    }
                }
            }
            else
            {
                data = CreateBallAndSocketConstraintData(ref m_otherLocalPivotMatrix, ref m_headLocalPivotMatrix);
                if (otherEntity is MyCharacter)
                {
                    HkMalleableConstraintData mcData = data as HkMalleableConstraintData;
                    mcData.Strength = 0.005f;
                }
            }


            m_otherEntity            = otherEntity;
            m_otherEntity.OnClosing += OtherEntity_OnClosing;

            //m_otherAngularDamping = m_otherRigidBody.AngularDamping;
            //m_otherLinearDamping = m_otherRigidBody.LinearDamping;
            m_otherRestitution        = m_otherRigidBody.Restitution;
            m_otherMaxLinearVelocity  = m_otherRigidBody.MaxLinearVelocity;
            m_otherMaxAngularVelocity = m_otherRigidBody.MaxAngularVelocity;

            SetManipulated(m_otherEntity, true);
            if (state == MyState.HOLD)
            {
                m_massChange = HkMassChangerUtil.Create(m_otherRigidBody, int.MaxValue, 1, 0.001f);
                //m_otherRigidBody.AngularDamping = TARGET_ANGULAR_DAMPING;
                //m_otherRigidBody.LinearDamping = TARGET_LINEAR_DAMPING;
                m_otherRigidBody.Restitution        = TARGET_RESTITUTION;
                m_otherRigidBody.MaxLinearVelocity  = m_limitingLinearVelocity;
                m_otherRigidBody.MaxAngularVelocity = (float)Math.PI;
                if (m_otherEntity is MyCharacter)
                {
                    foreach (var body in m_otherEntity.Physics.Ragdoll.RigidBodies)
                    {
                        //body.AngularDamping = TARGET_ANGULAR_DAMPING;
                        //body.LinearDamping = TARGET_LINEAR_DAMPING;
                        body.Restitution        = TARGET_RESTITUTION;
                        body.MaxLinearVelocity  = m_limitingLinearVelocity;
                        body.MaxAngularVelocity = (float)Math.PI;
                    }
                }

                const float holdingTransparency = 0.4f;
                SetTransparent(otherEntity, holdingTransparency); //TODO jt: why it must be called twice?
                SetTransparent(otherEntity, holdingTransparency);
            }

            m_constraint = new HkConstraint(m_otherRigidBody, Owner.VirtualPhysics.RigidBody, data);

            Owner.VirtualPhysics.AddConstraint(m_constraint);

            m_constraintCreationTime = MySandboxGame.Static.UpdateTime;

            m_state = state;

            m_previousCharacterMovementState = Owner.GetCurrentMovementState();

            if (m_state == MyState.HOLD)
            {
                Owner.PlayCharacterAnimation("PickLumber", false, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f);
            }
            else
            {
                Owner.PlayCharacterAnimation("PullLumber", false, MyPlayAnimationMode.Immediate | MyPlayAnimationMode.Play, 0.2f, 1f);
            }

            m_manipulatedEntitites.Add(m_otherEntity);

            Owner.ManipulatedEntity = m_otherEntity;
        }