Esempio n. 1
0
        private void CreateSubpartsConstraint(MyEntitySubpart subpart)
        {
            m_subpartsFixedData = new HkFixedConstraintData();
            m_subpartsFixedData.SetSolvingMethod(HkSolvingMethod.MethodStabilized);
            m_subpartsFixedData.SetInertiaStabilizationFactor(1);
            var matAD = MatrixD.CreateWorld(Position * CubeGrid.GridSize + Vector3D.Transform(Vector3D.Transform(m_subpartsConstraintPos, WorldMatrix), CubeGrid.PositionComp.LocalMatrix), PositionComp.LocalMatrix.Forward, PositionComp.LocalMatrix.Up);

            matAD.Translation = CubeGrid.Physics.WorldToCluster(matAD.Translation);
            var matA = (Matrix)matAD;
            var matB = subpart.PositionComp.LocalMatrix;

            m_subpartsFixedData.SetInWorldSpace(ref matA, ref matB, ref matB);
            //Dont dispose the fixed data or we wont have access to them

            HkConstraintData constraintData = m_subpartsFixedData;

            m_subpartsConstraint = new HkConstraint(CubeGrid.Physics.RigidBody, m_subpartPhysics.RigidBody, constraintData);
            var info = CubeGrid.Physics.RigidBody.GetCollisionFilterInfo();

            info = HkGroupFilter.CalcFilterInfo(CubeGrid.Physics.RigidBody.Layer, HkGroupFilter.GetSystemGroupFromFilterInfo(info), 1, 1);
            m_subpartPhysics.RigidBody.SetCollisionFilterInfo(info);
            CubeGrid.Physics.HavokWorld.RefreshCollisionFilterOnEntity(m_subpartPhysics.RigidBody);
            Debug.Assert(m_subpartsConstraint.RigidBodyA != null);
            m_subpartsConstraint.WantRuntime = true;
        }
Esempio n. 2
0
        private void InitSubpartsPhysics()
        {
            var subpart = m_subpart1;

            if (subpart == null || CubeGrid.Physics == null)
            {
                return;
            }
            m_subpartPhysics = new MyPhysicsBody(this, CubeGrid.IsStatic ? RigidBodyFlag.RBF_STATIC : (CubeGrid.GridSizeEnum == MyCubeSize.Large ? RigidBodyFlag.RBF_DOUBLED_KINEMATIC : RigidBodyFlag.RBF_DEFAULT));
            const float     threshold = 0.11f; // Must be bigger than 2x convex radius
            HkCylinderShape shape     = new HkCylinderShape(new Vector3(0, -2, 0), new Vector3(0, 2, 0), CubeGrid.GridSize / 2 - threshold, 0.05f);
            var             mass      = HkInertiaTensorComputer.ComputeCylinderVolumeMassProperties(new Vector3(0, -2, 0), new Vector3(0, 2, 0), CubeGrid.GridSize / 2, 40.0f * CubeGrid.GridSize);

            mass.Mass = BlockDefinition.Mass;
            m_subpartPhysics.CreateFromCollisionObject(shape, Vector3.Zero, subpart.WorldMatrix, mass);
            var info = HkGroupFilter.CalcFilterInfo(CubeGrid.Physics.RigidBody.Layer, CubeGrid.Physics.HavokCollisionSystemID, 1, 1);

            m_subpartPhysics.RigidBody.SetCollisionFilterInfo(info);
            shape.Base.RemoveReference();
            if (m_subpartPhysics.RigidBody2 != null)
            {
                m_subpartPhysics.RigidBody2.Layer = MyPhysics.CollisionLayers.KinematicDoubledCollisionLayer;
            }
            CubeGrid.OnHavokSystemIDChanged += CubeGrid_OnHavokSystemIDChanged;
            CreateSubpartsConstraint(subpart);

            m_posChanged = true;
        }
