private static bool RemoveGenerated(HkdBreakableBody b, MyCubeBlock block) { if (MyFakes.REMOVE_GENERATED_BLOCK_FRACTURES && ContainsGenerated(block)) { if (b.BreakableShape.IsCompound()) { b.BreakableShape.GetChildren(m_tmpInfos); for (int i = 0; i < m_tmpInfos.Count; i++) { if (DontCreateFracture(m_tmpInfos[i].Shape)) { m_tmpInfos.RemoveAt(i); i--; } } if (m_tmpInfos.Count == 0) { return true; } m_tmpInfos.Clear(); } else if (DontCreateFracture(b.BreakableShape)) { return true; } } return false; }
public static MyFracturedPiece CreateFracturePiece(HkdBreakableBody b, ref MatrixD worldMatrix, List <MyDefinitionId> originalBlocks, MyCubeBlock block = null, bool sync = true) { System.Diagnostics.Debug.Assert(Sync.IsServer, "Only on server"); if (block != null) { if (RemoveGenerated(b, block)) { return(null); } } ProfilerShort.Begin("CreateFracturePiece"); var fracturedPiece = MyFracturedPiecesManager.Static.GetPieceFromPool(0); fracturedPiece.InitFromBreakableBody(b, worldMatrix, block); fracturedPiece.NeedsUpdate |= Common.MyEntityUpdateEnum.BEFORE_NEXT_FRAME; //fracturedPiece.Physics.RigidBody.ContactPointCallbackDelay = 0; //fracturedPiece.Physics.RigidBody.ContactPointCallbackEnabled = true; ProfilerShort.End(); ProfilerShort.Begin("MyEntities.Add"); MyEntities.Add(fracturedPiece); ProfilerShort.End(); if (block == null) { fracturedPiece.OriginalBlocks.Clear(); fracturedPiece.OriginalBlocks.AddRange(originalBlocks); MyPhysicalModelDefinition def; if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(originalBlocks[0], out def)) { fracturedPiece.Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId; } } if (sync) { MySyncDestructions.CreateFracturePiece((Sandbox.Common.ObjectBuilders.MyObjectBuilder_FracturedPiece)fracturedPiece.GetObjectBuilder()); } return(fracturedPiece); }
public static MyFracturedPiece CreateFracturePiece(HkdBreakableBody b, ref MatrixD worldMatrix, List <MyDefinitionId> originalBlocks, MyCubeBlock block = null, bool sync = true) { System.Diagnostics.Debug.Assert(Sync.IsServer, "Only on server"); if (IsBodyWithoutGeneratedFracturedPieces(b, block)) { return(null); } ProfilerShort.Begin("CreateFracturePiece"); var fracturedPiece = MyFracturedPiecesManager.Static.GetPieceFromPool(0); fracturedPiece.InitFromBreakableBody(b, worldMatrix, block); fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; //fracturedPiece.Physics.RigidBody.ContactPointCallbackDelay = 0; //fracturedPiece.Physics.RigidBody.ContactPointCallbackEnabled = true; ProfilerShort.End(); if (originalBlocks != null && originalBlocks.Count != 0) { fracturedPiece.OriginalBlocks.Clear(); fracturedPiece.OriginalBlocks.AddRange(originalBlocks); MyPhysicalModelDefinition def; if (MyDefinitionManager.Static.TryGetDefinition <MyPhysicalModelDefinition>(originalBlocks[0], out def)) { fracturedPiece.Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId; } } // Check valid shapes from block definitions. if (MyFakes.ENABLE_FRACTURE_PIECE_SHAPE_CHECK) { fracturedPiece.DebugCheckValidShapes(); } ProfilerShort.Begin("MyEntities.Add"); MyEntities.RaiseEntityCreated(fracturedPiece); MyEntities.Add(fracturedPiece); ProfilerShort.End(); return(fracturedPiece); }
public static MyFracturedPiece CreateFracturePiece(HkdBreakableBody b, ref MatrixD worldMatrix, List<MyDefinitionId> originalBlocks, MyCubeBlock block = null, bool sync = true) { System.Diagnostics.Debug.Assert(Sync.IsServer, "Only on server"); if (block != null) { if (RemoveGenerated(b, block)) { return null; } } ProfilerShort.Begin("CreateFracturePiece"); var fracturedPiece = MyFracturedPiecesManager.Static.GetPieceFromPool(0); fracturedPiece.InitFromBreakableBody(b, worldMatrix, block); fracturedPiece.NeedsUpdate |= Common.MyEntityUpdateEnum.BEFORE_NEXT_FRAME; //fracturedPiece.Physics.RigidBody.ContactPointCallbackDelay = 0; //fracturedPiece.Physics.RigidBody.ContactPointCallbackEnabled = true; ProfilerShort.End(); ProfilerShort.Begin("MyEntities.Add"); MyEntities.Add(fracturedPiece); ProfilerShort.End(); if (block == null) { fracturedPiece.OriginalBlocks.Clear(); fracturedPiece.OriginalBlocks.AddRange(originalBlocks); MyPhysicalModelDefinition def; if(MyDefinitionManager.Static.TryGetDefinition<MyPhysicalModelDefinition>(originalBlocks[0], out def)) fracturedPiece.Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId; } if (sync) MySyncDestructions.CreateFracturePiece((Sandbox.Common.ObjectBuilders.MyObjectBuilder_FracturedPiece)fracturedPiece.GetObjectBuilder()); return fracturedPiece; }
public static MyFracturedPiece CreateFracturePiece(HkdBreakableBody b, ref MatrixD worldMatrix, List<MyDefinitionId> originalBlocks, MyCubeBlock block = null, bool sync = true) { System.Diagnostics.Debug.Assert(Sync.IsServer, "Only on server"); if (IsBodyWithoutGeneratedFracturedPieces(b, block)) return null; ProfilerShort.Begin("CreateFracturePiece"); var fracturedPiece = MyFracturedPiecesManager.Static.GetPieceFromPool(0); fracturedPiece.InitFromBreakableBody(b, worldMatrix, block); fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; //fracturedPiece.Physics.RigidBody.ContactPointCallbackDelay = 0; //fracturedPiece.Physics.RigidBody.ContactPointCallbackEnabled = true; ProfilerShort.End(); if (originalBlocks != null && originalBlocks.Count != 0) { fracturedPiece.OriginalBlocks.Clear(); fracturedPiece.OriginalBlocks.AddRange(originalBlocks); MyPhysicalModelDefinition def; if (MyDefinitionManager.Static.TryGetDefinition<MyPhysicalModelDefinition>(originalBlocks[0], out def)) fracturedPiece.Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId; } // Check valid shapes from block definitions. if (MyFakes.ENABLE_FRACTURE_PIECE_SHAPE_CHECK) fracturedPiece.DebugCheckValidShapes(); ProfilerShort.Begin("MyEntities.Add"); MyEntities.RaiseEntityCreated(fracturedPiece); MyEntities.Add(fracturedPiece); ProfilerShort.End(); return fracturedPiece; }
internal void InitFromBreakableBody(HkdBreakableBody b, MatrixD worldMatrix, MyCubeBlock block) { ProfilerShort.Begin("RemoveGen&SetFixed"); OriginalBlocks.Clear(); if (block != null) { if (block is MyCompoundCubeBlock) { foreach (var block2 in (block as MyCompoundCubeBlock).GetBlocks()) { OriginalBlocks.Add(block2.BlockDefinition.Id); } } else if (block is MyFracturedBlock) { OriginalBlocks.AddRange((block as MyFracturedBlock).OriginalBlocks); } else { OriginalBlocks.Add(block.BlockDefinition.Id); } } var rigidBody = b.GetRigidBody(); bool isFixed = MyDestructionHelper.IsFixed(b.BreakableShape); if (isFixed) { rigidBody.UpdateMotionType(HkMotionType.Fixed); rigidBody.LinearVelocity = Vector3.Zero; rigidBody.AngularVelocity = Vector3.Zero; } ProfilerShort.Begin("Sync"); if (SyncFlag) { CreateSync(); } ProfilerShort.End(); PositionComp.WorldMatrix = worldMatrix; Physics.Flags = isFixed ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS; Physics.BreakableBody = b; rigidBody.UserObject = Physics; if (!isFixed) { rigidBody.Motion.SetDeactivationClass(HkSolverDeactivation.High); rigidBody.EnableDeactivation = true; if (MyFakes.REDUCE_FRACTURES_COUNT) { if (b.BreakableShape.Volume < 1 && MyRandom.Instance.Next(6) > 1) { rigidBody.Layer = MyFracturedPiecesManager.FakePieceLayer; } else { rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer; } } else { rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer; } } else { rigidBody.Layer = MyPhysics.CollisionLayers.StaticCollisionLayer; } 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; } } ProfilerShort.BeginNextBlock("Enable"); Physics.Enabled = true; MyDestructionHelper.FixPosition(this); SetDataFromHavok(b.BreakableShape); var coml = b.GetRigidBody().CenterOfMassLocal; var comw = b.GetRigidBody().CenterOfMassWorld; var com = b.BreakableShape.CoM; b.GetRigidBody().CenterOfMassLocal = com; b.BreakableShape.RemoveReference(); ProfilerShort.End(); }
internal void InitFromBreakableBody(HkdBreakableBody b, MatrixD worldMatrix, MyCubeBlock block) { ProfilerShort.Begin("RemoveGen&SetFixed"); OriginalBlocks.Clear(); if (block != null) { if (block is MyCompoundCubeBlock) { foreach (var block2 in (block as MyCompoundCubeBlock).GetBlocks()) OriginalBlocks.Add(block2.BlockDefinition.Id); } else if (block is MyFracturedBlock) { OriginalBlocks.AddRange((block as MyFracturedBlock).OriginalBlocks); } else { OriginalBlocks.Add(block.BlockDefinition.Id); } } var rigidBody = b.GetRigidBody(); bool isFixed = MyDestructionHelper.IsFixed(b.BreakableShape); if (isFixed) { rigidBody.UpdateMotionType(HkMotionType.Fixed); rigidBody.LinearVelocity = Vector3.Zero; rigidBody.AngularVelocity = Vector3.Zero; } ProfilerShort.Begin("Sync"); if (SyncFlag) { CreateSync(); } ProfilerShort.End(); PositionComp.WorldMatrix = worldMatrix; Physics.Flags = isFixed ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS; Physics.BreakableBody = b; rigidBody.UserObject = Physics; if (!isFixed) { rigidBody.Motion.SetDeactivationClass(HkSolverDeactivation.High); rigidBody.EnableDeactivation = true; if (MyFakes.REDUCE_FRACTURES_COUNT) { if (b.BreakableShape.Volume < 1 && MyRandom.Instance.Next(6) > 1) rigidBody.Layer = MyFracturedPiecesManager.FakePieceLayer; else rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer; } else rigidBody.Layer = MyPhysics.CollisionLayers.DefaultCollisionLayer; } else rigidBody.Layer = MyPhysics.CollisionLayers.StaticCollisionLayer; 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; } ProfilerShort.BeginNextBlock("Enable"); Physics.Enabled = true; MyDestructionHelper.FixPosition(this); SetDataFromHavok(b.BreakableShape); var coml = b.GetRigidBody().CenterOfMassLocal; var comw = b.GetRigidBody().CenterOfMassWorld; var com = b.BreakableShape.CoM; b.GetRigidBody().CenterOfMassLocal = com; b.BreakableShape.RemoveReference(); ProfilerShort.End(); }
void BreakableBody_BeforeControllerOperation(HkdBreakableBody b) { ProfilerShort.Begin("BreakableBody_AfterControllerOperation"); if (m_recreateBody) b.BreakableShape.SetStrenghtRecursively(float.MaxValue, 0.7f); ProfilerShort.End(); }
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; }
/// <summary> /// Removes breakable shapes form fracture component. /// </summary> /// <param name="bBody">body with shapes</param> /// <param name="block">block</param> /// <param name="blocksToDelete">collection of blocks to remove from grid</param> /// <param name="blocksUpdateDamage">collection of blocks for updating their damage according to remaining shapes count</param> /// <returns>true if block was processes otherwise false (block in compound does not exist)</returns> private bool RemoveShapesFromFracturedBlocks(HkdBreakableBody bBody, MySlimBlock block, ushort? compoundId, HashSet<MySlimBlock> blocksToDelete, HashSet<MySlimBlock> blocksUpdateDamage) { Debug.Assert(MyFakes.ENABLE_FRACTURE_COMPONENT); // Block can be removed when the removed shape is the last one! MyFractureComponentCubeBlock fractureComponent = block.GetFractureComponent(); if (fractureComponent != null) { bool removeBlock = false; var bShape = bBody.BreakableShape; if (IsBreakableShapeCompound(bShape)) { m_tmpShapeNames.Clear(); m_tmpChildren_RemoveShapes.Clear(); bShape.GetChildren(m_tmpChildren_RemoveShapes); var shapesCount = m_tmpChildren_RemoveShapes.Count; for (int i = 0; i < shapesCount; ++i) { var child = m_tmpChildren_RemoveShapes[i]; if (string.IsNullOrEmpty(child.ShapeName)) child.Shape.GetChildren(m_tmpChildren_RemoveShapes); } m_tmpChildren_RemoveShapes.ForEach(delegate(HkdShapeInstanceInfo c) { var shapeName = c.ShapeName; if (!string.IsNullOrEmpty(shapeName)) m_tmpShapeNames.Add(shapeName); }); if (m_tmpShapeNames.Count != 0) { removeBlock = fractureComponent.RemoveChildShapes(m_tmpShapeNames); MySyncDestructions.RemoveShapesFromFractureComponent(block.CubeGrid.EntityId, block.Position, compoundId ?? 0xFFFF, m_tmpShapeNames); } m_tmpChildren_RemoveShapes.Clear(); m_tmpShapeNames.Clear(); } else { var name = bBody.BreakableShape.Name; removeBlock = fractureComponent.RemoveChildShapes(new string[] { name }); MySyncDestructions.RemoveShapeFromFractureComponent(block.CubeGrid.EntityId, block.Position, compoundId ?? 0xFFFF, name); } if (removeBlock) blocksToDelete.Add(block); else blocksUpdateDamage.Add(block); } else { blocksToDelete.Add(block); } return true; }
void BreakableBody_AfterControllerOperation(HkdBreakableBody b) { ProfilerShort.Begin("BreakableBody_AfterControllerOperation"); if (m_recreateBody) b.BreakableShape.SetStrenghtRecursively(MyDestructionConstants.STRENGTH, 0.7f); ProfilerShort.End(); }
private void ReturnToPoolInternal(HkdBreakableBody body) { var rb = body.GetRigidBody(); if(rb == null) { return; } rb.ContactPointCallbackEnabled = false; //Debug.Assert(m_givenRBs.Remove(rb), "New body from outside in pool!"); m_givenRBs.Remove(rb); foreach(var b0 in m_bodyPool) { if (body == b0.Breakable || rb == b0.Rigid) Debug.Fail("Body already in pool!"); } // body.BreakableShape.AddReference(); var bs = body.BreakableShape; bs.ClearConnections(); body.Clear(); Bodies b; b.Rigid = rb; b.Breakable = body; body.InitListener(); m_bodyPool.Enqueue(b); }
public void CreateConnectionToWorld(HkdBreakableBody destructionBody, HkWorld havokWorld) { if (BlocksConnectedToWorld.Count == 0) return; HkdFixedConnectivity conn = HkdFixedConnectivity.Create(); foreach (var pos in BlocksConnectedToWorld) { HkdFixedConnectivity.Connection c = new HkdFixedConnectivity.Connection(Vector3.Zero, Vector3.Up, 1, m_blocksShapes[pos].Shape, havokWorld.GetFixedBody(), 0); conn.AddConnection(ref c); c.RemoveReference(); } destructionBody.SetFixedConnectivity(conn); conn.RemoveReference(); }
public void RefreshBlocks(HkRigidBody rigidBody, HkRigidBody rigidBody2, MyGridPhysics.MyDirtyBlocksInfo dirtyCubesInfo, HkdBreakableBody destructionBody = null) { ProfilerShort.Begin("Refresh shape"); if (m_grid.Physics.HavokWorld != null) if (m_grid.BlocksDestructionEnabled) UnmarkBreakable(m_grid.Physics.HavokWorld, rigidBody); m_originalMassPropertiesSet = false; UpdateDirtyBlocks(dirtyCubesInfo.DirtyBlocks); UpdateMass(rigidBody, false); UpdateMassFromInventories(m_grid.CubeBlocks, rigidBody.GetBody()); UpdateShape(rigidBody, rigidBody2, destructionBody); if (m_grid.Physics.HavokWorld != null) if (m_grid.BlocksDestructionEnabled) MarkBreakable(m_grid.Physics.HavokWorld, rigidBody); ProfilerShort.End(); }
public void CreateConnectionToWorld(HkdBreakableBody destructionBody) { if (BlocksConnectedToWorld.Count == 0) return; HkdFixedConnectivity conn = HkdFixedConnectivity.Create(); var voxelMap = MySession.Static.VoxelMaps.Instances.Single(); foreach (var pos in BlocksConnectedToWorld) { HkdFixedConnectivity.Connection c = new HkdFixedConnectivity.Connection(Vector3.Zero, Vector3.Up, 1, m_blocksShapes[pos].Shape, voxelMap.Physics.RigidBody, 0); conn.AddConnection(ref c); c.RemoveReference(); } destructionBody.SetFixedConnectivity(conn); conn.RemoveReference(); }
private void UpdateShape(HkRigidBody rigidBody, HkRigidBody rigidBody2, HkdBreakableBody destructionBody) { ProfilerShort.Begin("SetShape"); if (destructionBody != null) { ProfilerShort.Begin("SetBreakableShape"); destructionBody.BreakableShape = BreakableShape; ProfilerShort.BeginNextBlock("ConnectToWorld"); CreateConnectionToWorld(destructionBody); ProfilerShort.End(); //breakableShape.Dispose(); } else { rigidBody.SetShape(m_root); if (rigidBody2 != null) { rigidBody2.SetShape(m_root); } } ProfilerShort.End(); }
public void RefreshBlocks(HkRigidBody rigidBody, HkRigidBody rigidBody2, MyGridPhysics.MyDirtyBlocksInfo dirtyCubesInfo, HkdBreakableBody destructionBody = null) { ProfilerShort.Begin("Refresh shape"); if (m_grid.Physics.HavokWorld != null) UnmarkBreakable(m_grid.Physics.HavokWorld, rigidBody); UpdateDirtyBlocks(dirtyCubesInfo.DirtyBlocks); UpdateMass(rigidBody); UpdateShape(rigidBody, rigidBody2, destructionBody); if (m_grid.Physics.HavokWorld != null) MarkBreakable(m_grid.Physics.HavokWorld, rigidBody); ProfilerShort.End(); }
public static void DebugDrawBreakable(HkdBreakableBody bb, Vector3 offset) { const float alpha = 0.3f; //var offset = MyPhysics.Clusters.GetObjectOffset(ClusterObjectID); DebugShapesPositions.Clear(); if (bb != null) { int index = 0; Matrix rbMatrix = bb.GetRigidBody().GetRigidBodyMatrix(); MatrixD worldMatrix = MatrixD.CreateWorld(rbMatrix.Translation + offset, rbMatrix.Forward, rbMatrix.Up); DrawBreakableShape(bb.BreakableShape, worldMatrix, alpha, ref index); DrawConnections(bb.BreakableShape, worldMatrix, alpha, ref index); } }
public void ReturnToPool(HkdBreakableBody body) { m_tmpToReturn.Add(body); }
public void ReturnToPool(HkdBreakableBody body) { m_tmpToReturn.Add(body); }
/// <summary> /// Returns true if the body does not generate fractured pieces. /// </summary> private static bool IsBodyWithoutGeneratedFracturedPieces(HkdBreakableBody b, MyCubeBlock block) { if (MyFakes.REMOVE_GENERATED_BLOCK_FRACTURES && (block == null || ContainsBlockWithoutGeneratedFracturedPieces(block))) { if (b.BreakableShape.IsCompound()) { Debug.Assert(m_tmpInfos.Count == 0); b.BreakableShape.GetChildren(m_tmpInfos); for (int i = m_tmpInfos.Count - 1; i >= 0; --i) { if (DontCreateFracture(m_tmpInfos[i].Shape)) m_tmpInfos.RemoveAt(i); else break; // Break because we know that there is block which creates fracture pieces and condition "m_tmpInfos.Count == 0" in bellow code cannot be true } if (m_tmpInfos.Count == 0) { return true; } m_tmpInfos.Clear(); } else if (DontCreateFracture(b.BreakableShape)) { return true; } } return false; }
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); } }