コード例 #1
0
        void CreateBreakableShapeFromCollisionShapes(MyModel model, Vector3 defaultSize, MyPhysicalModelDefinition modelDef)
        {
            // Make box half edge length of the grid so fractured block is smaller than not fractured, also good for compounds
            HkShape shape;

            if (model.HavokCollisionShapes != null && model.HavokCollisionShapes.Length > 0)
            {
                if (model.HavokCollisionShapes.Length > 1)
                {
                    shape = HkListShape.Create(model.HavokCollisionShapes, model.HavokCollisionShapes.Length, HkReferencePolicy.None);
                }
                else
                {
                    shape = model.HavokCollisionShapes[0];
                    shape.AddReference();
                }
            }
            else
            {
                //modelDef.Size * (modelDef.CubeSize == MyCubeSize.Large ? 2.5f : 0.25f)
                shape = new HkBoxShape(defaultSize * 0.5f, MyPerGameSettings.PhysicsConvexRadius);
            }

            var boxBreakable = new HkdBreakableShape(shape);

            boxBreakable.Name = model.AssetName;
            boxBreakable.SetMass(modelDef.Mass);
            model.HavokBreakableShapes = new HkdBreakableShape[] { boxBreakable };
            shape.RemoveReference();
        }
コード例 #2
0
        /// <summary>
        /// Sets model from havok to render component of this entity.
        /// </summary>
        public void SetDataFromHavok(HkdBreakableShape shape)
        {
            ProfilerShort.Begin("FP.SetDataFromHavok");
            Shape = shape;
            Shape.AddReference();
            if (Render != null)
            {
                if (shape.IsCompound() || string.IsNullOrEmpty(shape.Name))
                {
                    shape.GetChildren(m_shapeInfos);
                    Debug.Assert(m_shapeInfos.Count > 0);
                    foreach (var shapeInstanceInfo in m_shapeInfos)
                    {
                        //System.Diagnostics.Debug.Assert(shapeInstanceInfo.IsValid(), "Invalid shapeInstanceInfo!");
                        if (shapeInstanceInfo.IsValid())
                        {
                            Render.AddPiece(shapeInstanceInfo.ShapeName, shapeInstanceInfo.GetTransform());
                        }
                    }

                    m_shapeInfos.Clear();
                }
                else
                {
                    Render.AddPiece(shape.Name, Matrix.Identity);
                }
            }
            ProfilerShort.End();

            m_hitPoints = Shape.Volume * 100;
        }
コード例 #3
0
 public static bool IsFixed(HkdBreakableShape breakableShape)
 {
     System.Diagnostics.Debug.Assert(m_tmpInfos.Count == 0, "");
     if (!breakableShape.IsValid())
         return false;
     if ((breakableShape.UserObject & (uint)HkdBreakableShape.Flags.IS_FIXED) != 0)
     {
         return true;
     }
     else
     {
         Debug.Assert(m_tmpInfos.Count == 0);
         breakableShape.GetChildren(m_tmpInfos);
         foreach (var child in m_tmpInfos)
         {
             if ((child.Shape.UserObject & (uint)HkdBreakableShape.Flags.IS_FIXED) != 0)
             {
                 m_tmpInfos.Clear();
                 return true;
             }
         }
         m_tmpInfos.Clear();
     }
     return false;
 }
コード例 #4
0
 public static bool IsFixed(HkdBreakableShape breakableShape)
 {
     System.Diagnostics.Debug.Assert(m_tmpInfos.Count == 0, "");
     if (!breakableShape.IsValid())
     {
         return(false);
     }
     if ((breakableShape.UserObject & (uint)HkdBreakableShape.Flags.IS_FIXED) != 0)
     {
         return(true);
     }
     else
     {
         Debug.Assert(m_tmpInfos.Count == 0);
         breakableShape.GetChildren(m_tmpInfos);
         foreach (var child in m_tmpInfos)
         {
             if ((child.Shape.UserObject & (uint)HkdBreakableShape.Flags.IS_FIXED) != 0)
             {
                 m_tmpInfos.Clear();
                 return(true);
             }
         }
         m_tmpInfos.Clear();
     }
     return(false);
 }
コード例 #5
0
        private HkdBreakableShape AddMountForShape(HkdBreakableShape shape, Matrix transform, ref BoundingBox blockBB)
        {
            Vector4 min;
            Vector4 max;

            shape.GetShape().GetLocalAABB(0.01f, out min, out max);//.Transform(CubeGrid.PositionComp.WorldMatrix);
            var bb = new BoundingBox(new Vector3(min), new Vector3(max));

            bb      = bb.Transform(transform);
            bb.Min /= CubeGrid.GridSize; //normalize for mount point
            bb.Max /= CubeGrid.GridSize;

            bb.Inflate(0.04f);//add tolerance (fracture shapes are smaller than block)
            bb.Min += blockBB.HalfExtents;
            bb.Max += blockBB.HalfExtents;

            if (blockBB.Contains(bb) == ContainmentType.Intersects)
            {
                bb.Inflate(-0.04f);
                foreach (var directionEnum in Base6Directions.EnumDirections)
                {
                    int     dirEnum   = (int)directionEnum;
                    Vector3 direction = Base6Directions.Directions[dirEnum];
                    Vector3 absDir    = Vector3.Abs(direction);
                    var     mp        = new MyCubeBlockDefinition.MountPoint();
                    mp.Start = bb.Min;
                    mp.End   = bb.Max;
                    var  start = mp.Start * absDir / (blockBB.HalfExtents * 2) - absDir * 0.04f;
                    var  end   = mp.End * absDir / (blockBB.HalfExtents * 2) + absDir * 0.04f;
                    bool add   = false;
                    bool one   = false;
                    if (start.Max() < 1 && end.Max() > 1 && direction.Max() > 0)
                    {
                        add = true;
                        one = true;
                    }
                    else if (start.Min() < 0 && end.Max() > 0 && direction.Min() < 0)
                    {
                        add = true;
                    }
                    if (!add)
                    {
                        continue;
                    }
                    mp.Start -= mp.Start * absDir - absDir * 0.04f;
                    mp.End   -= mp.End * absDir + absDir * 0.04f;
                    if (one)
                    {
                        mp.Start += absDir * blockBB.HalfExtents * 2;
                        mp.End   += absDir * blockBB.HalfExtents * 2;
                    }
                    mp.Start -= blockBB.HalfExtents - Vector3.One / 2;
                    mp.End   -= blockBB.HalfExtents - Vector3.One / 2;
                    mp.Normal = new Vector3I(direction);
                    MountPoints.Add(mp);
                }
            }
            return(shape);
        }
コード例 #6
0
 private static bool DontCreateFracture(HkdBreakableShape breakableShape)
 {
     if (!breakableShape.IsValid())
     {
         return(false);
     }
     return((breakableShape.UserObject & (uint)HkdBreakableShape.Flags.DONT_CREATE_FRACTURE_PIECE) != 0);
 }