Esempio n. 3
0
 protected void CreateSubpartConstraint(VRage.Game.Entity.MyEntity subpart, out HkFixedConstraintData constraintData, out HkConstraint constraint)
 {
     constraintData = null;
     constraint     = null;
     if (base.CubeGrid.Physics != null)
     {
         HkRigidBody rigidBody;
         uint        info = HkGroupFilter.CalcFilterInfo(subpart.GetPhysicsBody().RigidBody.Layer, base.CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1);
         subpart.Physics.RigidBody.SetCollisionFilterInfo(info);
         subpart.Physics.Enabled = true;
         constraintData          = new HkFixedConstraintData();
         constraintData.SetSolvingMethod(HkSolvingMethod.MethodStabilized);
         constraintData.SetInertiaStabilizationFactor(1f);
         if ((base.CubeGrid.Physics.RigidBody2 == null) || !base.CubeGrid.Physics.Flags.HasFlag(RigidBodyFlag.RBF_DOUBLED_KINEMATIC))
         {
             rigidBody = base.CubeGrid.Physics.RigidBody;
         }
         else
         {
             rigidBody = base.CubeGrid.Physics.RigidBody2;
         }
         constraint             = new HkConstraint(rigidBody, subpart.Physics.RigidBody, constraintData);
         constraint.WantRuntime = true;
     }
 }
Esempio n. 4
0
        internal void UpdateHavokCollisionSystemID(int HavokCollisionSystemID)
        {
            foreach (var subpart in m_subparts)
            {
                if (subpart != null && subpart.Physics != null)
                {
                    if ((subpart.ModelCollision.HavokCollisionShapes != null) && (subpart.ModelCollision.HavokCollisionShapes.Length > 0))
                    {
                        var info = HkGroupFilter.CalcFilterInfo(MyPhysics.CollisionLayers.KinematicDoubledCollisionLayer, HavokCollisionSystemID, 1, 1);
                        subpart.Physics.RigidBody.SetCollisionFilterInfo(info);
                        if (subpart.GetPhysicsBody().HavokWorld != null)
                        {
                            subpart.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(subpart.Physics.RigidBody);
                        }
                        if (subpart.Physics.RigidBody2 != null)
                        {
                            info = HkGroupFilter.CalcFilterInfo(MyPhysics.CollisionLayers.DynamicDoubledCollisionLayer, HavokCollisionSystemID, 1, 1);
                            subpart.Physics.RigidBody2.SetCollisionFilterInfo(info);
                            if (subpart.GetPhysicsBody().HavokWorld != null)
                            {
                                subpart.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(subpart.Physics.RigidBody2);
                            }
                        }

                        /*if (this.CubeGrid.Physics != null && this.CubeGrid.GetPhysicsBody().HavokWorld != null)
                         * {
                         *  this.CubeGrid.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(m_subpartDoor1.Physics.RigidBody);
                         *  this.CubeGrid.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(m_subpartDoor1.Physics.RigidBody2);
                         * }*/
                    }
                }
            }
        }
Esempio n. 5
0
 void CubeGrid_OnHavokSystemIDChanged(int sysId)
 {
     if (CubeGrid.Physics != null && CubeGrid.Physics.RigidBody != null && m_subpartPhysics != null && m_subpartPhysics.RigidBody != null)
     {
         var info = HkGroupFilter.CalcFilterInfo(CubeGrid.Physics.RigidBody.Layer, sysId, 1, 1);
         m_subpartPhysics.RigidBody.SetCollisionFilterInfo(info);
     }
 }
Esempio n. 6
0
        protected override bool CreateConstraint(MyAttachableTopBlockBase rotor)
        {
            if (!base.CreateConstraint(rotor))
            {
                return(false);
            }
            var rotorBody = TopGrid.Physics.RigidBody;

            rotorBody.MaxAngularVelocity = float.MaxValue;
            rotorBody.Restitution        = 0.5f;
            CubeGrid.GetPhysicsBody().HavokWorld.BreakOffPartsUtil.UnmarkEntityBreakable(rotorBody);
            if (MyFakes.WHEEL_SOFTNESS)
            {
                HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio,
                                       MyPhysicsConfig.WheelSoftnessVelocity);
            }
            var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer,
                                                    CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1);

            rotorBody.SetCollisionFilterInfo(info);
            CubeGrid.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(rotorBody);
            HkWheelConstraintData data = new HkWheelConstraintData();
            var suspensionAx           = PositionComp.LocalMatrix.Forward;
            var posA      = DummyPosition + (suspensionAx * m_height);
            var posB      = (rotor as MyMotorRotor).DummyPosLoc;
            var axisA     = PositionComp.LocalMatrix.Up;
            var axisAPerp = PositionComp.LocalMatrix.Forward;
            var axisB     = rotor.PositionComp.LocalMatrix.Up;

            data.SetInBodySpace(posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics,
                                CubeGrid.Physics);
            //empirical values because who knows what havoc sees behind this
            //docs say one value should mean same effect for 2 ton or 200 ton vehicle
            //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity
            data.SetSuspensionDamping(m_damping);
            data.SetSuspensionStrength(m_strenth);
            //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit
            data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel);
            data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel);
            m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data);

            m_constraint.WantRuntime = true;
            CubeGrid.Physics.AddConstraint(m_constraint);
            if (!m_constraint.InWorld)
            {
                Debug.Fail("Constraint not added!");
                CubeGrid.Physics.RemoveConstraint(m_constraint);
                m_constraint = null;
                return(false);
            }
            m_constraint.Enabled = true;
            return(true);
        }
