private void Physics_onContactPoint(ref MyPhysics.MyContactPointEvent evt) { var bodyA = evt.ContactPointEvent.GetPhysicsBody(0); if (bodyA == null) { return; } int bodyIndex = bodyA.Entity == this ? 0 : 1; uint myShapekey = evt.ContactPointEvent.GetShapeKey(bodyIndex); if (myShapekey == uint.MaxValue) { return; } var bodyB = evt.ContactPointEvent.GetPhysicsBody(1 ^ bodyIndex); if (bodyB == null) { return; } var other = bodyB.Entity; int item = GetItemFromShapeKey(myShapekey); foreach (var callback in m_contactListeners) { callback.Invoke(item, (MyEntity)other, ref evt); } }
void listener_ContactPointCallback(ref MyPhysics.MyContactPointEvent value) { if (value.ContactPointEvent.EventType != HkContactPointEvent.Type.ManifoldAtEndOfStep) { OnContactStart(ref value); } }
public override void OnContactStart(ref MyPhysics.MyContactPointEvent value) { MyEntity collidedEntity = value.ContactPointEvent.GetOtherEntity(this) as MyEntity; if (collidedEntity == null) { return; } if (!Sandbox.Game.Multiplayer.Sync.IsServer) { m_collidedEntity = collidedEntity; m_collisionPoint = value.Position; m_collisionNormal = value.Normal; PlaceDecal(); Close(); return; } Debug.Assert(!collidedEntity.Closed); m_collidedEntity = collidedEntity; m_collidedEntity.OnClose += m_collidedEntity_OnClose; m_collisionPoint = value.Position; m_collisionNormal = value.Normal; Explode(); }
void RigidBody_ContactPointCallback(ref MyPhysics.MyContactPointEvent value) { if (this.MarkedForClose || !Entity.Physics.Enabled || m_closeAfterSimulation) { return; } Sandbox.ModAPI.IMyEntity other = GetOtherEntity(ref value.ContactPointEvent); if (Sync.IsServer) { if (other is MyCubeGrid && MySession.Static.DestructibleBlocks) { DestroyGrid(ref value, other as MyCubeGrid); } else if (other is MyCharacter) { (other as MyCharacter).DoDamage(50 * Entity.PositionComp.Scale.Value, MyDamageType.Environment, true); } else if (other is MyFloatingObject) { (other as MyFloatingObject).DoDamage(100 * Entity.PositionComp.Scale.Value, MyDamageType.Deformation, true); } else if (other is MyMeteor) { m_closeAfterSimulation = true; (other.GameLogic as MyMeteorGameLogic).m_closeAfterSimulation = true; } } if (other is MyVoxelMap) { CreateCrater(value, other as MyVoxelMap); } }
private void SectorOnContactPoint(int itemId, MyEntity other, ref MyPhysics.MyContactPointEvent e) { // if item is already disabled: puff // We get multiple contact points so this is for that if (m_sector.DataView.Items[itemId].ModelIndex < 0) { return; } var vel = Math.Abs(e.ContactPointEvent.SeparatingVelocity); if (other == null || other.Physics == null || other is MyFloatingObject) { return; } if (other is IMyHandheldGunObject <MyDeviceBase> ) { return; } // Prevent debris from breaking trees. // Debris flies in unpredictable ways and this could cause out of sync tree destruction which would is bad. if (other.Physics.RigidBody != null && other.Physics.RigidBody.Layer == MyPhysics.CollisionLayers.DebrisCollisionLayer) { return; } // On objects held in manipulation tool, Havok returns high velocities, after this contact is fired by contraint solver. // Therefore we disable damage from objects connected by constraint to character if (MyManipulationTool.IsEntityManipulated(other)) { return; } float otherMass = MyDestructionHelper.MassFromHavok(other.Physics.Mass); double impactEnergy = vel * vel * otherMass; // TODO: per item max impact energy if (impactEnergy > ItemResilience(itemId)) { var normal = e.ContactPointEvent.ContactPoint.Normal; impactEnergy = MathHelper.Clamp(impactEnergy, 0, ItemResilience(itemId) * 10); Impact impact = new Impact(e.Position, normal, impactEnergy); m_sector.RaiseItemEvent(this, itemId, impact); DisableItemAndCreateDebris(ref impact, itemId); } // Meteor destroy always if (other is MyMeteor) { m_sector.EnableItem(itemId, false); } }
protected Sandbox.ModAPI.IMyEntity GetOtherEntity(ref MyPhysics.MyContactPointEvent value) { if (value.ContactPointEvent.Base.BodyA.GetEntity() == this) { return(value.ContactPointEvent.Base.BodyB.GetEntity()); } else { return(value.ContactPointEvent.Base.BodyA.GetEntity()); } }
private void CreateCrater(MyPhysics.MyContactPointEvent value, MyVoxelBase voxel) { if (Math.Abs(Vector3.Normalize(-Entity.WorldMatrix.Forward).Dot(value.ContactPointEvent.ContactPoint.Normal)) < 0.1) { MyParticleEffect impactParticle1; if (InParticleVisibleRange && MyParticlesManager.TryCreateParticleEffect("Meteorit_Smoke1AfterHit", out impactParticle1)) { impactParticle1.WorldMatrix = Entity.WorldMatrix; impactParticle1.UserScale = (float)Entity.PositionComp.WorldVolume.Radius * 2; } m_particleVectorUp = Vector3.Zero; m_closeAfterSimulation = Sync.IsServer; return; } if (Sync.IsServer) { float craterRadius = Entity.PositionComp.Scale.Value * 5; BoundingSphereD sphere = new BoundingSphere(value.Position, craterRadius); Vector3 direction; // if contact was send after reflection we need to get former direction if (value.ContactPointEvent.SeparatingVelocity < 0) { direction = Vector3.Normalize(Entity.Physics.LinearVelocity); } else { direction = Vector3.Normalize(Vector3.Reflect(Entity.Physics.LinearVelocity, value.ContactPointEvent.ContactPoint.Normal)); } var material = VoxelMaterial; int tries = MyDefinitionManager.Static.GetVoxelMaterialDefinitions().Count() * 2; // max amount of tries while (!material.IsRare || !material.SpawnsFromMeteorites || material.MinVersion > MySession.Static.Settings.VoxelGeneratorVersion) { if (--tries < 0) // to prevent infinite loops in case all materials are disabled just use the meteorites' initial material { material = VoxelMaterial; break; } material = MyDefinitionManager.Static.GetVoxelMaterialDefinitions().ElementAt(MyUtils.GetRandomInt(MyDefinitionManager.Static.GetVoxelMaterialDefinitions().Count() - 1)); } voxel.CreateVoxelMeteorCrater(sphere.Center, (float)sphere.Radius, -direction, material); MyVoxelGenerator.MakeCrater(voxel, sphere, -direction, material); } m_soundEmitter.Entity = voxel as MyEntity; m_soundEmitter.SetPosition(Entity.PositionComp.GetPosition()); m_closeAfterSimulation = Sync.IsServer; }
void Physics_ContactPointCallback(ref MyPhysics.MyContactPointEvent e) { var vel = Math.Abs(e.ContactPointEvent.SeparatingVelocity); var other = e.ContactPointEvent.GetOtherEntity(this); if (other == null || other.Physics == null) { return; } float otherMass = MyDestructionHelper.MassFromHavok(other.Physics.Mass); if (other is Sandbox.Game.Entities.Character.MyCharacter) { otherMass = other.Physics.Mass; } float impactEnergy = vel * vel * otherMass; // If environment item is hit by a gun, nothing happens here. If you want a weapon damage to env. items, call DoDamage there if (impactEnergy > 350000 && !(other is IMyHandheldGunObject <MyDeviceBase>)) { int bodyId = e.ContactPointEvent.Base.BodyA.GetEntity() == this ? 0 : 1; var shapeKey = e.ContactPointEvent.GetShapeKey(bodyId); var position = Physics.ClusterToWorld(e.ContactPointEvent.ContactPoint.Position); var sectorId = MyEnvironmentSector.GetSectorId(position, m_definition.SectorSize); HkStaticCompoundShape shape = (HkStaticCompoundShape)Physics.RigidBody.GetShape(); int physicsInstanceId; uint childKey; if (shapeKey == uint.MaxValue) //jn: TODO find out why this happens, there is ticket for it https://app.asana.com/0/9887996365574/26645443970236 { ProfilerShort.End(); return; } shape.DecomposeShapeKey(shapeKey, out physicsInstanceId, out childKey); int itemInstanceId; if (m_physicsShapeInstanceIdToLocalId.TryGetValue(physicsInstanceId, out itemInstanceId)) { DoDamage(1.0f, itemInstanceId, e.Position, -e.ContactPointEvent.ContactPoint.Normal); } } }
private void DestroyGrid(ref MyPhysics.MyContactPointEvent value, MyCubeGrid grid) { MyGridContactInfo info = new MyGridContactInfo(ref value.ContactPointEvent, grid); info.EnableDeformation = false; info.EnableParticles = false; HkBreakOffPointInfo breakInfo = new HkBreakOffPointInfo() { ContactPoint = value.ContactPointEvent.ContactPoint, ContactPosition = info.ContactPosition, ContactPointProperties = value.ContactPointEvent.ContactProperties, IsContact = true, BreakingImpulse = grid.Physics.Shape.BreakImpulse, CollidingBody = value.ContactPointEvent.Base.BodyA == grid.Physics.RigidBody ? value.ContactPointEvent.Base.BodyB : value.ContactPointEvent.Base.BodyA, ContactPointDirection = value.ContactPointEvent.Base.BodyB == grid.Physics.RigidBody ? -1 : 1, }; grid.Physics.PerformMeteoritDeformation(ref breakInfo, value.ContactPointEvent.SeparatingVelocity); m_closeAfterSimulation = Sync.IsServer; }
void RigidBody_ContactPointCallback(ref MyPhysics.MyContactPointEvent value) { if (this.MarkedForClose || !Entity.Physics.Enabled || m_closeAfterSimulation) { return; } ProfilerShort.Begin("MyMeteor.CPCallback"); var other = value.ContactPointEvent.GetOtherEntity(Entity); if (Sync.IsServer) { if (other is MyCubeGrid) { var grid = other as MyCubeGrid; if (grid.BlocksDestructionEnabled) { DestroyGrid(ref value, grid); } } else if (other is MyCharacter) { (other as MyCharacter).DoDamage(50 * Entity.PositionComp.Scale.Value, MyDamageType.Environment, true, Entity.EntityId); } else if (other is MyFloatingObject) { (other as MyFloatingObject).DoDamage(100 * Entity.PositionComp.Scale.Value, MyDamageType.Deformation, true, Entity.EntityId); } else if (other is MyMeteor) { m_closeAfterSimulation = true; (other.GameLogic as MyMeteorGameLogic).m_closeAfterSimulation = true; } m_closeAfterSimulation = true; } if (other is MyVoxelBase) { CreateCrater(value, other as MyVoxelBase); } ProfilerShort.End(); }
private void CreateCrater(MyPhysics.MyContactPointEvent value, MyVoxelMap voxel) { if (Math.Abs(Vector3.Normalize(-Entity.WorldMatrix.Forward).Dot(value.ContactPointEvent.ContactPoint.Normal)) < 0.1) { MyParticleEffect impactParticle1; if (InParticleVisibleRange && MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.MeteorAsteroidCollision, out impactParticle1)) { impactParticle1.WorldMatrix = Entity.WorldMatrix; impactParticle1.UserScale = (float)Entity.PositionComp.WorldVolume.Radius * 2; } m_particleVectorUp = Vector3.Zero; return; } if (Sync.IsServer) { BoundingSphereD sphere = new BoundingSphere(value.Position, Entity.PositionComp.Scale.Value / 3); Vector3 direction; // if contact was send after reflection we need to get former direction if (value.ContactPointEvent.SeparatingVelocity < 0) { direction = Vector3.Normalize(Entity.Physics.LinearVelocity); } else { direction = Vector3.Normalize(Vector3.Reflect(Entity.Physics.LinearVelocity, value.ContactPointEvent.ContactPoint.Normal)); } var material = VoxelMaterial; while (!material.IsRare) { material = MyDefinitionManager.Static.GetVoxelMaterialDefinitions().ElementAt(MyUtils.GetRandomInt(MyDefinitionManager.Static.GetVoxelMaterialDefinitions().Count() - 1)); } voxel.SyncObject.CreateVoxelMeteorCrater(sphere.Center, (float)sphere.Radius, -direction, material); MyVoxelGenerator.MakeCrater(voxel, sphere, -direction, material); } m_closeAfterSimulation = true; }
public virtual void OnContactStart(ref MyPhysics.MyContactPointEvent value) { }