コード例 #7
0
        private void CreateBreakableShape(MyEnvironmentItemDefinition itemDefinition, ref MyEnvironmentItems.MyEnvironmentItemData itemData, ref Vector3D hitWorldPosition, Vector3 hitNormal, float forceMultiplier, string fallSound = "")
        {
            HkdBreakableShape oldBreakableShape = MyModels.GetModelOnlyData(itemDefinition.Model).HavokBreakableShapes[0].Clone();
            MatrixD           transformMatrix   = itemData.Transform.TransformMatrix;

            oldBreakableShape.SetMassRecursively(500f);
            oldBreakableShape.SetStrenghtRecursively(5000f, 0.7f);
            oldBreakableShape.GetChildren(base.m_childrenTmp);
            HkdBreakableShape[] havokBreakableShapes = MyModels.GetModelOnlyData(itemDefinition.Model).HavokBreakableShapes;
            Vector3D.Transform(hitWorldPosition, MatrixD.Normalize(MatrixD.Invert(transformMatrix)));
            float num = (float)(hitWorldPosition.Y - itemData.Transform.Position.Y);
            List <HkdShapeInstanceInfo> shapeList = new List <HkdShapeInstanceInfo>();
            List <HkdShapeInstanceInfo> list2     = new List <HkdShapeInstanceInfo>();
            HkdShapeInstanceInfo?       nullable  = null;

            foreach (HkdShapeInstanceInfo info in base.m_childrenTmp)
            {
                if ((nullable == null) || (info.CoM.Y < nullable.Value.CoM.Y))
                {
                    nullable = new HkdShapeInstanceInfo?(info);
                }
                if (info.CoM.Y > num)
                {
                    list2.Add(info);
                }
                else
                {
                    shapeList.Add(info);
                }
            }
            if (shapeList.Count != 2)
            {
                if ((shapeList.Count == 0) && list2.Remove(nullable.Value))
                {
                    shapeList.Add(nullable.Value);
                }
            }
            else if ((shapeList[0].CoM.Y < shapeList[1].CoM.Y) && (num < (shapeList[1].CoM.Y + 1.25f)))
            {
                list2.Insert(0, shapeList[1]);
                shapeList.RemoveAt(1);
            }
            else if ((shapeList[0].CoM.Y > shapeList[1].CoM.Y) && (num < (shapeList[0].CoM.Y + 1.25f)))
            {
                list2.Insert(0, shapeList[0]);
                shapeList.RemoveAt(0);
            }
            if (shapeList.Count > 0)
            {
                CreateFracturePiece(itemDefinition, oldBreakableShape, transformMatrix, hitNormal, shapeList, forceMultiplier, true, "");
            }
            if (list2.Count > 0)
            {
                CreateFracturePiece(itemDefinition, oldBreakableShape, transformMatrix, hitNormal, list2, forceMultiplier, false, fallSound);
            }
            base.m_childrenTmp.Clear();
        }
コード例 #8
0
        private bool GetCurrentFracturedShapeList(HkdBreakableShape breakableShape, List <MyObjectBuilder_FractureComponentBase.FracturedShape> shapeList, string[] excludeShapeNames = null)
        {
            var  shapeName      = breakableShape.Name;
            bool shapeNameEmpty = string.IsNullOrEmpty(shapeName);

            if (excludeShapeNames != null && !shapeNameEmpty)
            {
                foreach (var shapeNameToRemove in excludeShapeNames)
                {
                    if (shapeName == shapeNameToRemove)
                    {
                        return(false);
                    }
                }
            }

            if (breakableShape.GetChildrenCount() > 0)
            {
                List <HkdShapeInstanceInfo> shapeInst = new List <HkdShapeInstanceInfo>();
                breakableShape.GetChildren(shapeInst);

                bool allChildrenAdded = true;
                foreach (var inst in shapeInst)
                {
                    allChildrenAdded &= GetCurrentFracturedShapeList(inst.Shape, shapeList, excludeShapeNames: excludeShapeNames);
                }

                if (!shapeNameEmpty && allChildrenAdded)
                {
                    foreach (var inst in shapeInst)
                    {
                        shapeList.RemoveAll(s => s.Name == inst.ShapeName);
                    }

                    shapeList.Add(new MyObjectBuilder_FractureComponentBase.FracturedShape()
                    {
                        Name = shapeName, Fixed = breakableShape.IsFixed()
                    });
                }

                return(allChildrenAdded);
            }
            else
            {
                if (!shapeNameEmpty)
                {
                    shapeList.Add(new MyObjectBuilder_FractureComponentBase.FracturedShape()
                    {
                        Name = shapeName, Fixed = breakableShape.IsFixed()
                    });
                    return(true);
                }
            }

            return(false);
        }
コード例 #9
0
        private void DisableRefCountRec(HkdBreakableShape bShape)
        {
            bShape.DisableRefCount();
            var lst = new List <HkdShapeInstanceInfo>();

            bShape.GetChildren(lst);
            foreach (var child in lst)
            {
                DisableRefCountRec(child.Shape);
            }
        }
コード例 #10
0
 private static void RenameShapesRecursive(HkdBreakableShape shape, string shapeSuffix)
 {
     shape.Name += shapeSuffix;
     using (PoolManager.Get(out List <HkdShapeInstanceInfo> shapes))
     {
         shape.GetChildren(shapes);
         foreach (var child in shapes)
         {
             RenameShapesRecursive(child.Shape, shapeSuffix);
         }
     }
 }
コード例 #11
0
 private static void CollectShapeNamesRecursive(HkdBreakableShape shape, HashSet <string> shapeName)
 {
     shapeName.Add(shape.Name);
     using (PoolManager.Get(out List <HkdShapeInstanceInfo> shapes))
     {
         shape.GetChildren(shapes);
         foreach (var child in shapes)
         {
             CollectShapeNamesRecursive(child.Shape, shapeName);
         }
     }
 }
コード例 #12
0
 internal void SetDataFromHavok(HkdBreakableShape shape, bool compound)
 {
     this.Shape = shape;
     if (compound)
     {
         this.SetDataFromCompound(shape);
     }
     else
     {
         this.Render.AddPiece(shape.Name, Matrix.Identity);
     }
     this.CreateMountPoints();
 }
コード例 #13
0
        public void EnqueShape(string model, MyDefinitionId id, HkdBreakableShape shape)
        {
            using (m_poolLock.AcquireExclusiveUsing())
            {
                if (!m_pools.ContainsKey(id))
                    m_pools[id] = new Dictionary<string, ConcurrentQueue<HkdBreakableShape>>();
                if (!m_pools[id].ContainsKey(model))
                    m_pools[id][model] = new ConcurrentQueue<HkdBreakableShape>();
            }

            m_pools[id][model].Enqueue(shape);
            m_missing--;
        }