Esempio n. 7
0
 protected static void SetupDoorSubpart(MyEntitySubpart subpart, int havokCollisionSystemID, bool refreshInPlace)
 {
     if (((subpart != null) && ((subpart.Physics != null) && (subpart.ModelCollision.HavokCollisionShapes != null))) && (subpart.ModelCollision.HavokCollisionShapes.Length != 0))
     {
         uint info = HkGroupFilter.CalcFilterInfo(subpart.GetPhysicsBody().RigidBody.Layer, havokCollisionSystemID, 1, 1);
         subpart.Physics.RigidBody.SetCollisionFilterInfo(info);
         if ((subpart.GetPhysicsBody().HavokWorld != null) & refreshInPlace)
         {
             subpart.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(subpart.Physics.RigidBody);
         }
     }
 }
Esempio n. 8
0
        void CubeGrid_OnPhysicsChanged(MyEntity obj)
        {
            if (CubeGrid.Physics == null || m_topGrid == null || m_topGrid.Physics == null)
            {
                return;
            }
            var rotorBody = m_topGrid.Physics.RigidBody;

            if (rotorBody == null)
            {
                return;
            }
            var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1);

            rotorBody.SetCollisionFilterInfo(info);
        }
Esempio n. 9
0
        internal void UpdateHavokCollisionSystemID(int HavokCollisionSystemID)
        {
            foreach (var subpart in m_subparts)
            {
                if (subpart != null && subpart.Physics != null)
                {
                    if ((subpart.ModelCollision.HavokCollisionShapes != null) && (subpart.ModelCollision.HavokCollisionShapes.Length > 0))
                    {
                        var info = HkGroupFilter.CalcFilterInfo(MyPhysics.KinematicDoubledCollisionLayer, HavokCollisionSystemID, 1, 1);
                        subpart.Physics.RigidBody.SetCollisionFilterInfo(info);

                        info = HkGroupFilter.CalcFilterInfo(MyPhysics.DynamicDoubledCollisionLayer, HavokCollisionSystemID, 1, 1);
                        subpart.Physics.RigidBody2.SetCollisionFilterInfo(info);
                    }
                }
            }
        }
