Exemplo n.º 1
0
        protected void CutOutFromVoxel(MyVoxelMap voxelMap, ref BoundingSphere bigSphereForTunnel)
        {
            if (!IsDummy)
            {
                if (MyMultiplayerGameplay.IsRunning)
                {
                    MyMultiplayerGameplay.Static.CutOut(voxelMap, ref bigSphereForTunnel);
                }

                //remove decals
                MyDecals.HideTrianglesAfterExplosion(voxelMap, ref bigSphereForTunnel);

                //cut off
                MyVoxelGenerator.CutOutSphereFast(voxelMap, bigSphereForTunnel);


                if (MySession.Is25DSector)
                {
                    //  Create debris rocks thrown from the explosion
                    MyExplosionDebrisVoxel.CreateExplosionDebris(ref bigSphereForTunnel, 1, CommonLIB.AppCode.Networking.MyMwcVoxelMaterialsEnum.Ice_01, MinerWars.AppCode.Game.Managers.Session.MySession.PlayerShip.GroupMask, voxelMap);

                    BoundingBox boundingBox = BoundingBoxHelper.InitialBox;
                    BoundingBoxHelper.AddSphere(ref bigSphereForTunnel, ref boundingBox);

                    // we need local list because this method can be called from inside of the loop

                    var elements = MyEntities.GetElementsInBox(ref boundingBox);
                    foreach (var el in elements)
                    {
                        MyEntity entity = ((MinerWars.AppCode.Game.Physics.MyPhysicsBody)el.GetRigidBody().m_UserData).Entity;
                        MyExplosionDebrisVoxel debris = entity as MyExplosionDebrisVoxel;

                        if (debris == null)
                        {
                            continue;
                        }

                        Vector3 awayDirection = debris.GetPosition() - bigSphereForTunnel.Center;

                        debris.Physics.AddForce(
                            MinerWars.AppCode.Game.Physics.MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE,
                            awayDirection * MyExplosionsConstants.EXPLOSION_FORCE_RADIUS_MULTIPLIER * 100000,
                            bigSphereForTunnel.Center,
                            MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.GetRandomVector3Normalized() * 10000);
                    }

                    elements.Clear();
                }

                PlayVoxelCutCue();
            }
        }
        public static void CreateExplosionDebris(ref BoundingSphere explosionSphere, float voxelsCountInPercent, MyMwcVoxelMaterialsEnum voxelMaterial, MyGroupMask groupMask, MyVoxelMap voxelMap)
        {
            MyCommonDebugUtils.AssertDebug((voxelsCountInPercent >= 0.0f) && (voxelsCountInPercent <= 1.0f));
            MyCommonDebugUtils.AssertDebug(explosionSphere.Radius > 0);

            Render.MyRender.GetRenderProfiler().StartProfilingBlock("CreateExplosionDebris");

            Render.MyRender.GetRenderProfiler().StartProfilingBlock("Matrices");

            //  This matrix will rotate all newly created debrises, so they won't apper as alligned with coordinate system
            Matrix randomRotationMatrix = Matrix.CreateRotationX(MyMwcUtils.GetRandomRadian()) * Matrix.CreateRotationY(MyMwcUtils.GetRandomRadian());

            float highScale = MathHelper.Clamp(explosionSphere.Radius * DebrisScaleUpper, 0, DebrisScaleClamp);
            float lowScale  = highScale * (DebrisScaleLower / DebrisScaleUpper);

            int objectsToGenerate = (int)(m_positionOffsets.Count * voxelsCountInPercent * MyRenderConstants.RenderQualityProfile.ExplosionDebrisCountMultiplier);

            long dbgObjectsGenerated = 0;

            Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_positionOffsets");

            for (int i = 0; i < m_positionOffsets.Count; i++)
            {
                //  IMPORTANT: If you place explosion debris exactly in the center of an explosion, JLX will fail or end in endless loop
                //  Probably it's because it can't handle external force acting from inside the object.
                if (dbgObjectsGenerated >= objectsToGenerate)
                {
                    break;
                }

                const float cubeInsideSphereMod = 1 / 1.73f; // Resize sphere to fit inside cube

                Vector3 position = m_positionOffsets[i] * explosionSphere.Radius * cubeInsideSphereMod;
                Vector3.Transform(ref position, ref randomRotationMatrix, out position);
                position += explosionSphere.Center;

                MyExplosionDebrisVoxel newObj = Allocate();

                if (newObj != null)
                {
                    //  Check if new object won't intersect any existing triangle - because if yes, then it will decrease JLX performace a lot
                    float          randomNewScale = MyMwcUtils.GetRandomFloat(lowScale, highScale);
                    BoundingSphere sphere         = new BoundingSphere(position, newObj.m_modelLod0.BoundingSphere.Radius * randomNewScale);

                    Render.MyRender.GetRenderProfiler().StartProfilingBlock("GetIntersectionWithSphere");

                    //This takes 4-5ms, is it necessary?
                    // if (MyEntities.GetIntersectionWithSphere(ref sphere) == null)
                    //if (false)
                    {
                        Render.MyRender.GetRenderProfiler().StartProfilingBlock("newObj.Start");
                        newObj.Start(position, randomNewScale, voxelMaterial, groupMask, true);
                        MyEntities.Add(newObj);
                        Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                        /*
                         * Vector3 imp = position - explosionSphere.Center;
                         * imp.Normalize();
                         * imp *= MyExplosionsConstants.EXPLOSION_STRENGTH_IMPULSE;
                         *
                         * newObj.Physics.AddForce(PhysicsManager.Physics.MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, imp, explosionSphere.Center, Vector3.Zero);
                         */
                        if (MinerWars.AppCode.Game.Explosions.MyExplosion.DEBUG_EXPLOSIONS)
                        {
                            m_debugVoxelSpheres.Add(sphere);
                        }

                        dbgObjectsGenerated++;
                    }
                    //else
                    {
                        //  Put back to object pool
                        //newObj.Close();
                    }

                    Render.MyRender.GetRenderProfiler().EndProfilingBlock();

                    //if (newObj.Physics.Enabled)
                    //  newObj.Physics.Enabled = false;
                    // newObj.Physics.CollisionLayer = MyConstants.COLLISION_LAYER_UNCOLLIDABLE;
                }
            }

            Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            Render.MyRender.GetRenderProfiler().EndProfilingBlock();
        }