コード例 #14
0
        public void EnqueShape(string model, MyDefinitionId id, HkdBreakableShape shape)
        {
            if (!m_pools.ContainsKey(id))
            {
                m_pools[id] = new Dictionary <string, ConcurrentQueue <HkdBreakableShape> >();
            }
            if (!m_pools[id].ContainsKey(model))
            {
                m_pools[id][model] = new ConcurrentQueue <HkdBreakableShape>();
            }

            m_pools[id][model].Enqueue(shape);
            m_missing--;
        }
コード例 #15
0
 internal void SetDataFromHavok(HkdBreakableShape shape, bool compound)
 {
     Shape = shape;
     if (compound)
     {
         SetDataFromCompound(shape);
     }
     else
     {
         var render = this.Render as MyRenderComponentFracturedPiece;
         render.AddPiece(shape.Name, Matrix.Identity);
     }
     CreateMountPoints();
 }
コード例 #16
0
        private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation,
                                                                            HashSet <Tuple <string, float> > namesAndBuildProgress, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder, out float buildProgress)
        {
            buildProgress = 1f;

            var name = shape.Name;
            Tuple <string, float> foundTuple = null;

            foreach (var tuple in namesAndBuildProgress)
            {
                if (tuple.Item1 == name)
                {
                    foundTuple = tuple;
                    break;
                }
            }

            if (foundTuple != null)
            {
                MyBlockOrientation shapeOrientation = new MyBlockOrientation(ref shapeRotation);
                if (shapeOrientation == blockOrientation)
                {
                    MyObjectBuilder_FractureComponentCubeBlock.FracturedShape builderShape = new MyObjectBuilder_FractureComponentBase.FracturedShape();
                    builderShape.Name  = name;
                    builderShape.Fixed = MyDestructionHelper.IsFixed(shape);

                    fractureComponentBuilder.Shapes.Add(builderShape);
                    buildProgress = foundTuple.Item2;
                }
            }

            if (shape.GetChildrenCount() > 0)
            {
                List <HkdShapeInstanceInfo> children = new List <HkdShapeInstanceInfo>();
                shape.GetChildren(children);
                foreach (var child in children)
                {
                    var   childShapeRotation = child.GetTransform();
                    float localBuildProgress;
                    ConvertAllShapesToFractureComponentShapeBuilder(child.Shape, ref childShapeRotation, blockOrientation, namesAndBuildProgress,
                                                                    fractureComponentBuilder, out localBuildProgress);

                    if (foundTuple == null)
                    {
                        buildProgress = localBuildProgress;
                    }
                }
            }
        }
コード例 #17
0
        public static void CreateFracturePiece(MyEnvironmentItemDefinition itemDefinition, HkdBreakableShape oldBreakableShape, MatrixD worldMatrix, Vector3 hitNormal, List <HkdShapeInstanceInfo> shapeList, float forceMultiplier, bool canContainFixedChildren, string fallSound = "")
        {
            bool isStatic = false;

            if (canContainFixedChildren)
            {
                foreach (HkdShapeInstanceInfo info in shapeList)
                {
                    info.Shape.SetMotionQualityRecursively(HkdBreakableShape.BodyQualityType.QUALITY_DEBRIS);
                    Vector3D   translation = worldMatrix.Translation + (worldMatrix.Up * 1.5);
                    Quaternion rotation    = Quaternion.CreateFromRotationMatrix(worldMatrix.GetOrientation());
                    MyPhysics.GetPenetrationsShape(info.Shape.GetShape(), ref translation, ref rotation, MyEnvironmentItems.m_tmpResults, 15);
                    bool flag2 = false;
                    using (List <HkBodyCollision> .Enumerator enumerator2 = MyEnvironmentItems.m_tmpResults.GetEnumerator())
                    {
                        while (enumerator2.MoveNext())
                        {
                            if (enumerator2.Current.GetCollisionEntity() is MyVoxelMap)
                            {
                                info.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                                isStatic = true;
                                flag2    = true;
                            }
                            else if (!flag2)
                            {
                                continue;
                            }
                            break;
                        }
                    }
                    MyEnvironmentItems.m_tmpResults.Clear();
                }
            }
            HkdBreakableShape shape = (HkdBreakableShape) new HkdCompoundBreakableShape(new HkdBreakableShape?(oldBreakableShape), shapeList);

            shape.RecalcMassPropsFromChildren();
            MyFracturedPiece fp = MyDestructionHelper.CreateFracturePiece(shape, ref worldMatrix, isStatic, new MyDefinitionId?(itemDefinition.Id), true);

            if ((fp != null) && !canContainFixedChildren)
            {
                ApplyImpulseToTreeFracture(ref worldMatrix, ref hitNormal, shapeList, ref shape, fp, forceMultiplier);
                fp.Physics.ForceActivate();
                if (fallSound.Length > 0)
                {
                    fp.StartFallSound(fallSound);
                }
            }
        }
コード例 #18
0
 public void EnqueShape(string model, MyDefinitionId id, HkdBreakableShape shape)
 {
     using (this.m_poolLock.AcquireExclusiveUsing())
     {
         if (!this.m_pools.ContainsKey(id))
         {
             this.m_pools[id] = new Dictionary <string, ConcurrentQueue <HkdBreakableShape> >();
         }
         if (!this.m_pools[id].ContainsKey(model))
         {
             this.m_pools[id][model] = new ConcurrentQueue <HkdBreakableShape>();
         }
     }
     this.m_pools[id][model].Enqueue(shape);
     this.m_missing--;
 }
コード例 #19
0
        public void SetDataFromCompound(HkdBreakableShape compound)
        {
            MyRenderComponentFracturedPiece render = this.Render;

            if (render != null)
            {
                compound.GetChildren(m_shapeInfos);
                foreach (HkdShapeInstanceInfo info in m_shapeInfos)
                {
                    if (info.IsValid())
                    {
                        render.AddPiece(info.ShapeName, info.GetTransform());
                    }
                }
                m_shapeInfos.Clear();
            }
        }
コード例 #20
0
        public static void GetAllBlockBreakableShapeNames(HkdBreakableShape shape, HashSet <Tuple <string, float> > outNamesAndBuildProgress, float buildProgress)
        {
            string name = shape.Name;

            if (!string.IsNullOrEmpty(name))
            {
                outNamesAndBuildProgress.Add(new Tuple <string, float>(name, buildProgress));
            }
            if (shape.GetChildrenCount() > 0)
            {
                List <HkdShapeInstanceInfo> list = new List <HkdShapeInstanceInfo>();
                shape.GetChildren(list);
                foreach (HkdShapeInstanceInfo info in list)
                {
                    GetAllBlockBreakableShapeNames(info.Shape, outNamesAndBuildProgress, buildProgress);
                }
            }
        }
