private void PreparePhysicsBody()
        {
            m_activeShape = m_newShape;
            m_newShape    = null;

            Debug.Assert(m_activeShape != null);

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

            Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC);

            var physics = (MyPhysicsBody)Physics;

            HkMassProperties massProperties = new HkMassProperties();

            //MatrixD matrix = MatrixD.CreateTranslation();
            physics.CreateFromCollisionObject(m_activeShape.Shape, Vector3.Zero, PositionComp.WorldMatrix, massProperties);
            physics.ContactPointCallback += Physics_onContactPoint;
            physics.IsStaticForCluster    = true;

            if (m_contactListeners != null && m_contactListeners.Count != 0)
            {
                Physics.RigidBody.ContactPointCallbackEnabled = true;
            }

            //shape.RemoveReference();

            Physics.Enabled = true;
        }
示例#2
0
 public override void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties)
 {
     var sphereShape = new HkSphereShape(((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius * Entity.PositionComp.Scale.Value);
     shape = sphereShape;
     var mass = SphereMass(sphereShape.Radius, VoxelDensity);
     massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, mass);
 }
示例#3
0
 public virtual void ScalePhysicsShape(ref HkMassProperties massProperties)
 {
     var debriModel = Entity.Render.GetModel();
     HkShape shape;
     if (debriModel.HavokCollisionShapes != null && debriModel.HavokCollisionShapes.Length > 0)
     {
         shape = debriModel.HavokCollisionShapes[0];
         Vector4 min, max;
         shape.GetLocalAABB(0.1f, out min, out max);
         Vector3 he = new Vector3((max - min) * 0.5f);
         massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(he, he.Volume * 50);
         massProperties.CenterOfMass = new Vector3((min + max) * 0.5f);
     }
     else
     {
         var transformShape = (HkTransformShape)RigidBody.GetShape();
         var boxShape = (HkBoxShape)transformShape.ChildShape;
         boxShape.HalfExtents = ((debriModel.BoundingBox.Max - debriModel.BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value;
         massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, boxShape.HalfExtents.Volume * 0.5f);
         massProperties.CenterOfMass = transformShape.Transform.Translation;
         shape = transformShape;
     }
     RigidBody.SetShape(shape);
     RigidBody.SetMassProperties(ref massProperties);
     RigidBody.UpdateShape();
 }
示例#4
0
            public virtual void ScalePhysicsShape(ref HkMassProperties massProperties)
            {
                HkShape shape;
                MyModel model = base.Entity.Render.GetModel();

                if ((model.HavokCollisionShapes != null) && (model.HavokCollisionShapes.Length != 0))
                {
                    Vector4 vector;
                    Vector4 vector2;
                    shape = model.HavokCollisionShapes[0];
                    shape.GetLocalAABB(0.1f, out vector, out vector2);
                    Vector3 halfExtents = new Vector3((vector2 - vector) * 0.5f);
                    massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(halfExtents, halfExtents.Volume * 50f);
                    massProperties.CenterOfMass = new Vector3((vector + vector2) * 0.5f);
                }
                else
                {
                    HkTransformShape shape2     = (HkTransformShape)this.RigidBody.GetShape();
                    HkBoxShape       childShape = (HkBoxShape)shape2.ChildShape;
                    childShape.HalfExtents      = ((model.BoundingBox.Max - model.BoundingBox.Min) / 2f) * base.Entity.PositionComp.Scale.Value;
                    massProperties              = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(childShape.HalfExtents, childShape.HalfExtents.Volume * 0.5f);
                    massProperties.CenterOfMass = shape2.Transform.Translation;
                    shape = (HkShape)shape2;
                }
                this.RigidBody.SetShape(shape);
                this.RigidBody.SetMassProperties(ref massProperties);
                this.RigidBody.UpdateShape();
            }
示例#5
0
 private void CreateConstraint(MyEntitySubpart subpart, ref HkConstraint constraint, ref HkFixedConstraintData constraintData)
 {
     if (subpart != null)
     {
         bool flag = !Sync.IsServer;
         if (subpart.Physics == null)
         {
             HkShape[] havokCollisionShapes = subpart.ModelCollision.HavokCollisionShapes;
             if ((havokCollisionShapes != null) && (havokCollisionShapes.Length != 0))
             {
                 MyPhysicsBody body = new MyPhysicsBody(subpart, flag ? RigidBodyFlag.RBF_STATIC : (RigidBodyFlag.RBF_UNLOCKED_SPEEDS | RigidBodyFlag.RBF_DOUBLED_KINEMATIC))
                 {
                     IsSubpart = true
                 };
                 subpart.Physics = body;
                 HkShape shape = havokCollisionShapes[0];
                 MyPositionComponentBase positionComp = subpart.PositionComp;
                 Vector3          center     = positionComp.LocalVolume.Center;
                 HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(positionComp.LocalAABB.HalfExtents, 100f);
                 int collisionFilter         = base.CubeGrid.IsStatic ? 9 : 0x10;
                 body.CreateFromCollisionObject(shape, center, positionComp.WorldMatrix, new HkMassProperties?(properties), collisionFilter);
             }
         }
         if (flag)
         {
             subpart.Physics.Enabled = true;
         }
         else
         {
             base.CreateSubpartConstraint(subpart, out constraintData, out constraint);
             base.CubeGrid.Physics.AddConstraint(constraint);
             constraint.SetVirtualMassInverse(Vector4.Zero, Vector4.One);
         }
     }
 }
 public void AllocateForDefinition(string model, MyPhysicalModelDefinition definition, int count)
 {
     if (string.IsNullOrEmpty(model))
         return;
     ProfilerShort.Begin("Clone");
     var data = MyModels.GetModelOnlyData(model);
     if (MyFakes.LAZY_LOAD_DESTRUCTION && data.HavokBreakableShapes == null)
     {
         MyDestructionData.Static.LoadModelDestruction(model, definition, data.BoundingBoxSize);
     }               
     if (data.HavokBreakableShapes != null && data.HavokBreakableShapes.Length > 0)
     {
         if (!m_pools.ContainsKey(definition.Id))
             m_pools[definition.Id] = new Dictionary<string, ConcurrentQueue<HkdBreakableShape>>();
         if(!m_pools[definition.Id].ContainsKey(model))
             m_pools[definition.Id][model] = new ConcurrentQueue<HkdBreakableShape>();
         var queue = m_pools[definition.Id][model];
         for (int i = 0; i < count; i++)
         {
             var shape = data.HavokBreakableShapes[0].Clone();
             queue.Enqueue(shape);
             if (i == 0)
             {
                 var mp = new HkMassProperties();
                 shape.BuildMassProperties(ref mp);
                 if (!mp.InertiaTensor.IsValid())
                 {
                     MyLog.Default.WriteLine(string.Format("Block with wrong destruction! (q.isOk): {0}", definition.Model));
                     break;
                 }
             }
         }
     }
     ProfilerShort.End();
 }
        void AddMass(MySlimBlock block, IDictionary <Vector3I, HkMassElement> massResults)
        {
            float mass = block.GetMass();

            if (MyFakes.ENABLE_COMPOUND_BLOCKS && block.FatBlock is MyCompoundCubeBlock)
            {
                mass = 0f;
                MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock;
                foreach (var innerBlock in compoundBlock.GetBlocks())
                {
                    mass += innerBlock.GetMass();
                    Debug.Assert(innerBlock.BlockDefinition.Size == Vector3I.One, "Invalid block found in compound block - only blocks with size 1 can be set in compound block!");
                }
            }

            var size   = (block.Max - block.Min + Vector3I.One) * block.CubeGrid.GridSize;
            var center = (block.Min + block.Max) * 0.5f * block.CubeGrid.GridSize;
            HkMassProperties massProperties = new HkMassProperties();

            massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(size / 2, mass);
            massResults[block.Position] = new HkMassElement()
            {
                Properties = massProperties, Tranform = Matrix.CreateTranslation(center)
            };
        }
示例#8
0
        /// <summary>
        /// Prepares data for renderer and physics. Must be called after all items has been added.
        /// </summary>
        public void PrepareItemsPhysics(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld)
        {
            PositionComp.WorldAABB = aabbWorld;

            if (sectorRootShape.InstanceCount > 0)
            {
                Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0);

                Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC)
                {
                    MaterialType       = m_definition.Material,
                    AngularDamping     = MyPerGameSettings.DefaultAngularDamping,
                    LinearDamping      = MyPerGameSettings.DefaultLinearDamping,
                    IsStaticForCluster = true,
                };

                sectorRootShape.Bake();
                HkMassProperties massProperties = new HkMassProperties();
                MatrixD          matrix         = MatrixD.CreateTranslation(CellsOffset);
                Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, matrix, massProperties);

                Physics.ContactPointCallback += Physics_ContactPointCallback;
                Physics.RigidBody.ContactPointCallbackEnabled = true;

                sectorRootShape.Base.RemoveReference();

                Physics.Enabled = true;
            }
        }
