Beispiel #1
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;
            }
Beispiel #2
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;
 }
        public void PerformMeteoritDeformation(ref HkBreakOffPointInfo pt, float separatingVelocity)
        {
            ProfilerShort.Begin("PerformDeformation");

            Debug.Assert(Sync.IsServer, "Function PerformDeformation should not be called from client");

            // Calculate deformation offset
            float deformationOffset = 0.3f + Math.Max(0, ((float)Math.Sqrt(Math.Abs(separatingVelocity) + Math.Pow(pt.CollidingBody.Mass, 0.72))) / 10);
            deformationOffset *= 6;

            const float maxDeformationHardLimit = 5; // Max offset is 5 for meteors
            deformationOffset = Math.Min(deformationOffset, maxDeformationHardLimit);

            float softAreaPlanar = (float)Math.Pow(pt.CollidingBody.Mass, 0.15f);
            softAreaPlanar -= 0.3f;
            softAreaPlanar *= m_grid.GridSizeEnum == MyCubeSize.Large ? 4 : 1f; // About 4 meters for large grid and 1m for small
            float softAreaVertical = deformationOffset;
            softAreaVertical *= m_grid.GridSizeEnum == MyCubeSize.Large ? 1 : 0.2f;

            var invWorld = m_grid.PositionComp.GetWorldMatrixNormalizedInv();
            var pos = Vector3D.Transform(pt.ContactPosition, invWorld);
            var normal = Vector3.TransformNormal(pt.ContactPoint.Normal, invWorld) * pt.ContactPointDirection;

            bool destroyed = ApplyDeformation(deformationOffset, softAreaPlanar, softAreaVertical, pos, normal, MyDamageType.Deformation, 0, m_grid.GridSizeEnum == MyCubeSize.Large ? 0.6f : 0.16f);

            MyPhysics.CastRay(pt.ContactPoint.Position, pt.ContactPoint.Position - softAreaVertical * Vector3.Normalize(pt.ContactPoint.Normal), m_hitList);
            foreach (var hit in m_hitList)
            {
                var entity = hit.HkHitInfo.Body.GetEntity();
                if (entity != m_grid.Components && entity is MyCubeGrid)
                {
                    var grid = entity as MyCubeGrid;
                    invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv();
                    pos = Vector3D.Transform(pt.ContactPosition, invWorld);
                    normal = Vector3.TransformNormal(pt.ContactPoint.Normal, invWorld) * pt.ContactPointDirection;
                    grid.Physics.ApplyDeformation(deformationOffset,
                        softAreaPlanar * (m_grid.GridSizeEnum == grid.GridSizeEnum ? 1 : grid.GridSizeEnum == MyCubeSize.Large ? 2 : 0.25f),
                        softAreaVertical * (m_grid.GridSizeEnum == grid.GridSizeEnum ? 1 : grid.GridSizeEnum == MyCubeSize.Large ? 2.5f : 0.2f),
                        pos, normal, MyDamageType.Deformation, 0, grid.GridSizeEnum == MyCubeSize.Large ? 0.6f : 0.16f);
                }
            }
            m_hitList.Clear();

            float explosionRadius = Math.Max(m_grid.GridSize, deformationOffset * (m_grid.GridSizeEnum == MyCubeSize.Large ? 0.25f : 0.05f));
            if (explosionRadius > 0 && deformationOffset > m_grid.GridSize / 2 && destroyed)
            {
                var info = new ExplosionInfo()
                {
                    Position = pt.ContactPosition,
                    ExplosionType = MyExplosionTypeEnum.GRID_DESTRUCTION,
                    Radius = explosionRadius,
                    ModelDebris = destroyed,
                };

                m_explosions.Add(info);
            }
            else
            {
                AddCollisionEffect(pt.ContactPosition, normal);
            }

            ProfilerShort.End();
        }
        private void PerformDeformation(ref HkBreakOffPointInfo pt, bool fromBreakParts, float separatingVelocity)
        {
            ProfilerShort.Begin("PerformDeformation");

            Debug.Assert(Sync.IsServer, "Function PerformDeformation should not be called from client");

            var mass = this.Mass;
            if (IsStatic)
            {
                mass = pt.CollidingBody.Mass;
            }
            
            float velocity = separatingVelocity;
            float deltaV = pt.BreakingImpulse / mass;

            // Calculate deformation offset
            float deformationOffset = 0.3f + Math.Max(0, (Math.Abs(velocity) - deltaV) / 15);
            deformationOffset *= 2;
            deformationOffset *= MyFakes.DEFORMATION_RATIO;

            const float maxDeformationHardLimit = 25;
            // Happens during copy pasting
            //Debug.Assert(deformationOffset < maxDeformationHardLimit, "Deformation is bigger than maximum.");
            deformationOffset = Math.Min(deformationOffset, maxDeformationHardLimit);

            float explosionRadius = Math.Max(m_grid.GridSize, deformationOffset);
            MyEntity otherEntity = pt.CollidingBody.GetEntity() as MyEntity;
            bool hitVoxel = otherEntity is MyVoxelMap;
            if (hitVoxel)
            {
                // Hardness from 0 to 1
                float hardness = 0.0f;
                deformationOffset *= 1 + hardness;
                explosionRadius *= 1 - hardness;
            }

            float softAreaPlanar = m_grid.GridSizeEnum == MyCubeSize.Large ? 4 : 1.2f; // About 4 meters for large grid and 1.2m for small
            float softAreaVertical = 2 * deformationOffset;

            var invWorld = m_grid.PositionComp.GetWorldMatrixNormalizedInv();
            var pos = Vector3D.Transform(pt.ContactPosition, invWorld);
            var normal = Vector3D.TransformNormal(pt.ContactPoint.Normal, invWorld) * pt.ContactPointDirection;

            bool destroyed = ApplyDeformation(deformationOffset, softAreaPlanar, softAreaVertical, pos, normal, MyDamageType.Deformation);

            if (explosionRadius > 0 && deformationOffset > m_grid.GridSize / 2 && destroyed)
            {
                var info = new ExplosionInfo()
                {
                    Position = pt.ContactPosition,
                    //ExplosionType = destroyed ? MyExplosionTypeEnum.GRID_DESTRUCTION : MyExplosionTypeEnum.GRID_DEFORMATION,
                    ExplosionType = MyExplosionTypeEnum.GRID_DESTRUCTION,
                    Radius = explosionRadius,
                    ModelDebris = destroyed,
                };

                m_explosions.Add(info);
            }
            else
            {
                //cannot be here since its onlyexecuted on server
                //AddCollisionEffect(pt.ContactPoint.Position, normal);
            }

            ProfilerShort.End();
        }
 private bool BreakAtPoint(ref HkBreakOffPointInfo pt, ref HkArrayUInt32 brokenKeysOut)
 {
     return true;
 }
