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(); }