コード例 #21
0
        public virtual void SetShape(HkdBreakableShape shape, bool compound)
        {
            Debug.Assert(shape.IsValid());

            if (Shape.IsValid())
            {
                Shape.RemoveReference();
            }

            Shape = shape;

            var render = Entity.Render as MyRenderComponentFracturedPiece;

            Debug.Assert(render != null);

            if (render != null)
            {
                render.ClearModels();

                if (compound)
                {
                    Debug.Assert(m_tmpChildren.Count == 0);

                    shape.GetChildren(m_tmpChildren);

                    foreach (var shapeInstanceInfo in m_tmpChildren)
                    {
                        System.Diagnostics.Debug.Assert(shapeInstanceInfo.IsValid(), "Invalid shapeInstanceInfo!");
                        if (shapeInstanceInfo.IsValid())
                        {
                            render.AddPiece(shapeInstanceInfo.ShapeName, Matrix.Identity);
                        }
                    }

                    m_tmpChildren.Clear();
                }
                else
                {
                    render.AddPiece(shape.Name, Matrix.Identity);
                }

                render.UpdateRenderObject(true);
            }
        }
コード例 #22
0
        private static void GetAllBlockBreakableShapeNames(HkdBreakableShape shape, HashSet <string> outNames)
        {
            var name = shape.Name;

            if (!string.IsNullOrEmpty(name))
            {
                outNames.Add(name);
            }

            if (shape.GetChildrenCount() > 0)
            {
                List <HkdShapeInstanceInfo> children = new List <HkdShapeInstanceInfo>();
                shape.GetChildren(children);
                foreach (var child in children)
                {
                    GetAllBlockBreakableShapeNames(child.Shape, outNames);
                }
            }
        }
コード例 #23
0
        public override void SetShape(HkdBreakableShape shape, bool compound)
        {
            base.SetShape(shape, compound);

            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);
            }
        }
コード例 #24
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;
                     }
                 }
             }
         }
     }
 }
コード例 #25
0
        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);
        }
コード例 #26
0
        public void SetDataFromCompound(HkdBreakableShape compound)
        {
            var render = this.Render as MyRenderComponentFracturedPiece;

            if (render != null)
            {
                compound.GetChildren(m_shapeInfos);

                foreach (var shapeInstanceInfo in m_shapeInfos)
                {
                    System.Diagnostics.Debug.Assert(shapeInstanceInfo.IsValid(), "Invalid shapeInstanceInfo!");
                    if (shapeInstanceInfo.IsValid())
                    {
                        render.AddPiece(shapeInstanceInfo.ShapeName, shapeInstanceInfo.GetTransform());
                    }
                }

                m_shapeInfos.Clear();
            }
        }
コード例 #27
0
        private static void DrawBreakableShape(HkdBreakableShape breakableShape, MatrixD worldMatrix, float alpha, ref int shapeIndex, string customText = null, bool isPhantom = false)
        {
            object[] objArray1 = new object[] { breakableShape.Name, " Strength: ", breakableShape.GetStrenght(), " Static:", breakableShape.IsFixed().ToString() };
            DrawCollisionShape(breakableShape.GetShape(), worldMatrix, alpha, ref shapeIndex, string.Concat(objArray1), false);
            if (!string.IsNullOrEmpty(breakableShape.Name) && (breakableShape.Name != "PineTree175m_v2_001"))
            {
                breakableShape.IsFixed();
            }
            DebugShapesPositions[breakableShape.Name] = worldMatrix.Translation;
            List <HkdShapeInstanceInfo> list = new List <HkdShapeInstanceInfo>();

            breakableShape.GetChildren(list);
            Vector3 coM = breakableShape.CoM;

            foreach (HkdShapeInstanceInfo info in list)
            {
                Matrix matrix = (info.GetTransform() * worldMatrix) * Matrix.CreateTranslation(Vector3.Right * 2f);
                DrawBreakableShape(info.Shape, matrix, alpha, ref shapeIndex, null, false);
            }
        }
コード例 #28
0
        private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation, HashSet <Tuple <string, float> > namesAndBuildProgress, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder, out float buildProgress)
        {
            buildProgress = 1f;
            string name = shape.Name;
            Tuple <string, float> tuple = null;

            foreach (Tuple <string, float> tuple2 in namesAndBuildProgress)
            {
                if (tuple2.Item1 == name)
                {
                    tuple = tuple2;
                    break;
                }
            }
            if ((tuple != null) && (new MyBlockOrientation(ref shapeRotation) == blockOrientation))
            {
                MyObjectBuilder_FractureComponentBase.FracturedShape item = new MyObjectBuilder_FractureComponentBase.FracturedShape {
                    Name  = name,
                    Fixed = MyDestructionHelper.IsFixed(shape)
                };
                fractureComponentBuilder.Shapes.Add(item);
                buildProgress = tuple.Item2;
            }
            if (shape.GetChildrenCount() > 0)
            {
                List <HkdShapeInstanceInfo> list = new List <HkdShapeInstanceInfo>();
                shape.GetChildren(list);
                foreach (HkdShapeInstanceInfo info in list)
                {
                    float  num;
                    Matrix transform = info.GetTransform();
                    ConvertAllShapesToFractureComponentShapeBuilder(info.Shape, ref transform, blockOrientation, namesAndBuildProgress, fractureComponentBuilder, out num);
                    if (tuple == null)
                    {
                        buildProgress = num;
                    }
                }
            }
        }
コード例 #29
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="shape">Piece takes ownership of shape so clone it first</param>
        /// <param name="worldMatrix"></param>
        /// <param name="definition"> without definition the piece wont save</param>
        /// <returns></returns>
        public static MyFracturedPiece CreateFracturePiece(HkdBreakableShape shape, ref MatrixD worldMatrix, bool isStatic, MyDefinitionId?definition, bool sync)
        {
            System.Diagnostics.Debug.Assert(Sync.IsServer, "Only on server");
            var fracturedPiece = CreateFracturePiece(ref shape, ref worldMatrix, isStatic);

            if (definition.HasValue)
            {
                fracturedPiece.OriginalBlocks.Clear();
                fracturedPiece.OriginalBlocks.Add(definition.Value);

                MyPhysicalModelDefinition def;
                if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(definition.Value, out def))
                {
                    fracturedPiece.Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId;
                }
            }
            else
            {
                fracturedPiece.Save = false;
            }

            // Check valid shapes from block definitions.
            if (fracturedPiece.Save && MyFakes.ENABLE_FRACTURE_PIECE_SHAPE_CHECK)
            {
                fracturedPiece.DebugCheckValidShapes();
            }

            ProfilerShort.Begin("MyEntities.Add");
            if (MyExternalReplicable.FindByObject(fracturedPiece) == null)
            {
                MyEntities.RaiseEntityCreated(fracturedPiece);
            }
            MyEntities.Add(fracturedPiece);
            ProfilerShort.End();

            return(fracturedPiece);
        }
