Пример #1
0
        internal static void InitBoxPhysics(this IMyEntity entity, Matrix worldMatrix, MyStringId materialType, Vector3 center, Vector3 size, float mass, float linearDamping, float angularDamping, ushort collisionLayer, RigidBodyFlag rbFlag)
        {
            mass = (rbFlag & RigidBodyFlag.RBF_STATIC) != 0 ? 0 : mass;

            var massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(size / 2, mass);

            var physicsBody = new Sandbox.Engine.Physics.MyPhysicsBody(null, rbFlag)
            {
                MaterialType   = materialType,
                AngularDamping = angularDamping,
                LinearDamping  = linearDamping
            };

            //BoxShape shape = new BoxShape(size * 0.5f);
            HkBoxShape shape = new HkBoxShape(size * 0.5f);

            physicsBody.CreateFromCollisionObject((HkShape)shape, center, worldMatrix, massProperties);
            shape.Base.RemoveReference();

            entity.Physics = physicsBody;
            //return physicsBody;
        }
Пример #2
0
        public static void InitBoxPhysics(this IMyEntity entity, MyStringId materialType, Vector3 center, Vector3 size, float mass, float linearDamping, float angularDamping, ushort collisionLayer, RigidBodyFlag rbFlag)
        {
            System.Diagnostics.Debug.Assert(size.Length() > 0);

            mass = (rbFlag & RigidBodyFlag.RBF_STATIC) != 0 ? 0 : mass;

            var massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(size / 2, mass);

            var physics = new Sandbox.Engine.Physics.MyPhysicsBody(entity, rbFlag)
            {
                MaterialType   = materialType,
                AngularDamping = angularDamping,
                LinearDamping  = linearDamping
            };

            HkBoxShape shape = new HkBoxShape(size * 0.5f);

            physics.CreateFromCollisionObject((HkShape)shape, center, entity.PositionComp.WorldMatrix, massProperties);
            shape.Base.RemoveReference();

            entity.Physics = physics;
        }
Пример #3
0
        public void UpdateMassProps()
        {
            Debug.Assert(m_tmpElements.Count == 0, "mass elements not cleared!");
            if (RigidBody.IsFixedOrKeyframed)
            {
                return;
            }
            if (WeldInfo.Parent != null)
            {
                WeldInfo.Parent.UpdateMassProps();
                return;
            }
            m_tmpElements.Add(WeldInfo.MassElement);
            foreach (var child in WeldInfo.Children)
            {
                m_tmpElements.Add(child.WeldInfo.MassElement);
            }
            var mp = HkInertiaTensorComputer.CombineMassProperties(m_tmpElements);

            RigidBody.SetMassProperties(ref mp);
            m_tmpElements.Clear();
        }
Пример #4
0
            public override void CreatePhysicsShape(out HkShape shape, out HkMassProperties massProperties, float mass)
            {
                float num;
                float num2;

                shape = HkShape.Empty;
                MyModel     model       = base.Entity.Render.GetModel();
                BoundingBox boundingBox = model.BoundingBox;

                ComputeShapeDimensions(boundingBox, out num, out num2);
                Vector3 vector  = Vector3.Up * num;
                Vector3 vertexA = ((boundingBox.Min + boundingBox.Max) * 0.5f) + (vector * 0.2f);
                Vector3 vertexB = ((boundingBox.Min + boundingBox.Max) * 0.5f) - (vector * 0.45f);
                bool    flag    = true;

                if (MyFakes.TREE_MESH_FROM_MODEL)
                {
                    HkShape[] havokCollisionShapes = model.HavokCollisionShapes;
                    if ((havokCollisionShapes != null) && (havokCollisionShapes.Length != 0))
                    {
                        if (havokCollisionShapes.Length != 1)
                        {
                            shape = (HkShape) new HkListShape(havokCollisionShapes, HkReferencePolicy.None);
                        }
                        else
                        {
                            shape = havokCollisionShapes[0];
                            shape.AddReference();
                        }
                        flag = false;
                    }
                }
                if (flag)
                {
                    shape = (HkShape) new HkCapsuleShape(vertexA, vertexB, num2);
                }
                massProperties = HkInertiaTensorComputer.ComputeCapsuleVolumeMassProperties(vertexA, vertexB, num2, mass);
            }
Пример #5
0
        protected virtual HkShape GetPhysicsShape(float mass, float scale, out HkMassProperties massProperties)
        {
            HkShapeType sphere;

            if (base.Model == null)
            {
                MyLog.Default.WriteLine("Invalid floating object model: " + this.Item.GetDefinitionId());
            }
            if (this.VoxelMaterial != null)
            {
                sphere         = HkShapeType.Sphere;
                massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(base.Model.BoundingSphere.Radius * scale, mass);
            }
            else
            {
                sphere = HkShapeType.Box;
                Vector3 vector = (Vector3)((2f * (base.Model.BoundingBox.Max - base.Model.BoundingBox.Min)) / 2f);
                massProperties              = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(vector * scale, mass);
                massProperties.Mass         = mass;
                massProperties.CenterOfMass = base.Model.BoundingBox.Center;
            }
            return(MyDebris.Static.GetDebrisShape(base.Model, sphere, scale));
        }
