コード例 #1
0
        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);
            }
        }
コード例 #2
0
ファイル: MyAmmoBase.cs プロジェクト: rwohleb/SpaceEngineers
 void listener_ContactPointCallback(ref MyPhysics.MyContactPointEvent value)
 {
     if (value.ContactPointEvent.EventType != HkContactPointEvent.Type.ManifoldAtEndOfStep)
     {
         OnContactStart(ref value);
     }
 }
コード例 #3
0
ファイル: MyMissile.cs プロジェクト: feiyuren233/vrage
        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();
        }
コード例 #4
0
            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);
                }
            }
コード例 #5
0
        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);
            }
        }
コード例 #6
0
ファイル: MyAmmoBase.cs プロジェクト: rwohleb/SpaceEngineers
 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());
     }
 }
コード例 #7
0
 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;
 }
コード例 #8
0
        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);
                }
            }
        }
コード例 #9
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;
            }
コード例 #10
0
            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();
            }
コード例 #11
0
 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;
 }
コード例 #12
0
ファイル: MyAmmoBase.cs プロジェクト: rwohleb/SpaceEngineers
 public virtual void OnContactStart(ref MyPhysics.MyContactPointEvent value)
 {
 }