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);
        }
예제 #2
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 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);
        }
예제 #4
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;
                     }
                 }
             }
         }
     }
 }
        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;
        }
예제 #6
0
        public override void Init(MyObjectBuilder_CubeBlock builder, MyCubeGrid cubeGrid)
        {
            base.Init(builder, cubeGrid);
            base.CheckConnectionAllowed = true;
            MyObjectBuilder_FracturedBlock block = builder as MyObjectBuilder_FracturedBlock;

            if (block.Shapes.Count == 0)
            {
                if (!block.CreatingFracturedBlock)
                {
                    throw new Exception("No relevant shape was found for fractured block. It was probably reexported and names changed.");
                }
            }
            else
            {
                this.OriginalBlocks = new List <MyDefinitionId>();
                this.Orientations   = new List <MyBlockOrientation>();
                List <HkdShapeInstanceInfo> list = new List <HkdShapeInstanceInfo>();
                foreach (SerializableDefinitionId id in block.BlockDefinitions)
                {
                    MyCubeBlockDefinition cubeBlockDefinition = MyDefinitionManager.Static.GetCubeBlockDefinition(id);
                    string model = cubeBlockDefinition.Model;
                    if (MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                    {
                        MyDestructionData.Static.LoadModelDestruction(model, cubeBlockDefinition, Vector3.One, true, false);
                    }
                    HkdBreakableShape    shape       = MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                    Quaternion?          rotation    = null;
                    Vector3?             translation = null;
                    HkdShapeInstanceInfo item        = new HkdShapeInstanceInfo(shape, rotation, translation);
                    list.Add(item);
                    m_children.Add(item);
                    shape.GetChildren(m_children);
                    if (cubeBlockDefinition.BuildProgressModels != null)
                    {
                        MyCubeBlockDefinition.BuildProgressModel[] buildProgressModels = cubeBlockDefinition.BuildProgressModels;
                        for (int j = 0; j < buildProgressModels.Length; j++)
                        {
                            model = buildProgressModels[j].File;
                            if (MyModels.GetModelOnlyData(model).HavokBreakableShapes == null)
                            {
                                MyDestructionData.Static.LoadModelDestruction(model, cubeBlockDefinition, Vector3.One, true, false);
                            }
                            shape       = MyModels.GetModelOnlyData(model).HavokBreakableShapes[0];
                            rotation    = null;
                            translation = null;
                            item        = new HkdShapeInstanceInfo(shape, rotation, translation);
                            list.Add(item);
                            m_children.Add(item);
                            shape.GetChildren(m_children);
                        }
                    }
                    this.OriginalBlocks.Add(id);
                }
                foreach (SerializableBlockOrientation orientation in block.BlockOrientations)
                {
                    this.Orientations.Add((MyBlockOrientation)orientation);
                }
                if (block.MultiBlocks.Count > 0)
                {
                    this.MultiBlocks = new List <MultiBlockPartInfo>();
                    foreach (MyObjectBuilder_FracturedBlock.MyMultiBlockPart part in block.MultiBlocks)
                    {
                        if (part == null)
                        {
                            this.MultiBlocks.Add(null);
                            continue;
                        }
                        MultiBlockPartInfo item = new MultiBlockPartInfo();
                        item.MultiBlockDefinition = part.MultiBlockDefinition;
                        item.MultiBlockId         = part.MultiBlockId;
                        this.MultiBlocks.Add(item);
                    }
                }
                this.m_shapes.AddRange(block.Shapes);
                for (int i = 0; i < m_children.Count; i++)
                {
                    HkdShapeInstanceInfo child = m_children[i];
                    Func <MyObjectBuilder_FracturedBlock.ShapeB, bool>  predicate = s => s.Name == child.ShapeName;
                    IEnumerable <MyObjectBuilder_FracturedBlock.ShapeB> source    = this.m_shapes.Where <MyObjectBuilder_FracturedBlock.ShapeB>(predicate);
                    if (source.Count <MyObjectBuilder_FracturedBlock.ShapeB>() <= 0)
                    {
                        child.GetChildren(m_children);
                    }
                    else
                    {
                        MyObjectBuilder_FracturedBlock.ShapeB item = source.First <MyObjectBuilder_FracturedBlock.ShapeB>();
                        Matrix transform = Matrix.CreateFromQuaternion((Quaternion)item.Orientation);
                        transform.Translation = child.GetTransform().Translation;
                        HkdShapeInstanceInfo info2 = new HkdShapeInstanceInfo(child.Shape.Clone(), transform);
                        if (item.Fixed)
                        {
                            info2.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                        }
                        list.Add(info2);
                        m_shapeInfos.Add(info2);
                        this.m_shapes.Remove(item);
                    }
                }
                if (m_shapeInfos.Count == 0)
                {
                    m_children.Clear();
                    throw new Exception("No relevant shape was found for fractured block. It was probably reexported and names changed.");
                }
                foreach (HkdShapeInstanceInfo info3 in m_shapeInfos)
                {
                    HkdBreakableShape shape = info3.Shape;
                    if (!string.IsNullOrEmpty(shape.Name))
                    {
                        this.Render.AddPiece(info3.Shape.Name, Matrix.CreateFromQuaternion(Quaternion.CreateFromRotationMatrix(info3.GetTransform().GetOrientation())));
                    }
                }
                if (base.CubeGrid.CreatePhysics)
                {
                    HkdBreakableShape?oldParent = null;
                    HkdBreakableShape shape3    = (HkdBreakableShape) new HkdCompoundBreakableShape(oldParent, m_shapeInfos);
                    shape3.RecalcMassPropsFromChildren();
                    this.Shape = shape3;
                    HkMassProperties massProperties = new HkMassProperties();
                    shape3.BuildMassProperties(ref massProperties);
                    this.Shape = new HkdBreakableShape(shape3.GetShape(), ref massProperties);
                    shape3.RemoveReference();
                    foreach (HkdShapeInstanceInfo info4 in m_shapeInfos)
                    {
                        this.Shape.AddShape(ref info4);
                    }
                    this.Shape.SetStrenght(MyDestructionConstants.STRENGTH);
                    this.CreateMountPoints();
                }
                m_children.Clear();
                foreach (HkdShapeInstanceInfo info5 in m_shapeInfos)
                {
                    info5.Shape.RemoveReference();
                }
                foreach (HkdShapeInstanceInfo info6 in list)
                {
                    info6.RemoveReference();
                }
                m_shapeInfos.Clear();
            }
        }
 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;
 }
예제 #8
0
        public override void Init(MyObjectBuilder_EntityBase objectBuilder)
        {
            base.Init(objectBuilder);
            var ob = objectBuilder as MyObjectBuilder_FracturedPiece;

            if (ob.Shapes.Count == 0)
            {
                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, MyPhysics.SingleWorld.DestructionWorld, (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();
        }