Пример #6
0
        private bool CreateOwnerVirtualPhysics()
        {
            if (Owner == null)
            {
                return(false);
            }

            OwnerVirtualPhysics = new MyCharacterVirtualPhysicsBody(Owner, RigidBodyFlag.RBF_KINEMATIC);
            var     massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(0.1f, MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(Owner.Definition.Mass) : Owner.Definition.Mass);
            HkShape sh             = new HkSphereShape(0.1f);

            OwnerVirtualPhysics.InitialSolverDeactivation = HkSolverDeactivation.Off;
            MatrixD headWorldMatrix = Owner.GetHeadMatrix(false, forceHeadBone: true);

            OwnerVirtualPhysics.CreateFromCollisionObject(sh, Vector3.Zero, headWorldMatrix, massProperties, Sandbox.Engine.Physics.MyPhysics.NoCollisionLayer);
            OwnerVirtualPhysics.RigidBody.EnableDeactivation = false;
            // Character ray casts includes also NoCollision layer shapes so setup property for ignoring the body
            OwnerVirtualPhysics.RigidBody.SetProperty(HkCharacterRigidBody.MANIPULATED_OBJECT, 0);
            sh.RemoveReference();

            OwnerVirtualPhysics.Enabled = true;

            return(true);
        }
Пример #7
0
        private void InitSubpartsPhysics()
        {
            var subpart = m_subpart1;

            if (subpart == null || CubeGrid.Physics == null)
            {
                return;
            }
            subpart.Physics = new MyPhysicsBody(subpart, CubeGrid.IsStatic ? RigidBodyFlag.RBF_STATIC : (CubeGrid.GridSizeEnum == MyCubeSize.Large ? RigidBodyFlag.RBF_DOUBLED_KINEMATIC : RigidBodyFlag.RBF_DEFAULT));
            HkCylinderShape shape = new HkCylinderShape(Vector3.Zero, new Vector3(0, 0, 2), CubeGrid.GridSize / 2);
            var             mass  = HkInertiaTensorComputer.ComputeCylinderVolumeMassProperties(Vector3.Zero, Vector3.One, 1, 40.0f * CubeGrid.GridSize);

            subpart.GetPhysicsBody().CreateFromCollisionObject(shape, Vector3.Zero, subpart.WorldMatrix, mass);
            shape.Base.RemoveReference();
            subpart.Physics.RigidBody.Layer = CubeGrid.Physics.RigidBody.Layer;
            if (subpart.Physics.RigidBody2 != null)
            {
                subpart.Physics.RigidBody2.Layer = MyPhysics.CollisionLayers.KinematicDoubledCollisionLayer;
            }

            CreateSubpartsConstraint(subpart);

            m_posChanged = true;
        }
        /// <summary>
        ///  Sets default values for ragdoll bodies and constraints - useful if ragdoll model is not correct
        /// </summary>
        public void SetRagdollDefaults()
        {
            if (MyFakes.ENABLE_RAGDOLL_DEBUG)
            {
                Debug.WriteLine("MyPhysicsBody.SetRagdollDefaults");
                MyLog.Default.WriteLine("MyPhysicsBody.SetRagdollDefaults");
            }

            var wasKeyframed = Ragdoll.IsKeyframed;

            Ragdoll.SetToDynamic();

            // Compute total mass of the character and distribute it amongs ragdoll bodies
            var definedMass = (Entity as MyCharacter).Definition.Mass;

            if (definedMass <= 1)
            {
                definedMass = 80;
            }

            float totalVolume = 0f;

            foreach (var body in Ragdoll.RigidBodies)
            {
                float bodyLength = 0;

                var shape = body.GetShape();

                Vector4 min, max;

                shape.GetLocalAABB(0.01f, out min, out max);

                bodyLength = (max - min).Length();

                totalVolume += bodyLength;
            }

            // correcting the total volume
            if (totalVolume <= 0)
            {
                totalVolume = 1;
            }

            // bodies default settings
            foreach (var body in Ragdoll.RigidBodies)
            {
                body.MaxLinearVelocity  = 1000.0f;
                body.MaxAngularVelocity = 1000.0f;

                var shape = body.GetShape();

                Vector4 min, max;

                shape.GetLocalAABB(0.01f, out min, out max);

                float bodyLength = (max - min).Length();

                float computedMass = definedMass / totalVolume * bodyLength;

                body.Mass = MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(computedMass) : computedMass;

                float radius = shape.ConvexRadius;
                if (shape.ShapeType == HkShapeType.Capsule)
                {
                    HkCapsuleShape   capsule        = (HkCapsuleShape)shape;
                    HkMassProperties massProperties = HkInertiaTensorComputer.ComputeCapsuleVolumeMassProperties(capsule.VertexA, capsule.VertexB, radius, body.Mass);
                    body.InertiaTensor = massProperties.InertiaTensor;
                }
                else
                {
                    HkMassProperties massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(Vector3.One * bodyLength * 0.5f, body.Mass);
                    body.InertiaTensor = massProperties.InertiaTensor;
                }

                Debug.Assert(body.Mass != 0.0f, "Body's mass was set to 0!");
                body.AngularDamping          = 0.005f;
                body.LinearDamping           = 0.0f;
                body.Friction                = 6f;
                body.AllowedPenetrationDepth = 0.1f;
                body.Restitution             = 0.05f;
            }

            Ragdoll.OptimizeInertiasOfConstraintTree();

            if (wasKeyframed)
            {
                Ragdoll.SetToKeyframed();
            }

            // Constraints default settings
            foreach (var constraint in Ragdoll.Constraints)
            {
                if (constraint.ConstraintData is HkRagdollConstraintData)
                {
                    var constraintData = constraint.ConstraintData as HkRagdollConstraintData;
                    constraintData.MaxFrictionTorque = MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(0.5f) : 3f;
                }
                else if (constraint.ConstraintData is HkFixedConstraintData)
                {
                    var constraintData = constraint.ConstraintData as HkFixedConstraintData;
                    constraintData.MaximumLinearImpulse  = 3.40282e28f;
                    constraintData.MaximumAngularImpulse = 3.40282e28f;
                }
                else if (constraint.ConstraintData is HkHingeConstraintData)
                {
                    var constraintData = constraint.ConstraintData as HkHingeConstraintData;
                    constraintData.MaximumAngularImpulse = 3.40282e28f;
                    constraintData.MaximumLinearImpulse  = 3.40282e28f;
                }
                else if (constraint.ConstraintData is HkLimitedHingeConstraintData)
                {
                    var constraintData = constraint.ConstraintData as HkLimitedHingeConstraintData;
                    constraintData.MaxFrictionTorque = MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(0.5f) : 3f;
                }
            }

            if (MyFakes.ENABLE_RAGDOLL_DEBUG)
            {
                Debug.WriteLine("MyPhysicsBody.SetRagdollDefaults FINISHED");
                MyLog.Default.WriteLine("MyPhysicsBody.SetRagdollDefaults FINISHED");
            }
        }