示例#9
0
            public override void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties)
            {
                var sphereShape = new HkSphereShape(((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius *Entity.PositionComp.Scale.Value);

                shape          = sphereShape;
                massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, 1);
            }
示例#10
0
        // Don't call remove reference on this, this shape is pooled
        protected virtual HkShape GetPhysicsShape(float mass, float scale, out HkMassProperties massProperties)
        {
            const bool SimpleShape = false;

            Debug.Assert(Model != null, "Invalid floating object model: " + Item.GetDefinitionId());
            if (Model == null)
            {
                MyLog.Default.WriteLine("Invalid floating object model: " + Item.GetDefinitionId());
            }

            Vector3     halfExtents = (Model.BoundingBox.Max - Model.BoundingBox.Min) / 2;
            HkShapeType shapeType;

            if (VoxelMaterial != null)
            {
                shapeType      = HkShapeType.Sphere;
                massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(Model.BoundingSphere.Radius * scale, mass);
            }
            else
            {
                shapeType      = HkShapeType.Box;
                massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(halfExtents, mass);
                massProperties.CenterOfMass = Model.BoundingBox.Center;
            }

            return(MyDebris.Static.GetDebrisShape(Model, SimpleShape ? shapeType : HkShapeType.ConvexVertices));
        }
示例#11
0
            public virtual void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties)
            {
                var boxShape = new HkBoxShape(((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value);

                shape          = boxShape;
                massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, massProperties.Mass);
            }
示例#12
0
            public virtual void ScalePhysicsShape(ref HkMassProperties massProperties)
            {
                var     debriModel = Entity.Render.GetModel();
                HkShape shape;

                if (debriModel.HavokCollisionShapes != null && debriModel.HavokCollisionShapes.Length > 0)
                {
                    shape = debriModel.HavokCollisionShapes[0];
                    Vector4 min, max;
                    shape.GetLocalAABB(0.1f, out min, out max);
                    Vector3 he = new Vector3((max - min) * 0.5f);
                    massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(he, he.Volume * 50);
                    massProperties.CenterOfMass = new Vector3((min + max) * 0.5f);
                }
                else
                {
                    var transformShape = (HkTransformShape)RigidBody.GetShape();
                    var boxShape       = (HkBoxShape)transformShape.ChildShape;
                    boxShape.HalfExtents        = ((debriModel.BoundingBox.Max - debriModel.BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value;
                    massProperties              = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, boxShape.HalfExtents.Volume * 0.5f);
                    massProperties.CenterOfMass = transformShape.Transform.Translation;
                    shape = transformShape;
                }
                RigidBody.SetShape(shape);
                RigidBody.SetMassProperties(ref massProperties);
                RigidBody.UpdateShape();
            }
示例#13
0
        private static MyFracturedPiece CreateFracturePiece(ref HkdBreakableShape shape, ref MatrixD worldMatrix, bool isStatic)
        {
            MyFracturedPiece pieceFromPool = MyFracturedPiecesManager.Static.GetPieceFromPool(0L, false);

            pieceFromPool.PositionComp.WorldMatrix = worldMatrix;
            pieceFromPool.Physics.Flags            = isStatic ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS;
            MyPhysicsBody    physics        = pieceFromPool.Physics;
            HkMassProperties massProperties = new HkMassProperties();

            shape.BuildMassProperties(ref massProperties);
            physics.InitialSolverDeactivation = HkSolverDeactivation.High;
            physics.CreateFromCollisionObject(shape.GetShape(), Vector3.Zero, worldMatrix, new HkMassProperties?(massProperties), 15);
            physics.LinearDamping  = MyPerGameSettings.DefaultLinearDamping;
            physics.AngularDamping = MyPerGameSettings.DefaultAngularDamping;
            physics.BreakableBody  = new HkdBreakableBody(shape, physics.RigidBody, null, (Matrix)worldMatrix);
            physics.BreakableBody.AfterReplaceBody += new BreakableBodyReplaced(physics.FracturedBody_AfterReplaceBody);
            if (pieceFromPool.SyncFlag)
            {
                pieceFromPool.CreateSync();
            }
            pieceFromPool.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
            pieceFromPool.SetDataFromHavok(shape);
            pieceFromPool.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
            shape.RemoveReference();
            return(pieceFromPool);
        }
        private bool CheckVolumeMassRec(HkdBreakableShape bShape, float minVolume, float minMass)
        {
            if (bShape.Name.Contains("Fake"))
            {
                return(true);
            }
            if (bShape.Volume <= minVolume)
            {
                return(false);
            }
            HkMassProperties mp = new HkMassProperties();

            bShape.BuildMassProperties(ref mp);
            if (mp.Mass <= minMass)
            {
                return(false);
            }
            if (mp.InertiaTensor.M11 == 0 || mp.InertiaTensor.M22 == 0 || mp.InertiaTensor.M33 == 0)
            {
                return(false);
            }
            for (int i = 0; i < bShape.GetChildrenCount(); i++)
            {
                if (!CheckVolumeMassRec(bShape.GetChildShape(i), minVolume, minMass))
                {
                    return(false);
                }
            }
            return(true);
        }
示例#15
0
            public override void CreatePhysicsShape(out HkShape shape, out HkMassProperties massProperties, float mass)
            {
                HkSphereShape shape2 = new HkSphereShape((0.5f * ((MyEntity)base.Entity).Render.GetModel().BoundingSphere.Radius) * base.Entity.PositionComp.Scale.Value);

                shape          = (HkShape)shape2;
                massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(shape2.Radius * 0.5f, mass);
            }
示例#16
0
            public virtual void CreatePhysicsShape(out HkShape shape, out HkMassProperties massProperties, float mass)
            {
                HkBoxShape shape2      = new HkBoxShape(((((MyEntity)base.Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)base.Entity).Render.GetModel().BoundingBox.Min) / 2f) * base.Entity.PositionComp.Scale.Value);
                Vector3    translation = (((MyEntity)base.Entity).Render.GetModel().BoundingBox.Max + ((MyEntity)base.Entity).Render.GetModel().BoundingBox.Min) / 2f;

                shape          = (HkShape) new HkTransformShape((HkShape)shape2, ref translation, ref Quaternion.Identity);
                massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(shape2.HalfExtents, mass);
                massProperties.CenterOfMass = translation;
            }
示例#17
0
 public virtual void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties)
 {
     var boxShape = new HkBoxShape(((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value);
     var pos = ((((MyEntity)Entity).Render.GetModel().BoundingBox.Max + ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2);
     shape = new HkTransformShape(boxShape, ref pos, ref Quaternion.Identity);
     //shape = boxShape;
     massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, boxShape.HalfExtents.Volume * 0.5f);
     massProperties.CenterOfMass = pos;
 }
示例#18
0
            public virtual void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties)
            {
                var boxShape = new HkBoxShape(((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value);
                var pos      = ((((MyEntity)Entity).Render.GetModel().BoundingBox.Max + ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2);

                shape = new HkTransformShape(boxShape, ref pos, ref Quaternion.Identity);
                //shape = boxShape;
                massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, boxShape.HalfExtents.Volume * 0.5f);
                massProperties.CenterOfMass = pos;
            }
示例#19
0
            public override void ScalePhysicsShape(ref HkMassProperties massProperties)
            {
                var shape = RigidBody.GetShape();
                var sphereShape = (HkSphereShape)shape;
                sphereShape.Radius = ((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius * Entity.PositionComp.Scale.Value;
                massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, 1);

                RigidBody.SetShape(sphereShape);
                RigidBody.SetMassProperties(ref massProperties);
                RigidBody.UpdateShape();
            }
 internal void UpdateMassProps(HkRigidBody rb)
 {
     var mp = new HkMassProperties();
     mp.InertiaTensor = rb.InertiaTensor;
     mp.Mass = rb.Mass;
     mp.CenterOfMass = rb.CenterOfMassLocal;
     MassElement = new HkMassElement();
     MassElement.Properties = mp;
     MassElement.Tranform = Transform;
     //MassElement.Tranform.Translation = Vector3.Transform(rb.CenterOfMassLocal, Transform);
 }
示例#21
0
            public virtual void ScalePhysicsShape(ref HkMassProperties massProperties)
            {
                var shape = RigidBody.GetShape();
                var boxShape = (HkBoxShape)shape;
                boxShape.HalfExtents = ((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value;
                massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, massProperties.Mass);

                RigidBody.SetShape(boxShape);
                RigidBody.SetMassProperties(ref massProperties);
                RigidBody.UpdateShape();
            }
 internal void UpdateMassProps(HkRigidBody rb)
 {
     var mp = new HkMassProperties();
     mp.InertiaTensor = rb.InertiaTensor;
     mp.Mass = rb.Mass;
     mp.CenterOfMass = rb.CenterOfMassLocal;
     MassElement = new HkMassElement();
     MassElement.Properties = mp;
     MassElement.Tranform = Transform;
     //MassElement.Tranform.Translation = Vector3.Transform(rb.CenterOfMassLocal, Transform);
 }
示例#23
0
            public override void ScalePhysicsShape(ref HkMassProperties massProperties)
            {
                var shape       = RigidBody.GetShape();
                var sphereShape = (HkSphereShape)shape;

                sphereShape.Radius = ((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius *Entity.PositionComp.Scale.Value;
                massProperties     = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, 1);

                RigidBody.SetShape(sphereShape);
                RigidBody.SetMassProperties(ref massProperties);
                RigidBody.UpdateShape();
            }
示例#24
0
            public virtual void ScalePhysicsShape(ref HkMassProperties massProperties)
            {
                var shape    = RigidBody.GetShape();
                var boxShape = (HkBoxShape)shape;

                boxShape.HalfExtents = ((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value;
                massProperties       = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, massProperties.Mass);

                RigidBody.SetShape(boxShape);
                RigidBody.SetMassProperties(ref massProperties);
                RigidBody.UpdateShape();
            }
示例#25
0
            public override void ScalePhysicsShape(ref HkMassProperties massProperties)
            {
                HkSphereShape shape = (HkSphereShape)this.RigidBody.GetShape();

                shape.Radius = ((MyEntity)base.Entity).Render.GetModel().BoundingSphere.Radius *base.Entity.PositionComp.Scale.Value;
                float mass = this.SphereMass(shape.Radius, 260f);

                massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(shape.Radius, mass);
                this.RigidBody.SetShape((HkShape)shape);
                this.RigidBody.SetMassProperties(ref massProperties);
                this.RigidBody.UpdateShape();
            }
示例#26
0
        public void AllocateForDefinition(string model, MyPhysicalModelDefinition definition, int count)
        {
            if (string.IsNullOrEmpty(model))
            {
                return;
            }
            ProfilerShort.Begin("Clone");
            var data = VRage.Game.Models.MyModels.GetModelOnlyData(model);

            if (data.HavokBreakableShapes == null)
            {
                MyDestructionData.Static.LoadModelDestruction(model, definition, data.BoundingBoxSize);
            }

            if (data.HavokBreakableShapes != null && data.HavokBreakableShapes.Length > 0)
            {
                ConcurrentQueue <HkdBreakableShape> queue;
                using (m_poolLock.AcquireExclusiveUsing())
                {
                    if (!m_pools.ContainsKey(definition.Id))
                    {
                        m_pools[definition.Id] = new Dictionary <string, ConcurrentQueue <HkdBreakableShape> >();
                    }
                    if (!m_pools[definition.Id].ContainsKey(model))
                    {
                        m_pools[definition.Id][model] = new ConcurrentQueue <HkdBreakableShape>();
                    }
                    queue = m_pools[definition.Id][model];
                }
                for (int i = 0; i < count; i++)
                {
                    var shape = data.HavokBreakableShapes[0].Clone();
                    queue.Enqueue(shape);
                    if (i == 0)
                    {
                        var mp = new HkMassProperties();
                        shape.BuildMassProperties(ref mp);
                        if (!mp.InertiaTensor.IsValid())
                        {
                            MyLog.Default.WriteLine(string.Format("Block with wrong destruction! (q.isOk): {0}", definition.Model));
                            break;
                        }
                    }
                }
            }
            ProfilerShort.End();
        }
示例#27
0
        public void InitFromDefinition(MyObjectBuilder_EntityBase entityBuilder, MyDefinitionId definitionId)
        {
            Debug.Assert(entityBuilder != null, "Invalid arguments!");

            MyPhysicalItemDefinition entityDefinition;

            if (!MyDefinitionManager.Static.TryGetDefinition(definitionId, out entityDefinition))
            {
                Debug.Fail("Definition: " + DefinitionId.ToString() + " was not found!");
                return;
            }

            DefinitionId = definitionId;

            Flags |= EntityFlags.Visible | EntityFlags.NeedsDraw | EntityFlags.Sync | EntityFlags.InvalidateOnMove;

            StringBuilder name = new StringBuilder(entityDefinition.DisplayNameText);

            Init(name, entityDefinition.Model, null, null, null);

            CreateSync();

            if (entityBuilder.PositionAndOrientation.HasValue)
            {
                MatrixD worldMatrix = MatrixD.CreateWorld(
                    (Vector3D)entityBuilder.PositionAndOrientation.Value.Position,
                    (Vector3)entityBuilder.PositionAndOrientation.Value.Forward,
                    (Vector3)entityBuilder.PositionAndOrientation.Value.Up);
                PositionComp.SetWorldMatrix(worldMatrix);
            }

            Name = name.Append("_(").Append(entityBuilder.EntityId).Append(")").ToString();

            Render.UpdateRenderObject(true);

            Physics = new Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT);
            if (ModelCollision != null && ModelCollision.HavokCollisionShapes.Length >= 1)
            {
                HkMassProperties massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(entityDefinition.Size / 2, (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(entityDefinition.Mass) : entityDefinition.Mass));;
                Physics.CreateFromCollisionObject(ModelCollision.HavokCollisionShapes[0], Vector3.Zero, WorldMatrix, massProperties);
                Physics.RigidBody.AngularDamping = 2;
                Physics.RigidBody.LinearDamping  = 1;
            }
            Physics.Enabled = true;

            EntityId = entityBuilder.EntityId;
        }
示例#28
0
        public static void InitSpherePhysics(this IMyEntity entity, MyStringHash materialType, Vector3 sphereCenter, float sphereRadius, float mass, float linearDamping, float angularDamping, ushort collisionLayer, RigidBodyFlag rbFlag)
        {
            float single1 = mass;

            mass = ((rbFlag & RigidBodyFlag.RBF_STATIC) != RigidBodyFlag.RBF_DEFAULT) ? 0f : single1;
            MyPhysicsBody body1 = new MyPhysicsBody(entity, rbFlag);

            body1.MaterialType   = materialType;
            body1.AngularDamping = angularDamping;
            body1.LinearDamping  = linearDamping;
            MyPhysicsBody    body       = body1;
            HkMassProperties properties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereRadius, mass);
            HkSphereShape    shape      = new HkSphereShape(sphereRadius);

            body.CreateFromCollisionObject((HkShape)shape, sphereCenter, entity.PositionComp.WorldMatrix, new HkMassProperties?(properties), 15);
            shape.Base.RemoveReference();
            entity.Physics = body;
        }
示例#29
0
        internal static void InitBoxPhysics(this IMyEntity entity, Matrix worldMatrix, MyStringHash materialType, Vector3 center, Vector3 size, float mass, float linearDamping, float angularDamping, ushort collisionLayer, RigidBodyFlag rbFlag)
        {
            float single1 = mass;

            mass = ((rbFlag & RigidBodyFlag.RBF_STATIC) != RigidBodyFlag.RBF_DEFAULT) ? 0f : single1;
            HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(size / 2f, mass);
            MyPhysicsBody    body1      = new MyPhysicsBody(null, rbFlag);

            body1.MaterialType   = materialType;
            body1.AngularDamping = angularDamping;
            body1.LinearDamping  = linearDamping;
            MyPhysicsBody body  = body1;
            HkBoxShape    shape = new HkBoxShape(size * 0.5f);

            body.CreateFromCollisionObject((HkShape)shape, center, worldMatrix, new HkMassProperties?(properties), 15);
            shape.Base.RemoveReference();
            entity.Physics = body;
        }
        private static MyFracturedPiece CreateFracturePiece(ref HkdBreakableShape shape, HkdWorld world, ref MatrixD worldMatrix, bool isStatic)
        {
            Debug.Assert(shape.IsValid());
            ProfilerShort.Begin("CreateFracturePiece");
            var fracturedPiece = MyFracturedPiecesManager.Static.GetPieceFromPool(0);//new MyFracturedPiece();

            fracturedPiece.PositionComp.WorldMatrix = worldMatrix;
            fracturedPiece.Physics.Flags            = isStatic ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS;
            var physicsBody = fracturedPiece.Physics as MyPhysicsBody;//new MyPhysicsBody(fracturedPiece,isFixed ?RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS);

            HkMassProperties mp = new HkMassProperties();

            shape.BuildMassProperties(ref mp);
            physicsBody.InitialSolverDeactivation = HkSolverDeactivation.High;
            physicsBody.CreateFromCollisionObject(shape.GetShape(), Vector3.Zero, worldMatrix, mp);

            physicsBody.LinearDamping  = MyPerGameSettings.DefaultLinearDamping;
            physicsBody.AngularDamping = MyPerGameSettings.DefaultAngularDamping;

            System.Diagnostics.Debug.Assert(physicsBody.BreakableBody == null, "physicsBody.DestructionBody == null");
            physicsBody.BreakableBody = new HkdBreakableBody(shape, physicsBody.RigidBody, world, worldMatrix);
            physicsBody.BreakableBody.AfterReplaceBody += physicsBody.FracturedBody_AfterReplaceBody;
            ProfilerShort.End();

            ProfilerShort.Begin("Sync");
            if (fracturedPiece.SyncFlag)
            {
                fracturedPiece.CreateSync();
            }
            ProfilerShort.End();
            fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
            //physicsBody.RigidBody.ContactPointCallbackDelay = 0;
            //physicsBody.RigidBody.ContactPointCallbackEnabled = true;
            fracturedPiece.Physics = physicsBody;
            //FixPosition(fracturedPiece);
            fracturedPiece.SetDataFromHavok(shape);
            ProfilerShort.Begin("AddToWorld");
            fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
            shape.RemoveReference();
            ProfilerShort.End();
            return(fracturedPiece);
        }
示例#31
0
        public HkMassProperties UpdateMass()
        {
            HkMassElement element = new HkMassElement {
                Tranform = Matrix.Identity
            };
            bool flag = false;

            foreach (Vector3I vectori in base.DirtyCells)
            {
                MySparseGrid <HkMassElement, MassCellData> .Cell cell;
                if (!base.TryGetCell(vectori, out cell))
                {
                    flag = true;
                    continue;
                }
                float num = 0f;
                foreach (KeyValuePair <Vector3I, HkMassElement> pair in cell.Items)
                {
                    TmpElements.Add(pair.Value);
                    num += pair.Value.Properties.Mass;
                }
                if (Math.Abs((float)(1f - (cell.CellData.LastMass / num))) > this.m_updateThreshold)
                {
                    element.Properties        = InertiaComputer.CombineMassPropertiesInstance(TmpElements);
                    cell.CellData.MassElement = element;
                    cell.CellData.LastMass    = num;
                    flag = true;
                }
                TmpElements.Clear();
            }
            base.UnmarkDirtyAll();
            if (flag)
            {
                foreach (KeyValuePair <Vector3I, MySparseGrid <HkMassElement, MassCellData> .Cell> pair2 in this)
                {
                    TmpElements.Add(pair2.Value.CellData.MassElement);
                }
                this.m_massProperties = (TmpElements.Count <= 0) ? new HkMassProperties() : InertiaComputer.CombineMassPropertiesInstance(TmpElements);
                TmpElements.Clear();
            }
            return(this.m_massProperties);
        }
示例#32
0
 public void AllocateForDefinition(string model, MyPhysicalModelDefinition definition, int count)
 {
     if (!string.IsNullOrEmpty(model))
     {
         MyModel modelOnlyData = MyModels.GetModelOnlyData(model);
         if (modelOnlyData.HavokBreakableShapes == null)
         {
             MyDestructionData.Static.LoadModelDestruction(model, definition, modelOnlyData.BoundingBoxSize, true, false);
         }
         if ((modelOnlyData.HavokBreakableShapes != null) && (modelOnlyData.HavokBreakableShapes.Length != 0))
         {
             ConcurrentQueue <HkdBreakableShape> queue;
             using (this.m_poolLock.AcquireExclusiveUsing())
             {
                 if (!this.m_pools.ContainsKey(definition.Id))
                 {
                     this.m_pools[definition.Id] = new Dictionary <string, ConcurrentQueue <HkdBreakableShape> >();
                 }
                 if (!this.m_pools[definition.Id].ContainsKey(model))
                 {
                     this.m_pools[definition.Id][model] = new ConcurrentQueue <HkdBreakableShape>();
                 }
                 queue = this.m_pools[definition.Id][model];
             }
             for (int i = 0; i < count; i++)
             {
                 HkdBreakableShape item = modelOnlyData.HavokBreakableShapes[0].Clone();
                 queue.Enqueue(item);
                 if (i == 0)
                 {
                     HkMassProperties massProperties = new HkMassProperties();
                     item.BuildMassProperties(ref massProperties);
                     if (!massProperties.InertiaTensor.IsValid())
                     {
                         MyLog.Default.WriteLine($"Block with wrong destruction! (q.isOk): {definition.Model}");
                         return;
                     }
                 }
             }
         }
     }
 }
示例#33
0
        private void AddMass(MySlimBlock block, IDictionary <Vector3I, HkMassElement> massResults)
        {
            float mass = block.BlockDefinition.Mass;

            if (MyFakes.ENABLE_COMPOUND_BLOCKS && (block.FatBlock is MyCompoundCubeBlock))
            {
                mass = 0f;
                foreach (MySlimBlock block2 in (block.FatBlock as MyCompoundCubeBlock).GetBlocks())
                {
                    mass += block2.GetMass();
                }
            }
            HkMassProperties properties = new HkMassProperties();
            HkMassElement    element    = new HkMassElement {
                Properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties((((block.Max - block.Min) + Vector3I.One) * block.CubeGrid.GridSize) / 2f, mass),
                Tranform   = Matrix.CreateTranslation(((block.Min + block.Max) * 0.5f) * block.CubeGrid.GridSize)
            };

            massResults[block.Position] = element;
        }
示例#34
0
            // Don't call remove reference on this, this shape is pooled
            protected virtual HkShape GetPhysicsShape(HkMassProperties massProperties, float mass, float scale)
            {
                const bool SimpleShape = false;

                Vector3     halfExtents = (Entity.Render.GetModel().BoundingBox.Max - Entity.Render.GetModel().BoundingBox.Min) / 2;
                HkShapeType shapeType;

                if (VoxelMaterial != null)
                {
                    shapeType      = HkShapeType.Sphere;
                    massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(Entity.Render.GetModel().BoundingSphere.Radius *scale, mass);
                }
                else
                {
                    shapeType      = HkShapeType.Box;
                    massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(halfExtents, mass);
                }

                return(MyDebris.Static.GetDebrisShape(Entity.Render.GetModel(), SimpleShape ? shapeType : HkShapeType.ConvexVertices));
            }
示例#35
0
        private void CreateConstraints()
        {
            this.UpdateDoorPosition();
            bool flag = !Sync.IsServer;

            foreach (MyEntitySubpart subpart in this.m_subparts)
            {
                if (((subpart.Physics == null) && (subpart.ModelCollision.HavokCollisionShapes != null)) && (subpart.ModelCollision.HavokCollisionShapes.Length != 0))
                {
                    HkShape shape = subpart.ModelCollision.HavokCollisionShapes[0];
                    subpart.Physics = new MyPhysicsBody(subpart, flag ? RigidBodyFlag.RBF_STATIC : (RigidBodyFlag.RBF_UNLOCKED_SPEEDS | RigidBodyFlag.RBF_DOUBLED_KINEMATIC));
                    HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(subpart.PositionComp.LocalAABB.HalfExtents, 100f);
                    properties.Volume = subpart.PositionComp.LocalAABB.Volume();
                    subpart.GetPhysicsBody().CreateFromCollisionObject(shape, subpart.PositionComp.LocalVolume.Center, subpart.WorldMatrix, new HkMassProperties?(properties), 9);
                    ((MyPhysicsBody)subpart.Physics).IsSubpart = true;
                }
                if (subpart.Physics != null)
                {
                    if (flag)
                    {
                        subpart.Physics.Enabled = true;
                    }
                    else
                    {
                        HkFixedConstraintData data;
                        HkConstraint          constraint;
                        base.CreateSubpartConstraint(subpart, out data, out constraint);
                        this.m_subpartConstraintsData.Add(data);
                        this.m_subpartConstraints.Add(constraint);
                        base.CubeGrid.Physics.AddConstraint(constraint);
                        constraint.SetVirtualMassInverse(Vector4.Zero, Vector4.One);
                    }
                }
            }
            base.CubeGrid.OnHavokSystemIDChanged -= new Action <int>(this.CubeGrid_OnHavokSystemIDChanged);
            base.CubeGrid.OnHavokSystemIDChanged += new Action <int>(this.CubeGrid_OnHavokSystemIDChanged);
            if (base.CubeGrid.Physics != null)
            {
                this.UpdateHavokCollisionSystemID(base.CubeGrid.GetPhysicsBody().HavokCollisionSystemID, false);
            }
        }
示例#36
0
        /// <summary>
        /// Prepares data for renderer and physics. Must be called after all items has been added.
        /// </summary>
        public void PrepareItems(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld)
        {
            PositionComp.LocalAABB = (BoundingBox)aabbWorld;

            if (sectorRootShape.InstanceCount > 0)
            {
                Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0);

                Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC)
                {
                    MaterialType       = m_definition.Material,
                    AngularDamping     = MyPerGameSettings.DefaultAngularDamping,
                    LinearDamping      = MyPerGameSettings.DefaultLinearDamping,
                    IsStaticForCluster = true,
                };

                sectorRootShape.Bake();
                HkMassProperties massProperties = new HkMassProperties();
                Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, WorldMatrix, massProperties);
                if (Sandbox.Game.MyPerGameSettings.Destruction)
                {
                    Physics.ContactPointCallback += Physics_ContactPointCallback;
                    Physics.RigidBody.ContactPointCallbackEnabled = true;
                }
                sectorRootShape.Base.RemoveReference();

                Physics.Enabled = true;
            }

            foreach (var pair in m_sectors)
            {
                pair.Value.UpdateRenderInstanceData();
            }

            foreach (var pair in m_sectors)
            {
                pair.Value.UpdateRenderEntitiesData(WorldMatrix, m_subtypeToModel);
            }
        }
示例#37
0
            /// <summary>
            /// One time initialization for debris entity. These are settings that do not change
            /// when this debris entity is pulled from the pool.
            /// Also note that this is the only way Debris should be initialized. It calls other Init methods with
            /// correct arguments.
            /// </summary>
            public virtual void Init(MyDebrisBaseDescription desc)
            {
                base.Init(null, desc.Model, null, 1.0f);
                RandomScale = MyUtils.GetRandomFloat(desc.ScaleMin, desc.ScaleMax);
                Container.Entity.PositionComp.Scale = RandomScale;
                LifespanInMiliseconds = MyUtils.GetRandomInt(desc.LifespanMinInMiliseconds, desc.LifespanMaxInMiliseconds);

                HkShape shape;

                m_massProperties         = new HkMassProperties();
                m_massProperties.Mass    = 50;
                Container.Entity.Physics = GetPhysics(RigidBodyFlag.RBF_DEBRIS);
                (Container.Entity.Physics as MyDebrisPhysics).CreatePhysicsShape(out shape, ref m_massProperties);
                (Container.Entity.Physics as MyDebrisPhysics).CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, m_massProperties, MyPhysics.CollisionLayers.DebrisCollisionLayer);
                Container.Entity.Physics.Enabled = false;
                shape.RemoveReference();

                m_entity.Save = false;
                Container.Entity.Physics.PlayCollisionCueEnabled = true;
                NeedsUpdate       = MyEntityUpdateEnum.EACH_FRAME;
                m_onCloseCallback = desc.OnCloseAction;
            }
示例#38
0
            /// <summary>
            /// One time initialization for debris entity. These are settings that do not change 
            /// when this debris entity is pulled from the pool.
            /// Also note that this is the only way Debris should be initialized. It calls other Init methods with 
            /// correct arguments.
            /// </summary>
            public virtual void Init(MyDebrisBaseDescription desc)
            {
                base.Init(null, desc.Model, null, 1.0f);
                m_randomScale = MyUtils.GetRandomFloat(desc.ScaleMin, desc.ScaleMax);
                Container.Entity.PositionComp.Scale = m_randomScale;
                m_lifespanInMiliseconds = MyUtils.GetRandomInt(desc.LifespanMinInMiliseconds, desc.LifespanMaxInMiliseconds);

                HkShape shape;
                m_massProperties = new HkMassProperties();
                m_massProperties.Mass = 50;
                Container.Entity.Physics = GetPhysics(RigidBodyFlag.RBF_DEBRIS);
                (Container.Entity.Physics as MyDebrisPhysics).CreatePhysicsShape(out shape, ref m_massProperties);
                (Container.Entity.Physics as MyDebrisPhysics).CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, m_massProperties, MyPhysics.DebrisCollisionLayer);
                Container.Entity.Physics.Enabled = false;
                shape.RemoveReference();

                m_entity.Save = false;
                Container.Entity.Physics.PlayCollisionCueEnabled = true;
                NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
                m_onCloseCallback = desc.OnCloseAction;
            }