Esempio n. 10
0
 internal void UpdateHavokCollisionSystemID(int HavokCollisionSystemID)
 {
     foreach (MyEntitySubpart subpart in this.m_subparts)
     {
         if (subpart == null)
         {
             continue;
         }
         if ((subpart.Physics != null) && ((subpart.ModelCollision.HavokCollisionShapes != null) && (subpart.ModelCollision.HavokCollisionShapes.Length != 0)))
         {
             uint info = HkGroupFilter.CalcFilterInfo(15, HavokCollisionSystemID, 1, 1);
             subpart.Physics.RigidBody.SetCollisionFilterInfo(info);
             if (subpart.GetPhysicsBody().HavokWorld != null)
             {
                 subpart.GetPhysicsBody().HavokWorld.RefreshCollisionFilterOnEntity(subpart.Physics.RigidBody);
             }
         }
     }
 }
 internal void DisableRagdollBodiesCollisions()
 {
     Debug.Assert(Ragdoll != null, "Ragdoll is null!");
     if (MyFakes.ENABLE_RAGDOLL_DEBUG)
     {
         var world = HavokWorld;
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.StaticCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.VoxelCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.DefaultCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CharacterCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CharacterNetworkCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.DynamicDoubledCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.KinematicDoubledCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.DebrisCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.LightFloatingObjectCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.GravityPhantomLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.VirtualMassLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.NoCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.ExplosionRaycastLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CollisionLayerWithoutCharacter), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CollideWithStaticLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CollectorCollisionLayer), "Collision isn't disabled!");
         Debug.Assert(!world.IsCollisionEnabled(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.AmmoLayer), "Collision isn't disabled!");
     }
     if (Ragdoll != null)
     {
         foreach (var body in Ragdoll.RigidBodies)
         {
             var info = HkGroupFilter.CalcFilterInfo(MyPhysics.CollisionLayers.RagdollCollisionLayer, 0, 0, 0);
             //HavokWorld.DisableCollisionsBetween(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.RagdollCollisionLayer);
             //HavokWorld.DisableCollisionsBetween(MyPhysics.CollisionLayers.RagdollCollisionLayer, MyPhysics.CollisionLayers.CharacterCollisionLayer);
             body.SetCollisionFilterInfo(info);
             body.LinearVelocity  = Vector3.Zero;// Character.Physics.LinearVelocity;
             body.AngularVelocity = Vector3.Zero;
             HavokWorld.RefreshCollisionFilterOnEntity(body);
             Debug.Assert(body.InWorld, "Body isn't in world!");
             Debug.Assert(MyPhysics.CollisionLayers.RagdollCollisionLayer == HkGroupFilter.GetLayerFromFilterInfo(body.GetCollisionFilterInfo()), "Body is in wrong layer!");
         }
     }
 }
        /// <summary>
        /// Handles camera collisions with environment
        /// </summary>
        /// <param name="controlledEntity"></param>
        /// <param name="shakeActive"></param>
        /// <param name="headPosition"></param>
        /// <param name="headDirection"></param>
        /// <returns>False if no correct position was found</returns>
        private bool HandleIntersection(MyEntity controlledEntity, MyOrientedBoundingBoxD safeOBB, bool requireRaycast, bool shakeActive, Vector3D headPosition, Vector3 headDirection)
        {
            var line = new LineD(m_target, m_position);

            var      safeOBBLine = new LineD(line.From, line.From + line.Direction * 2 * safeOBB.HalfExtent.Length());
            Vector3D castStartSafe;

            {
                MyOrientedBoundingBoxD safeObbWithCollisionExtents = new MyOrientedBoundingBoxD(safeOBB.Center, safeOBB.HalfExtent + 2 * CAMERA_RADIUS, safeOBB.Orientation);
                double?safeIntersection = safeObbWithCollisionExtents.Intersects(ref safeOBBLine);
                if (!safeIntersection.HasValue)
                {
                    safeIntersection = safeOBB.HalfExtent.Length();
                }
                double safeDistance = safeIntersection.Value;
                castStartSafe = line.From + line.Direction * safeDistance;
            }

            {
                double?unsafeIntersection = safeOBB.Intersects(ref safeOBBLine);
                if (!requireRaycast && unsafeIntersection.HasValue)
                {
                    var castStartUnsafe = line.From + line.Direction * unsafeIntersection.Value;
                    var castEndUnsafe   = castStartSafe + line.Direction;
                    // short raycast, not causing problems with asteroids generating geometry
                    Physics.MyPhysics.CastRay(castStartUnsafe, castEndUnsafe, m_raycastList, MyPhysics.DefaultCollisionLayer);
                    if (!IsRaycastOK(m_raycastList))
                    {
                        return(false);
                    }
                }
            }

            if (requireRaycast)
            {
                // short raycast, not causing problems with asteroids generating geometry
                Physics.MyPhysics.CastRay(line.From, castStartSafe + line.Direction, m_raycastList, MyPhysics.DefaultCollisionLayer);
                if (!IsRaycastOK(m_raycastList))
                {
                    return(false);
                }
            }

            HkShape shape = new HkSphereShape(CAMERA_RADIUS);

            try
            {
                // small shape, not causing problems with asteroids generating geometry
                Physics.MyPhysics.GetPenetrationsShape(shape, ref castStartSafe, ref Quaternion.Identity, m_rigidList, 15);
                if (m_rigidList.Count > 0)
                {
                    bool sameGrid = false;
                    if (MySession.ControlledEntity != null && m_rigidList[0] != null)
                    {
                        sameGrid = m_rigidList[0].UserObject == ((MyEntity)MySession.ControlledEntity).Physics;
                    }

                    if (sameGrid)
                    {
                        castStartSafe += line.Direction;
                    }
                }

                var  shapeCastLine = new LineD(castStartSafe, m_position);
                uint steps         = 1;
                uint stepIdx       = 0;
                if (shapeCastLine.Length > SHAPE_CAST_STEP)
                {
                    steps = (uint)Math.Ceiling(shapeCastLine.Length / SHAPE_CAST_STEP);
                    if (steps >= SHAPE_CAST_MAX_STEP_COUNT)
                    {
                        steps = SHAPE_CAST_MAX_STEP_COUNT - 1;
                    }
                    stepIdx = m_updateCount % steps;
                    m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity;

                    Vector3D step = shapeCastLine.Direction * (shapeCastLine.Length / steps);
                    shapeCastLine = new LineD(castStartSafe + stepIdx * step, castStartSafe + (stepIdx + 1) * step);
                }

                if (false)
                {
                    BoundingBoxD bbox = BoundingBoxD.CreateInvalid();
                    bbox.Include(new BoundingSphereD(shapeCastLine.From, CAMERA_RADIUS));
                    bbox.Include(new BoundingSphereD(shapeCastLine.To, CAMERA_RADIUS));
                    VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Color.Crimson, 1f, 1f, true);
                }

                var matrix = MatrixD.CreateTranslation(shapeCastLine.From);
                HkContactPointData?cpd;
                if (controlledEntity.Physics.CharacterProxy != null)
                {
                    cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, controlledEntity.Physics.CharacterCollisionFilter, 0.0f);
                }
                else
                {
                    cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, HkGroupFilter.CalcFilterInfo(MyPhysics.DefaultCollisionLayer, 0), 0.0f);
                }
                if (cpd.HasValue)
                {
                    var point = shapeCastLine.From + shapeCastLine.Direction * shapeCastLine.Length * cpd.Value.DistanceFraction;
                    m_lastShapeCastDistance[stepIdx] = (float)(castStartSafe - point).Length();
                }
                else
                {
                    m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity;
                }


                float?dist = null;
                for (int i = 0; i < steps; ++i)
                {
                    if (m_lastShapeCastDistance[i] != float.PositiveInfinity)
                    {
                        dist = Math.Min(m_lastShapeCastDistance[i], dist ?? float.PositiveInfinity);
                    }
                }

                if (dist.HasValue)
                {
                    if (dist == 0.0f)
                    {
                        return(false);
                    }
                    else
                    {
                        m_positionSafe = castStartSafe + shapeCastLine.Direction * dist.Value;
                    }
                }
                else
                {
                    m_positionSafe = m_position;
                }
                return(true);
            }
            finally
            {
                shape.RemoveReference();
            }
        }
