private void PreparePhysicsBody() { m_activeShape = m_newShape; m_newShape = null; Debug.Assert(m_activeShape != null); if (Physics != null) { Physics.Close(); } Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC); var physics = (MyPhysicsBody)Physics; HkMassProperties massProperties = new HkMassProperties(); //MatrixD matrix = MatrixD.CreateTranslation(); physics.CreateFromCollisionObject(m_activeShape.Shape, Vector3.Zero, PositionComp.WorldMatrix, massProperties); physics.ContactPointCallback += Physics_onContactPoint; physics.IsStaticForCluster = true; if (m_contactListeners != null && m_contactListeners.Count != 0) { Physics.RigidBody.ContactPointCallbackEnabled = true; } //shape.RemoveReference(); Physics.Enabled = true; }
public override void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties) { var sphereShape = new HkSphereShape(((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius * Entity.PositionComp.Scale.Value); shape = sphereShape; var mass = SphereMass(sphereShape.Radius, VoxelDensity); massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, mass); }
public virtual void ScalePhysicsShape(ref HkMassProperties massProperties) { var debriModel = Entity.Render.GetModel(); HkShape shape; if (debriModel.HavokCollisionShapes != null && debriModel.HavokCollisionShapes.Length > 0) { shape = debriModel.HavokCollisionShapes[0]; Vector4 min, max; shape.GetLocalAABB(0.1f, out min, out max); Vector3 he = new Vector3((max - min) * 0.5f); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(he, he.Volume * 50); massProperties.CenterOfMass = new Vector3((min + max) * 0.5f); } else { var transformShape = (HkTransformShape)RigidBody.GetShape(); var boxShape = (HkBoxShape)transformShape.ChildShape; boxShape.HalfExtents = ((debriModel.BoundingBox.Max - debriModel.BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, boxShape.HalfExtents.Volume * 0.5f); massProperties.CenterOfMass = transformShape.Transform.Translation; shape = transformShape; } RigidBody.SetShape(shape); RigidBody.SetMassProperties(ref massProperties); RigidBody.UpdateShape(); }
public virtual void ScalePhysicsShape(ref HkMassProperties massProperties) { HkShape shape; MyModel model = base.Entity.Render.GetModel(); if ((model.HavokCollisionShapes != null) && (model.HavokCollisionShapes.Length != 0)) { Vector4 vector; Vector4 vector2; shape = model.HavokCollisionShapes[0]; shape.GetLocalAABB(0.1f, out vector, out vector2); Vector3 halfExtents = new Vector3((vector2 - vector) * 0.5f); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(halfExtents, halfExtents.Volume * 50f); massProperties.CenterOfMass = new Vector3((vector + vector2) * 0.5f); } else { HkTransformShape shape2 = (HkTransformShape)this.RigidBody.GetShape(); HkBoxShape childShape = (HkBoxShape)shape2.ChildShape; childShape.HalfExtents = ((model.BoundingBox.Max - model.BoundingBox.Min) / 2f) * base.Entity.PositionComp.Scale.Value; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(childShape.HalfExtents, childShape.HalfExtents.Volume * 0.5f); massProperties.CenterOfMass = shape2.Transform.Translation; shape = (HkShape)shape2; } this.RigidBody.SetShape(shape); this.RigidBody.SetMassProperties(ref massProperties); this.RigidBody.UpdateShape(); }
private void CreateConstraint(MyEntitySubpart subpart, ref HkConstraint constraint, ref HkFixedConstraintData constraintData) { if (subpart != null) { bool flag = !Sync.IsServer; if (subpart.Physics == null) { HkShape[] havokCollisionShapes = subpart.ModelCollision.HavokCollisionShapes; if ((havokCollisionShapes != null) && (havokCollisionShapes.Length != 0)) { MyPhysicsBody body = new MyPhysicsBody(subpart, flag ? RigidBodyFlag.RBF_STATIC : (RigidBodyFlag.RBF_UNLOCKED_SPEEDS | RigidBodyFlag.RBF_DOUBLED_KINEMATIC)) { IsSubpart = true }; subpart.Physics = body; HkShape shape = havokCollisionShapes[0]; MyPositionComponentBase positionComp = subpart.PositionComp; Vector3 center = positionComp.LocalVolume.Center; HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(positionComp.LocalAABB.HalfExtents, 100f); int collisionFilter = base.CubeGrid.IsStatic ? 9 : 0x10; body.CreateFromCollisionObject(shape, center, positionComp.WorldMatrix, new HkMassProperties?(properties), collisionFilter); } } if (flag) { subpart.Physics.Enabled = true; } else { base.CreateSubpartConstraint(subpart, out constraintData, out constraint); base.CubeGrid.Physics.AddConstraint(constraint); constraint.SetVirtualMassInverse(Vector4.Zero, Vector4.One); } } }
public void AllocateForDefinition(string model, MyPhysicalModelDefinition definition, int count) { if (string.IsNullOrEmpty(model)) return; ProfilerShort.Begin("Clone"); var data = MyModels.GetModelOnlyData(model); if (MyFakes.LAZY_LOAD_DESTRUCTION && data.HavokBreakableShapes == null) { MyDestructionData.Static.LoadModelDestruction(model, definition, data.BoundingBoxSize); } if (data.HavokBreakableShapes != null && data.HavokBreakableShapes.Length > 0) { if (!m_pools.ContainsKey(definition.Id)) m_pools[definition.Id] = new Dictionary<string, ConcurrentQueue<HkdBreakableShape>>(); if(!m_pools[definition.Id].ContainsKey(model)) m_pools[definition.Id][model] = new ConcurrentQueue<HkdBreakableShape>(); var queue = m_pools[definition.Id][model]; for (int i = 0; i < count; i++) { var shape = data.HavokBreakableShapes[0].Clone(); queue.Enqueue(shape); if (i == 0) { var mp = new HkMassProperties(); shape.BuildMassProperties(ref mp); if (!mp.InertiaTensor.IsValid()) { MyLog.Default.WriteLine(string.Format("Block with wrong destruction! (q.isOk): {0}", definition.Model)); break; } } } } ProfilerShort.End(); }
void AddMass(MySlimBlock block, IDictionary <Vector3I, HkMassElement> massResults) { float mass = block.GetMass(); if (MyFakes.ENABLE_COMPOUND_BLOCKS && block.FatBlock is MyCompoundCubeBlock) { mass = 0f; MyCompoundCubeBlock compoundBlock = block.FatBlock as MyCompoundCubeBlock; foreach (var innerBlock in compoundBlock.GetBlocks()) { mass += innerBlock.GetMass(); Debug.Assert(innerBlock.BlockDefinition.Size == Vector3I.One, "Invalid block found in compound block - only blocks with size 1 can be set in compound block!"); } } var size = (block.Max - block.Min + Vector3I.One) * block.CubeGrid.GridSize; var center = (block.Min + block.Max) * 0.5f * block.CubeGrid.GridSize; HkMassProperties massProperties = new HkMassProperties(); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(size / 2, mass); massResults[block.Position] = new HkMassElement() { Properties = massProperties, Tranform = Matrix.CreateTranslation(center) }; }
/// <summary> /// Prepares data for renderer and physics. Must be called after all items has been added. /// </summary> public void PrepareItemsPhysics(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld) { PositionComp.WorldAABB = aabbWorld; if (sectorRootShape.InstanceCount > 0) { Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC) { MaterialType = m_definition.Material, AngularDamping = MyPerGameSettings.DefaultAngularDamping, LinearDamping = MyPerGameSettings.DefaultLinearDamping, IsStaticForCluster = true, }; sectorRootShape.Bake(); HkMassProperties massProperties = new HkMassProperties(); MatrixD matrix = MatrixD.CreateTranslation(CellsOffset); Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, matrix, massProperties); Physics.ContactPointCallback += Physics_ContactPointCallback; Physics.RigidBody.ContactPointCallbackEnabled = true; sectorRootShape.Base.RemoveReference(); Physics.Enabled = true; } }
public override void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties) { var sphereShape = new HkSphereShape(((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius *Entity.PositionComp.Scale.Value); shape = sphereShape; massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, 1); }
// Don't call remove reference on this, this shape is pooled protected virtual HkShape GetPhysicsShape(float mass, float scale, out HkMassProperties massProperties) { const bool SimpleShape = false; Debug.Assert(Model != null, "Invalid floating object model: " + Item.GetDefinitionId()); if (Model == null) { MyLog.Default.WriteLine("Invalid floating object model: " + Item.GetDefinitionId()); } Vector3 halfExtents = (Model.BoundingBox.Max - Model.BoundingBox.Min) / 2; HkShapeType shapeType; if (VoxelMaterial != null) { shapeType = HkShapeType.Sphere; massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(Model.BoundingSphere.Radius * scale, mass); } else { shapeType = HkShapeType.Box; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(halfExtents, mass); massProperties.CenterOfMass = Model.BoundingBox.Center; } return(MyDebris.Static.GetDebrisShape(Model, SimpleShape ? shapeType : HkShapeType.ConvexVertices)); }
public virtual void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties) { var boxShape = new HkBoxShape(((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value); shape = boxShape; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, massProperties.Mass); }
private static MyFracturedPiece CreateFracturePiece(ref HkdBreakableShape shape, ref MatrixD worldMatrix, bool isStatic) { MyFracturedPiece pieceFromPool = MyFracturedPiecesManager.Static.GetPieceFromPool(0L, false); pieceFromPool.PositionComp.WorldMatrix = worldMatrix; pieceFromPool.Physics.Flags = isStatic ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS; MyPhysicsBody physics = pieceFromPool.Physics; HkMassProperties massProperties = new HkMassProperties(); shape.BuildMassProperties(ref massProperties); physics.InitialSolverDeactivation = HkSolverDeactivation.High; physics.CreateFromCollisionObject(shape.GetShape(), Vector3.Zero, worldMatrix, new HkMassProperties?(massProperties), 15); physics.LinearDamping = MyPerGameSettings.DefaultLinearDamping; physics.AngularDamping = MyPerGameSettings.DefaultAngularDamping; physics.BreakableBody = new HkdBreakableBody(shape, physics.RigidBody, null, (Matrix)worldMatrix); physics.BreakableBody.AfterReplaceBody += new BreakableBodyReplaced(physics.FracturedBody_AfterReplaceBody); if (pieceFromPool.SyncFlag) { pieceFromPool.CreateSync(); } pieceFromPool.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; pieceFromPool.SetDataFromHavok(shape); pieceFromPool.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; shape.RemoveReference(); return(pieceFromPool); }
private bool CheckVolumeMassRec(HkdBreakableShape bShape, float minVolume, float minMass) { if (bShape.Name.Contains("Fake")) { return(true); } if (bShape.Volume <= minVolume) { return(false); } HkMassProperties mp = new HkMassProperties(); bShape.BuildMassProperties(ref mp); if (mp.Mass <= minMass) { return(false); } if (mp.InertiaTensor.M11 == 0 || mp.InertiaTensor.M22 == 0 || mp.InertiaTensor.M33 == 0) { return(false); } for (int i = 0; i < bShape.GetChildrenCount(); i++) { if (!CheckVolumeMassRec(bShape.GetChildShape(i), minVolume, minMass)) { return(false); } } return(true); }
public override void CreatePhysicsShape(out HkShape shape, out HkMassProperties massProperties, float mass) { HkSphereShape shape2 = new HkSphereShape((0.5f * ((MyEntity)base.Entity).Render.GetModel().BoundingSphere.Radius) * base.Entity.PositionComp.Scale.Value); shape = (HkShape)shape2; massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(shape2.Radius * 0.5f, mass); }
public virtual void CreatePhysicsShape(out HkShape shape, out HkMassProperties massProperties, float mass) { HkBoxShape shape2 = new HkBoxShape(((((MyEntity)base.Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)base.Entity).Render.GetModel().BoundingBox.Min) / 2f) * base.Entity.PositionComp.Scale.Value); Vector3 translation = (((MyEntity)base.Entity).Render.GetModel().BoundingBox.Max + ((MyEntity)base.Entity).Render.GetModel().BoundingBox.Min) / 2f; shape = (HkShape) new HkTransformShape((HkShape)shape2, ref translation, ref Quaternion.Identity); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(shape2.HalfExtents, mass); massProperties.CenterOfMass = translation; }
public virtual void CreatePhysicsShape(out HkShape shape, ref HkMassProperties massProperties) { var boxShape = new HkBoxShape(((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value); var pos = ((((MyEntity)Entity).Render.GetModel().BoundingBox.Max + ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2); shape = new HkTransformShape(boxShape, ref pos, ref Quaternion.Identity); //shape = boxShape; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, boxShape.HalfExtents.Volume * 0.5f); massProperties.CenterOfMass = pos; }
public override void ScalePhysicsShape(ref HkMassProperties massProperties) { var shape = RigidBody.GetShape(); var sphereShape = (HkSphereShape)shape; sphereShape.Radius = ((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius * Entity.PositionComp.Scale.Value; massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, 1); RigidBody.SetShape(sphereShape); RigidBody.SetMassProperties(ref massProperties); RigidBody.UpdateShape(); }
internal void UpdateMassProps(HkRigidBody rb) { var mp = new HkMassProperties(); mp.InertiaTensor = rb.InertiaTensor; mp.Mass = rb.Mass; mp.CenterOfMass = rb.CenterOfMassLocal; MassElement = new HkMassElement(); MassElement.Properties = mp; MassElement.Tranform = Transform; //MassElement.Tranform.Translation = Vector3.Transform(rb.CenterOfMassLocal, Transform); }
public virtual void ScalePhysicsShape(ref HkMassProperties massProperties) { var shape = RigidBody.GetShape(); var boxShape = (HkBoxShape)shape; boxShape.HalfExtents = ((((MyEntity)Entity).Render.GetModel().BoundingBox.Max - ((MyEntity)Entity).Render.GetModel().BoundingBox.Min) / 2) * Entity.PositionComp.Scale.Value; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(boxShape.HalfExtents, massProperties.Mass); RigidBody.SetShape(boxShape); RigidBody.SetMassProperties(ref massProperties); RigidBody.UpdateShape(); }
public override void ScalePhysicsShape(ref HkMassProperties massProperties) { var shape = RigidBody.GetShape(); var sphereShape = (HkSphereShape)shape; sphereShape.Radius = ((MyEntity)Entity).Render.GetModel().BoundingSphere.Radius *Entity.PositionComp.Scale.Value; massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereShape.Radius, 1); RigidBody.SetShape(sphereShape); RigidBody.SetMassProperties(ref massProperties); RigidBody.UpdateShape(); }
public override void ScalePhysicsShape(ref HkMassProperties massProperties) { HkSphereShape shape = (HkSphereShape)this.RigidBody.GetShape(); shape.Radius = ((MyEntity)base.Entity).Render.GetModel().BoundingSphere.Radius *base.Entity.PositionComp.Scale.Value; float mass = this.SphereMass(shape.Radius, 260f); massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(shape.Radius, mass); this.RigidBody.SetShape((HkShape)shape); this.RigidBody.SetMassProperties(ref massProperties); this.RigidBody.UpdateShape(); }
public void AllocateForDefinition(string model, MyPhysicalModelDefinition definition, int count) { if (string.IsNullOrEmpty(model)) { return; } ProfilerShort.Begin("Clone"); var data = VRage.Game.Models.MyModels.GetModelOnlyData(model); if (data.HavokBreakableShapes == null) { MyDestructionData.Static.LoadModelDestruction(model, definition, data.BoundingBoxSize); } if (data.HavokBreakableShapes != null && data.HavokBreakableShapes.Length > 0) { ConcurrentQueue <HkdBreakableShape> queue; using (m_poolLock.AcquireExclusiveUsing()) { if (!m_pools.ContainsKey(definition.Id)) { m_pools[definition.Id] = new Dictionary <string, ConcurrentQueue <HkdBreakableShape> >(); } if (!m_pools[definition.Id].ContainsKey(model)) { m_pools[definition.Id][model] = new ConcurrentQueue <HkdBreakableShape>(); } queue = m_pools[definition.Id][model]; } for (int i = 0; i < count; i++) { var shape = data.HavokBreakableShapes[0].Clone(); queue.Enqueue(shape); if (i == 0) { var mp = new HkMassProperties(); shape.BuildMassProperties(ref mp); if (!mp.InertiaTensor.IsValid()) { MyLog.Default.WriteLine(string.Format("Block with wrong destruction! (q.isOk): {0}", definition.Model)); break; } } } } ProfilerShort.End(); }
public void InitFromDefinition(MyObjectBuilder_EntityBase entityBuilder, MyDefinitionId definitionId) { Debug.Assert(entityBuilder != null, "Invalid arguments!"); MyPhysicalItemDefinition entityDefinition; if (!MyDefinitionManager.Static.TryGetDefinition(definitionId, out entityDefinition)) { Debug.Fail("Definition: " + DefinitionId.ToString() + " was not found!"); return; } DefinitionId = definitionId; Flags |= EntityFlags.Visible | EntityFlags.NeedsDraw | EntityFlags.Sync | EntityFlags.InvalidateOnMove; StringBuilder name = new StringBuilder(entityDefinition.DisplayNameText); Init(name, entityDefinition.Model, null, null, null); CreateSync(); if (entityBuilder.PositionAndOrientation.HasValue) { MatrixD worldMatrix = MatrixD.CreateWorld( (Vector3D)entityBuilder.PositionAndOrientation.Value.Position, (Vector3)entityBuilder.PositionAndOrientation.Value.Forward, (Vector3)entityBuilder.PositionAndOrientation.Value.Up); PositionComp.SetWorldMatrix(worldMatrix); } Name = name.Append("_(").Append(entityBuilder.EntityId).Append(")").ToString(); Render.UpdateRenderObject(true); Physics = new Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT); if (ModelCollision != null && ModelCollision.HavokCollisionShapes.Length >= 1) { HkMassProperties massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(entityDefinition.Size / 2, (MyPerGameSettings.Destruction ? MyDestructionHelper.MassToHavok(entityDefinition.Mass) : entityDefinition.Mass));; Physics.CreateFromCollisionObject(ModelCollision.HavokCollisionShapes[0], Vector3.Zero, WorldMatrix, massProperties); Physics.RigidBody.AngularDamping = 2; Physics.RigidBody.LinearDamping = 1; } Physics.Enabled = true; EntityId = entityBuilder.EntityId; }
public static void InitSpherePhysics(this IMyEntity entity, MyStringHash materialType, Vector3 sphereCenter, float sphereRadius, float mass, float linearDamping, float angularDamping, ushort collisionLayer, RigidBodyFlag rbFlag) { float single1 = mass; mass = ((rbFlag & RigidBodyFlag.RBF_STATIC) != RigidBodyFlag.RBF_DEFAULT) ? 0f : single1; MyPhysicsBody body1 = new MyPhysicsBody(entity, rbFlag); body1.MaterialType = materialType; body1.AngularDamping = angularDamping; body1.LinearDamping = linearDamping; MyPhysicsBody body = body1; HkMassProperties properties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(sphereRadius, mass); HkSphereShape shape = new HkSphereShape(sphereRadius); body.CreateFromCollisionObject((HkShape)shape, sphereCenter, entity.PositionComp.WorldMatrix, new HkMassProperties?(properties), 15); shape.Base.RemoveReference(); entity.Physics = body; }
internal static void InitBoxPhysics(this IMyEntity entity, Matrix worldMatrix, MyStringHash materialType, Vector3 center, Vector3 size, float mass, float linearDamping, float angularDamping, ushort collisionLayer, RigidBodyFlag rbFlag) { float single1 = mass; mass = ((rbFlag & RigidBodyFlag.RBF_STATIC) != RigidBodyFlag.RBF_DEFAULT) ? 0f : single1; HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(size / 2f, mass); MyPhysicsBody body1 = new MyPhysicsBody(null, rbFlag); body1.MaterialType = materialType; body1.AngularDamping = angularDamping; body1.LinearDamping = linearDamping; MyPhysicsBody body = body1; HkBoxShape shape = new HkBoxShape(size * 0.5f); body.CreateFromCollisionObject((HkShape)shape, center, worldMatrix, new HkMassProperties?(properties), 15); shape.Base.RemoveReference(); entity.Physics = body; }
private static MyFracturedPiece CreateFracturePiece(ref HkdBreakableShape shape, HkdWorld world, ref MatrixD worldMatrix, bool isStatic) { Debug.Assert(shape.IsValid()); ProfilerShort.Begin("CreateFracturePiece"); var fracturedPiece = MyFracturedPiecesManager.Static.GetPieceFromPool(0);//new MyFracturedPiece(); fracturedPiece.PositionComp.WorldMatrix = worldMatrix; fracturedPiece.Physics.Flags = isStatic ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS; var physicsBody = fracturedPiece.Physics as MyPhysicsBody;//new MyPhysicsBody(fracturedPiece,isFixed ?RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS); HkMassProperties mp = new HkMassProperties(); shape.BuildMassProperties(ref mp); physicsBody.InitialSolverDeactivation = HkSolverDeactivation.High; physicsBody.CreateFromCollisionObject(shape.GetShape(), Vector3.Zero, worldMatrix, mp); physicsBody.LinearDamping = MyPerGameSettings.DefaultLinearDamping; physicsBody.AngularDamping = MyPerGameSettings.DefaultAngularDamping; System.Diagnostics.Debug.Assert(physicsBody.BreakableBody == null, "physicsBody.DestructionBody == null"); physicsBody.BreakableBody = new HkdBreakableBody(shape, physicsBody.RigidBody, world, worldMatrix); physicsBody.BreakableBody.AfterReplaceBody += physicsBody.FracturedBody_AfterReplaceBody; ProfilerShort.End(); ProfilerShort.Begin("Sync"); if (fracturedPiece.SyncFlag) { fracturedPiece.CreateSync(); } ProfilerShort.End(); fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; //physicsBody.RigidBody.ContactPointCallbackDelay = 0; //physicsBody.RigidBody.ContactPointCallbackEnabled = true; fracturedPiece.Physics = physicsBody; //FixPosition(fracturedPiece); fracturedPiece.SetDataFromHavok(shape); ProfilerShort.Begin("AddToWorld"); fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; shape.RemoveReference(); ProfilerShort.End(); return(fracturedPiece); }
public HkMassProperties UpdateMass() { HkMassElement element = new HkMassElement { Tranform = Matrix.Identity }; bool flag = false; foreach (Vector3I vectori in base.DirtyCells) { MySparseGrid <HkMassElement, MassCellData> .Cell cell; if (!base.TryGetCell(vectori, out cell)) { flag = true; continue; } float num = 0f; foreach (KeyValuePair <Vector3I, HkMassElement> pair in cell.Items) { TmpElements.Add(pair.Value); num += pair.Value.Properties.Mass; } if (Math.Abs((float)(1f - (cell.CellData.LastMass / num))) > this.m_updateThreshold) { element.Properties = InertiaComputer.CombineMassPropertiesInstance(TmpElements); cell.CellData.MassElement = element; cell.CellData.LastMass = num; flag = true; } TmpElements.Clear(); } base.UnmarkDirtyAll(); if (flag) { foreach (KeyValuePair <Vector3I, MySparseGrid <HkMassElement, MassCellData> .Cell> pair2 in this) { TmpElements.Add(pair2.Value.CellData.MassElement); } this.m_massProperties = (TmpElements.Count <= 0) ? new HkMassProperties() : InertiaComputer.CombineMassPropertiesInstance(TmpElements); TmpElements.Clear(); } return(this.m_massProperties); }
public void AllocateForDefinition(string model, MyPhysicalModelDefinition definition, int count) { if (!string.IsNullOrEmpty(model)) { MyModel modelOnlyData = MyModels.GetModelOnlyData(model); if (modelOnlyData.HavokBreakableShapes == null) { MyDestructionData.Static.LoadModelDestruction(model, definition, modelOnlyData.BoundingBoxSize, true, false); } if ((modelOnlyData.HavokBreakableShapes != null) && (modelOnlyData.HavokBreakableShapes.Length != 0)) { ConcurrentQueue <HkdBreakableShape> queue; using (this.m_poolLock.AcquireExclusiveUsing()) { if (!this.m_pools.ContainsKey(definition.Id)) { this.m_pools[definition.Id] = new Dictionary <string, ConcurrentQueue <HkdBreakableShape> >(); } if (!this.m_pools[definition.Id].ContainsKey(model)) { this.m_pools[definition.Id][model] = new ConcurrentQueue <HkdBreakableShape>(); } queue = this.m_pools[definition.Id][model]; } for (int i = 0; i < count; i++) { HkdBreakableShape item = modelOnlyData.HavokBreakableShapes[0].Clone(); queue.Enqueue(item); if (i == 0) { HkMassProperties massProperties = new HkMassProperties(); item.BuildMassProperties(ref massProperties); if (!massProperties.InertiaTensor.IsValid()) { MyLog.Default.WriteLine($"Block with wrong destruction! (q.isOk): {definition.Model}"); return; } } } } } }
private void AddMass(MySlimBlock block, IDictionary <Vector3I, HkMassElement> massResults) { float mass = block.BlockDefinition.Mass; if (MyFakes.ENABLE_COMPOUND_BLOCKS && (block.FatBlock is MyCompoundCubeBlock)) { mass = 0f; foreach (MySlimBlock block2 in (block.FatBlock as MyCompoundCubeBlock).GetBlocks()) { mass += block2.GetMass(); } } HkMassProperties properties = new HkMassProperties(); HkMassElement element = new HkMassElement { Properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties((((block.Max - block.Min) + Vector3I.One) * block.CubeGrid.GridSize) / 2f, mass), Tranform = Matrix.CreateTranslation(((block.Min + block.Max) * 0.5f) * block.CubeGrid.GridSize) }; massResults[block.Position] = element; }
// Don't call remove reference on this, this shape is pooled protected virtual HkShape GetPhysicsShape(HkMassProperties massProperties, float mass, float scale) { const bool SimpleShape = false; Vector3 halfExtents = (Entity.Render.GetModel().BoundingBox.Max - Entity.Render.GetModel().BoundingBox.Min) / 2; HkShapeType shapeType; if (VoxelMaterial != null) { shapeType = HkShapeType.Sphere; massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(Entity.Render.GetModel().BoundingSphere.Radius *scale, mass); } else { shapeType = HkShapeType.Box; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(halfExtents, mass); } return(MyDebris.Static.GetDebrisShape(Entity.Render.GetModel(), SimpleShape ? shapeType : HkShapeType.ConvexVertices)); }
private void CreateConstraints() { this.UpdateDoorPosition(); bool flag = !Sync.IsServer; foreach (MyEntitySubpart subpart in this.m_subparts) { if (((subpart.Physics == null) && (subpart.ModelCollision.HavokCollisionShapes != null)) && (subpart.ModelCollision.HavokCollisionShapes.Length != 0)) { HkShape shape = subpart.ModelCollision.HavokCollisionShapes[0]; subpart.Physics = new MyPhysicsBody(subpart, flag ? RigidBodyFlag.RBF_STATIC : (RigidBodyFlag.RBF_UNLOCKED_SPEEDS | RigidBodyFlag.RBF_DOUBLED_KINEMATIC)); HkMassProperties properties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(subpart.PositionComp.LocalAABB.HalfExtents, 100f); properties.Volume = subpart.PositionComp.LocalAABB.Volume(); subpart.GetPhysicsBody().CreateFromCollisionObject(shape, subpart.PositionComp.LocalVolume.Center, subpart.WorldMatrix, new HkMassProperties?(properties), 9); ((MyPhysicsBody)subpart.Physics).IsSubpart = true; } if (subpart.Physics != null) { if (flag) { subpart.Physics.Enabled = true; } else { HkFixedConstraintData data; HkConstraint constraint; base.CreateSubpartConstraint(subpart, out data, out constraint); this.m_subpartConstraintsData.Add(data); this.m_subpartConstraints.Add(constraint); base.CubeGrid.Physics.AddConstraint(constraint); constraint.SetVirtualMassInverse(Vector4.Zero, Vector4.One); } } } base.CubeGrid.OnHavokSystemIDChanged -= new Action <int>(this.CubeGrid_OnHavokSystemIDChanged); base.CubeGrid.OnHavokSystemIDChanged += new Action <int>(this.CubeGrid_OnHavokSystemIDChanged); if (base.CubeGrid.Physics != null) { this.UpdateHavokCollisionSystemID(base.CubeGrid.GetPhysicsBody().HavokCollisionSystemID, false); } }
/// <summary> /// Prepares data for renderer and physics. Must be called after all items has been added. /// </summary> public void PrepareItems(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld) { PositionComp.LocalAABB = (BoundingBox)aabbWorld; if (sectorRootShape.InstanceCount > 0) { Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC) { MaterialType = m_definition.Material, AngularDamping = MyPerGameSettings.DefaultAngularDamping, LinearDamping = MyPerGameSettings.DefaultLinearDamping, IsStaticForCluster = true, }; sectorRootShape.Bake(); HkMassProperties massProperties = new HkMassProperties(); Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, WorldMatrix, massProperties); if (Sandbox.Game.MyPerGameSettings.Destruction) { Physics.ContactPointCallback += Physics_ContactPointCallback; Physics.RigidBody.ContactPointCallbackEnabled = true; } sectorRootShape.Base.RemoveReference(); Physics.Enabled = true; } foreach (var pair in m_sectors) { pair.Value.UpdateRenderInstanceData(); } foreach (var pair in m_sectors) { pair.Value.UpdateRenderEntitiesData(WorldMatrix, m_subtypeToModel); } }
/// <summary> /// One time initialization for debris entity. These are settings that do not change /// when this debris entity is pulled from the pool. /// Also note that this is the only way Debris should be initialized. It calls other Init methods with /// correct arguments. /// </summary> public virtual void Init(MyDebrisBaseDescription desc) { base.Init(null, desc.Model, null, 1.0f); RandomScale = MyUtils.GetRandomFloat(desc.ScaleMin, desc.ScaleMax); Container.Entity.PositionComp.Scale = RandomScale; LifespanInMiliseconds = MyUtils.GetRandomInt(desc.LifespanMinInMiliseconds, desc.LifespanMaxInMiliseconds); HkShape shape; m_massProperties = new HkMassProperties(); m_massProperties.Mass = 50; Container.Entity.Physics = GetPhysics(RigidBodyFlag.RBF_DEBRIS); (Container.Entity.Physics as MyDebrisPhysics).CreatePhysicsShape(out shape, ref m_massProperties); (Container.Entity.Physics as MyDebrisPhysics).CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, m_massProperties, MyPhysics.CollisionLayers.DebrisCollisionLayer); Container.Entity.Physics.Enabled = false; shape.RemoveReference(); m_entity.Save = false; Container.Entity.Physics.PlayCollisionCueEnabled = true; NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME; m_onCloseCallback = desc.OnCloseAction; }
/// <summary> /// One time initialization for debris entity. These are settings that do not change /// when this debris entity is pulled from the pool. /// Also note that this is the only way Debris should be initialized. It calls other Init methods with /// correct arguments. /// </summary> public virtual void Init(MyDebrisBaseDescription desc) { base.Init(null, desc.Model, null, 1.0f); m_randomScale = MyUtils.GetRandomFloat(desc.ScaleMin, desc.ScaleMax); Container.Entity.PositionComp.Scale = m_randomScale; m_lifespanInMiliseconds = MyUtils.GetRandomInt(desc.LifespanMinInMiliseconds, desc.LifespanMaxInMiliseconds); HkShape shape; m_massProperties = new HkMassProperties(); m_massProperties.Mass = 50; Container.Entity.Physics = GetPhysics(RigidBodyFlag.RBF_DEBRIS); (Container.Entity.Physics as MyDebrisPhysics).CreatePhysicsShape(out shape, ref m_massProperties); (Container.Entity.Physics as MyDebrisPhysics).CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, m_massProperties, MyPhysics.DebrisCollisionLayer); Container.Entity.Physics.Enabled = false; shape.RemoveReference(); m_entity.Save = false; Container.Entity.Physics.PlayCollisionCueEnabled = true; NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME; m_onCloseCallback = desc.OnCloseAction; }
public void UpdateMassFromInventories(HashSet<MySlimBlock> blocks, MyPhysicsBody rb) { if (rb.RigidBody.IsFixedOrKeyframed) return; ProfilerShort.Begin("GridShape.UpdateMassFromInv"); Debug.Assert(BreakableShape.IsValid(), "This routine works with breakable shape mass properties."); foreach (var block in blocks) { var owner = block.FatBlock as IMyInventoryOwner; if (owner == null) continue; float mass = 0; for (int i = 0; i < owner.InventoryCount; i++) { mass += (float)owner.GetInventory(i).CurrentMass; } var size = (block.Max - block.Min + Vector3I.One) * block.CubeGrid.GridSize; var center = (block.Min + block.Max) * 0.5f * block.CubeGrid.GridSize; HkMassProperties massProperties = new HkMassProperties(); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(size / 2, mass); m_tmpElements.Add(new HkMassElement() { Properties = massProperties, Tranform = Matrix.CreateTranslation(center) }); } HkMassProperties originalMp = new HkMassProperties(); BreakableShape.BuildMassProperties(ref originalMp); m_tmpElements.Add(new HkMassElement() { Properties = originalMp, Tranform = Matrix.Identity }); var mp = HkInertiaTensorComputer.CombineMassProperties(m_tmpElements); m_tmpElements.Clear(); rb.RigidBody.SetMassProperties(ref mp); if (!rb.RigidBody.IsActive) rb.RigidBody.Activate(); ProfilerShort.End(); }
/// <summary> /// Searches for blocks which will create fracture components from cached m_fracturedSlimBlocksShapes /// </summary> private void FindFractureComponentBlocks() { Debug.Assert(MyFakes.ENABLE_FRACTURE_COMPONENT); foreach (var pair in m_fracturedSlimBlocksShapes) { var slimBlock = pair.Key; var shapeList = pair.Value; if (slimBlock.FatBlock.Components.Has<MyFractureComponentBase>()) { // Block has fracture component - ignore continue; } else { int totalBreakableShapesCountForModel = slimBlock.GetTotalBreakableShapeChildrenCount(); Debug.Assert(shapeList.Count <= totalBreakableShapesCountForModel); // No removed pieces? Then ignore. if (slimBlock.BlockDefinition.CreateFracturedPieces && totalBreakableShapesCountForModel == shapeList.Count) continue; foreach (var s in shapeList) { s.SetTransform(ref Matrix.Identity); } ProfilerShort.Begin("CreateShapeComponent"); HkdBreakableShape compound = new HkdCompoundBreakableShape(null, shapeList); ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren(); var mp = new HkMassProperties(); compound.BuildMassProperties(ref mp); HkdBreakableShape shape = compound; var sh = compound.GetShape(); shape = new HkdBreakableShape(sh, ref mp); //shape.SetMassProperties(mp); //important! pass mp to constructor foreach (var si in shapeList) { var siRef = si; shape.AddShape(ref siRef); } compound.RemoveReference(); ProfilerShort.BeginNextBlock("Connect"); //shape.SetChildrenParent(shape); ConnectPiecesInBlock(shape, shapeList); MyFractureComponentBase.Info info = new MyFractureComponentBase.Info() { Entity = slimBlock.FatBlock, Shape = shape, Compound = true }; m_fractureBlockComponentsCache.Add(info); ProfilerShort.End(); } } m_fracturedSlimBlocksShapes.Clear(); }
// Don't call remove reference on this, this shape is pooled protected virtual HkShape GetPhysicsShape(HkMassProperties massProperties, float mass, float scale) { const bool SimpleShape = false; Vector3 halfExtents = (Entity.Render.GetModel().BoundingBox.Max - Entity.Render.GetModel().BoundingBox.Min) / 2; HkShapeType shapeType; if (VoxelMaterial != null) { shapeType = HkShapeType.Sphere; massProperties = HkInertiaTensorComputer.ComputeSphereVolumeMassProperties(Entity.Render.GetModel().BoundingSphere.Radius * scale, mass); } else { shapeType = HkShapeType.Box; massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(halfExtents, mass); } return MyDebris.Static.GetDebrisShape(Entity.Render.GetModel(), SimpleShape ? shapeType : HkShapeType.ConvexVertices); }
public override void Init(MyObjectBuilder_EntityBase objectBuilder) { base.Init(objectBuilder); var ob = objectBuilder as MyObjectBuilder_FracturedPiece; if (ob.Shapes.Count == 0) { return; //Debug.Fail("Invalid fracture piece! Dont call init without valid OB. Use pool/noinit."); //throw new Exception("Fracture piece has no shapes."); //throwing exception, otherwise there is fp with null physics which can mess up somwhere else } foreach (var shape in ob.Shapes) { Render.AddPiece(shape.Name, Matrix.CreateFromQuaternion(shape.Orientation)); } OriginalBlocks.Clear(); foreach (var def in ob.BlockDefinitions) { string model = null; MyPhysicalModelDefinition mdef; if (MyDefinitionManager.Static.TryGetDefinition<MyPhysicalModelDefinition>(def, out mdef)) model = mdef.Model; MyCubeBlockDefinition blockDef = null; MyDefinitionManager.Static.TryGetDefinition<MyCubeBlockDefinition>(def, out blockDef); if (model == null) { Debug.Fail("Fracture piece Definition not found"); continue; } model = mdef.Model; if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null) MyDestructionData.Static.LoadModelDestruction(model, mdef, Vector3.One); var shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0]; var si = new HkdShapeInstanceInfo(shape, null, null); m_children.Add(si); shape.GetChildren(m_children); if (blockDef != null && blockDef.BuildProgressModels != null) { foreach (var progress in blockDef.BuildProgressModels) { model = progress.File; if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null) MyDestructionData.Static.LoadModelDestruction(model, blockDef, Vector3.One); shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0]; si = new HkdShapeInstanceInfo(shape, null, null); m_children.Add(si); shape.GetChildren(m_children); } } OriginalBlocks.Add(def); } m_shapes.AddRange(ob.Shapes); Vector3? offset = null; int shapeAtZero = 0; for (int i = 0; i < m_children.Count; i++) { var child = m_children[i]; Func<MyObjectBuilder_FracturedPiece.Shape, bool> x = s => s.Name == child.ShapeName; var result = m_shapes.Where(x); if (result.Count() > 0) { var found = result.First(); var m = Matrix.CreateFromQuaternion(found.Orientation); if (!offset.HasValue && found.Name == m_shapes[0].Name) { offset = child.GetTransform().Translation; shapeAtZero = m_shapeInfos.Count; } m.Translation = child.GetTransform().Translation; var si = new HkdShapeInstanceInfo(child.Shape.Clone(), m); if(found.Fixed) si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED); m_shapeInfos.Add(si); m_shapes.Remove(found); } else { child.GetChildren(m_children); } } if (m_shapeInfos.Count == 0) { List<string> shapesToLoad = new List<string>(); foreach (var obShape in ob.Shapes) shapesToLoad.Add(obShape.Name); var shapesStr = shapesToLoad.Aggregate((str1, str2) => str1 + ", " + str2); var blocksStr = OriginalBlocks.Aggregate("", (str, defId) => str + ", " + defId.ToString()); var failMsg = "No relevant shape was found for fractured piece. It was probably reexported and names changed. Shapes: " + shapesStr + ". Original blocks: " + shapesStr; Debug.Fail(failMsg); //HkdShapeInstanceInfo si = new HkdShapeInstanceInfo(new HkdBreakableShape((HkShape)new HkBoxShape(Vector3.One)), Matrix.Identity); //m_shapeInfos.Add(si); throw new Exception(failMsg); } if (offset.HasValue) { for (int i = 0; i < m_shapeInfos.Count; i++) { var m = m_shapeInfos[i].GetTransform(); m.Translation -= offset.Value; m_shapeInfos[i].SetTransform(ref m); } { var m = m_shapeInfos[shapeAtZero].GetTransform(); m.Translation = Vector3.Zero; m_shapeInfos[shapeAtZero].SetTransform(ref m); } } if (m_shapeInfos.Count > 0) { if (m_shapeInfos.Count == 1) Shape = m_shapeInfos[0].Shape; else { Shape = new HkdCompoundBreakableShape(null, m_shapeInfos); ((HkdCompoundBreakableShape)Shape).RecalcMassPropsFromChildren(); } Shape.SetStrenght(MyDestructionConstants.STRENGTH); var mp = new HkMassProperties(); Shape.BuildMassProperties(ref mp); Shape.SetChildrenParent(Shape); Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS); Physics.CanUpdateAccelerations = true; Physics.InitialSolverDeactivation = HkSolverDeactivation.High; Physics.CreateFromCollisionObject(Shape.GetShape(), Vector3.Zero, PositionComp.WorldMatrix, mp); Physics.BreakableBody = new HkdBreakableBody(Shape, Physics.RigidBody, null, (Matrix)PositionComp.WorldMatrix); Physics.BreakableBody.AfterReplaceBody += Physics.FracturedBody_AfterReplaceBody; if (OriginalBlocks.Count > 0) { MyPhysicalModelDefinition def; if (MyDefinitionManager.Static.TryGetDefinition<MyPhysicalModelDefinition>(OriginalBlocks[0], out def)) Physics.MaterialType = def.PhysicalMaterial.Id.SubtypeId; } var rigidBody = Physics.RigidBody; bool isFixed = MyDestructionHelper.IsFixed(Physics.BreakableBody.BreakableShape); if (isFixed) { rigidBody.UpdateMotionType(HkMotionType.Fixed); rigidBody.LinearVelocity = Vector3.Zero; rigidBody.AngularVelocity = Vector3.Zero; } Physics.Enabled = true; } m_children.Clear(); m_shapeInfos.Clear(); }
/// <summary> /// Prepares data for renderer and physics. Must be called after all items has been added. /// </summary> private void PrepareItemsPhysics(HkStaticCompoundShape sectorRootShape, ref BoundingBoxD aabbWorld, Dictionary<MyStringHash, HkShape> subtypeIdToShape) { foreach (var item in m_itemsData) { if (!item.Value.Enabled) continue; int physicsShapeInstanceId; MatrixD transform = item.Value.Transform.TransformMatrix; if (AddPhysicsShape(item.Value.SubtypeId, item.Value.Model, ref transform, sectorRootShape, subtypeIdToShape, out physicsShapeInstanceId)) { // Map to data index - note that itemData is added after this to its list! m_physicsShapeInstanceIdToLocalId[physicsShapeInstanceId] = item.Value.Id; m_localIdToPhysicsShapeInstanceId[item.Value.Id] = physicsShapeInstanceId; } } PositionComp.WorldAABB = aabbWorld; if (sectorRootShape.InstanceCount > 0) { Debug.Assert(m_physicsShapeInstanceIdToLocalId.Count > 0); Physics = new Sandbox.Engine.Physics.MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC) { MaterialType = m_definition.Material, AngularDamping = MyPerGameSettings.DefaultAngularDamping, LinearDamping = MyPerGameSettings.DefaultLinearDamping, IsStaticForCluster = true, }; sectorRootShape.Bake(); HkMassProperties massProperties = new HkMassProperties(); MatrixD matrix = MatrixD.CreateTranslation(CellsOffset); Physics.CreateFromCollisionObject((HkShape)sectorRootShape, Vector3.Zero, matrix, massProperties); Physics.ContactPointCallback += Physics_ContactPointCallback; Physics.RigidBody.ContactPointCallbackEnabled = true; Physics.Enabled = true; } }
public override void Init(MyObjectBuilder_CubeBlock builder, MyCubeGrid cubeGrid) { base.Init(builder, cubeGrid); ProfilerShort.Begin("FP.Init"); CheckConnectionAllowed = true; var ob = builder as MyObjectBuilder_FracturedBlock; if (ob.Shapes.Count == 0) { ProfilerShort.End(); return; } OriginalBlocks = new List<MyDefinitionId>(); Orientations = new List<MyBlockOrientation>(); var lst = new List<HkdShapeInstanceInfo>(); foreach (var def in ob.BlockDefinitions) { var blockDef = MyDefinitionManager.Static.GetCubeBlockDefinition(def); if (MyModels.GetModelOnlyData(blockDef.Model).HavokBreakableShapes == null) { MyDestructionData.Static.LoadModelDestruction(blockDef, false, Vector3.One); } var shape = MyModels.GetModelOnlyData(blockDef.Model).HavokBreakableShapes[0]; var si = new HkdShapeInstanceInfo(shape, null, null); lst.Add(si); m_children.Add(si); shape.GetChildren(m_children); OriginalBlocks.Add(def); } foreach (var or in ob.BlockOrientations) { Orientations.Add(or); } m_shapes.AddRange(ob.Shapes); for (int i = 0; i < m_children.Count; i++) { var child = m_children[i]; Func<MyObjectBuilder_FracturedBlock.ShapeB, bool> x = s => s.Name == child.ShapeName; var result = m_shapes.Where(x); if (result.Count() > 0) { var found = result.First(); var m = Matrix.CreateFromQuaternion(found.Orientation); m.Translation = child.GetTransform().Translation; var si = new HkdShapeInstanceInfo(child.Shape.Clone(), m); if(found.Fixed) si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED); lst.Add(si); m_shapeInfos.Add(si); m_shapes.Remove(found); } else { child.GetChildren(m_children); } } if (m_shapeInfos.Count == 0) { m_children.Clear(); ProfilerShort.End(); Debug.Fail("No relevant shape was found for fractured block. It was probably reexported and names changed."); throw new Exception("No relevant shape was found for fractured block. It was probably reexported and names changed."); } foreach (var shape in m_shapeInfos) { if(! string.IsNullOrEmpty(shape.Shape.Name)) Render.AddPiece(shape.Shape.Name, Matrix.CreateFromQuaternion(Quaternion.CreateFromRotationMatrix(shape.GetTransform().GetOrientation()))); } if (CubeGrid.CreatePhysics) { HkdBreakableShape compound = new HkdCompoundBreakableShape(null, m_shapeInfos); ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren(); Shape = compound; var mp = new HkMassProperties(); compound.BuildMassProperties(ref mp); Shape = new HkdBreakableShape(compound.GetShape(), ref mp); compound.RemoveReference(); foreach (var si in m_shapeInfos) { var siRef = si; Shape.AddShape(ref siRef); } Shape.SetStrenght(MyDestructionConstants.STRENGTH); CreateMountPoints(); } m_children.Clear(); foreach (var si in m_shapeInfos) si.Shape.RemoveReference(); foreach (var si in lst) si.RemoveReference(); m_shapeInfos.Clear(); ProfilerShort.End(); }
private bool CheckVolumeMassRec(HkdBreakableShape bShape, float minVolume, float minMass) { if (bShape.Name.Contains("Fake")) return true; if (bShape.Volume <= minVolume) return false; HkMassProperties mp = new HkMassProperties(); bShape.BuildMassProperties(ref mp); if (mp.Mass <= minMass) return false; if (mp.InertiaTensor.M11 == 0 || mp.InertiaTensor.M22 == 0 || mp.InertiaTensor.M33 == 0) return false; for (int i = 0; i < bShape.GetChildrenCount(); i++) { if (!CheckVolumeMassRec(bShape.GetChildShape(i), minVolume, minMass)) return false; } return true; }
private void InitInternal() { // TODO: This will be fixed and made much more simple once ore models are done // https://app.asana.com/0/6594565324126/10473934569658 var physicalItem = MyDefinitionManager.Static.GetPhysicalItemDefinition(Item.Content); string model = physicalItem.Model; VoxelMaterial = null; float scale = 1.0f; if (Item.Content is MyObjectBuilder_Ore) { string oreSubTypeId = physicalItem.Id.SubtypeId.ToString(); foreach (var mat in MyDefinitionManager.Static.GetVoxelMaterialDefinitions()) { if (oreSubTypeId == mat.MinedOre) { VoxelMaterial = mat; model = MyDebris.GetRandomDebrisVoxel(); scale = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f); break; } } scale = (float)Math.Pow((float)Item.Amount * physicalItem.Volume / MyDebris.VoxelDebrisModelVolume, 0.333f); } if (scale < 0.05f) Close(); else if (scale < 0.15f) scale = 0.15f; FormatDisplayName(m_displayedText, Item); Init(m_displayedText, model, null, null, null); PositionComp.Scale = scale; // Must be set after init var massProperties = new HkMassProperties(); HkShape shape = GetPhysicsShape(physicalItem.Mass * (float)Item.Amount, scale, out massProperties); var scaleMatrix = Matrix.CreateScale(scale); if (Physics != null) Physics.Close(); Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEBRIS); if (VoxelMaterial != null) { HkConvexTransformShape transform = new HkConvexTransformShape((HkConvexShape)shape, ref scaleMatrix, HkReferencePolicy.None); Physics.CreateFromCollisionObject(transform, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.FloatingObjectCollisionLayer); Physics.Enabled = true; transform.Base.RemoveReference(); } else { Physics.CreateFromCollisionObject(shape, Vector3.Zero, MatrixD.Identity, massProperties, MyPhysics.FloatingObjectCollisionLayer); Physics.Enabled = true; } Physics.MaterialType = VoxelMaterial != null ? MyMaterialType.ROCK : MyMaterialType.METAL; Physics.PlayCollisionCueEnabled = true; NeedsUpdate = MyEntityUpdateEnum.EACH_FRAME; }
protected virtual void CreateBody(ref HkShape shape, HkMassProperties? massProperties) { ProfilerShort.Begin("CreateBody"); HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo(); rbInfo.AngularDamping = m_angularDamping; rbInfo.LinearDamping = m_linearDamping; rbInfo.Shape = shape; rbInfo.SolverDeactivation = InitialSolverDeactivation; rbInfo.ContactPointCallbackDelay = ContactPointDelay; if (massProperties.HasValue) { rbInfo.SetMassProperties(massProperties.Value); } GetInfoFromFlags(rbInfo, Flags); RigidBody = new HkRigidBody(rbInfo); ProfilerShort.End(); }
private HkdBreakableShape? CreateBlockShape(Sandbox.Game.Entities.Cube.MySlimBlock b, out Matrix blockTransform) { ProfilerShort.Begin("CreateBlockShape"); blockTransform = Matrix.Identity; if (b.FatBlock == null) { Debug.Fail("Armor blocks are not allowed in medieval"); ProfilerShort.End(); return null; } HkdBreakableShape breakableShape; Matrix compoundChildTransform = Matrix.Identity; if (b.FatBlock is MyCompoundCubeBlock) { ProfilerShort.Begin("Cmpnd"); blockTransform.Translation = b.FatBlock.PositionComp.LocalMatrix.Translation; var cb = b.FatBlock as MyCompoundCubeBlock; if (cb.GetBlocksCount() == 1) { ProfilerShort.Begin("SingleBlock"); var block = cb.GetBlocks()[0]; var defId = block.FatBlock.BlockDefinition; Matrix m; var model = block.CalculateCurrentModel(out m); if (MyFakes.LAZY_LOAD_DESTRUCTION || HasBreakableShape(model, defId)) { ProfilerShort.Begin("Clone"); breakableShape = GetBreakableShape(model, defId); ProfilerShort.End(); } block.Orientation.GetMatrix(out compoundChildTransform); blockTransform = compoundChildTransform * blockTransform; ProfilerShort.End(); } else { var pos = b.Position * m_grid.GridSize; float mass = 0; ProfilerShort.Begin("GetBlocks"); foreach (var block in cb.GetBlocks()) { block.Orientation.GetMatrix(out compoundChildTransform); compoundChildTransform.Translation = Vector3.Zero; var blockDef = block.BlockDefinition; Matrix m; var model = block.CalculateCurrentModel(out m); if (MyFakes.LAZY_LOAD_DESTRUCTION || HasBreakableShape(model, blockDef)) { ProfilerShort.Begin("Clone"); breakableShape = GetBreakableShape(model, blockDef); breakableShape.UserObject |= (uint)HkdBreakableShape.Flags.FRACTURE_PIECE; System.Diagnostics.Debug.Assert(breakableShape.IsValid(), "Invalid breakableShape"); ProfilerShort.End(); mass += blockDef.Mass; m_shapeInfosList2.Add(new HkdShapeInstanceInfo(breakableShape, compoundChildTransform)); } } if (m_shapeInfosList2.Count == 0) { ProfilerShort.End(); return null; } ProfilerShort.BeginNextBlock("CreateCompoundBlockShape"); //HkShape hkpShape = new HkListShape(m_khpShapeList.ToArray(), m_khpShapeList.Count, HkReferencePolicy.None); //m_khpShapeList.Clear(); HkdBreakableShape compound = new HkdCompoundBreakableShape(null, m_shapeInfosList2); ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren(); var mp = new HkMassProperties(); compound.BuildMassProperties(ref mp); breakableShape = new HkdBreakableShape(compound.GetShape(), ref mp); compound.RemoveReference(); foreach (var si in m_shapeInfosList2) { var siRef = si; breakableShape.AddShape(ref siRef); } ProfilerShort.BeginNextBlock("Connect"); //slow slow slow //breakableShape.AutoConnect(MyDestructionData.Static.TemporaryWorld); //slow wrong //breakableShape.ConnectSemiAccurate(MyDestructionData.Static.TemporaryWorld); //fast frong for (int i = 0; i < m_shapeInfosList2.Count; i++) { for (int j = 0; j < m_shapeInfosList2.Count; j++) { if (i != j) { ConnectShapesWithChildren(breakableShape, m_shapeInfosList2[i].Shape, m_shapeInfosList2[j].Shape); } } } ProfilerShort.BeginNextBlock("Cleanup"); foreach (var si in m_shapeInfosList2) { si.Shape.RemoveReference(); si.RemoveReference(); } m_shapeInfosList2.Clear(); ProfilerShort.End(); } ProfilerShort.End(); } else { ProfilerShort.Begin("SingleBlock"); b.Orientation.GetMatrix(out blockTransform); blockTransform.Translation = b.FatBlock.PositionComp.LocalMatrix.Translation; Matrix m; var model = b.CalculateCurrentModel(out m); if (b.FatBlock is MyFracturedBlock) { ProfilerShort.Begin("CloneFracture"); breakableShape = (b.FatBlock as MyFracturedBlock).Shape; if(!breakableShape.IsValid()) { Debug.Fail("Fractured block Breakable shape invalid!"); throw new Exception("Fractured block Breakable shape invalid!"); } breakableShape.AddReference(); ProfilerShort.End(); } else if (MyFakes.LAZY_LOAD_DESTRUCTION || HasBreakableShape(model, b.BlockDefinition)) { ProfilerShort.Begin("Clone"); breakableShape = GetBreakableShape(model, b.BlockDefinition); ProfilerShort.End(); } ProfilerShort.End(); } ProfilerShort.Begin("Property"); HkPropertyBase posProp = new HkVec3IProperty(b.Position); Debug.Assert(breakableShape.IsValid()); breakableShape.SetPropertyRecursively(HkdBreakableShape.PROPERTY_GRID_POSITION, posProp); posProp.RemoveReference(); ProfilerShort.End(); //breakableShape.DisableRefCountRecursively(); ProfilerShort.End(); return breakableShape; }
private HkShape CreateBreakableBody(HkShape shape, HkMassProperties? massProperties) { ProfilerShort.Begin("CreateGridBody"); HkdBreakableShape breakable; HkMassProperties massProps = massProperties.HasValue ? massProperties.Value : new HkMassProperties(); if (!Shape.BreakableShape.IsValid()) Shape.CreateBreakableShape(); breakable = Shape.BreakableShape; if (!breakable.IsValid()) { breakable = new HkdBreakableShape(shape); if (massProperties.HasValue) { var mp = massProperties.Value; breakable.SetMassProperties(ref mp); } else breakable.SetMassRecursively(50); } else breakable.BuildMassProperties(ref massProps); shape = breakable.GetShape(); //doesnt add reference HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo(); rbInfo.AngularDamping = m_angularDamping; rbInfo.LinearDamping = m_linearDamping; rbInfo.SolverDeactivation = m_grid.IsStatic ? InitialSolverDeactivation : HkSolverDeactivation.Low; rbInfo.ContactPointCallbackDelay = ContactPointDelay; rbInfo.Shape = shape; rbInfo.SetMassProperties(massProps); //rbInfo.Position = Entity.PositionComp.GetPosition(); //obsolete with large worlds? GetInfoFromFlags(rbInfo, Flags); if (m_grid.IsStatic) { rbInfo.MotionType = HkMotionType.Dynamic; rbInfo.QualityType = HkCollidableQualityType.Moving; } HkRigidBody rb = new HkRigidBody(rbInfo); if (m_grid.IsStatic) { rb.UpdateMotionType(HkMotionType.Fixed); } rb.EnableDeactivation = true; BreakableBody = new HkdBreakableBody(breakable, rb, null, Matrix.Identity); //DestructionBody.ConnectToWorld(HavokWorld, 0.05f); BreakableBody.AfterReplaceBody += FracturedBody_AfterReplaceBody; //RigidBody.SetWorldMatrix(Entity.PositionComp.WorldMatrix); //breakable.Dispose(); ProfilerShort.End(); return shape; }
private void InitDeadBodyPhysics() { Vector3 velocity = Vector3.Zero; RadioBroadcaster.BroadcastRadius = 5; if (Physics != null) { velocity = Physics.LinearVelocity; Physics.Enabled = false; Physics.Close(); Physics = null; } //if (Physics == null) { var massProperties = new HkMassProperties(); massProperties.Mass = 500; HkShape shape; // CH: Need to rethink this. It does not belong here, but I don't want to add "DeadCharacterBodyCenterOfMass" to the character definition either... // MZ: See ticket "Correct dying for characters", https://app.asana.com/0/64822442925263/75411538582998 // dead body shape can now be specified in character's SBC if (Definition.DeadBodyShape != null) { HkBoxShape bshape = new HkBoxShape(PositionComp.LocalAABB.HalfExtents * Definition.DeadBodyShape.BoxShapeScale); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(bshape.HalfExtents, massProperties.Mass); massProperties.CenterOfMass = bshape.HalfExtents * Definition.DeadBodyShape.RelativeCenterOfMass; shape = bshape; Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT); Vector3D offset = PositionComp.LocalAABB.HalfExtents * Definition.DeadBodyShape.RelativeShapeTranslation; MatrixD pos = MatrixD.CreateTranslation(offset); Physics.CreateFromCollisionObject(shape, PositionComp.LocalVolume.Center + offset, pos, massProperties, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer); Physics.Friction = Definition.DeadBodyShape.Friction; Physics.RigidBody.MaxAngularVelocity = MathHelper.PiOver2; Physics.LinearVelocity = velocity; shape.RemoveReference(); Physics.Enabled = true; } else // no special definition => use AABB { HkBoxShape bshape = new HkBoxShape(PositionComp.LocalAABB.HalfExtents); massProperties = HkInertiaTensorComputer.ComputeBoxVolumeMassProperties(bshape.HalfExtents, massProperties.Mass); massProperties.CenterOfMass = new Vector3(bshape.HalfExtents.X, 0, 0); shape = bshape; Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_DEFAULT); Physics.CreateFromCollisionObject(shape, PositionComp.LocalVolume.Center, MatrixD.Identity, massProperties, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer); Physics.Friction = 0.5f; Physics.RigidBody.MaxAngularVelocity = MathHelper.PiOver2; Physics.LinearVelocity = velocity; shape.RemoveReference(); Physics.Enabled = true; } } NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; }
private void FindFracturedBlocks(HkdBreakableBodyInfo b) { ProfilerShort.Begin("DBHelper"); var dbHelper = new HkdBreakableBodyHelper(b); ProfilerShort.BeginNextBlock("GetRBMatrix"); var bodyMatrix = dbHelper.GetRigidBodyMatrix(); ProfilerShort.BeginNextBlock("SearchChildren"); dbHelper.GetChildren(m_children); foreach (var child in m_children) { if (!child.IsFracturePiece()) continue; //var blockPosWorld = ClusterToWorld(Vector3.Transform(child.GetTransform().Translation, bodyMatrix)); var bShape = child.Shape; HkVec3IProperty pProp = bShape.GetProperty(HkdBreakableShape.PROPERTY_GRID_POSITION); var blockPos = pProp.Value; //Vector3I.Round(child.GetTransform().Translation / m_grid.GridSize); if (!m_grid.CubeExists(blockPos)) { //Debug.Fail("FindFracturedBlocks:Fracture piece missing block");//safe to ignore continue; } if (MyFakes.ENABLE_FRACTURE_COMPONENT) { var block = m_grid.GetCubeBlock(blockPos); if (block == null) continue; if (!FindFractureComponentBlocks(block, child)) continue; } else { if (!m_fracturedBlocksShapes.ContainsKey(blockPos)) m_fracturedBlocksShapes[blockPos] = new List<HkdShapeInstanceInfo>(); m_fracturedBlocksShapes[blockPos].Add(child); } } ProfilerShort.BeginNextBlock("CreateFreacturedBlocks"); if (!MyFakes.ENABLE_FRACTURE_COMPONENT) { foreach (var key in m_fracturedBlocksShapes.Keys) { HkdBreakableShape shape; var shapeList = m_fracturedBlocksShapes[key]; foreach (var s in shapeList) { var matrix = s.GetTransform(); matrix.Translation = Vector3.Zero; s.SetTransform(ref matrix); } ProfilerShort.Begin("CreateShape"); HkdBreakableShape compound = new HkdCompoundBreakableShape(null, shapeList); ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren(); var mp = new HkMassProperties(); compound.BuildMassProperties(ref mp); shape = compound; var sh = compound.GetShape(); shape = new HkdBreakableShape(sh, ref mp); //shape.SetMassProperties(mp); //important! pass mp to constructor foreach (var si in shapeList) { var siRef = si; shape.AddShape(ref siRef); } compound.RemoveReference(); ProfilerShort.BeginNextBlock("Connect"); //shape.SetChildrenParent(shape); ConnectPiecesInBlock(shape, shapeList); ProfilerShort.End(); var info = new MyFracturedBlock.Info() { Shape = shape, Position = key, Compound = true, }; var originalBlock = m_grid.GetCubeBlock(key); if (originalBlock == null) { //Debug.Fail("Missing fracture piece original block.");//safe to ignore shape.RemoveReference(); continue; } Debug.Assert(originalBlock != null); if (originalBlock.FatBlock is MyFracturedBlock) { var fractured = originalBlock.FatBlock as MyFracturedBlock; info.OriginalBlocks = fractured.OriginalBlocks; info.Orientations = fractured.Orientations; info.MultiBlocks = fractured.MultiBlocks; } else if (originalBlock.FatBlock is MyCompoundCubeBlock) { info.OriginalBlocks = new List<MyDefinitionId>(); info.Orientations = new List<MyBlockOrientation>(); MyCompoundCubeBlock compoundBlock = originalBlock.FatBlock as MyCompoundCubeBlock; bool hasMultiBlockPart = false; var blocksInCompound = compoundBlock.GetBlocks(); foreach (var block in blocksInCompound) { info.OriginalBlocks.Add(block.BlockDefinition.Id); info.Orientations.Add(block.Orientation); hasMultiBlockPart = hasMultiBlockPart || block.IsMultiBlockPart; } if (hasMultiBlockPart) { info.MultiBlocks = new List<MyFracturedBlock.MultiBlockPartInfo>(); foreach (var block in blocksInCompound) { if (block.IsMultiBlockPart) info.MultiBlocks.Add(new MyFracturedBlock.MultiBlockPartInfo() { MultiBlockDefinition = block.MultiBlockDefinition.Id, MultiBlockId = block.MultiBlockId }); else info.MultiBlocks.Add(null); } } } else { info.OriginalBlocks = new List<MyDefinitionId>(); info.Orientations = new List<MyBlockOrientation>(); info.OriginalBlocks.Add(originalBlock.BlockDefinition.Id); info.Orientations.Add(originalBlock.Orientation); if (originalBlock.IsMultiBlockPart) { info.MultiBlocks = new List<MyFracturedBlock.MultiBlockPartInfo>(); info.MultiBlocks.Add(new MyFracturedBlock.MultiBlockPartInfo() { MultiBlockDefinition = originalBlock.MultiBlockDefinition.Id, MultiBlockId = originalBlock.MultiBlockId }); } } m_fractureBlocksCache.Add(info); } } m_fracturedBlocksShapes.Clear(); m_children.Clear(); ProfilerShort.End(); }
protected override void CreateBody(ref HkShape shape, HkMassProperties? massProperties) { if (MyPerGameSettings.Destruction)// && shape.ShapeType == HkShapeType.StaticCompound) { shape = CreateBreakableBody(shape, massProperties); } else { HkRigidBodyCinfo rbInfo = new HkRigidBodyCinfo(); rbInfo.AngularDamping = m_angularDamping; rbInfo.LinearDamping = m_linearDamping; rbInfo.Shape = shape; rbInfo.SolverDeactivation = InitialSolverDeactivation; rbInfo.ContactPointCallbackDelay = ContactPointDelay; if (massProperties.HasValue) { rbInfo.SetMassProperties(massProperties.Value); } GetInfoFromFlags(rbInfo, Flags); if (m_grid.IsStatic) { rbInfo.MotionType = HkMotionType.Dynamic; rbInfo.QualityType = HkCollidableQualityType.Moving; } RigidBody = new HkRigidBody(rbInfo); if (m_grid.IsStatic) { RigidBody.UpdateMotionType(HkMotionType.Fixed); } //RigidBody.UpdateMotionType(HkMotionType.Dynamic); //base.CreateBody(ref shape, massProperties); } }
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); } }
public virtual void CreateFromCollisionObject(HkShape shape, Vector3 center, MatrixD worldTransform, HkMassProperties? massProperties = null, int collisionFilter = MyPhysics.DefaultCollisionLayer) { MyPhysics.AssertThread(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyPhysicsBody::CreateFromCollisionObject()"); Debug.Assert(RigidBody == null, "Must be removed from scene and null"); CloseRigidBody(); Center = center; CanUpdateAccelerations = true; //m_motionState = new MyMotionState(worldTransform); CreateBody(ref shape, massProperties); RigidBody.UserObject = this; //RigidBody.SetWorldMatrix(worldTransform); RigidBody.Layer = collisionFilter; if ((int)(Flags & RigidBodyFlag.RBF_DISABLE_COLLISION_RESPONSE) > 0) { RigidBody.Layer = MyPhysics.NoCollisionLayer; } if ((int)(Flags & RigidBodyFlag.RBF_DOUBLED_KINEMATIC) > 0) { HkRigidBodyCinfo rbInfo2 = new HkRigidBodyCinfo(); rbInfo2.AngularDamping = m_angularDamping; rbInfo2.LinearDamping = m_linearDamping; rbInfo2.Shape = shape; rbInfo2.MotionType = HkMotionType.Keyframed; rbInfo2.QualityType = HkCollidableQualityType.Keyframed; RigidBody2 = new HkRigidBody(rbInfo2); RigidBody2.UserObject = this; RigidBody2.SetWorldMatrix(worldTransform); } //m_motionState.Body = this; VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); }
protected override void RecreateShape(List<MyObjectBuilder_FractureComponentBase.FracturedShape> shapeList) { Debug.Assert(m_tmpChildren.Count == 0); Debug.Assert(m_tmpShapeInfos.Count == 0); ProfilerShort.Begin("FractureComponent.RecreateShape"); if (Shape.IsValid()) { Shape.RemoveReference(); Shape = new HkdBreakableShape(); } var render = Block.FatBlock.Render as MyRenderComponentFracturedPiece; if (render != null) { render.ClearModels(); render.UpdateRenderObject(false); } else { Debug.Fail("Invalid render type"); } if (shapeList.Count == 0) { ProfilerShort.End(); return; } var removeRefsList = new List<HkdShapeInstanceInfo>(); { var blockDef = Block.BlockDefinition; var model = blockDef.Model; if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null) MyDestructionData.Static.LoadModelDestruction(model, blockDef, Vector3.One); var shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0]; var si = new HkdShapeInstanceInfo(shape, null, null); removeRefsList.Add(si); m_tmpChildren.Add(si); shape.GetChildren(m_tmpChildren); if (blockDef.BuildProgressModels != null) { foreach (var progress in blockDef.BuildProgressModels) { model = progress.File; if (VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes == null) MyDestructionData.Static.LoadModelDestruction(model, blockDef, Vector3.One); shape = VRage.Game.Models.MyModels.GetModelOnlyData(model).HavokBreakableShapes[0]; si = new HkdShapeInstanceInfo(shape, null, null); removeRefsList.Add(si); m_tmpChildren.Add(si); shape.GetChildren(m_tmpChildren); } } } Debug.Assert(m_tmpShapeListInit.Count == 0); m_tmpShapeListInit.Clear(); m_tmpShapeListInit.AddList(shapeList); for (int i = 0; i < m_tmpChildren.Count; i++) { var child = m_tmpChildren[i]; var result = m_tmpShapeListInit.Where(s => s.Name == child.ShapeName); if (result.Count() > 0) { var found = result.First(); var si = new HkdShapeInstanceInfo(child.Shape.Clone(), Matrix.Identity); if (found.Fixed) si.Shape.SetFlagRecursively(HkdBreakableShape.Flags.IS_FIXED); removeRefsList.Add(si); m_tmpShapeInfos.Add(si); m_tmpShapeListInit.Remove(found); } else { child.GetChildren(m_tmpChildren); } } m_tmpShapeListInit.Clear(); if (shapeList.Count > 0 && m_tmpShapeInfos.Count == 0) { ProfilerShort.End(); m_tmpChildren.Clear(); Debug.Fail("No relevant shape was found for fractured block. It was probably reexported and names changed. Block definition: " + Block.BlockDefinition.Id.ToString()); throw new Exception("No relevant shape was found for fractured block. It was probably reexported and names changed. Block definition: " + Block.BlockDefinition.Id.ToString()); } if (render != null) { foreach (var shape in m_tmpShapeInfos) { if (!string.IsNullOrEmpty(shape.Shape.Name)) render.AddPiece(shape.Shape.Name, Matrix.Identity); } render.UpdateRenderObject(true); } m_tmpChildren.Clear(); if (Block.CubeGrid.CreatePhysics) { HkdBreakableShape compound = new HkdCompoundBreakableShape(null, m_tmpShapeInfos); ((HkdCompoundBreakableShape)compound).RecalcMassPropsFromChildren(); var mp = new HkMassProperties(); compound.BuildMassProperties(ref mp); Shape = new HkdBreakableShape(compound.GetShape(), ref mp); compound.RemoveReference(); foreach (var si in m_tmpShapeInfos) { var siRef = si; Shape.AddShape(ref siRef); } Shape.SetStrenght(MyDestructionConstants.STRENGTH); CreateMountPoints(); // Update neighbours for parent block var blockOnPosition = Block.CubeGrid.GetCubeBlock(Block.Position); if (blockOnPosition != null) blockOnPosition.CubeGrid.UpdateBlockNeighbours(blockOnPosition); if (Block.CubeGrid.Physics != null) Block.CubeGrid.Physics.AddDirtyBlock(Block); } foreach (var si in m_tmpShapeInfos) si.Shape.RemoveReference(); m_tmpShapeInfos.Clear(); foreach (var si in removeRefsList) si.RemoveReference(); ProfilerShort.End(); }
public override void CreateCharacterCollision(Vector3 center, float characterWidth, float characterHeight, float crouchHeight, float ladderHeight, float headSize, float headHeight, MatrixD worldTransform, float mass, ushort collisionLayer, bool isOnlyVertical, float maxSlope, bool networkProxy) { Center = center; CanUpdateAccelerations = false; if (networkProxy) { //create kinematic body for network proxy HkShape shape = MyCharacterProxy.CreateCharacterShape(characterHeight, characterWidth, characterHeight + headHeight, headSize, 0.0f); HkMassProperties massProperties = new HkMassProperties(); massProperties.Mass = mass; massProperties.InertiaTensor = Matrix.Identity; massProperties.Volume = characterWidth * characterWidth * (characterHeight + 2 * characterWidth); CreateFromCollisionObject(shape, center, worldTransform, massProperties, collisionLayer); CanUpdateAccelerations = false; return; } Vector3 transformedCenter = Vector3.TransformNormal(Center, worldTransform); Matrix worldTransformCentered = Matrix.CreateWorld(transformedCenter + worldTransform.Translation, worldTransform.Forward, worldTransform.Up); CharacterProxy = new MyCharacterProxy( #if DYNAMIC_CHARACTER_CONTROLLER true, #else false, #endif true, characterWidth, characterHeight, crouchHeight, ladderHeight, headSize, headHeight, worldTransformCentered.Translation, worldTransform.Up, worldTransform.Forward, mass, this, isOnlyVertical, maxSlope); //CharacterProxy.Gravity = new Vector3(0, -20, 0); }
private static MyFracturedPiece CreateFracturePiece(ref HkdBreakableShape shape, HkdWorld world, ref MatrixD worldMatrix, bool isStatic) { Debug.Assert(shape.IsValid()); ProfilerShort.Begin("CreateFracturePiece"); var fracturedPiece = MyFracturedPiecesManager.Static.GetPieceFromPool(0);//new MyFracturedPiece(); fracturedPiece.PositionComp.WorldMatrix = worldMatrix; fracturedPiece.Physics.Flags = isStatic ? RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS; var physicsBody = fracturedPiece.Physics as MyPhysicsBody;//new MyPhysicsBody(fracturedPiece,isFixed ?RigidBodyFlag.RBF_STATIC : RigidBodyFlag.RBF_DEBRIS); HkMassProperties mp = new HkMassProperties(); shape.BuildMassProperties(ref mp); physicsBody.InitialSolverDeactivation = HkSolverDeactivation.High; physicsBody.CreateFromCollisionObject(shape.GetShape(), Vector3.Zero, worldMatrix, mp); physicsBody.LinearDamping = MyPerGameSettings.DefaultLinearDamping; physicsBody.AngularDamping = MyPerGameSettings.DefaultAngularDamping; System.Diagnostics.Debug.Assert(physicsBody.BreakableBody == null, "physicsBody.DestructionBody == null"); physicsBody.BreakableBody = new HkdBreakableBody(shape, physicsBody.RigidBody, world, worldMatrix); physicsBody.BreakableBody.AfterReplaceBody += physicsBody.FracturedBody_AfterReplaceBody; ProfilerShort.End(); ProfilerShort.Begin("Sync"); if (fracturedPiece.SyncFlag) { fracturedPiece.CreateSync(); } ProfilerShort.End(); fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; //physicsBody.RigidBody.ContactPointCallbackDelay = 0; //physicsBody.RigidBody.ContactPointCallbackEnabled = true; fracturedPiece.Physics = physicsBody; //FixPosition(fracturedPiece); fracturedPiece.SetDataFromHavok(shape); ProfilerShort.Begin("AddToWorld"); fracturedPiece.NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; shape.RemoveReference(); ProfilerShort.End(); return fracturedPiece; }
/// <summary> /// Loads Ragdoll data /// </summary> /// <param name="ragDollFile"></param> public bool InitRagdoll() { if (MyFakes.ENABLE_RAGDOLL_DEBUG) Debug.WriteLine("RagdollComponent.InitRagdoll"); if (Character.Physics.Ragdoll != null) { Character.Physics.CloseRagdollMode(); Character.Physics.Ragdoll.ResetToRigPose(); Character.Physics.Ragdoll.SetToKeyframed(); return true; } Character.Physics.Ragdoll = new HkRagdoll(); bool dataLoaded = false; if (Character.Model.HavokData != null && Character.Model.HavokData.Length > 0) { try { dataLoaded = Character.Physics.Ragdoll.LoadRagdollFromBuffer(Character.Model.HavokData); } catch (Exception e) { Debug.Fail("Error loading ragdoll from buffer: " + e.Message); Character.Physics.CloseRagdoll(); Character.Physics.Ragdoll = null; } } else if (Character.Definition.RagdollDataFile != null) { String ragDollFile = System.IO.Path.Combine(MyFileSystem.ContentPath, Character.Definition.RagdollDataFile); if (System.IO.File.Exists(ragDollFile)) { dataLoaded = Character.Physics.Ragdoll.LoadRagdollFromFile(ragDollFile); } else { System.Diagnostics.Debug.Fail("Cannot find ragdoll file: " + ragDollFile); } } if (Character.Definition.RagdollRootBody != String.Empty) { if (!Character.Physics.Ragdoll.SetRootBody(Character.Definition.RagdollRootBody)) { Debug.Fail("Can not set root body with name: " + Character.Definition.RagdollRootBody + " on model " + Character.ModelName + ". Please check your definitions."); } } if (!dataLoaded) { Character.Physics.Ragdoll.Dispose(); Character.Physics.Ragdoll = null; } foreach (var body in Character.Physics.Ragdoll.RigidBodies) body.UserObject = Character; if (Character.Physics.Ragdoll != null && MyPerGameSettings.Destruction) //scaling weights and IT { Character.Physics.Ragdoll.SetToDynamic(); var mp = new HkMassProperties(); foreach (var body in Character.Physics.Ragdoll.RigidBodies) { mp.Mass = MyDestructionHelper.MassToHavok(body.Mass); mp.InertiaTensor = Matrix.CreateScale(1.0f / 25.0f) * body.InertiaTensor; body.SetMassProperties(ref mp); } Character.Physics.Ragdoll.SetToKeyframed(); } if (Character.Physics.Ragdoll != null && MyFakes.ENABLE_RAGDOLL_DEFAULT_PROPERTIES) { Character.Physics.SetRagdollDefaults(); } return dataLoaded; }