Beispiel #6
0
        private bool PerformDeformation(ref HkBreakOffPointInfo pt, bool fromBreakParts, float separatingVelocity, MyEntity otherEntity)
        {
            if (!m_grid.BlocksDestructionEnabled)
                return false;
            
            ProfilerShort.Begin("PerformDeformation");

            Debug.Assert(Sync.IsServer, "Function PerformDeformation should not be called from client");

            var mass = this.Mass;
            if (IsStatic)
            {
                mass = pt.CollidingBody.Mass;
            }

            float velocity = separatingVelocity;
            float deltaV = pt.BreakingImpulse / mass;

            // Calculate deformation offset
            float deformationOffset = 0.3f + Math.Max(0, (Math.Abs(velocity) - deltaV) / 15);
            deformationOffset *= 3;
            deformationOffset *= MyFakes.DEFORMATION_RATIO;

            const float maxDeformationHardLimit = 20;
            // Happens during copy pasting
            //Debug.Assert(deformationOffset < maxDeformationHardLimit, "Deformation is bigger than maximum.");
            deformationOffset = Math.Min(deformationOffset, maxDeformationHardLimit);

            float explosionRadius = Math.Max(m_grid.GridSize, deformationOffset);
            explosionRadius = Math.Min(explosionRadius, 10);
            bool hitVoxel = otherEntity is MyVoxelBase;
            if (hitVoxel)
            {
                // Hardness from 0 to 1
                float hardness = 0.0f;
                deformationOffset *= 1 + hardness;
                explosionRadius *= 1 - hardness;
            }

            float softAreaPlanar = m_grid.GridSizeEnum == MyCubeSize.Large ? 4 : 1.2f; // About 4 meters for large grid and 1.2m for small
            float softAreaVertical = 1.5f * deformationOffset;

            var invWorld = m_grid.PositionComp.WorldMatrixNormalizedInv;
            var pos = Vector3D.Transform(pt.ContactPosition, invWorld);
            var velAtPoint = GetVelocityAtPoint(pt.ContactPosition);
            if (!velAtPoint.IsValid() || velAtPoint == Vector3.Zero)
                velAtPoint = pt.ContactPoint.Normal;
            var len = velAtPoint.Normalize();
            Vector3 normal;
            if (len > 5)
            {
                normal = Vector3.TransformNormal(velAtPoint, invWorld) * pt.ContactPointDirection;
                normal.Normalize();
            }
            else
                normal = pt.ContactPointDirection * pt.ContactPoint.Normal;
            int destroyed = ApplyDeformation(deformationOffset, softAreaPlanar, softAreaVertical, pos, normal, MyDamageType.Deformation, attackerId: otherEntity != null ? otherEntity.EntityId : 0);
            if (destroyed != 0)
            {
                if (len > 1)
                    len = len / 10;
                RigidBody.ApplyPointImpulse(-velAtPoint *0.3f* Math.Min(destroyed * len * (Mass / 5), Mass * 5), pt.ContactPoint.Position);
                RigidBody.Gravity = Vector3.Zero;
                DisableGravity = 1;
            }
            if (explosionRadius > 0 && deformationOffset > m_grid.GridSize / 2 && destroyed != 0)
            {
                var info = new ExplosionInfo()
                {
                    Position = pt.ContactPosition + pt.ContactPointDirection * pt.ContactPoint.Normal * explosionRadius * 0.5f,
                    //ExplosionType = destroyed ? MyExplosionTypeEnum.GRID_DESTRUCTION : MyExplosionTypeEnum.GRID_DEFORMATION,
                    ExplosionType = MyExplosionTypeEnum.GRID_DESTRUCTION,
                    Radius = explosionRadius,
                    ShowParticles = (otherEntity is MyVoxelPhysics) == false && (otherEntity is MyTrees) == false,
                    GenerateDebris = true
                };
                m_explosions.Add(info);
            }
            else
            {
                //cannot be here since its onlyexecuted on server
                //AddCollisionEffect(pt.ContactPoint.Position, normal);
            }
            ProfilerShort.End();
            return destroyed != 0;
        }