Пример #9
0
            private void InitInternal()
            {
                // TODO: This will be fixed and made much more simple once ore models are done
                // https://app.asana.com/0/6594565324126/10473934569658
                var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(Item.Content);

                var ore = Item.Content as MyObjectBuilder_Ore;

                string model = physicalItem.Model;
                float  scale = 1.0f;

                VoxelMaterial = null;
                if (ore != null)
                {
                    foreach (var mat in MyDefinitionManager.Static.GetVoxelMaterialDefinitions())
                    {
                        if (mat.MinedOre == ore.SubtypeName)
                        {
                            VoxelMaterial = mat;
                            model         = MyDebris.GetRandomDebrisVoxel();
                            scale         = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f);
                            break;
                        }
                    }
                }

                if (scale < 0.15f)
                {
                    scale = 0.15f;
                }

                var voxelRender = (Entity.Render as MyRenderComponentDebrisVoxel);

                voxelRender.VoxelMaterialIndex = VoxelMaterial.Index;
                voxelRender.TexCoordOffset     = 5;
                voxelRender.TexCoordScale      = 8;
                Entity.Init(new StringBuilder("Meteor"), model, null, null, null);

                Entity.PositionComp.Scale = scale; // Must be set after init

                var           massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(Entity.PositionComp.LocalVolume.Radius, (float)(4 / 3f * Math.PI * Math.Pow(Entity.PositionComp.LocalVolume.Radius, 3)) * 3.7f);
                HkSphereShape transform      = new HkSphereShape(Entity.PositionComp.LocalVolume.Radius);

                if (Entity.Physics != null)
                {
                    Entity.Physics.Close();
                }

                Entity.Physics = new MyPhysicsBody(Entity, RigidBodyFlag.RBF_BULLET);
                Entity.Physics.ReportAllContacts = true;
                Entity.GetPhysicsBody().CreateFromCollisionObject(transform, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.CollisionLayers.DefaultCollisionLayer);
                Entity.Physics.Enabled = true;
                Entity.Physics.RigidBody.ContactPointCallbackEnabled = true;
                Entity.GetPhysicsBody().ContactPointCallback += RigidBody_ContactPointCallback;
                transform.Base.RemoveReference();
                Entity.Physics.PlayCollisionCueEnabled = true;

                m_timeCreated = MySandboxGame.TotalGamePlayTimeInMilliseconds;

                NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME | MyEntityUpdateEnum.EACH_100TH_FRAME;

                StartLoopSound();
            }