コード例 #30
0
        protected override void UnloadData()
        {
            Clusters.Dispose();

            Clusters.OnClusterCreated -= OnClusterCreated;
            Clusters.OnClusterRemoved -= OnClusterRemoved;
            Clusters = null;

            if (MyFakes.ENABLE_HAVOK_MULTITHREADING)
            {
                m_threadPool.RemoveReference();
                m_threadPool = null;

                m_jobQueue.Dispose();
                m_jobQueue = null;
            }
            m_destructionQueue.Clear();

            if (MyPerGameSettings.Destruction)
            {
                //Dispose material otherwise memory is corrupted on DS service and memory leaks
                HkdBreakableShape.DisposeSharedMaterial();
            }
        }
コード例 #31
0
 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;
 }
コード例 #32
0
        void CreateBreakableShapeFromCollisionShapes(MyModel model, Vector3 defaultSize, MyPhysicalModelDefinition modelDef)
        {
            // Make box half edge length of the grid so fractured block is smaller than not fractured, also good for compounds
            HkShape shape;
            if (model.HavokCollisionShapes != null && model.HavokCollisionShapes.Length > 0)
            {
                if (model.HavokCollisionShapes.Length > 1)
                {
                    shape = HkListShape.Create(model.HavokCollisionShapes, model.HavokCollisionShapes.Length, HkReferencePolicy.None);
                }
                else
                {
                    shape = model.HavokCollisionShapes[0];
                    shape.AddReference();
                }
            }
            else
            {
                //modelDef.Size * (modelDef.CubeSize == MyCubeSize.Large ? 2.5f : 0.25f)
                shape = new HkBoxShape(defaultSize * 0.5f, MyPerGameSettings.PhysicsConvexRadius);
            }

            var boxBreakable = new HkdBreakableShape(shape);
            boxBreakable.Name = model.AssetName;
            boxBreakable.SetMass(modelDef.Mass);
            model.HavokBreakableShapes = new HkdBreakableShape[] { boxBreakable };
            shape.RemoveReference();
        }
コード例 #33
0
 private void SetConvexRadius(HkdBreakableShape bShape, float radius)
 {
     var sh = bShape.GetShape();
     if (sh.IsConvex)
     {
         var convex = (HkConvexShape)sh;
         if(convex.ConvexRadius > radius)
             convex.ConvexRadius = radius;
         return;
     }
     if (sh.IsContainer())
     {
         HkShapeContainerIterator container = sh.GetContainer();
         while (container.IsValid)
         {
             if (container.CurrentValue.IsConvex)
             {
                 var convex = (HkConvexShape)container.CurrentValue;
                 if (convex.ConvexRadius > radius)
                     convex.ConvexRadius = radius;
             }
             container.Next();
         }
     }
 }
コード例 #34
0
 private static bool DontCreateFracture(HkdBreakableShape breakableShape)
 {
     if (!breakableShape.IsValid())
         return false;
     return (breakableShape.UserObject & (uint)HkdBreakableShape.Flags.DONT_CREATE_FRACTURE_PIECE) != 0;
 }
コード例 #35
0
        void FractureBreakableShape(HkdBreakableShape bShape, MyModelFractures modelFractures, string modPath)
        {
            HkdFracture fracture = null;
            HkReferenceObject geometry = null;

            if (modelFractures.Fractures[0] is RandomSplitFractureSettings)
            {
                var settings = (RandomSplitFractureSettings)modelFractures.Fractures[0];
                fracture = new HkdRandomSplitFracture()
                {
                    NumObjectsOnLevel1 = settings.NumObjectsOnLevel1,
                    NumObjectsOnLevel2 = settings.NumObjectsOnLevel2,
                    RandomRange = settings.RandomRange,
                    RandomSeed1 = settings.RandomSeed1,
                    RandomSeed2 = settings.RandomSeed2,
                    SplitGeometryScale = Vector4.One
                };

                if (!string.IsNullOrEmpty(settings.SplitPlane))
                {
                    var splitPlane = settings.SplitPlane;
                    if (!string.IsNullOrEmpty(modPath))
                        splitPlane = Path.Combine(modPath, settings.SplitPlane);

                    geometry = CreateGeometryFromSplitPlane(splitPlane);
                    if (geometry != null)
                    {
                        ((HkdRandomSplitFracture)fracture).SetGeometry(geometry);
                        VRageRender.MyRenderProxy.PreloadMaterials(splitPlane);
                    }
                }
            }
            if (modelFractures.Fractures[0] is VoronoiFractureSettings)
            {
                var settings = (VoronoiFractureSettings)modelFractures.Fractures[0];
                fracture = new HkdVoronoiFracture()
                {
                    Seed = settings.Seed,
                    NumSitesToGenerate = settings.NumSitesToGenerate,
                    NumIterations = settings.NumIterations
                };

                if (!string.IsNullOrEmpty(settings.SplitPlane))
                {
                    var splitPlane = settings.SplitPlane;
                    if (!string.IsNullOrEmpty(modPath))
                        splitPlane = Path.Combine(modPath, settings.SplitPlane);

                    geometry = CreateGeometryFromSplitPlane(splitPlane);

                    var pspm = MyModels.GetModel(splitPlane);

                    if (geometry != null)
                    {
                        ((HkdVoronoiFracture)fracture).SetGeometry(geometry);
                        VRageRender.MyRenderProxy.PreloadMaterials(splitPlane);
                    }
                }

            }
            if (modelFractures.Fractures[0] is WoodFractureSettings)
            {
                //TODO: Apply wood fracture algorithm
                var settings = (WoodFractureSettings)modelFractures.Fractures[0];
                fracture = new HkdWoodFracture()
                {
                    //Seed = settings.Seed,
                    //NumSitesToGenerate = settings.NumSitesToGenerate,
                    //NumIterations = settings.NumIterations
                };

                //if (!string.IsNullOrEmpty(settings.SplitPlane))
                //{
                //    var splitPlane = settings.SplitPlane;
                //    if (!string.IsNullOrEmpty(modPath))
                //        splitPlane = Path.Combine(modPath, settings.SplitPlane);

                //    geometry = CreateGeometryFromSplitPlane(splitPlane);

                //    var pspm = MyModels.GetModel(splitPlane);

                //    if (geometry != null)
                //    {
                //        ((HkdWoodFracture)fracture).SetGeometry(geometry);
                //        VRageRender.MyRenderProxy.PreloadMaterials(splitPlane);
                //    }
                //}
            }
           
            //if (woodButton.IsChecked)
            //{
            //    fracture = new HkdWoodFracture()
            //    {
            //        RandomSeed = 123456,
            //        BoardSplittingData = new HkdWoodFracture.SplittingData()
            //        {
            //        },
            //        SplinterSplittingData = new HkdWoodFracture.SplittingData()
            //        {
            //        }
            //    };
            //}

            if (fracture != null)
            {
                Storage.FractureShape(bShape, fracture);
                fracture.Dispose();
            }

            if (geometry != null)
                geometry.Dispose();
        }