示例#39
0
 public void UpdateMassFromInventories(HashSet<MySlimBlock> blocks, MyPhysicsBody rb)
 {
     if (rb.RigidBody.IsFixedOrKeyframed)
         return;
     ProfilerShort.Begin("GridShape.UpdateMassFromInv");
     Debug.Assert(BreakableShape.IsValid(), "This routine works with breakable shape mass properties.");
     foreach (var block in blocks)
     {
         var owner = block.FatBlock as IMyInventoryOwner;
         if (owner == null) continue;
         float mass = 0;
         for (int i = 0; i < owner.InventoryCount; i++)
         {
             mass += (float)owner.GetInventory(i).CurrentMass;
         }
         var size = (block.Max - block.Min + Vector3I.One) * block.CubeGrid.GridSize;
         var center = (block.Min + block.Max) * 0.5f * block.CubeGrid.GridSize;
         HkMassProperties massProperties = new HkMassProperties();
         massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(size / 2, mass);
         m_tmpElements.Add(new HkMassElement() { Properties = massProperties, Tranform = Matrix.CreateTranslation(center) });
     }
     HkMassProperties originalMp = new HkMassProperties();
     BreakableShape.BuildMassProperties(ref originalMp);
     m_tmpElements.Add(new HkMassElement() { Properties = originalMp, Tranform = Matrix.Identity });
     var mp = HkInertiaTensorComputer.CombineMassProperties(m_tmpElements);
     m_tmpElements.Clear();
     rb.RigidBody.SetMassProperties(ref mp);
     if (!rb.RigidBody.IsActive)
         rb.RigidBody.Activate();
     ProfilerShort.End();
 }
        /// <summary>
        /// Searches for blocks which will create fracture components from cached m_fracturedSlimBlocksShapes
        /// </summary>
        private void FindFractureComponentBlocks()
        {
            Debug.Assert(MyFakes.ENABLE_FRACTURE_COMPONENT);

            foreach (var pair in m_fracturedSlimBlocksShapes)
            {
                var slimBlock = pair.Key;
                var shapeList = pair.Value;

                if (slimBlock.FatBlock.Components.Has<MyFractureComponentBase>())
                {
                    // Block has fracture component - ignore
                    continue;
                }
                else
                {
                    int totalBreakableShapesCountForModel = slimBlock.GetTotalBreakableShapeChildrenCount();
                    Debug.Assert(shapeList.Count <= totalBreakableShapesCountForModel);
                    // No removed pieces? Then ignore.
                    if (slimBlock.BlockDefinition.CreateFracturedPieces && totalBreakableShapesCountForModel == shapeList.Count)
                        continue;

                    foreach (var s in shapeList)
                    {
                        s.SetTransform(ref Matrix.Identity);
                    }
                    ProfilerShort.Begin("CreateShapeComponent");
                    HkdBreakableShape compound = new HkdCompoundBreakableShape(null, shapeList);
                    ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();
                    var mp = new HkMassProperties();
                    compound.BuildMassProperties(ref mp);
                    HkdBreakableShape shape = compound;
                    var sh = compound.GetShape();
                    shape = new HkdBreakableShape(sh, ref mp);
                    //shape.SetMassProperties(mp); //important! pass mp to constructor
                    foreach (var si in shapeList)
                    {
                        var siRef = si;
                        shape.AddShape(ref siRef);
                    }
                    compound.RemoveReference();

                    ProfilerShort.BeginNextBlock("Connect");
                    //shape.SetChildrenParent(shape);
                    ConnectPiecesInBlock(shape, shapeList);

                    MyFractureComponentBase.Info info = new MyFractureComponentBase.Info()
                    {
                        Entity = slimBlock.FatBlock,
                        Shape = shape,
                        Compound = true
                    };

                    m_fractureBlockComponentsCache.Add(info);

                    ProfilerShort.End();
                }
            }

            m_fracturedSlimBlocksShapes.Clear();
        }
