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)) { BreakAt(itemId, e.Position, e.ContactPointEvent.ContactPoint.Normal, impactEnergy); } // Meteor destroy always if (other is MyMeteor) m_sector.EnableItem(itemId, false); }
private int CompareHits(MyPhysics.HitInfo info1, MyPhysics.HitInfo info2) { IMyEntity entity1 = info1.HkHitInfo.GetHitEntity(); IMyEntity entity2 = info2.HkHitInfo.GetHitEntity(); Type entity1Type = entity1.GetType(); Type entity2Type = entity2.GetType(); if (entity1Type != entity2Type) { // Fix highlighting order on legacy worlds Type voxelMapType = typeof(MyVoxelMap); if (entity1Type == voxelMapType) return 1; if (entity2Type == voxelMapType) return -1; // Fix highlighting order on planets Type voxelPhysicsType = typeof(MyVoxelPhysics); if (entity1Type == voxelPhysicsType) return 1; if (entity2Type == voxelPhysicsType) return -1; Type cubeGridType = typeof(MyCubeGrid); if (entity1Type == cubeGridType) return 1; if (entity2Type == cubeGridType) return -1; } Vector3D deltaPos1 = info1.Position - m_rayOrigin; Vector3D deltaPos2 = info2.Position - m_rayOrigin; float dot1 = Vector3.Dot(m_rayDirection, Vector3.Normalize(deltaPos1)); float dot2 = Vector3.Dot(m_rayDirection, Vector3.Normalize(deltaPos2)); int dotResult = dot2.CompareTo(dot1); if (dotResult != 0) return dotResult; int distanceCheck = deltaPos2.LengthSquared().CompareTo(deltaPos1.LengthSquared()); if (distanceCheck != 0) return distanceCheck; return 0; }
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; }
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((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; 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_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; } } if (other is MyVoxelBase) { CreateCrater(value, other as MyVoxelBase); } ProfilerShort.End(); }
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 || other is MyFloatingObject) 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 as MyEntity)) { 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 > 200000 && !(other is IMyHandheldGunObject<MyDeviceBase>)) { int bodyId = e.ContactPointEvent.Base.BodyA.GetEntity(0) == 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 { return; } shape.DecomposeShapeKey(shapeKey, out physicsInstanceId, out childKey); int itemInstanceId; if (m_physicsShapeInstanceIdToLocalId.TryGetValue(physicsInstanceId, out itemInstanceId)) { DoDamage(100.0f, itemInstanceId, e.Position, -e.ContactPointEvent.ContactPoint.Normal, MyStringHash.NullOrEmpty); } } }
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 || 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 as MyEntity)) { return; } float otherMass = MyDestructionHelper.MassFromHavok(other.Physics.Mass); if (other is Character.MyCharacter) otherMass = other.Physics.Mass; double impactEnergy = vel*vel*otherMass; // TODO: per item max impact energy if (impactEnergy > 200000) { int bodyId = 0; var normal = e.ContactPointEvent.ContactPoint.Normal; if (e.ContactPointEvent.Base.BodyA.GetEntity(0) != this) { bodyId = 1; normal *= -1; } var shapeKey = e.ContactPointEvent.GetShapeKey(bodyId); if (shapeKey == uint.MaxValue) //jn: TODO find out why this happens, there is ticket for it https://app.asana.com/0/9887996365574/26645443970236 { return; } HkStaticCompoundShape shape = (HkStaticCompoundShape) Physics.RigidBody.GetShape(); int physicsInstanceId; uint childKey; shape.DecomposeShapeKey(shapeKey, out physicsInstanceId, out childKey); int itemInstanceId; if (m_physicsShapeInstanceIdToLocalId.TryGetValue(physicsInstanceId, out itemInstanceId)) { var position = Physics.ClusterToWorld(e.ContactPointEvent.ContactPoint.Position); if (PlanetSpawnerDefinition != null) { MyMultiplayer.RaiseEvent(PlanetSector, x => x.BreakEnvironmentItem, (SerializableDefinitionId)PlanetSpawnerDefinition.Value, position, normal, impactEnergy, itemInstanceId); } DestroyItemAndCreateDebris(position, normal, impactEnergy, itemInstanceId); } } }
public override void OnContactStart(ref MyPhysics.MyContactPointEvent value) { MyEntity collidedEntity = GetOtherEntity(ref value) as MyEntity; if (collidedEntity == null) return; if (!Sandbox.Game.Multiplayer.Sync.IsServer) { Close(); return; } Debug.Assert(!collidedEntity.Closed); m_collidedEntity = collidedEntity; m_collidedEntity.OnClose += m_collidedEntity_OnClose; m_collisionPoint = value.Position; Explode(); }
public virtual void OnContactStart(ref MyPhysics.MyContactPointEvent value) { }
void listener_ContactPointCallback(ref MyPhysics.MyContactPointEvent value) { if (value.ContactPointEvent.EventType != HkContactPointEvent.Type.ManifoldAtEndOfStep) { OnContactStart(ref value); } }
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(); }
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 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; }
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); } }