コード例 #36
0
        private void DrawBreakableShape(HkdBreakableShape breakableShape, MatrixD worldMatrix, float alpha, ref int shapeIndex, string customText = null, bool isPhantom = false)
        {
            //VRageRender.MyRenderProxy.DebugDrawText3D(worldMatrix.Translation, , Color.White, 1, false);
            DrawCollisionShape(breakableShape.GetShape(), worldMatrix, alpha, ref shapeIndex, breakableShape.Name + " Strength: " + breakableShape.GetStrenght() + " Static:" + breakableShape.IsFixed());

            if (!string.IsNullOrEmpty(breakableShape.Name) && breakableShape.Name != "PineTree175m_v2_001" && breakableShape.IsFixed())
            {
            }

            DebugShapesPositions[breakableShape.Name] = worldMatrix.Translation;

            List<HkdShapeInstanceInfo> children = new List<HkdShapeInstanceInfo>();
            breakableShape.GetChildren(children);

            Vector3 parentCom =  breakableShape.CoM;

            foreach (var shapeInst in children)
            {
                Matrix transform = shapeInst.GetTransform();
              //  transform.Translation += (shapeInst.Shape.CoM - parentCom);
                Matrix trWorld = transform * worldMatrix * Matrix.CreateTranslation(Vector3.Right * 2);
                DrawBreakableShape(shapeInst.Shape, trWorld, alpha, ref shapeIndex);
            }
        }
コード例 #37
0
 internal void SetDataFromHavok(HkdBreakableShape shape, bool compound)
 {
     Shape = shape;
     if (compound)
     {
         SetDataFromCompound(shape);
     }
     else
     {
         var render = this.Render as MyRenderComponentFracturedPiece;
         render.AddPiece(shape.Name, Matrix.Identity);
     }
     CreateMountPoints();
 }
コード例 #38
0
ファイル: MyTrees.cs プロジェクト: Krulac/SpaceEngineers
        public static void ApplyImpulseToTreeFracture(ref MatrixD worldMatrix, ref Vector3 hitNormal, List<HkdShapeInstanceInfo> shapeList, ref HkdBreakableShape compound, MyFracturedPiece fp, float forceMultiplier = 1.0f)
        {
            float mass = compound.GetMass();
            Vector3 coMMaxY = Vector3.MinValue;
            shapeList.ForEach(s => coMMaxY = (s.CoM.Y > coMMaxY.Y) ? s.CoM : coMMaxY);

            Vector3 forceVector = hitNormal;
            forceVector.Y = 0;
            forceVector.Normalize();

            Vector3 force = 0.3f * forceMultiplier * mass * forceVector;
            fp.Physics.Enabled = true;//so we get the body in world
            Vector3 worldForcePoint = fp.Physics.WorldToCluster(Vector3D.Transform(coMMaxY, worldMatrix));

            fp.Physics.RigidBody.AngularDamping = MyPerGameSettings.DefaultAngularDamping;
            fp.Physics.RigidBody.LinearDamping = MyPerGameSettings.DefaultLinearDamping;

            fp.Physics.RigidBody.ApplyPointImpulse(force, worldForcePoint);
        }
コード例 #39
0
        public override void SetShape(HkdBreakableShape shape, bool compound)
        {
            base.SetShape(shape, compound);

            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);
        }
コード例 #40
0
 private static void ConnectPiecesInBlock(HkdBreakableShape parent, List<HkdShapeInstanceInfo> shapeList)
 {
     for (int i = 0; i < shapeList.Count; i++)
     {
         for (int j = 0; j < shapeList.Count; j++)
         {
             if (i == j) continue;
             MyGridShape.ConnectShapesWithChildren(parent, shapeList[i].Shape, shapeList[j].Shape);
         }
     }
 }
コード例 #41
0
ファイル: MyTrees.cs プロジェクト: Krulac/SpaceEngineers
        public static void CreateFracturePiece(MyEnvironmentItemDefinition itemDefinition, HkdBreakableShape oldBreakableShape, MatrixD worldMatrix, Vector3 hitNormal, List<HkdShapeInstanceInfo> shapeList,
            float forceMultiplier, bool canContainFixedChildren)
        {
            bool containsFixedChildren = false;
            if (canContainFixedChildren)
            {
                foreach (var shapeInst in shapeList)
                {
                    shapeInst.Shape.SetMotionQualityRecursively(HkdBreakableShape.BodyQualityType.QUALITY_DEBRIS);

                    var t = worldMatrix.Translation + worldMatrix.Up * 1.5f;
                    var o = Quaternion.CreateFromRotationMatrix(worldMatrix.GetOrientation());
                    MyPhysics.GetPenetrationsShape(shapeInst.Shape.GetShape(), ref t, ref o, m_tmpResults, MyPhysics.DefaultCollisionLayer);
                    bool flagSet = false;
                    foreach (var res in m_tmpResults)
                    {
                        var entity = res.GetCollisionEntity();

                        if (entity is MyVoxelMap)
                        {
                            shapeInst.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                            containsFixedChildren = true;
                            flagSet = true;
                            break;
                        }

                        if (flagSet)
                            break;
                    }
                    m_tmpResults.Clear();
                }
            }

            HkdBreakableShape compound = new HkdCompoundBreakableShape(oldBreakableShape, shapeList);
            ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();
            //compound.SetMassRecursively(500);
            //compound.SetStrenghtRecursively(5000, 0.7f);

            var fp = MyDestructionHelper.CreateFracturePiece(compound, MyPhysics.SingleWorld.DestructionWorld, ref worldMatrix, containsFixedChildren, itemDefinition.Id, true);
            if (fp != null && !canContainFixedChildren)
            {
                ApplyImpulseToTreeFracture(ref worldMatrix, ref hitNormal, shapeList, ref compound, fp, forceMultiplier);
                fp.Physics.ForceActivate();
            }
        }
コード例 #42
0
        /// <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();
        }
コード例 #43
0
        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();
        }
コード例 #44
0
        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();
        }
コード例 #45
0
 private void DisableRefCountRec(HkdBreakableShape bShape)
 {
     bShape.DisableRefCount();
     var lst = new List<HkdShapeInstanceInfo>();
     bShape.GetChildren(lst);
     foreach (var child in lst)
         DisableRefCountRec(child.Shape);
 }