示例#41
0
            // Don't call remove reference on this, this shape is pooled
            protected virtual HkShape GetPhysicsShape(HkMassProperties massProperties, float mass, float scale)
            {
                const bool SimpleShape = false;

                Vector3 halfExtents = (Entity.Render.GetModel().BoundingBox.Max - Entity.Render.GetModel().BoundingBox.Min) / 2;
                HkShapeType shapeType;

                if (VoxelMaterial != null)
                {
                    shapeType = HkShapeType.Sphere;
                    massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(Entity.Render.GetModel().BoundingSphere.Radius * scale, mass);
                }
                else
                {
                    shapeType = HkShapeType.Box;
                    massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(halfExtents, mass);
                }

                return MyDebris.Static.GetDebrisShape(Entity.Render.GetModel(), SimpleShape ? shapeType : HkShapeType.ConvexVertices);
            }
示例#42
0
        public override void Init(MyObjectBuilder_EntityBase objectBuilder)
        {
            base.Init(objectBuilder);
            var ob = objectBuilder as MyObjectBuilder_FracturedPiece;
            if (ob.Shapes.Count == 0)
            {
                return;
                //Debug.Fail("Invalid fracture piece! Dont call init without valid OB. Use pool/noinit.");
                //throw new Exception("Fracture piece has no shapes."); //throwing exception, otherwise there is fp with null physics which can mess up somwhere else
            }

            foreach (var shape in ob.Shapes)
            {
                Render.AddPiece(shape.Name, Matrix.CreateFromQuaternion(shape.Orientation));
            }
            OriginalBlocks.Clear();
            foreach (var def in ob.BlockDefinitions)
            {
                string model = null;
                MyPhysicalModelDefinition mdef;
                if (MyDefinitionManager.Static.TryGetDefinition<MyPhysicalModelDefinition>(def, out mdef))
                    model = mdef.Model;
                MyCubeBlockDefinition blockDef = null;
                MyDefinitionManager.Static.TryGetDefinition<MyCubeBlockDefinition>(def, out blockDef);

                if (model == null)
                {
                    Debug.Fail("Fracture piece Definition not found");
                    continue;
                }

                model = mdef.Model;
                if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                    MyDestructionData.Static.LoadModelDestruction(model, mdef, Vector3.One);
                var shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                var si = new HkdShapeInstanceInfo(shape, null, null);
                m_children.Add(si);
                shape.GetChildren(m_children);

                if (blockDef != null && blockDef.BuildProgressModels != null)
                {
                    foreach (var progress in blockDef.BuildProgressModels)
                    {
                        model = progress.File;
                        if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                            MyDestructionData.Static.LoadModelDestruction(model, blockDef, Vector3.One);
                        shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                        si = new HkdShapeInstanceInfo(shape, null, null);
                        m_children.Add(si);
                        shape.GetChildren(m_children);
                    }
                }

                OriginalBlocks.Add(def);
            }
            m_shapes.AddRange(ob.Shapes);

            Vector3? offset = null;
            int shapeAtZero = 0;
            for (int i = 0; i < m_children.Count; i++)
            {
                var child = m_children[i];
                Func<MyObjectBuilder_FracturedPiece.Shape, bool> x = s => s.Name == child.ShapeName;
                var result = m_shapes.Where(x);
                if (result.Count() > 0)
                {
                    var found = result.First();
                    var m = Matrix.CreateFromQuaternion(found.Orientation);
                    if (!offset.HasValue && found.Name == m_shapes[0].Name)
                    {
                        offset = child.GetTransform().Translation;
                        shapeAtZero = m_shapeInfos.Count;
                    }
                    m.Translation = child.GetTransform().Translation;
                    var si = new HkdShapeInstanceInfo(child.Shape.Clone(), m);
                    if(found.Fixed)
                        si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                    m_shapeInfos.Add(si);
                    m_shapes.Remove(found);
                }
                else
                {
                    child.GetChildren(m_children);
                }
            }

            if (m_shapeInfos.Count == 0)
            {
                List<string> shapesToLoad = new List<string>();
                foreach (var obShape in ob.Shapes)
                    shapesToLoad.Add(obShape.Name);

                var shapesStr = shapesToLoad.Aggregate((str1, str2) => str1 + ", " + str2);
                var blocksStr = OriginalBlocks.Aggregate("", (str, defId) => str + ", " + defId.ToString());
                var failMsg = "No relevant shape was found for fractured piece. It was probably reexported and names changed. Shapes: " + shapesStr + ". Original blocks: " + shapesStr;

                Debug.Fail(failMsg);
                //HkdShapeInstanceInfo si = new HkdShapeInstanceInfo(new HkdBreakableShape((HkShape)new HkBoxShape(Vector3.One)), Matrix.Identity);
                //m_shapeInfos.Add(si);
                throw new Exception(failMsg);
            }

            if (offset.HasValue)
            {
                for (int i = 0; i < m_shapeInfos.Count; i++)
                {
                    var m = m_shapeInfos[i].GetTransform();
                    m.Translation -= offset.Value;
                    m_shapeInfos[i].SetTransform(ref m);
                }
                {
                    var m = m_shapeInfos[shapeAtZero].GetTransform();
                    m.Translation = Vector3.Zero;
                    m_shapeInfos[shapeAtZero].SetTransform(ref m);
                }
            }

            if (m_shapeInfos.Count > 0)
            {
                if (m_shapeInfos.Count == 1)
                    Shape = m_shapeInfos[0].Shape;
                else
                {
                    Shape = new HkdCompoundBreakableShape(null, m_shapeInfos);
                    ((HkdCompoundBreakableShape)Shape).RecalcMassPropsFromChildren();
                }
                Shape.SetStrenght(MyDestructionConstants.STRENGTH);
                var mp = new HkMassProperties();
                Shape.BuildMassProperties(ref mp);
                Shape.SetChildrenParent(Shape);
                Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);
                Physics.CanUpdateAccelerations = true;
                Physics.InitialSolverDeactivation = HkSolverDeactivation.High;
                Physics.CreateFromCollisionObject(Shape.GetShape(), Vector3.Zero, PositionComp.WorldMatrix, mp);
                Physics.BreakableBody = new HkdBreakableBody(Shape, Physics.RigidBody, null, (Matrix)PositionComp.WorldMatrix);
                Physics.BreakableBody.AfterReplaceBody += Physics.FracturedBody_AfterReplaceBody;

                if (OriginalBlocks.Count > 0)
                {
                    MyPhysicalModelDefinition def;
                    if (MyDefinitionManager.Static.TryGetDefinition<MyPhysicalModelDefinition>(OriginalBlocks[0], out def))
                        Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId;
                }


                var rigidBody = Physics.RigidBody;
                bool isFixed = MyDestructionHelper.IsFixed(Physics.BreakableBody.BreakableShape);
                if (isFixed)
                {
                    rigidBody.UpdateMotionType(HkMotionType.Fixed);
                    rigidBody.LinearVelocity = Vector3.Zero;
                    rigidBody.AngularVelocity = Vector3.Zero;
                }


                Physics.Enabled = true;
            }
            m_children.Clear();
            m_shapeInfos.Clear();
        }
