protected override void Start(Vector3 position, float scale, MyGroupMask groupMask, bool explosionType) { base.Start(position, scale, groupMask, explosionType); //apply random rotation impulse Physics.AngularVelocity = new Vector3(MyMwcUtils.GetRandomRadian(), MyMwcUtils.GetRandomRadian(), MyMwcUtils.GetRandomRadian()); Physics.Enabled = true; InitDrawTechniques(); }
public static void CreateExplosionDebris(ref BoundingSphere explosionSphere, MyGroupMask groupMask, MyEntity entity, MyVoxelMap voxelMap, ref BoundingBox bb) { // Number of debris is random, but not more than size of the offset array float scaleMul = explosionSphere.Radius / 4.0f; GeneratePositions(bb); foreach (Vector3 positionInLocalSpace in m_positions) { var positionInWorldSpace = Vector3.Transform(positionInLocalSpace, entity.WorldMatrix); MyExplosionDebrisModel newObj = m_objectPool.Allocate(true); if (newObj == null) { continue; } // 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(scaleMul / 4, scaleMul); var sphere = new BoundingSphere(positionInWorldSpace, newObj.m_modelLod0.BoundingSphere.Radius * randomNewScale); MyEntity myEntitiesGetIntersectionWithSphere = MyEntities.GetIntersectionWithSphere(ref sphere); if ((myEntitiesGetIntersectionWithSphere == null || myEntitiesGetIntersectionWithSphere == entity) && (voxelMap == null || !voxelMap.DoOverlapSphereTest(sphere.Radius, sphere.Center))) { if (Vector3.DistanceSquared(positionInWorldSpace, explosionSphere.Center) > MyMwcMathConstants.EPSILON_SQUARED) { newObj.Start(positionInWorldSpace, randomNewScale, groupMask, true); newObj.Physics.LinearVelocity = GetDirection(positionInWorldSpace, explosionSphere.Center) * MyExplosionsConstants.EXPLOSION_DEBRIS_SPEED; MyEntities.Add(newObj); if (MyExplosion.DEBUG_EXPLOSIONS) { m_debugVoxelSpheres.Add(sphere); } } } else { // Put back to object pool newObj.Close(); } } }
// IMPORTANT: This class isn't realy inicialized by constructor, but by Start() // So don't initialize members here, do it in Start() protected virtual void Start(Vector3 position, float scale, MyGroupMask groupMask, bool explosionType) { Save = false; m_explosionType = explosionType; m_createdTime = MyMinerGame.TotalGamePlayTimeInMilliseconds; Matrix worldMat = Matrix.Identity;//; Matrix.CreateScale(scale); Scale = scale; worldMat.Translation = position; SetWorldMatrix(worldMat); // This is here because we are restarting the object after it was sleeping in object pool this.Physics.Clear(); if (m_explosionType) { NeedsUpdate = true; this.Physics.PlayCollisionCueEnabled = true; //reset the physical radius of object! if ((this.Physics as MyPhysicsBody).GetRBElementList().Count > 0) { MyRBElement element = (this.Physics as MyPhysicsBody).GetRBElementList()[0]; (element as MyRBSphereElement).Radius = this.ModelLod0.BoundingSphere.Radius * scale; } //this.Physics.Enabled = true; this.Physics.GroupMask = groupMask; this.Physics.AngularDamping = MySession.Is25DSector ? 0.5f : 0.1f; //this.Physics.Update(); } else { NeedsUpdate = false; } }
public void Start(float playerDamage, float damage, float empDamage, MyExplosionTypeEnum type, BoundingSphere explosionSphere, int lifespanInMiliseconds, MyExplosionForceDirection explosionForceDirection, MyGroupMask groupMask, bool createExplosionDebris, int cascadeLevel = 0, MyEntity hitEntity = null, float particleScale = 1.0f, MyEntity ownerEntity = null, bool affectVoxels = true, bool applyForceAndDamage = true, bool createDecals = true, Vector3?direction = null, bool forceDebris = false, bool playSound = false) { MyExplosionInfo info = new MyExplosionInfo(playerDamage, damage, empDamage, explosionSphere, type, playSound) { LifespanMiliseconds = lifespanInMiliseconds, ExplosionForceDirection = explosionForceDirection, GroupMask = groupMask, ExplosionFlags = MyExplosionFlags.CREATE_PARTICLE_EFFECT, CascadeLevel = cascadeLevel, HitEntity = hitEntity, ParticleScale = particleScale, OwnerEntity = ownerEntity, Direction = direction, VoxelCutoutScale = 1.0f, }; info.AffectVoxels = affectVoxels; info.ApplyForceAndDamage = applyForceAndDamage; info.CreateDebris = createExplosionDebris; info.CreateDecals = createDecals; info.ForceDebris = forceDebris; info.VoxelExplosionCenter = explosionSphere.Center; Start(ref info); }
public static void CreateExplosionDebris(ref BoundingSphere explosionSphere, MyGroupMask groupMask, MyEntity entity, MyVoxelMap voxelMap) { CreateExplosionDebris(ref explosionSphere, groupMask, entity, voxelMap, ref entity.GetModelLod0().BoundingBox); }
public void Start(Vector3 position, float scale, MyMwcVoxelMaterialsEnum voxelMaterial, MyGroupMask groupMask, bool explosionType) { base.Start(position, scale, groupMask, explosionType); if (explosionType) { //apply random rotation impulse base.Physics.AngularVelocity = new Vector3(MyMwcUtils.GetRandomRadian(), MyMwcUtils.GetRandomRadian(), MyMwcUtils.GetRandomRadian()) * 0.7f; if (base.Physics.AngularVelocity.Length() == 0) { Debug.Assert(false); } if (!Physics.Enabled) { Physics.Enabled = true; } } else { if (Physics.Enabled) { Physics.Enabled = false; } } VoxelMaterial = voxelMaterial; InitDrawTechniques(); RenderObjects[0].NeedsResolveCastShadow = true; RenderObjects[0].FastCastShadowResolve = true; }
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(); }