コード例 #46
0
 private HkdBreakableShape AddMountForShape(HkdBreakableShape shape, Matrix transform, ref BoundingBox blockBB)
 {
     Vector4 min;
     Vector4 max;
     shape.GetShape().GetLocalAABB(0.01f, out min, out max);//.Transform(CubeGrid.PositionComp.WorldMatrix);
     var bb = new BoundingBox(new Vector3(min), new Vector3(max));
     bb = bb.Transform(transform);
     bb.Min /= CubeGrid.GridSize; //normalize for mount point
     bb.Max /= CubeGrid.GridSize;
     
     bb.Inflate(0.04f);//add tolerance (fracture shapes are smaller than block)
     bb.Min += blockBB.HalfExtents;
     bb.Max += blockBB.HalfExtents;
     
     if (blockBB.Contains(bb) == ContainmentType.Intersects)
     {
         bb.Inflate(-0.04f);
         foreach (var directionEnum in Base6Directions.EnumDirections)
         {
             int dirEnum = (int)directionEnum;
             Vector3 direction = Base6Directions.Directions[dirEnum];
             Vector3 absDir = Vector3.Abs(direction);
             var mp = new MyCubeBlockDefinition.MountPoint();
             mp.Start = bb.Min;
             mp.End = bb.Max;
             var start = mp.Start * absDir / (blockBB.HalfExtents * 2) - absDir * 0.04f;
             var end = mp.End * absDir / (blockBB.HalfExtents * 2) + absDir * 0.04f;
             bool add = false;
             bool one = false;
             if (start.Max() < 1 && end.Max() > 1 && direction.Max() > 0)
             {
                 add = true;
                 one = true;
             }
             else if (start.Min() < 0 && end.Max() > 0 && direction.Min() < 0)
             {
                 add = true;
             }
             if (!add)
             {
                 continue;
             }
             mp.Start -= mp.Start * absDir - absDir * 0.04f;
             mp.End -= mp.End * absDir + absDir * 0.04f;
             if (one)
             {
                 mp.Start += absDir * blockBB.HalfExtents * 2;
                 mp.End += absDir * blockBB.HalfExtents * 2;
             }
             mp.Start -= blockBB.HalfExtents - Vector3.One / 2;
             mp.End -= blockBB.HalfExtents - Vector3.One / 2;
             mp.Normal = new Vector3I(direction);
             MountPoints.Add(mp);
         }
     }
     return shape;
 }
コード例 #47
0
        private void CreatePieceData(MyModel model, HkdBreakableShape breakableShape)
        {
            //Root shape for fractured compound blocks
            {
                var msg = VRageRender.MyRenderProxy.PrepareAddRuntimeModel();
                ProfilerShort.Begin("GetDataFromShape");
                m_tmpMesh.Data = msg.ModelData;
                MyDestructionData.Static.Storage.GetDataFromShape(breakableShape, m_tmpMesh);
                System.Diagnostics.Debug.Assert(msg.ModelData.Sections.Count > 0, "Invalid data");
                if (msg.ModelData.Sections.Count > 0)
                {
                    if(MyFakes.USE_HAVOK_MODELS)
                        msg.ReplacedModel = model.AssetName;
                    VRageRender.MyRenderProxy.AddRuntimeModel(breakableShape.ShapeName, msg);
                }
                ProfilerShort.End();
            }

            using (m_tmpChildrenList.GetClearToken())
            {
                breakableShape.GetChildren(m_tmpChildrenList);
                LoadChildrenShapes(m_tmpChildrenList);
            }
        }
コード例 #48
0
        public void SetDataFromCompound(HkdBreakableShape compound)
        {
            var render = this.Render as MyRenderComponentFracturedPiece;

            if (render != null)
            {
                compound.GetChildren(m_shapeInfos);

                foreach (var shapeInstanceInfo in m_shapeInfos)
                {
                    System.Diagnostics.Debug.Assert(shapeInstanceInfo.IsValid(), "Invalid shapeInstanceInfo!");
                    if (shapeInstanceInfo.IsValid())
                    {
                        render.AddPiece(shapeInstanceInfo.ShapeName, shapeInstanceInfo.GetTransform());
                    }
                }

                m_shapeInfos.Clear();
            }
        }
コード例 #49
0
        private void DrawConnections(HkdBreakableShape breakableShape, MatrixD worldMatrix, float alpha, ref int shapeIndex, string customText = null, bool isPhantom = false)
        {
            List<HkdConnection> connections = new List<HkdConnection>();
            breakableShape.GetConnectionList(connections);

            List<HkdShapeInstanceInfo> children = new List<HkdShapeInstanceInfo>();
            breakableShape.GetChildren(children);

            foreach (var conn in connections)
            {
                var posA = DebugShapesPositions[conn.ShapeAName];
                var posB = DebugShapesPositions[conn.ShapeBName];

                bool cont = false;
                foreach (var child in children)
                {
                    if ((child.ShapeName == conn.ShapeAName) || (child.ShapeName == conn.ShapeBName))
                        cont = true;
                }

                if (cont)
                    VRageRender.MyRenderProxy.DebugDrawLine3D(posA, posB, Color.White, Color.White, false);
            }
        }
コード例 #50
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="shape">Piece takes ownership of shape so clone it first</param>
        /// <param name="worldMatrix"></param>
        /// <param name="definition"> without definition the piece wont save</param>
        /// <returns></returns>
        public static MyFracturedPiece CreateFracturePiece(HkdBreakableShape shape, HkdWorld world, ref MatrixD worldMatrix, bool isStatic, MyDefinitionId? definition, bool sync)
        {
            System.Diagnostics.Debug.Assert(Sync.IsServer, "Only on server");
            var fracturedPiece = CreateFracturePiece(ref shape, world, ref worldMatrix, isStatic);

            if (definition.HasValue)
            {
                fracturedPiece.OriginalBlocks.Clear();
                fracturedPiece.OriginalBlocks.Add(definition.Value);
                MyPhysicalModelDefinition def;
                if (MyDefinitionManager.Static.TryGetDefinition<MyPhysicalModelDefinition>(definition.Value, out def))
                    fracturedPiece.Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId;
            }
            else
                fracturedPiece.Save = false;

            if (sync)
                MySyncDestructions.CreateFracturePiece((Sandbox.Common.ObjectBuilders.MyObjectBuilder_FracturedPiece)fracturedPiece.GetObjectBuilder());

            return fracturedPiece;
        }