示例#43
0
        /// <summary>
        /// Prepares data for renderer and physics. Must be called after all items has been added.
        /// </summary>
      
        private void PrepareItemsPhysics(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld, Dictionary<MyStringHash, HkShape> subtypeIdToShape)
        {
            foreach (var item in m_itemsData)
            {
                if (!item.Value.Enabled)
                    continue;

                int physicsShapeInstanceId;
                MatrixD transform = item.Value.Transform.TransformMatrix;
                if (AddPhysicsShape(item.Value.SubtypeId, item.Value.Model, ref transform, sectorRootShape, subtypeIdToShape, out physicsShapeInstanceId))
                {
                    // Map to data index - note that itemData is added after this to its list!
                    m_physicsShapeInstanceIdToLocalId[physicsShapeInstanceId] = item.Value.Id;
                    m_localIdToPhysicsShapeInstanceId[item.Value.Id] = physicsShapeInstanceId;

                }
            }

            PositionComp.WorldAABB = aabbWorld;

            if (sectorRootShape.InstanceCount > 0)
            {
                Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0);

                Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC)
                {
                    MaterialType = m_definition.Material,
                    AngularDamping = MyPerGameSettings.DefaultAngularDamping,
                    LinearDamping = MyPerGameSettings.DefaultLinearDamping,
                    IsStaticForCluster = true,
                };

                sectorRootShape.Bake();
                HkMassProperties massProperties = new HkMassProperties();
                MatrixD matrix = MatrixD.CreateTranslation(CellsOffset);
                Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, matrix, massProperties);

                Physics.ContactPointCallback += Physics_ContactPointCallback;
                Physics.RigidBody.ContactPointCallbackEnabled = true;

                Physics.Enabled = true;
            }           
        }
        public override void Init(MyObjectBuilder_CubeBlock builder, MyCubeGrid cubeGrid)
        {
            base.Init(builder, cubeGrid);
            ProfilerShort.Begin("FP.Init");
            CheckConnectionAllowed = true;
            var ob = builder as MyObjectBuilder_FracturedBlock;
            if (ob.Shapes.Count == 0)
            {
                ProfilerShort.End();
                return;
            }
            
            OriginalBlocks = new List<MyDefinitionId>();
            Orientations = new List<MyBlockOrientation>();
            var lst = new List<HkdShapeInstanceInfo>();
            foreach (var def in ob.BlockDefinitions)
            {
                var blockDef = MyDefinitionManager.Static.GetCubeBlockDefinition(def);
                if (MyModels.GetModelOnlyData(blockDef.Model).HavokBreakableShapes == null)
                {
                    MyDestructionData.Static.LoadModelDestruction(blockDef, false, Vector3.One);
                }
                var shape = MyModels.GetModelOnlyData(blockDef.Model).HavokBreakableShapes[0];
                var si = new HkdShapeInstanceInfo(shape, null, null);
                lst.Add(si);
                m_children.Add(si);
                shape.GetChildren(m_children);
                OriginalBlocks.Add(def);
            }
            foreach (var or in ob.BlockOrientations)
            {
                Orientations.Add(or);
            }
            m_shapes.AddRange(ob.Shapes);
            for (int i = 0; i < m_children.Count; i++)
            {
                var child = m_children[i];
                Func<MyObjectBuilder_FracturedBlock.ShapeB, bool> x = s => s.Name == child.ShapeName;
                var result = m_shapes.Where(x);
                if (result.Count() > 0)
                {
                    var found = result.First();
                    var m = Matrix.CreateFromQuaternion(found.Orientation);
                    m.Translation = child.GetTransform().Translation;
                    var si = new HkdShapeInstanceInfo(child.Shape.Clone(), m);
                    if(found.Fixed)
                        si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                    lst.Add(si);
                    m_shapeInfos.Add(si);
                    m_shapes.Remove(found);
                }
                else
                {
                    child.GetChildren(m_children);
                }
            }

            if (m_shapeInfos.Count == 0)
            {
                m_children.Clear();
                ProfilerShort.End();
                Debug.Fail("No relevant shape was found for fractured block. It was probably reexported and names changed.");
                throw new Exception("No relevant shape was found for fractured block. It was probably reexported and names changed.");
            }

            foreach (var shape in m_shapeInfos)
            {
                if(! string.IsNullOrEmpty(shape.Shape.Name))
                    Render.AddPiece(shape.Shape.Name, Matrix.CreateFromQuaternion(Quaternion.CreateFromRotationMatrix(shape.GetTransform().GetOrientation())));
            }

            if (CubeGrid.CreatePhysics)
            {
                HkdBreakableShape compound = new HkdCompoundBreakableShape(null, m_shapeInfos);
                ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();
                Shape = compound;
                var mp = new HkMassProperties();
                compound.BuildMassProperties(ref mp);
                Shape = new HkdBreakableShape(compound.GetShape(), ref mp);
                compound.RemoveReference();
                foreach (var si in m_shapeInfos)
                {
                    var siRef = si;
                    Shape.AddShape(ref siRef);
                }
                Shape.SetStrenght(MyDestructionConstants.STRENGTH);
                CreateMountPoints();
            }
            m_children.Clear();
            foreach (var si in m_shapeInfos)
                si.Shape.RemoveReference();
            foreach (var si in lst)
                si.RemoveReference();
            m_shapeInfos.Clear();

            ProfilerShort.End();
        }
 private bool CheckVolumeMassRec(HkdBreakableShape bShape, float minVolume, float minMass)
 {
     if (bShape.Name.Contains("Fake"))
         return true;
     if (bShape.Volume <= minVolume)
         return false;
     HkMassProperties mp = new HkMassProperties();
     bShape.BuildMassProperties(ref mp);
     if (mp.Mass <= minMass)
         return false;
     if (mp.InertiaTensor.M11 == 0 || mp.InertiaTensor.M22 == 0 || mp.InertiaTensor.M33 == 0)
         return false;
     for (int i = 0; i < bShape.GetChildrenCount(); i++)
     {
         if (!CheckVolumeMassRec(bShape.GetChildShape(i), minVolume, minMass))
             return false;
     }
     return true;
 }
示例#46
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);

            string model = physicalItem.Model;

            VoxelMaterial = null;
            float scale = 1.0f;

            if (Item.Content is MyObjectBuilder_Ore)
            {
                string oreSubTypeId = physicalItem.Id.SubtypeId.ToString();
                foreach (var mat in MyDefinitionManager.Static.GetVoxelMaterialDefinitions())
                {
                    if (oreSubTypeId == mat.MinedOre)
                    {
                        VoxelMaterial = mat;
                        model = MyDebris.GetRandomDebrisVoxel();
                        scale = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f);
                        break;
                    }
                }

                scale = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f);
            }

            if (scale < 0.05f)
                Close();
            else if (scale < 0.15f)
                scale = 0.15f;

            FormatDisplayName(m_displayedText, Item);
            Init(m_displayedText, model, null, null, null);

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


            var massProperties = new HkMassProperties();
            HkShape shape = GetPhysicsShape(physicalItem.Mass * (float)Item.Amount, scale, out massProperties);
            var scaleMatrix = Matrix.CreateScale(scale);

            if (Physics != null)
                Physics.Close();
            Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS);

            if (VoxelMaterial != null)
            {
                HkConvexTransformShape transform = new HkConvexTransformShape((HkConvexShape)shape, ref scaleMatrix, HkReferencePolicy.None);
        
                Physics.CreateFromCollisionObject(transform, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.FloatingObjectCollisionLayer);
               
                Physics.Enabled = true;
                transform.Base.RemoveReference();
            }
            else
            {
                Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.FloatingObjectCollisionLayer);
                Physics.Enabled = true;
            }

            Physics.MaterialType = VoxelMaterial != null ? MyMaterialType.ROCK : MyMaterialType.METAL;
            Physics.PlayCollisionCueEnabled = true;

            NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME;
        }
示例#47
0
        protected virtual void CreateBody(ref HkShape shape, HkMassProperties? massProperties)
        {
            ProfilerShort.Begin("CreateBody");
            HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo();

            rbInfo.AngularDamping = m_angularDamping;
            rbInfo.LinearDamping = m_linearDamping;
            rbInfo.Shape = shape;
            rbInfo.SolverDeactivation = InitialSolverDeactivation;
            rbInfo.ContactPointCallbackDelay = ContactPointDelay;

            if (massProperties.HasValue)
            {
                rbInfo.SetMassProperties(massProperties.Value);
            }

            GetInfoFromFlags(rbInfo, Flags);

            RigidBody = new HkRigidBody(rbInfo);

            ProfilerShort.End();
        }