Beispiel #7
0
 private bool PerformDeformationOnGroup(MyEntity entity, MyEntity other, ref HkBreakOffPointInfo pt, float separatingVelocity)
 {
     bool destroyed = false;
     var group = MyWeldingGroups.Static.GetGroup((MyEntity)entity);
     if (group != null)
     {
         foreach (var node in group.Nodes)
         {
             if (node.NodeData.MarkedForClose)
                 continue;
             m_tmpEntities.Add(node.NodeData);
         }
         foreach (var node in m_tmpEntities)
         {
             var gp = node.Physics as MyGridPhysics;
             if (gp == null || gp.Entity.PositionComp.WorldAABB.Contains(pt.ContactPosition) == ContainmentType.Disjoint)
                 continue;
             destroyed |= gp.PerformDeformation(ref pt, false, separatingVelocity, other as MyEntity);
         }
         m_tmpEntities.Clear();
     }
     return destroyed;
 }
Beispiel #8
0
        private bool BreakAtPoint(ref HkBreakOffPointInfo pt, ref HkArrayUInt32 brokenKeysOut)
        {
            //if (pt.BreakingImpulse < Shape.BreakImpulse * 0.75f && MyUtils.GetRandomInt(3) != 0)
                //return false;
            if(RigidBody == null || pt.CollidingBody == null)
            {
                VRage.Trace.MyTrace.Send(VRage.Trace.TraceWindow.Analytics, string.Format("BreakAtPoint:Breaking body {0} null", RigidBody == null ? "A" : "B"));
                return false;
            }
            var separatingVelocity = Math.Abs(HkUtils.CalculateSeparatingVelocity(RigidBody, pt.CollidingBody, ref pt.ContactPoint));
            //if (separatingVelocity < 2)
            //    return false;
            var otherEntity = pt.CollidingBody.GetEntity(0);
            if (otherEntity is Sandbox.Game.WorldEnvironment.MyEnvironmentSector) //jn:HACK //ab:HACK
                return false;
            if (otherEntity.GetTopMostParent() == Entity)
                return false;
            pt.ContactPosition = ClusterToWorld(pt.ContactPoint.Position);

            var destroyed = PerformDeformationOnGroup((MyEntity)Entity, (MyEntity)otherEntity, ref pt, separatingVelocity);
            pt.ContactPointDirection *= -1;
            destroyed |= PerformDeformationOnGroup((MyEntity)otherEntity, (MyEntity)Entity, ref pt, separatingVelocity);
            return destroyed;
        }