Esempio n. 13
0
        protected override bool Attach(MyAttachableTopBlockBase rotor, bool updateGroup = true)
        {
            Debug.Assert(rotor != null, "Rotor cannot be null!");
            Debug.Assert(m_constraint == null, "Already attached, call detach first!");


            if (rotor is MyMotorRotor)
            {
                if (CubeGrid.Physics != null && CubeGrid.Physics.Enabled)
                {
                    m_topBlock = rotor;
                    m_topGrid  = m_topBlock.CubeGrid;
                    var rotorBody = m_topGrid.Physics.RigidBody;
                    rotorBody.MaxAngularVelocity = float.MaxValue;
                    rotorBody.Restitution        = 0.5f;
                    CubeGrid.GetPhysicsBody().HavokWorld.BreakOffPartsUtil.UnmarkEntityBreakable(rotorBody);
                    if (MyFakes.WHEEL_SOFTNESS)
                    {
                        HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity);
                    }
                    var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.GetPhysicsBody().HavokCollisionSystemID, 1, 1);
                    rotorBody.SetCollisionFilterInfo(info);
                    HkWheelConstraintData data = new HkWheelConstraintData();
                    var suspensionAx           = PositionComp.LocalMatrix.Forward;
                    var posA      = DummyPosition + (suspensionAx * m_height);
                    var posB      = (rotor as MyMotorRotor).DummyPosLoc;
                    var axisA     = PositionComp.LocalMatrix.Up;
                    var axisAPerp = PositionComp.LocalMatrix.Forward;
                    var axisB     = rotor.PositionComp.LocalMatrix.Up;
                    //empirical values because who knows what havoc sees behind this
                    //docs say one value should mean same effect for 2 ton or 200 ton vehicle
                    //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity
                    data.SetSuspensionDamping(m_damping);
                    data.SetSuspensionStrength(m_strenth);
                    //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit
                    data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel);
                    data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel);
                    data.SetInBodySpace(posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics);
                    m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data);

                    m_constraint.WantRuntime = true;
                    CubeGrid.Physics.AddConstraint(m_constraint);
                    if (!m_constraint.InWorld)
                    {
                        Debug.Fail("Constraint not added!");
                        CubeGrid.Physics.RemoveConstraint(m_constraint);
                        m_constraint = null;
                        return(false);
                    }
                    m_constraint.Enabled = true;

                    m_topBlock.Attach(this);
                    m_isAttached = true;
                    PropagateFriction(m_friction);
                    UpdateIsWorking();

                    if (m_updateBrakeNeeded)
                    {
                        UpdateBrake();
                    }
                    if (m_updateFrictionNeeded)
                    {
                        FrictionChanged();
                    }


                    if (updateGroup)
                    {
                        OnConstraintAdded(GridLinkTypeEnum.Physical, m_topGrid);
                        OnConstraintAdded(GridLinkTypeEnum.Logical, m_topGrid);
                    }

                    return(true);
                }
            }
            return(false);
        }