示例#48
0
 public virtual void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties)
 {
     var boxShape = new HkBoxShape(((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value);
     shape = boxShape;
     massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, massProperties.Mass);
 }
示例#49
0
        private HkdBreakableShape? CreateBlockShape(Sandbox.Game.Entities.Cube.MySlimBlock b, out Matrix blockTransform)
        {
            ProfilerShort.Begin("CreateBlockShape");
            blockTransform = Matrix.Identity;
            if (b.FatBlock == null)
            {
                Debug.Fail("Armor blocks are not allowed in medieval");
                ProfilerShort.End();
                return null;
            }

            HkdBreakableShape breakableShape;
            Matrix compoundChildTransform = Matrix.Identity;

            if (b.FatBlock is MyCompoundCubeBlock)
            {
                ProfilerShort.Begin("Cmpnd");
                blockTransform.Translation = b.FatBlock.PositionComp.LocalMatrix.Translation;
                var cb = b.FatBlock as MyCompoundCubeBlock;
                if (cb.GetBlocksCount() == 1)
                {
                    ProfilerShort.Begin("SingleBlock");
                    var block = cb.GetBlocks()[0];
                    var defId = block.FatBlock.BlockDefinition;
                    Matrix m;
                    var model = block.CalculateCurrentModel(out m);
                    if (MyFakes.LAZY_LOAD_DESTRUCTION || HasBreakableShape(model, defId))
                    {
                        ProfilerShort.Begin("Clone");
                        breakableShape = GetBreakableShape(model, defId);
                        ProfilerShort.End();
                    }

                    block.Orientation.GetMatrix(out compoundChildTransform);
                    blockTransform = compoundChildTransform * blockTransform;
                    ProfilerShort.End();
                }
                else
                {
                    var pos = b.Position * m_grid.GridSize;

                    float mass = 0;
                    ProfilerShort.Begin("GetBlocks");
                    foreach (var block in cb.GetBlocks())
                    {
                        block.Orientation.GetMatrix(out compoundChildTransform);
                        compoundChildTransform.Translation = Vector3.Zero;
                        var blockDef = block.BlockDefinition;
                        Matrix m;
                        var model = block.CalculateCurrentModel(out m);
                        if (MyFakes.LAZY_LOAD_DESTRUCTION || HasBreakableShape(model, blockDef))
                        {
                            ProfilerShort.Begin("Clone");

                            breakableShape = GetBreakableShape(model, blockDef);
                            breakableShape.UserObject |= (uint)HkdBreakableShape.Flags.FRACTURE_PIECE;
                            System.Diagnostics.Debug.Assert(breakableShape.IsValid(), "Invalid breakableShape");

                            ProfilerShort.End();
                            mass += blockDef.Mass;
                            m_shapeInfosList2.Add(new HkdShapeInstanceInfo(breakableShape, compoundChildTransform));
                        }
                    }

                    if (m_shapeInfosList2.Count == 0)
                    {
                        ProfilerShort.End();
                        return null;
                    }

                    ProfilerShort.BeginNextBlock("CreateCompoundBlockShape");
                    //HkShape hkpShape = new HkListShape(m_khpShapeList.ToArray(), m_khpShapeList.Count, HkReferencePolicy.None);
                    //m_khpShapeList.Clear();
                    HkdBreakableShape compound = new HkdCompoundBreakableShape(null, m_shapeInfosList2);
                    ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();
                    var mp = new HkMassProperties();
                    compound.BuildMassProperties(ref mp);
                    breakableShape = new HkdBreakableShape(compound.GetShape(), ref mp);
                    compound.RemoveReference();
                    foreach (var si in m_shapeInfosList2)
                    {
                        var siRef = si;
                        breakableShape.AddShape(ref siRef);
                    }

                    ProfilerShort.BeginNextBlock("Connect");
                    //slow slow slow
                    //breakableShape.AutoConnect(MyDestructionData.Static.TemporaryWorld);
                    //slow wrong
                    //breakableShape.ConnectSemiAccurate(MyDestructionData.Static.TemporaryWorld);
                    //fast frong
                    for (int i = 0; i < m_shapeInfosList2.Count; i++)
                    {
                        for (int j = 0; j < m_shapeInfosList2.Count; j++)
                        {
                            if (i != j)
                            {
                                ConnectShapesWithChildren(breakableShape, m_shapeInfosList2[i].Shape, m_shapeInfosList2[j].Shape);
                            }
                        }
                    }
                    ProfilerShort.BeginNextBlock("Cleanup");
                    foreach (var si in m_shapeInfosList2)
                    {
                        si.Shape.RemoveReference();
                        si.RemoveReference();
                    }
                    m_shapeInfosList2.Clear();
                    ProfilerShort.End();
                }
                ProfilerShort.End();
            }
            else
            {
                ProfilerShort.Begin("SingleBlock");
                b.Orientation.GetMatrix(out blockTransform);
                blockTransform.Translation = b.FatBlock.PositionComp.LocalMatrix.Translation;
                Matrix m;
                var model = b.CalculateCurrentModel(out m);
                if (b.FatBlock is MyFracturedBlock)
                {
                    ProfilerShort.Begin("CloneFracture");
                    breakableShape = (b.FatBlock as MyFracturedBlock).Shape;
                    if(!breakableShape.IsValid())
                    {
                        Debug.Fail("Fractured block Breakable shape invalid!");
                        throw new Exception("Fractured block Breakable shape invalid!");
                    }
                    breakableShape.AddReference();
                    ProfilerShort.End();
                }
                else if (MyFakes.LAZY_LOAD_DESTRUCTION || HasBreakableShape(model, b.BlockDefinition))
                {
                    ProfilerShort.Begin("Clone");
                    breakableShape = GetBreakableShape(model, b.BlockDefinition);
                    ProfilerShort.End();
                }
                ProfilerShort.End();
            }
            ProfilerShort.Begin("Property");
            HkPropertyBase posProp = new HkVec3IProperty(b.Position);
            Debug.Assert(breakableShape.IsValid());
            breakableShape.SetPropertyRecursively(HkdBreakableShape.PROPERTY_GRID_POSITION, posProp);
            posProp.RemoveReference();
            ProfilerShort.End();
            //breakableShape.DisableRefCountRecursively();
            ProfilerShort.End();
            return breakableShape;
        }
        private HkShape CreateBreakableBody(HkShape shape, HkMassProperties? massProperties)
        {
            ProfilerShort.Begin("CreateGridBody");

            HkdBreakableShape breakable;
            HkMassProperties massProps = massProperties.HasValue ? massProperties.Value : new HkMassProperties();

            if (!Shape.BreakableShape.IsValid())
                Shape.CreateBreakableShape();

            breakable = Shape.BreakableShape;

            if (!breakable.IsValid())
            {
                breakable = new HkdBreakableShape(shape);
                if (massProperties.HasValue)
                {
                    var mp = massProperties.Value;
                    breakable.SetMassProperties(ref mp);
                }
                else
                    breakable.SetMassRecursively(50);
            }
            else
                breakable.BuildMassProperties(ref massProps);

            shape = breakable.GetShape(); //doesnt add reference
            HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo();
            rbInfo.AngularDamping = m_angularDamping;
            rbInfo.LinearDamping = m_linearDamping;
            rbInfo.SolverDeactivation = m_grid.IsStatic ? InitialSolverDeactivation : HkSolverDeactivation.Low;
            rbInfo.ContactPointCallbackDelay = ContactPointDelay;
            rbInfo.Shape = shape;
            rbInfo.SetMassProperties(massProps);
            //rbInfo.Position = Entity.PositionComp.GetPosition(); //obsolete with large worlds?
            GetInfoFromFlags(rbInfo, Flags);
            if (m_grid.IsStatic)
            {
                rbInfo.MotionType = HkMotionType.Dynamic;
                rbInfo.QualityType = HkCollidableQualityType.Moving;
            }
            HkRigidBody rb = new HkRigidBody(rbInfo);
            if (m_grid.IsStatic)
            {
                rb.UpdateMotionType(HkMotionType.Fixed);
            }
            rb.EnableDeactivation = true;
            BreakableBody = new HkdBreakableBody(breakable, rb, null, Matrix.Identity);
            //DestructionBody.ConnectToWorld(HavokWorld, 0.05f);

            BreakableBody.AfterReplaceBody += FracturedBody_AfterReplaceBody;

            //RigidBody.SetWorldMatrix(Entity.PositionComp.WorldMatrix);
            //breakable.Dispose();

            ProfilerShort.End();
            return shape;
        }
        private void InitDeadBodyPhysics()
        {
            Vector3 velocity = Vector3.Zero;

            RadioBroadcaster.BroadcastRadius = 5;

            if (Physics != null)
            {
                velocity = Physics.LinearVelocity;

                Physics.Enabled = false;
                Physics.Close();
                Physics = null;
            }

            //if (Physics == null)
            {
                var massProperties = new HkMassProperties();
                massProperties.Mass = 500;

                HkShape shape;
                // CH: Need to rethink this. It does not belong here, but I don't want to add "DeadCharacterBodyCenterOfMass" to the character definition either...
                // MZ: See ticket "Correct dying for characters", https://app.asana.com/0/64822442925263/75411538582998
                //     dead body shape can now be specified in character's SBC
                if (Definition.DeadBodyShape != null)
                {
                    HkBoxShape bshape = new HkBoxShape(PositionComp.LocalAABB.HalfExtents * Definition.DeadBodyShape.BoxShapeScale);
                    massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(bshape.HalfExtents, massProperties.Mass);
                    massProperties.CenterOfMass = bshape.HalfExtents * Definition.DeadBodyShape.RelativeCenterOfMass;
                    shape = bshape;

                    Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT);
                    Vector3D offset = PositionComp.LocalAABB.HalfExtents * Definition.DeadBodyShape.RelativeShapeTranslation;
                    MatrixD pos = MatrixD.CreateTranslation(offset);
                    Physics.CreateFromCollisionObject(shape, PositionComp.LocalVolume.Center + offset, pos, massProperties, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer);
                    Physics.Friction = Definition.DeadBodyShape.Friction;
                    Physics.RigidBody.MaxAngularVelocity = MathHelper.PiOver2;
                    Physics.LinearVelocity = velocity;
                    shape.RemoveReference();

                    Physics.Enabled = true;
                }
                else // no special definition => use AABB
                {
                    HkBoxShape bshape = new HkBoxShape(PositionComp.LocalAABB.HalfExtents);
                    massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(bshape.HalfExtents, massProperties.Mass);
                    massProperties.CenterOfMass = new Vector3(bshape.HalfExtents.X, 0, 0);
                    shape = bshape;

                    Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT);
                    Physics.CreateFromCollisionObject(shape, PositionComp.LocalVolume.Center, MatrixD.Identity, massProperties, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer);
                    Physics.Friction = 0.5f;
                    Physics.RigidBody.MaxAngularVelocity = MathHelper.PiOver2;
                    Physics.LinearVelocity = velocity;
                    shape.RemoveReference();

                    Physics.Enabled = true;
                }
            }

            NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
        }
        private void FindFracturedBlocks(HkdBreakableBodyInfo b)
        {
            ProfilerShort.Begin("DBHelper");
            var dbHelper = new HkdBreakableBodyHelper(b);
            ProfilerShort.BeginNextBlock("GetRBMatrix");
            var bodyMatrix = dbHelper.GetRigidBodyMatrix();
            ProfilerShort.BeginNextBlock("SearchChildren");
            dbHelper.GetChildren(m_children);
            foreach (var child in m_children)
            {
                if (!child.IsFracturePiece())
                    continue;
                //var blockPosWorld = ClusterToWorld(Vector3.Transform(child.GetTransform().Translation, bodyMatrix));
                var bShape = child.Shape;
                HkVec3IProperty pProp = bShape.GetProperty(HkdBreakableShape.PROPERTY_GRID_POSITION);
                var blockPos = pProp.Value; //Vector3I.Round(child.GetTransform().Translation / m_grid.GridSize);
                if (!m_grid.CubeExists(blockPos))
                {
                    //Debug.Fail("FindFracturedBlocks:Fracture piece missing block");//safe to ignore
                    continue;
                }

                if (MyFakes.ENABLE_FRACTURE_COMPONENT)
                {
                    var block = m_grid.GetCubeBlock(blockPos);
                    if (block == null)
                        continue;

                    if (!FindFractureComponentBlocks(block, child))
                        continue;
                }
                else
                {
                    if (!m_fracturedBlocksShapes.ContainsKey(blockPos))
                        m_fracturedBlocksShapes[blockPos] = new List<HkdShapeInstanceInfo>();
                    m_fracturedBlocksShapes[blockPos].Add(child);
                }
            }
            ProfilerShort.BeginNextBlock("CreateFreacturedBlocks");
            if (!MyFakes.ENABLE_FRACTURE_COMPONENT)
            {
                foreach (var key in m_fracturedBlocksShapes.Keys)
                {
                    HkdBreakableShape shape;
                    var shapeList = m_fracturedBlocksShapes[key];
                    foreach (var s in shapeList)
                    {
                        var matrix = s.GetTransform();
                        matrix.Translation = Vector3.Zero;
                        s.SetTransform(ref matrix);
                    }
                    ProfilerShort.Begin("CreateShape");
                    HkdBreakableShape compound = new HkdCompoundBreakableShape(null, shapeList);
                    ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();
                    var mp = new HkMassProperties();
                    compound.BuildMassProperties(ref mp);
                    shape = compound;
                    var sh = compound.GetShape();
                    shape = new HkdBreakableShape(sh, ref mp);
                    //shape.SetMassProperties(mp); //important! pass mp to constructor
                    foreach (var si in shapeList)
                    {
                        var siRef = si;
                        shape.AddShape(ref siRef);
                    }
                    compound.RemoveReference();
                    ProfilerShort.BeginNextBlock("Connect");
                    //shape.SetChildrenParent(shape);
                    ConnectPiecesInBlock(shape, shapeList);
                    ProfilerShort.End();

                    var info = new MyFracturedBlock.Info()
                    {
                        Shape = shape,
                        Position = key,
                        Compound = true,
                    };
                    var originalBlock = m_grid.GetCubeBlock(key);
                    if (originalBlock == null)
                    {
                        //Debug.Fail("Missing fracture piece original block.");//safe to ignore
                        shape.RemoveReference();
                        continue;
                    }
                    Debug.Assert(originalBlock != null);
                    if (originalBlock.FatBlock is MyFracturedBlock)
                    {
                        var fractured = originalBlock.FatBlock as MyFracturedBlock;
                        info.OriginalBlocks = fractured.OriginalBlocks;
                        info.Orientations = fractured.Orientations;
                        info.MultiBlocks = fractured.MultiBlocks;
                    }
                    else if (originalBlock.FatBlock is MyCompoundCubeBlock)
                    {
                        info.OriginalBlocks = new List<MyDefinitionId>();
                        info.Orientations = new List<MyBlockOrientation>();
                        MyCompoundCubeBlock compoundBlock = originalBlock.FatBlock as MyCompoundCubeBlock;
                        bool hasMultiBlockPart = false;
                        var blocksInCompound = compoundBlock.GetBlocks();
                        foreach (var block in blocksInCompound)
                        {
                            info.OriginalBlocks.Add(block.BlockDefinition.Id);
                            info.Orientations.Add(block.Orientation);

                            hasMultiBlockPart = hasMultiBlockPart || block.IsMultiBlockPart;
                        }

                        if (hasMultiBlockPart)
                        {
                            info.MultiBlocks = new List<MyFracturedBlock.MultiBlockPartInfo>();

                            foreach (var block in blocksInCompound)
                            {
                                if (block.IsMultiBlockPart)
                                    info.MultiBlocks.Add(new MyFracturedBlock.MultiBlockPartInfo() { MultiBlockDefinition = block.MultiBlockDefinition.Id, MultiBlockId = block.MultiBlockId });
                                else
                                    info.MultiBlocks.Add(null);
                            }
                        }
                    }
                    else
                    {
                        info.OriginalBlocks = new List<MyDefinitionId>();
                        info.Orientations = new List<MyBlockOrientation>();
                        info.OriginalBlocks.Add(originalBlock.BlockDefinition.Id);
                        info.Orientations.Add(originalBlock.Orientation);

                        if (originalBlock.IsMultiBlockPart)
                        {
                            info.MultiBlocks = new List<MyFracturedBlock.MultiBlockPartInfo>();
                            info.MultiBlocks.Add(new MyFracturedBlock.MultiBlockPartInfo() { MultiBlockDefinition = originalBlock.MultiBlockDefinition.Id, MultiBlockId = originalBlock.MultiBlockId });
                        }
                    }
                    m_fractureBlocksCache.Add(info);
                }
            }
            m_fracturedBlocksShapes.Clear();
            m_children.Clear();

            ProfilerShort.End();
        }