コード例 #51
0
        public static void CreateFracturePiece(MyEnvironmentItemDefinition itemDefinition, HkdBreakableShape oldBreakableShape, MatrixD worldMatrix, Vector3 hitNormal, List <HkdShapeInstanceInfo> shapeList,
                                               float forceMultiplier, bool canContainFixedChildren, string fallSound = "")
        {
            bool containsFixedChildren = false;

            if (canContainFixedChildren)
            {
                foreach (var shapeInst in shapeList)
                {
                    shapeInst.Shape.SetMotionQualityRecursively(HkdBreakableShape.BodyQualityType.QUALITY_DEBRIS);

                    var t = worldMatrix.Translation + worldMatrix.Up * 1.5f;
                    var o = Quaternion.CreateFromRotationMatrix(worldMatrix.GetOrientation());
                    MyPhysics.GetPenetrationsShape(shapeInst.Shape.GetShape(), ref t, ref o, m_tmpResults, MyPhysics.CollisionLayers.DefaultCollisionLayer);
                    bool flagSet = false;
                    foreach (var res in m_tmpResults)
                    {
                        var entity = res.GetCollisionEntity();

                        if (entity is MyVoxelMap)
                        {
                            shapeInst.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED);
                            containsFixedChildren = true;
                            flagSet = true;
                            break;
                        }

                        if (flagSet)
                        {
                            break;
                        }
                    }
                    m_tmpResults.Clear();
                }
            }

            HkdBreakableShape compound = new HkdCompoundBreakableShape(oldBreakableShape, shapeList);

            ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren();
            //compound.SetMassRecursively(500);
            //compound.SetStrenghtRecursively(5000, 0.7f);

            var fp = MyDestructionHelper.CreateFracturePiece(compound, MyPhysics.SingleWorld.DestructionWorld, ref worldMatrix, containsFixedChildren, itemDefinition.Id, true);

            if (fp != null && !canContainFixedChildren)
            {
                ApplyImpulseToTreeFracture(ref worldMatrix, ref hitNormal, shapeList, ref compound, fp, forceMultiplier);
                fp.Physics.ForceActivate();
                if (fallSound.Length > 0)
                {
                    fp.StartFallSound(fallSound);
                }
            }
        }
コード例 #52
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="shape">Piece takes ownership of shape so clone it first</param>
        /// <param name="worldMatrix"></param>
        /// <param name="definition"> without definition the piece wont save</param>
        /// <returns></returns>
        public static MyFracturedPiece CreateFracturePiece(HkdBreakableShape shape, HkdWorld world, ref MatrixD worldMatrix, bool isStatic, MyDefinitionId? definition, bool sync)
        {
            System.Diagnostics.Debug.Assert(Sync.IsServer, "Only on server");
            var fracturedPiece = CreateFracturePiece(ref shape, world, ref worldMatrix, isStatic);

            if (definition.HasValue)
            {
                fracturedPiece.OriginalBlocks.Clear();
                fracturedPiece.OriginalBlocks.Add(definition.Value);

                MyPhysicalModelDefinition def;
                if (MyDefinitionManager.Static.TryGetDefinition<MyPhysicalModelDefinition>(definition.Value, out def))
                    fracturedPiece.Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId;
            }
            else
                fracturedPiece.Save = false;

            // Check valid shapes from block definitions. 
            if (fracturedPiece.Save && MyFakes.ENABLE_FRACTURE_PIECE_SHAPE_CHECK)
                fracturedPiece.DebugCheckValidShapes();

            ProfilerShort.Begin("MyEntities.Add");
            MyEntities.RaiseEntityCreated(fracturedPiece);
            MyEntities.Add(fracturedPiece);
            ProfilerShort.End();

            return fracturedPiece;
        }
コード例 #53
0
        private static void GetAllBlockBreakableShapeNames(HkdBreakableShape shape, HashSet<string> outNames)
        {
            var name = shape.Name;
            if (!string.IsNullOrEmpty(name))
                outNames.Add(name);

            if (shape.GetChildrenCount() > 0)
            {
                List<HkdShapeInstanceInfo> children = new List<HkdShapeInstanceInfo>();
                shape.GetChildren(children);
                foreach (var child in children)
                    GetAllBlockBreakableShapeNames(child.Shape, outNames);
            }
        }
コード例 #54
0
        private static void ConvertAllShapesToFractureComponentShapeBuilder(HkdBreakableShape shape, ref Matrix shapeRotation, MyBlockOrientation blockOrientation, HashSet<string> names, MyObjectBuilder_FractureComponentCubeBlock fractureComponentBuilder)
        {
            var name = shape.Name;
            if (names.Contains(name))
            {
                MyBlockOrientation shapeOrientation = new MyBlockOrientation(ref shapeRotation);
                if (shapeOrientation == blockOrientation)
                {
                    MyObjectBuilder_FractureComponentCubeBlock.FracturedShape builderShape = new MyObjectBuilder_FractureComponentBase.FracturedShape();
                    builderShape.Name = name;
                    builderShape.Fixed = MyDestructionHelper.IsFixed(shape);

                    fractureComponentBuilder.Shapes.Add(builderShape);
                }
            }

            if (shape.GetChildrenCount() > 0)
            {
                List<HkdShapeInstanceInfo> children = new List<HkdShapeInstanceInfo>();
                shape.GetChildren(children);
                foreach (var child in children) 
                {
                    var childShapeRotation = child.GetTransform();
                    ConvertAllShapesToFractureComponentShapeBuilder(child.Shape, ref childShapeRotation, blockOrientation, names, fractureComponentBuilder);
                }
            }

        }
コード例 #55
0
        public static void ApplyImpulseToTreeFracture(ref MatrixD worldMatrix, ref Vector3 hitNormal, List <HkdShapeInstanceInfo> shapeList, ref HkdBreakableShape compound, MyFracturedPiece fp, float forceMultiplier = 1.0f)
        {
            float   mass    = compound.GetMass();
            Vector3 coMMaxY = Vector3.MinValue;

            shapeList.ForEach(s => coMMaxY = (s.CoM.Y > coMMaxY.Y) ? s.CoM : coMMaxY);

            Vector3 forceVector = hitNormal;

            forceVector.Y = 0;
            forceVector.Normalize();

            Vector3 force = 0.3f * forceMultiplier * mass * forceVector;

            fp.Physics.Enabled = true;//so we get the body in world
            Vector3 worldForcePoint = fp.Physics.WorldToCluster(Vector3D.Transform(coMMaxY, worldMatrix));

            fp.Physics.RigidBody.AngularDamping = MyPerGameSettings.DefaultAngularDamping;
            fp.Physics.RigidBody.LinearDamping  = MyPerGameSettings.DefaultLinearDamping;

            fp.Physics.RigidBody.ApplyPointImpulse(force, worldForcePoint);
        }
コード例 #56
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);            
            }
        }
コード例 #57
0
        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;
        }
コード例 #58
0
 private static bool IsBreakableShapeCompound(HkdBreakableShape shape)
 {
     return (string.IsNullOrEmpty(shape.Name) || shape.IsCompound() || shape.GetChildrenCount() > 0);
 }
コード例 #59
0
        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();
        }
コード例 #60
0
        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;
        }