Esempio n. 14
0
        public override bool Attach(MyMotorRotor rotor, bool updateSync = false, bool updateGroup = true)
        {
            if (CubeGrid.Physics == null || SafeConstraint != null)
            {
                return(false);
            }

            Debug.Assert(SafeConstraint == null);

            if (CubeGrid.Physics.Enabled && rotor != null)
            {
                m_rotorBlock   = rotor;
                m_rotorBlockId = rotor.EntityId;

                if (updateSync)
                {
                    SyncObject.AttachRotor(m_rotorBlock);
                }

                m_rotorGrid = m_rotorBlock.CubeGrid;
                var rotorBody = m_rotorGrid.Physics.RigidBody;
                rotorBody.MaxAngularVelocity = float.MaxValue;
                rotorBody.AngularDamping    *= 4;
                if (MyFakes.WHEEL_SOFTNESS)
                {
                    HkUtils.SetSoftContact(rotorBody, null, MyPhysicsConfig.WheelSoftnessRatio, MyPhysicsConfig.WheelSoftnessVelocity);
                }
                var info = HkGroupFilter.CalcFilterInfo(rotorBody.Layer, CubeGrid.Physics.HavokCollisionSystemID, 1, 1);
                rotorBody.SetCollisionFilterInfo(info);
                HkWheelConstraintData data = new HkWheelConstraintData();
                var suspensionAx           = PositionComp.LocalMatrix.Forward;
                var posA      = DummyPosition + (suspensionAx * m_height);
                var posB      = rotor.DummyPosLoc;
                var axisA     = PositionComp.LocalMatrix.Up;
                var axisAPerp = PositionComp.LocalMatrix.Forward;
                var axisB     = rotor.PositionComp.LocalMatrix.Up;
                //empirical values because who knows what havoc sees behind this
                //docs say one value should mean same effect for 2 ton or 200 ton vehicle
                //but we have virtual mass blocks so real mass doesnt corespond to actual "weight" in game and varying gravity
                data.SetSuspensionDamping(Damping);
                data.SetSuspensionStrength(Strength);
                //Min/MaxHeight also define the limits of the suspension and SuspensionTravel lowers this limit
                data.SetSuspensionMinLimit((BlockDefinition.MinHeight - m_height) * SuspensionTravel);
                data.SetSuspensionMaxLimit((BlockDefinition.MaxHeight - m_height) * SuspensionTravel);
                data.SetInBodySpace(posB, posA, axisB, axisA, suspensionAx, suspensionAx, RotorGrid.Physics, CubeGrid.Physics);
                m_constraint = new HkConstraint(rotorBody, CubeGrid.Physics.RigidBody, data);

                m_constraint.WantRuntime = true;
                CubeGrid.Physics.AddConstraint(m_constraint);
                m_constraint.Enabled = true;

                m_rotorBlock.Attach(this);
                PropagateFriction(m_friction);
                UpdateIsWorking();

                if (updateGroup)
                {
                    OnConstraintAdded(GridLinkTypeEnum.Physical, m_rotorGrid);
                    OnConstraintAdded(GridLinkTypeEnum.Logical, m_rotorGrid);
                }

                return(true);
            }

            return(false);
        }