示例#53
0
        protected override void CreateBody(ref HkShape shape, HkMassProperties? massProperties)
        {
            if (MyPerGameSettings.Destruction)// && shape.ShapeType == HkShapeType.StaticCompound)
            {
                shape = CreateBreakableBody(shape, massProperties);
            }
            else
            {
                HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo();

                rbInfo.AngularDamping = m_angularDamping;
                rbInfo.LinearDamping = m_linearDamping;
                rbInfo.Shape = shape;
                rbInfo.SolverDeactivation = InitialSolverDeactivation;
                rbInfo.ContactPointCallbackDelay = ContactPointDelay;

                if (massProperties.HasValue)
                {
                    rbInfo.SetMassProperties(massProperties.Value);
                }

                GetInfoFromFlags(rbInfo, Flags);
                if (m_grid.IsStatic)
                {
                    rbInfo.MotionType = HkMotionType.Dynamic;
                    rbInfo.QualityType = HkCollidableQualityType.Moving;
                }
                RigidBody = new HkRigidBody(rbInfo);

                if (m_grid.IsStatic)
                {
                    RigidBody.UpdateMotionType(HkMotionType.Fixed);
                }
                //RigidBody.UpdateMotionType(HkMotionType.Dynamic);

                //base.CreateBody(ref shape, massProperties);
            }
        }
示例#54
0
        protected override void CreateBody(ref HkShape shape, HkMassProperties? massProperties)
        {
            if (MyPerGameSettings.Destruction)// && shape.ShapeType == HkShapeType.StaticCompound)
            {
                ProfilerShort.Begin("CreateGridBody");

                HkdBreakableShape breakable;
                HkMassProperties massProps = massProperties.HasValue ? massProperties.Value : new HkMassProperties();

                if (!Shape.BreakableShape.IsValid())
                    Shape.CreateBreakableShape();

                breakable = Shape.BreakableShape;

                if (!breakable.IsValid())
                {
                    breakable = new HkdBreakableShape(shape);
                    if (massProperties.HasValue)
                    {
                        var mp = massProperties.Value;
                        breakable.SetMassProperties(ref mp);
                    }
                    else
                        breakable.SetMassRecursively(50);
                }
                else
                    breakable.BuildMassProperties(ref massProps);

                shape = breakable.GetShape(); //doesnt add reference
                HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo();
                rbInfo.AngularDamping = m_angularDamping;
                rbInfo.LinearDamping = m_linearDamping;
                rbInfo.SolverDeactivation = m_grid.IsStatic ? InitialSolverDeactivation : HkSolverDeactivation.Low;
                rbInfo.ContactPointCallbackDelay = ContactPointDelay;
                rbInfo.Shape = shape;
                rbInfo.SetMassProperties(massProps);
                //rbInfo.Position = Entity.PositionComp.GetPosition(); //obsolete with large worlds?
                GetInfoFromFlags(rbInfo, Flags);
                HkRigidBody rb = new HkRigidBody(rbInfo);
                rb.EnableDeactivation = true;
                BreakableBody = new HkdBreakableBody(breakable, rb, MyPhysics.SingleWorld.DestructionWorld, Matrix.Identity);
                //DestructionBody.ConnectToWorld(HavokWorld, 0.05f);

                BreakableBody.AfterReplaceBody += FracturedBody_AfterReplaceBody;

                //RigidBody.SetWorldMatrix(Entity.PositionComp.WorldMatrix);
                //breakable.Dispose();

                ProfilerShort.End();
            }
            else
            {
                base.CreateBody(ref shape, massProperties);            
            }
        }