Beispiel #9
0
        private bool BreakAtPoint(ref HkBreakOffPointInfo pt, ref HkArrayUInt32 brokenKeysOut)
        {
            //if (pt.BreakingImpulse < Shape.BreakImpulse * 0.75f && MyUtils.GetRandomInt(3) != 0)
                //return false;
            if(RigidBody == null || pt.CollidingBody == null)
            {
                VRage.Trace.MyTrace.Send(VRage.Trace.TraceWindow.Analytics, string.Format("BreakAtPoint:Breaking body {0} null", RigidBody == null ? "A" : "B"));
                return false;
            }
            var separatingVelocity = Math.Abs(HkUtils.CalculateSeparatingVelocity(RigidBody, pt.CollidingBody, ref pt.ContactPoint));
            if (Math.Abs(separatingVelocity) < 2)
                return false;
            var otherEntity = pt.CollidingBody.GetEntity(0);
            pt.ContactPosition = ClusterToWorld(pt.ContactPoint.Position);

            var destroyed = false;
            var group = MyWeldingGroups.Static.GetGroup((MyEntity)Entity);
            if (group != null)
            {
                foreach (var node in group.Nodes)
                {
                    m_tmpEntities.Add(node.NodeData);
                }
                foreach (var node in m_tmpEntities)
                {
                    if (node.MarkedForClose)
                        continue;
                    var gp = node.Physics as MyGridPhysics;
                    if (gp == null)
                        continue;
                    destroyed |= gp.PerformDeformation(ref pt, false, separatingVelocity, otherEntity as MyEntity);
                }
                m_tmpEntities.Clear();
            }
            group = MyWeldingGroups.Static.GetGroup((MyEntity)otherEntity);
            if (group != null)
            {
                foreach (var node in group.Nodes)
                {
                    m_tmpEntities.Add(node.NodeData);
                }

                pt.ContactPointDirection *= -1;
                foreach (var node in m_tmpEntities)
                {
                    if (node.MarkedForClose)
                        continue;
                    var gp = node.Physics as MyGridPhysics;
                    if (gp == null)
                        continue;
                    destroyed |= gp.PerformDeformation(ref pt, false, separatingVelocity, Entity as MyEntity);
                }
            }
            return destroyed;
        }