Esempio n. 15
0
        private void ActivateJetpackRagdoll()
        {
            if (RagdollMapper == null || Character.Physics == null || Character.Physics.Ragdoll == null)
            {
                return;
            }
            if (!MyPerGameSettings.EnableRagdollModels)
            {
                return;
            }
            if (!MyPerGameSettings.EnableRagdollInJetpack)
            {
                return;
            }
            if (Character.Physics.HavokWorld == null)
            {
                return;
            }

            List <string> bodies = new List <string>();

            string[] bodiesArray;

            if (Character.CurrentWeapon == null)
            {
                if (Character.Definition.RagdollPartialSimulations.TryGetValue("Jetpack", out bodiesArray))
                {
                    bodies.AddArray(bodiesArray);
                }
                else
                {
                    // Fallback if missing definitions
                    bodies.Add("Ragdoll_SE_rig_LUpperarm001");
                    bodies.Add("Ragdoll_SE_rig_LForearm001");
                    bodies.Add("Ragdoll_SE_rig_LPalm001");
                    bodies.Add("Ragdoll_SE_rig_RUpperarm001");
                    bodies.Add("Ragdoll_SE_rig_RForearm001");
                    bodies.Add("Ragdoll_SE_rig_RPalm001");

                    bodies.Add("Ragdoll_SE_rig_LThigh001");
                    bodies.Add("Ragdoll_SE_rig_LCalf001");
                    bodies.Add("Ragdoll_SE_rig_LFoot001");
                    bodies.Add("Ragdoll_SE_rig_RThigh001");
                    bodies.Add("Ragdoll_SE_rig_RCalf001");
                    bodies.Add("Ragdoll_SE_rig_RFoot001");
                }
            }
            else
            {
                if (Character.Definition.RagdollPartialSimulations.TryGetValue("Jetpack_Weapon", out bodiesArray))
                {
                    bodies.AddArray(bodiesArray);
                }
                else
                {
                    bodies.Add("Ragdoll_SE_rig_LThigh001");
                    bodies.Add("Ragdoll_SE_rig_LCalf001");
                    bodies.Add("Ragdoll_SE_rig_LFoot001");
                    bodies.Add("Ragdoll_SE_rig_RThigh001");
                    bodies.Add("Ragdoll_SE_rig_RCalf001");
                    bodies.Add("Ragdoll_SE_rig_RFoot001");
                }
            }

            List <int> simulatedBodies = new List <int>();

            foreach (var body in bodies)
            {
                simulatedBodies.Add(RagdollMapper.BodyIndex(body));
            }

            if (!Character.Physics.IsRagdollModeActive)
            {
                Character.Physics.SwitchToRagdollMode(false);
            }

            if (Character.Physics.IsRagdollModeActive)
            {
                RagdollMapper.ActivatePartialSimulation(simulatedBodies);
            }

            // This is hack, ragdoll in jetpack sometimes can't settle and simulation is broken, if we find another way how to avoid that, this can be disabled
            if (!MyFakes.ENABLE_JETPACK_RAGDOLL_COLLISIONS)
            {
                foreach (var body in Character.Physics.Ragdoll.RigidBodies)
                {
                    var info = HkGroupFilter.CalcFilterInfo(MyPhysics.RagdollCollisionLayer, 0, 0, 0);
                    Character.Physics.HavokWorld.DisableCollisionsBetween(MyPhysics.RagdollCollisionLayer, MyPhysics.RagdollCollisionLayer);
                    body.SetCollisionFilterInfo(info);
                    body.LinearVelocity  = Vector3.Zero;
                    body.AngularVelocity = Vector3.Zero;
                }
            }

            RagdollMapper.ResetRagdoll(Character.WorldMatrix);
        }