示例#55
0
        public virtual void CreateFromCollisionObject(HkShape shape, Vector3 center, MatrixD worldTransform, HkMassProperties? massProperties = null, int collisionFilter = MyPhysics.DefaultCollisionLayer)
        {
            MyPhysics.AssertThread();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyPhysicsBody::CreateFromCollisionObject()");
            Debug.Assert(RigidBody == null, "Must be removed from scene and null");

            CloseRigidBody();

            Center = center;
            CanUpdateAccelerations = true;

            //m_motionState = new MyMotionState(worldTransform);

            CreateBody(ref shape, massProperties);

            RigidBody.UserObject = this;
            //RigidBody.SetWorldMatrix(worldTransform);
            RigidBody.Layer = collisionFilter;

            if ((int)(Flags & RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE) > 0)
            {
                RigidBody.Layer = MyPhysics.NoCollisionLayer;
            }
            
            if ((int)(Flags & RigidBodyFlag.RBF_DOUBLED_KINEMATIC) > 0)
            {
                HkRigidBodyCinfo rbInfo2 = new HkRigidBodyCinfo();
                rbInfo2.AngularDamping = m_angularDamping;
                rbInfo2.LinearDamping = m_linearDamping;
                rbInfo2.Shape = shape;

                rbInfo2.MotionType = HkMotionType.Keyframed;
                rbInfo2.QualityType = HkCollidableQualityType.Keyframed;

                RigidBody2 = new HkRigidBody(rbInfo2);
                RigidBody2.UserObject = this;
                RigidBody2.SetWorldMatrix(worldTransform);
            }

            //m_motionState.Body = this;

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
        protected override void RecreateShape(List<MyObjectBuilder_FractureComponentBase.FracturedShape> shapeList)
        {
            Debug.Assert(m_tmpChildren.Count == 0);
            Debug.Assert(m_tmpShapeInfos.Count == 0);

            ProfilerShort.Begin("FractureComponent.RecreateShape");

            if (Shape.IsValid())
            {
                Shape.RemoveReference();
                Shape = new HkdBreakableShape();
            }

            var render = Block.FatBlock.Render as MyRenderComponentFracturedPiece;
            if (render != null)
            {
                render.ClearModels();
                render.UpdateRenderObject(false);
            }
            else
            {
                Debug.Fail("Invalid render type");
            }

            if (shapeList.Count == 0)
            {
                ProfilerShort.End();
                return;
            }

            var removeRefsList = new List<HkdShapeInstanceInfo>();

            {
                var blockDef = Block.BlockDefinition;
                var model = blockDef.Model;
                if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                    MyDestructionData.Static.LoadModelDestruction(model, blockDef, Vector3.One);

                var shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                var si = new HkdShapeInstanceInfo(shape, null, null);
                removeRefsList.Add(si);
                m_tmpChildren.Add(si);
                shape.GetChildren(m_tmpChildren);

                if (blockDef.BuildProgressModels != null)
                {
                    foreach (var progress in blockDef.BuildProgressModels)
                    {
                        model = progress.File;

                        if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                            MyDestructionData.Static.LoadModelDestruction(model, blockDef, Vector3.One);

                        shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                        si = new HkdShapeInstanceInfo(shape, null, null);
                        removeRefsList.Add(si);
                        m_tmpChildren.Add(si);
                        shape.GetChildren(m_tmpChildren);
                    }
                }
            }

            Debug.Assert(m_tmpShapeListInit.Count == 0);
            m_tmpShapeListInit.Clear();
            m_tmpShapeListInit.AddList(shapeList);

            for (int i = 0; i < m_tmpChildren.Count; i++)
            {
                var child = m_tmpChildren[i];
                var result = m_tmpShapeListInit.Where(s => s.Name == child.ShapeName);
                if (result.Count() > 0)
                {
                    var found = result.First();
                    var si = new HkdShapeInstanceInfo(child.Shape.Clone(), Matrix.Identity);
                    if (found.Fixed)
                        si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                    removeRefsList.Add(si);
                    m_tmpShapeInfos.Add(si);
                    m_tmpShapeListInit.Remove(found);
                }
                else
                {
                    child.GetChildren(m_tmpChildren);
                }
            }

            m_tmpShapeListInit.Clear();

            if (shapeList.Count > 0 && m_tmpShapeInfos.Count == 0)
            {
                ProfilerShort.End();
                m_tmpChildren.Clear();
                Debug.Fail("No relevant shape was found for fractured block. It was probably reexported and names changed. Block definition: " + Block.BlockDefinition.Id.ToString());
                throw new Exception("No relevant shape was found for fractured block. It was probably reexported and names changed. Block definition: " + Block.BlockDefinition.Id.ToString());
            }

            if (render != null)
            {
                foreach (var shape in m_tmpShapeInfos)
                {
                    if (!string.IsNullOrEmpty(shape.Shape.Name))
                        render.AddPiece(shape.Shape.Name, Matrix.Identity);
                }

                render.UpdateRenderObject(true);
            }

            m_tmpChildren.Clear();

            if (Block.CubeGrid.CreatePhysics)
            {
                HkdBreakableShape compound = new HkdCompoundBreakableShape(null, m_tmpShapeInfos);
                ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();
                var mp = new HkMassProperties();
                compound.BuildMassProperties(ref mp);
                Shape = new HkdBreakableShape(compound.GetShape(), ref mp);
                compound.RemoveReference();
                foreach (var si in m_tmpShapeInfos)
                {
                    var siRef = si;
                    Shape.AddShape(ref siRef);
                }
                Shape.SetStrenght(MyDestructionConstants.STRENGTH);
                CreateMountPoints();

                // Update neighbours for parent block
                var blockOnPosition = Block.CubeGrid.GetCubeBlock(Block.Position);
                if (blockOnPosition != null)
                    blockOnPosition.CubeGrid.UpdateBlockNeighbours(blockOnPosition);

                if (Block.CubeGrid.Physics != null)
                    Block.CubeGrid.Physics.AddDirtyBlock(Block);
            }

            foreach (var si in m_tmpShapeInfos)
                si.Shape.RemoveReference();
            m_tmpShapeInfos.Clear();

            foreach (var si in removeRefsList)
                si.RemoveReference();

            ProfilerShort.End();
        }
示例#57
0
        public override void CreateCharacterCollision(Vector3 center, float characterWidth, float characterHeight,
            float crouchHeight, float ladderHeight, float headSize, float headHeight,
            MatrixD worldTransform, float mass, ushort collisionLayer, bool isOnlyVertical, float maxSlope, bool networkProxy)
        {
            Center = center;
            CanUpdateAccelerations = false;

            if (networkProxy)
            { //create kinematic body for network proxy
                HkShape shape = MyCharacterProxy.CreateCharacterShape(characterHeight, characterWidth, characterHeight + headHeight, headSize, 0.0f);
                HkMassProperties massProperties = new HkMassProperties();
                massProperties.Mass = mass;
                massProperties.InertiaTensor = Matrix.Identity;
                massProperties.Volume = characterWidth * characterWidth * (characterHeight + 2 * characterWidth);
                CreateFromCollisionObject(shape, center, worldTransform, massProperties, collisionLayer);
                CanUpdateAccelerations = false;
                return;
            }


            Vector3 transformedCenter = Vector3.TransformNormal(Center, worldTransform);
            Matrix worldTransformCentered = Matrix.CreateWorld(transformedCenter + worldTransform.Translation, worldTransform.Forward, worldTransform.Up);


            CharacterProxy = new MyCharacterProxy(
#if DYNAMIC_CHARACTER_CONTROLLER
true,
#else
false,
#endif
 true, characterWidth, characterHeight,
        crouchHeight, ladderHeight, headSize, headHeight,
 worldTransformCentered.Translation,
                worldTransform.Up, worldTransform.Forward, mass,
                this,
                isOnlyVertical,
                maxSlope);


            //CharacterProxy.Gravity = new Vector3(0, -20, 0);


        }
示例#58
0
        /// <summary>
        /// Prepares data for renderer and physics. Must be called after all items has been added.
        /// </summary>
        public void PrepareItemsPhysics(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld)
        {
            PositionComp.WorldAABB = aabbWorld;

            if (sectorRootShape.InstanceCount > 0)
            {
                Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0);

                Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC)
                {
                    MaterialType = m_definition.Material,
                    AngularDamping = MyPerGameSettings.DefaultAngularDamping,
                    LinearDamping = MyPerGameSettings.DefaultLinearDamping,
                    IsStaticForCluster = true,
                };

                sectorRootShape.Bake();
                HkMassProperties massProperties = new HkMassProperties();
                MatrixD matrix = MatrixD.CreateTranslation(CellsOffset);
                Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, matrix, massProperties);

                Physics.ContactPointCallback += Physics_ContactPointCallback;
                Physics.RigidBody.ContactPointCallbackEnabled = true;

                sectorRootShape.Base.RemoveReference();

                Physics.Enabled = true;
            }
        }
        private static MyFracturedPiece CreateFracturePiece(ref HkdBreakableShape shape, HkdWorld world, ref MatrixD worldMatrix, bool isStatic)
        {
            Debug.Assert(shape.IsValid());
            ProfilerShort.Begin("CreateFracturePiece");
            var fracturedPiece = MyFracturedPiecesManager.Static.GetPieceFromPool(0);//new MyFracturedPiece();
            fracturedPiece.PositionComp.WorldMatrix = worldMatrix;
            fracturedPiece.Physics.Flags = isStatic ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS;
            var physicsBody = fracturedPiece.Physics as MyPhysicsBody;//new MyPhysicsBody(fracturedPiece,isFixed ?RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS);

            HkMassProperties mp = new HkMassProperties();
            shape.BuildMassProperties(ref mp);
            physicsBody.InitialSolverDeactivation = HkSolverDeactivation.High;
            physicsBody.CreateFromCollisionObject(shape.GetShape(), Vector3.Zero, worldMatrix, mp);

            physicsBody.LinearDamping = MyPerGameSettings.DefaultLinearDamping;
            physicsBody.AngularDamping = MyPerGameSettings.DefaultAngularDamping;

            System.Diagnostics.Debug.Assert(physicsBody.BreakableBody == null, "physicsBody.DestructionBody == null");
            physicsBody.BreakableBody = new HkdBreakableBody(shape, physicsBody.RigidBody, world, worldMatrix);
            physicsBody.BreakableBody.AfterReplaceBody += physicsBody.FracturedBody_AfterReplaceBody;
            ProfilerShort.End();

            ProfilerShort.Begin("Sync");
            if (fracturedPiece.SyncFlag)
            {
                fracturedPiece.CreateSync();
            }
            ProfilerShort.End();
            fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
            //physicsBody.RigidBody.ContactPointCallbackDelay = 0;
            //physicsBody.RigidBody.ContactPointCallbackEnabled = true;
            fracturedPiece.Physics = physicsBody;
            //FixPosition(fracturedPiece);
            fracturedPiece.SetDataFromHavok(shape);
            ProfilerShort.Begin("AddToWorld");
            fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
            shape.RemoveReference();
            ProfilerShort.End();
            return fracturedPiece;
        }
        /// <summary>
        /// Loads Ragdoll data
        /// </summary>
        /// <param name="ragDollFile"></param>
        public bool InitRagdoll()
        {
            if (MyFakes.ENABLE_RAGDOLL_DEBUG) Debug.WriteLine("RagdollComponent.InitRagdoll");
            if (Character.Physics.Ragdoll != null)
            {
                Character.Physics.CloseRagdollMode();
                Character.Physics.Ragdoll.ResetToRigPose();
                
                Character.Physics.Ragdoll.SetToKeyframed();
                return true;
            }

            Character.Physics.Ragdoll = new HkRagdoll();

            bool dataLoaded = false;

            if (Character.Model.HavokData != null && Character.Model.HavokData.Length > 0)
            {
                try
                {
                    dataLoaded = Character.Physics.Ragdoll.LoadRagdollFromBuffer(Character.Model.HavokData);
                }
                catch (Exception e)
                {
                    Debug.Fail("Error loading ragdoll from buffer: " + e.Message);
                    Character.Physics.CloseRagdoll();
                    Character.Physics.Ragdoll = null;
                }
            }
            else if (Character.Definition.RagdollDataFile != null)
            {
                String ragDollFile = System.IO.Path.Combine(MyFileSystem.ContentPath, Character.Definition.RagdollDataFile);
                if (System.IO.File.Exists(ragDollFile))
                {
                    dataLoaded = Character.Physics.Ragdoll.LoadRagdollFromFile(ragDollFile);
                }
                else
                {
                    System.Diagnostics.Debug.Fail("Cannot find ragdoll file: " + ragDollFile);
                }
            }

            if (Character.Definition.RagdollRootBody != String.Empty)
            {
                if (!Character.Physics.Ragdoll.SetRootBody(Character.Definition.RagdollRootBody))
                {
                    Debug.Fail("Can not set root body with name: " + Character.Definition.RagdollRootBody + " on model " + Character.ModelName + ". Please check your definitions.");
                }
            }

            if (!dataLoaded)
            {
                Character.Physics.Ragdoll.Dispose();
                Character.Physics.Ragdoll = null;
            }
            foreach (var body in Character.Physics.Ragdoll.RigidBodies)
                body.UserObject = Character;

            if (Character.Physics.Ragdoll != null && MyPerGameSettings.Destruction) //scaling weights and IT
            {
                Character.Physics.Ragdoll.SetToDynamic();
                var mp = new HkMassProperties();
                foreach (var body in Character.Physics.Ragdoll.RigidBodies)
                {
                    mp.Mass = MyDestructionHelper.MassToHavok(body.Mass);
                    mp.InertiaTensor = Matrix.CreateScale(1.0f / 25.0f) * body.InertiaTensor;
                    body.SetMassProperties(ref mp);
                }
                Character.Physics.Ragdoll.SetToKeyframed();
            }

            if (Character.Physics.Ragdoll != null && MyFakes.ENABLE_RAGDOLL_DEFAULT_PROPERTIES)
            {
                Character.Physics.SetRagdollDefaults();
            }

            return dataLoaded;

        }