private void FollowToRoutePosition(MySmallShipBot bot) { // Fly to visible position, if too close look for new visible position if (Vector3.DistanceSquared(m_followPosition.Value, bot.GetPosition()) < 5 * 5) { m_followPosition = null; } else { bot.Move(m_followPosition.Value, m_followPosition.Value, bot.WorldMatrix.Up, false, 1, 2); if (m_stuckTimer > STUCK_TIME) { if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE) { m_followPosition = null; } else { m_followPosition = m_stuckPosition + MyMwcUtils.GetRandomVector3Normalized() * 1000; } } else if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE) { ResetStuck(bot); } else { m_stuckTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } } }
static void UpdateExplosionLines() { foreach (LinkedListNode <ExplosionLine> explosionLine in m_preallocatedExplosionLines) { explosionLine.Value.ActualTime += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS; if (explosionLine.Value.ActualTime > explosionLine.Value.TotalTime) { m_preallocatedExplosionLines.MarkForDeallocate(explosionLine); continue; } explosionLine.Value.ActualDir = Vector3.Lerp(explosionLine.Value.StartDir, explosionLine.Value.EndDir, explosionLine.Value.ActualTime / (float)explosionLine.Value.TotalTime); } m_preallocatedExplosionLines.DeallocateAllMarked(); if (m_State == NuclearState.FADE_IN && MyMwcUtils.GetRandomFloat(0, 1) > 0.75f) { ExplosionLine line = m_preallocatedExplosionLines.Allocate(true); if (line != null) { line.TotalTime = 5000; line.ActualTime = 0; line.StartDir = MyMwcUtils.GetRandomVector3Normalized(); Vector3 rotDir = MyMwcUtils.GetRandomVector3Normalized(); Matrix rotMatrix = Matrix.CreateFromAxisAngle(rotDir, 0.3f); line.EndDir = Vector3.Transform(line.StartDir, rotMatrix); } } }
public static void Start() { Clear(); IsActive = true; startTime = MyMinerGame.TotalGamePlayTimeInMilliseconds; ambientSound = MyAudio.AddCue3D(MySoundCuesEnum.SfxSolarWind, MyCamera.Position + MyCamera.ForwardVector * MaxSoundDistance, Vector3.Forward, Vector3.Up, Vector3.Zero, 0); sphereCenter = MyCamera.Position + MyCamera.ForwardVector * 400; for (int i = 0; i < SmokeCount; i++) { Vector3 pos = sphereCenter + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, SmokeSphereRadius); var smokePart = new SmokeParticle { Angle = MyMwcUtils.GetRandomRadian(), Color = Vector4.Zero, AngularVelocity = MyMwcUtils.GetRandomFloat(-0.15f, 0.15f), Pos = pos, Velocity = MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 30f) }; smokeParticles.Add(smokePart); } }
// I used this method only when we didn't have real persistant sectors... for fly-through animations List <MyVoxelMapImpostor> CreateFakeImpostors() { List <MyVoxelMapImpostor> ret = new List <MyVoxelMapImpostor>(ImpostorProperties.ImpostorsCount); for (int i = 0; i < ImpostorProperties.ImpostorsCount; i++) { Vector3 sectorCenter = Vector3.Zero; float randomDistance = MyMwcUtils.GetRandomFloat(ImpostorProperties.MinDistance, ImpostorProperties.MaxDistance); Vector3 randomPositionWithinSector = MyMwcUtils.GetRandomVector3Normalized() * randomDistance; float radius = MyMwcUtils.GetRandomFloat(ImpostorProperties.MinRadius, ImpostorProperties.MaxRadius); Vector3 position = sectorCenter + randomPositionWithinSector; float angle = MyMwcUtils.GetRandomRadian(); ret.Add(new MyVoxelMapImpostor(position, radius, angle)); } // Sort by distance (back-to-front) so alpha won't make problems on overlapping quads ret.Sort(); return(ret); }
void UpdateGoals(MySmallShipBot bot) { moveTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000; lookTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000; up = MyMwcUtils.GetRandomVector3Normalized() * 1000; shoot = MyMwcUtils.GetRandomBool(2); }
// This method will start sun wind. Or if there is one coming, this will reset it so it will start again. public static void Start() { IsActive = true; //m_burningCue = MyAudio.AddCue3D(MySoundCuesEnum.SfxSolarWind, m_initialSunWindPosition, m_directionFromSunNormalized, Vector3.Up, Vector3.Zero); const int meteorsCount = 5; //const int frontDistance = 1000; //const int sideDistance = 3000; const int minSpeed = 1000; const int maxSpeed = 4000; //Vector3 sphereCenter = MyCamera.Position + MyCamera.ForwardVector * frontDistance - MyCamera.LeftVector * sideDistance; Vector3 sphereCenter = MyCamera.Position + MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized() * 10000; //Vector3 windForwardDirection = MyCamera.LeftVector ; int i = 0; while (i < meteorsCount) { //float distance = MyMwcUtils.GetRandomFloat(0, sphereRadius); //Vector3 position = sphereCenter + MyMwcUtils.GetRandomVector3Normalized() * new Vector3(distance, distance, distance); //Vector3 meteorDirection = (windForwardDirection + (MyMwcUtils.GetRandomVector3Normalized() * 0.05f)) * MyMwcUtils.GetRandomInt(minSpeed, maxSpeed); //Vector3 meteorDirection = -MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized();// MyMwcUtils.GetRandomVector3HemisphereNormalized(-MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized()); Vector3 meteorDirection = MyMwcUtils.GetRandomVector3HemisphereNormalized(-MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized()); Vector3 position = sphereCenter + meteorDirection * MyMwcUtils.GetRandomInt(100, 5000); //float normalizedDistance = distance / sphereRadius; float size = MyMwcUtils.GetRandomInt(minSize, maxSize); MyLine line = new MyLine(position, position + meteorDirection * 100); MyIntersectionResultLineBoundingSphere?result = MyEntities.GetIntersectionWithLineAndBoundingSphere(ref line, null, null, 1, null, true); if (result != null) { //Do not create meteors colliding with base if (!(result.Value.PhysObject is MyMeteor)) { continue; } } Matrix worldMatrix = Matrix.CreateFromAxisAngle(MyMwcUtils.GetRandomVector3Normalized(), MyMwcUtils.GetRandomFloat(0, MathHelper.Pi)); worldMatrix.Translation = position; MyMeteor meteor = MyMeteor.GenerateMeteor(size, worldMatrix, position, m_fireMeteorMaterials[MyMwcUtils.GetRandomInt(0, m_fireMeteorMaterials.Count)]); float speed = MyMwcUtils.GetRandomInt(minSpeed, maxSpeed); meteor.Start(meteorDirection * speed, MyMwcUtils.GetRandomFloat(0, 1) > 0.92f ? 101 : 100); i++; } }
public static void Draw() { if (!IsActive) { return; } // main smoke foreach (SmokeParticle part in smokeParticles) { MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.Smoke, part.Color, part.Pos, 900, part.Angle, 0, true); } float darkeningPhase; float dt; GetDarkeningPhase(out darkeningPhase, out dt); // small pieces of debris if (darkeningPhase > 0.2) { var color = new Vector4(1, 1, 1, darkeningPhase); for (int i = 0; i < 100; i++) { Vector3 pos = MyCamera.Position + GetRandomVector3CircleNormalizedFixed(MyCamera.ForwardVector) * MyMwcUtils.GetRandomFloat(0, 500) + MyCamera.ForwardVector * 20; MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.particle_stone, color, pos, MyMwcUtils.GetRandomFloat(0.008f, 0.05f), MyMwcUtils.GetRandomRadian()); } for (int i = 0; i < 100; i++) { Vector3 pos = MyCamera.Position + GetRandomVector3CircleNormalizedFixed(MyCamera.ForwardVector) * MyMwcUtils.GetRandomFloat(0, 500) + MyCamera.ForwardVector * 20; MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.Sparks_b, color, pos, MyMwcUtils.GetRandomFloat(0.008f, 0.05f), MyMwcUtils.GetRandomRadian()); } } // storm aftersparks foreach (ElectricStorm storm in storms) { MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.Sparks_a, new Vector4(1f, 1f, 1f, 1f), storm.Position + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 50), MyMwcUtils.GetRandomFloat(10, 20), MyMwcUtils.GetRandomRadian()); } }
internal bool TrySwitchExploreSearch(MySmallShipBot bot) { Vector3 flyTo = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 100); if (bot.TryTestPosition(flyTo, bot.GetPosition())) { m_state = CuriousState.EXPLORE_SEARCHING; return(true); } return(false); }
private static Vector3 GetDirection(Vector3 position, Vector3 sphereCenter) { Vector3 dist = position - sphereCenter; if (MyUtils.IsValid(dist) && MyMwcUtils.HasValidLength(dist)) { return(Vector3.Normalize(dist)); } else { return(MyMwcUtils.GetRandomVector3Normalized()); } }
public static MyMeteor CreateComet(Vector3 position, Vector3 direction) { float size = MyMwcUtils.GetRandomInt(m_sizeMin, m_sizeMax); Matrix worldMatrix = Matrix.CreateFromAxisAngle(MyMwcUtils.GetRandomVector3Normalized(), MyMwcUtils.GetRandomFloat(0, MathHelper.Pi)); worldMatrix.Translation = position; MyMeteor meteor = MyMeteor.GenerateMeteor(size, worldMatrix, position, m_iceMeteorMaterials[MyMwcUtils.GetRandomInt(0, m_iceMeteorMaterials.Count)]); meteor.Start(direction, 953); return(meteor); }
internal static void Start() { IsActive = true; m_startTime = MyMinerGame.TotalGamePlayTimeInMilliseconds; const int meteorsCount = 3; const int minSpeed = 1200; const int maxSpeed = 1400; Vector3 sphereCenter = MyCamera.Position + MyCamera.ForwardVector * m_frontDistance - MyCamera.LeftVector * m_sideDistance; Vector3 windForwardDirection = MyCamera.LeftVector; for (int i = 0; i < meteorsCount; i++) { Vector3 meteorDirection = (windForwardDirection + (MyMwcUtils.GetRandomVector3Normalized() * 0.001f)) * MyMwcUtils.GetRandomInt(minSpeed, maxSpeed); float distance = MyMwcUtils.GetRandomFloat(1000, 1500); CreateComet(sphereCenter + MyMwcUtils.GetRandomVector3Normalized() * new Vector3(distance, distance, distance), meteorDirection); } }
public static MyMeteor GenerateMeteor(float sizeInMeters, Matrix worldMatrix, Vector3 position, MyMwcVoxelMaterialsEnum material) { int size = MySectorGenerator.FindAsteroidSize(sizeInMeters, MyMwcObjectBuilder_StaticAsteroid.AsteroidSizes); asteroids.Clear(); MyMwcObjectBuilder_Meteor.GetAsteroids(size, MyStaticAsteroidTypeSetEnum.A, asteroids); int rndIndex = MyMwcUtils.GetRandomInt(0, asteroids.Count); var builder = new MyMwcObjectBuilder_Meteor(asteroids[rndIndex], material); builder.PositionAndOrientation.Position = position; builder.PositionAndOrientation.Forward = MyMwcUtils.GetRandomVector3Normalized(); builder.PositionAndOrientation.Up = MyMwcUtils.GetRandomVector3Normalized(); builder.UseModelTechnique = false; MyMeteor meteor = (MyMeteor)MyEntities.CreateFromObjectBuilderAndAdd(null, builder, worldMatrix); meteor.m_size = sizeInMeters; return(meteor); }
private bool GetSafePositionForSpawn(MyMwcObjectBuilder_SmallShip_TypesEnum shipType, out Vector3?safePosition) { var shipRadius = MyModels.GetModelOnlyData(MyShipTypeConstants.GetShipTypeProperties(shipType).Visual.ModelLod0Enum).BoundingSphere.Radius; for (int c = MAX_SPAWN_ATTEMPTS; c-- != 0;) { Vector3 randomPointInSphere = MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 1) * BoundingSphereRadius; // Random point in sphere Vector3 newTestPos = GetPosition() + randomPointInSphere; BoundingSphere bsphere = new BoundingSphere(newTestPos, shipRadius); MyEntity col = MyEntities.GetIntersectionWithSphere(ref bsphere); if (col == null) { safePosition = newTestPos; return(true); } } safePosition = null; return(false); }
/// <summary> /// Once per few frames, generates a flicker. /// Actually only manipulates the m_scale vector in order to simulate flicker appearance. /// </summary> private void GenerateFlicker() { // TODO simon how do I make this independent of FPS? bool startFlickerNow = MyMwcUtils.GetRandomBool(MyHologramConstants.FLICKER_FREQUENCY); if (startFlickerNow && m_flickerElapsedMilliseconds > MyHologramConstants.FLICKER_DURATION) { m_flickerElapsedMilliseconds = 0; m_flickerScale = MyMwcUtils.GetRandomVector3Normalized(); } if (m_flickerElapsedMilliseconds < MyHologramConstants.FLICKER_DURATION) { float flickerProgress = m_flickerElapsedMilliseconds / MyHologramConstants.FLICKER_DURATION; Vector3 maxFlickerScale = MyHologramConstants.FLICKER_MAX_SIZE * Vector3.One; m_scale = Vector3.Lerp(maxFlickerScale, m_flickerScale, flickerProgress); } else { m_scale = Vector3.One; } m_flickerElapsedMilliseconds += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS; }
private void FollowPath(MySmallShipBot bot) { if (m_currentPathPosition >= m_followPath.Count) { m_followPath = null; // reached the goal or got stuck } else if (Vector3.DistanceSquared(m_followPath[m_currentPathPosition], bot.GetPosition()) < PATH_NEAR_DISTANCE_SQR) { m_currentPathPosition++; // next waypoint reached } else { bot.Move(m_followPath[m_currentPathPosition], m_followPath[m_currentPathPosition], bot.WorldMatrix.Up, false, 1, 2); if (m_stuckTimer > STUCK_TIME) { if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE) { m_currentPathPosition++; // try skipping ahead to the next waypoint instead of getting stuck right away ResetStuck(bot); } else { m_followPath[m_currentPathPosition] += MyMwcUtils.GetRandomVector3Normalized() * 1000; // jitter the sub-goal } } else if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE) { ResetStuck(bot); } else { m_stuckTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; } } }
public void CalculateStartPosition(float elapsedTime, Matrix worldMatrix, float userScale, out Vector3 startOffset, out Vector3 startPosition) { Vector3 currentOffsetUntransformed; Offset.GetInterpolatedValue <Vector3>(elapsedTime, out currentOffsetUntransformed); float currentSize; Size.GetInterpolatedValue <float>(elapsedTime, out currentSize); currentSize *= MyMwcUtils.GetRandomFloat(RadiusMin, RadiusMax) * userScale; Vector3 localPos = Vector3.Zero; Vector3 worldOffset; Vector3.Transform(ref currentOffsetUntransformed, ref worldMatrix, out worldOffset); switch (Type) { case MyParticleEmitterType.Point: localPos = Vector3.Zero; break; case MyParticleEmitterType.Line: localPos = Vector3.Forward * MyMwcUtils.GetRandomFloat(0.0f, currentSize); break; case MyParticleEmitterType.Sphere: localPos = MyMwcUtils.GetRandomVector3Normalized() * currentSize; break; case MyParticleEmitterType.Box: float currentSizeHalf = currentSize * 0.5f; localPos = new Vector3( MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.GetRandomFloat(-currentSizeHalf, currentSizeHalf), MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.GetRandomFloat(-currentSizeHalf, currentSizeHalf), MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.GetRandomFloat(-currentSizeHalf, currentSizeHalf) ); break; case MyParticleEmitterType.Hemisphere: localPos = MyMwcUtils.GetRandomVector3HemisphereNormalized(Vector3.Forward) * currentSize; break; case MyParticleEmitterType.Circle: localPos = MyMwcUtils.GetRandomVector3CircleNormalized() * currentSize; break; default: System.Diagnostics.Debug.Assert(false); break; } Vector3 worldPos; if (DirToCamera) { Matrix WorldView = worldMatrix * MyCamera.ViewMatrix; WorldView.Translation += currentOffsetUntransformed; Matrix newWorld = WorldView * Matrix.Invert(MyCamera.ViewMatrix); Vector3 dir = MyCamera.Position - newWorld.Translation; dir.Normalize(); Matrix matrix = MyMath.MatrixFromDir(dir); matrix.Translation = newWorld.Translation; Vector3.Transform(ref localPos, ref matrix, out worldPos); startOffset = newWorld.Translation; startPosition = worldPos; } else { Vector3.TransformNormal(ref localPos, ref worldMatrix, out worldPos); startOffset = worldOffset; startPosition = worldOffset + worldPos; } }
public override void UpdateBeforeSimulation() { try { MyRender.GetRenderProfiler().StartProfilingBlock("MyCannonShot.UpdateBeforeSimulation"); if (this.WorldMatrix.Translation != m_previousPosition) { MyLine line = new MyLine(this.WorldMatrix.Translation, m_previousPosition); MyDangerZones.Instance.Notify(line, OwnerEntity); } // Kill this missile if (m_isExploded && !m_wasPenetration) { // Create explosion MyExplosion newExplosion = MyExplosions.AddExplosion(); if (newExplosion != null) { float radius = MyMwcUtils.GetRandomFloat(m_ammoProperties.ExplosionRadius - 2, m_ammoProperties.ExplosionRadius + 2); BoundingSphere explosionSphere = new BoundingSphere((m_collisionPoint.HasValue ? m_collisionPoint.Value : GetPosition()), radius); MyExplosionInfo info = new MyExplosionInfo(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, explosionSphere, m_explosionType, true) { GroupMask = Physics.GroupMask, CascadeLevel = CascadedExplosionLevel, HitEntity = m_collidedEntity, OwnerEntity = this.OwnerEntity, Direction = WorldMatrix.Forward, ParticleScale = 1.5f, VoxelExplosionCenter = explosionSphere.Center + radius * WorldMatrix.Forward * 0.6f, }; info.CreateParticleEffect = !m_hasExplosion; newExplosion.Start(ref info); } if (m_collidedEntity != null && !m_collidedEntity.IsExploded()) { m_collidedEntity.Physics.AddForce( MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, WorldMatrix.Forward * MyMissileConstants.HIT_STRENGTH_IMPULSE, GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 2, MyMissileConstants.HIT_STRENGTH_IMPULSE * MyMwcUtils.GetRandomVector3Normalized()); } MarkForClose(); return; } base.UpdateBeforeSimulation(); // Chech timeout and max distance if ((m_elapsedMiliseconds > MyCannonConstants.SHOT_TIMEOUT) || (Vector3.Distance(this.WorldMatrix.Translation, m_origin) >= m_ammoProperties.MaxTrajectory)) { MarkForClose(); return; } Matrix orientation = GetWorldRotation(); // Update thruster cue/sound MyAudio.UpdateCuePosition(m_thrusterCue, this.WorldMatrix.Translation, orientation.Forward, orientation.Up, this.Physics.LinearVelocity); Vector3 pos = this.WorldMatrix.Translation; if (m_penetratedVoxelMap == null) { if (m_smokeEffect != null) { m_smokeEffect.WorldMatrix = WorldMatrix; } } /* * if (m_wasPenetration) * { * // Create explosion * MyExplosion newExplosion = MyExplosions.AddExplosion(); * if (newExplosion != null) * { * float radius = MyMwcUtils.GetRandomFloat(1, 2); * float particleScale = 2.2f; // must be large enough to cover the hole * newExplosion.StartWithPositionOffset(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_explosionType, m_penetrationOrigin - WorldMatrix.Forward * 2, radius, MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadedExplosionLevel, particleScale: particleScale, hitEntity: m_collidedEntity, ownerEntity: m_ownerEntity); * } * m_wasPenetration = false; * m_hasExplosion = true; * } */ if (m_usedAmmo.AmmoType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Proximity_Explosive) { // Look for small ships in shots's proximity BoundingSphere boundingSphere = new BoundingSphere(GetPosition(), MyCannonShotConstants.PROXIMITY_DETECTION_RADIUS); BoundingBox boundingBox = new BoundingBox(); BoundingBox.CreateFromSphere(ref boundingSphere, out boundingBox); var elements = MyEntities.GetElementsInBox(ref boundingBox); for (int i = 0; i < elements.Count; i++) { var rigidBody = (MyPhysicsBody)elements[i].GetRigidBody().m_UserData; var entity = rigidBody.Entity; if (!(entity is MinerWars.AppCode.Game.Entities.MySmallShip)) { continue; } if (entity == OwnerEntity) { continue; } if (entity == this) { continue; } Explode(entity); break; } elements.Clear(); } /* * if (m_usedAmmo.AmmoType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Tunnel_Buster) * { * m_cuttingSphere.Center = GetPosition(); * * // We found voxel so lets make tunel into it * MyPhysObjectBase collisionResult = MyEntities.GetIntersectionWithSphere(ref m_cuttingSphere, this, (MySmallShip)Parent); * if (collisionResult is MyVoxelMap) * { * MyVoxelMap voxelMap = collisionResult as MyVoxelMap; * if (m_penetratedVoxelMap == null) * { * m_penetratedVoxelMap = voxelMap; * m_penetrationOrigin = GetPosition(); * } * * Game.Voxels.MyVoxelGenerator.CutOutSphereFast(voxelMap, m_cuttingSphere); * } * } */ /* * if (m_usedAmmo.AmmoType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Tunnel_Buster) * { * if (m_penetratedVoxelMap != null) * { * //MyCannonShotConstants.BUSTER_PENETRATION_LENGTH * float busterPenetrationLength = m_ammoProperties.ExplosionRadius * 0.75f; * if (Vector3.Distance(m_penetrationOrigin, GetPosition()) >= busterPenetrationLength) * { * m_collisionPoint = GetPosition(); //We want to explode inside voxel, not on collision point * Explode(m_penetratedVoxelMap); * } * } * } */ } finally { MyRender.GetRenderProfiler().EndProfilingBlock(); } }
// Random vector distributed over the circle about normal. // Returns random vector that always lies on circle public static Vector3 GetRandomVector3CircleNormalizedFixed(Vector3 normal) { return(MyMwcUtils.GetRandomVector3Normalized() * normal); }
public static void Update() { // Update only if sun wind is active if (IsActive == false) { return; } float darkeningPhase; float dt; int relTime = GetDarkeningPhase(out darkeningPhase, out dt); if (relTime > MaxTimeMs) { Clear(); return; } MyAudio.UpdateCuePosition(ambientSound, MyCamera.Position + MyCamera.ForwardVector * -MaxSoundDistance * (1 - darkeningPhase), MyCamera.ForwardVector, MyCamera.UpVector, Vector3.Zero); MyAudio.UpdateCueVolume(ambientSound, darkeningPhase * MaxAmbientVolume); // update smoke foreach (SmokeParticle part in smokeParticles) { Vector3 toCamera = (MyCamera.Position - part.Pos); toCamera.Normalize(); float alpha = darkeningPhase * MaxSmokeAlpha; part.Color = new Vector4(alpha, alpha, alpha, alpha); //part.Color.W = darkeningPhase; part.Pos += part.Velocity * dt + toCamera * CenterBias * dt; part.Angle += part.AngularVelocity * dt; } // remove old ice and sparks m_iceList.Clear(); foreach (IceParticle particle in iceParticles) { if (particle.StartTime + 4000 < relTime) { m_iceList.Add(particle); } } foreach (IceParticle ice in m_iceList) { ice.AsteroidEntity.MarkForClose(); Debug.Assert(ice.TrailEffect != null, "ice.TrailEffect != null"); ice.TrailEffect.Stop(); ice.TrailEffect = null; StopCue(ice.Sound); iceParticles.Remove(ice); } int c = 0; while (c < storms.Count) { ElectricStorm storm = storms[c]; if (storm.StartTime + 1500 < relTime) { storms.RemoveAt(c); continue; } c++; } // if its dark add new sparks and ice balls if (darkeningPhase >= 1) { if (storms.Count < MaxSparkCount && MyMwcUtils.GetRandomInt(SparkEveryMs) < dt * 1000.0f) { var storm = new ElectricStorm { Position = MyCamera.Position + MyCamera.ForwardVector * 250 + MyMwcUtils.GetRandomVector3HemisphereNormalized(MyCamera.ForwardVector) * MyMwcUtils.GetRandomFloat(0, 300), StartTime = relTime, Effect = MyParticlesManager.CreateParticleEffect( (int)MyParticleEffectsIDEnum.Damage_Sparks), }; storm.Effect.WorldMatrix = Matrix.CreateTranslation(storm.Position); storm.Effect.AutoDelete = true; storm.Effect.UserScale = 2; storm.Sound = MyAudio.AddCue2D(MySoundCuesEnum.SfxSpark); storms.Add(storm); } if (iceParticles.Count < MaxIceCount && MyMwcUtils.GetRandomInt(IceEveryMs) < dt * 1000.0f) { Vector3 dir = MyMwcUtils.GetRandomVector3HemisphereNormalized(MyCamera.ForwardVector); Vector3 pos = MyCamera.Position + MyCamera.ForwardVector * 250 + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 200) + dir * MyMwcUtils.GetRandomFloat(0, 500); MyMwcObjectBuilder_StaticAsteroid rockModel = MySectorGenerator.GenerateStaticAsteroid(MyMwcUtils.GetRandomFloat(0.1f, 2f), MyStaticAsteroidTypeSetEnum.A, MyMwcVoxelMaterialsEnum.Ice_01, pos, random, asteroidTypes); Matrix matrix = Matrix.CreateFromAxisAngle(MyMwcUtils.GetRandomVector3Normalized(), MyMwcUtils.GetRandomFloat(0, MathHelper.Pi)); matrix.Translation = pos; MyEntity asteroid = MyEntities.CreateFromObjectBuilderAndAdd(null, rockModel, matrix); asteroid.Physics.Enabled = false; asteroid.CastShadows = false; MyParticleEffect effect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_CannonShot); Vector3 velocity = -dir *MyMwcUtils.GetRandomInt(150, 400); iceParticles.Add(new IceParticle { StartTime = relTime, Position = pos, Direction = -dir, AsteroidEntity = asteroid, TrailEffect = effect, RotAxis = MyMwcUtils.GetRandomVector3Normalized(), RotAngle = MyMwcUtils.GetRandomRadian(), AngularVelocity = MyMwcUtils.GetRandomFloat(0.2f, 10f), Velocity = velocity, Sound = MyAudio.AddCue3D(MySoundCuesEnum.WepSniperHighFire2d, pos, dir, dir * -dir, velocity) }); } } // update ice parts foreach (IceParticle particle in iceParticles) { particle.RotAngle += particle.AngularVelocity * dt; particle.Position += particle.Velocity * dt; Matrix matrix = Matrix.CreateFromAxisAngle(particle.RotAxis, particle.RotAngle); matrix.Translation = particle.Position; particle.AsteroidEntity.SetWorldMatrix(matrix); Matrix trans = Matrix.CreateTranslation(-particle.Direction * 10); particle.TrailEffect.WorldMatrix = matrix * trans; MyAudio.UpdateCuePosition(particle.Sound, particle.Position, particle.Direction, particle.Direction * -particle.Direction, particle.Velocity); } lastUpdateMs = MyMinerGame.TotalGamePlayTimeInMilliseconds; }
// Update position, check collisions, etc. and draw if particle still lives. // Return false if particle dies/timeouts in this tick. public bool Draw(MyBillboard billboard) { MyTransparentGeometry.StartParticleProfilingBlock("Distance calculation"); // This time is scaled according to planned lifespan of the particle // Distance for sorting Vector3 campos = MyCamera.Position; Vector3.DistanceSquared(ref campos, ref m_actualPosition, out billboard.DistanceSquared); MyTransparentGeometry.EndParticleProfilingBlock(); // If distance to camera is really small don't draw it. if (billboard.DistanceSquared <= 1) { return(false); } MyTransparentGeometry.StartParticleProfilingBlock("Quad calculation"); MyTransparentGeometry.StartParticleProfilingBlock("actualRadius"); float actualRadius = 1; Radius.GetInterpolatedValue <float>(m_normalizedTime, out actualRadius); MyTransparentGeometry.EndParticleProfilingBlock(); billboard.ContainedBillboards.Clear(); billboard.Near = m_generation.GetEffect().Near; billboard.Lowres = m_generation.GetEffect().LowRes || MyRenderConstants.RenderQualityProfile.LowResParticles; float alpha = 1; if (Type == MyParticleTypeEnum.Point) { MyTransparentGeometry.StartParticleProfilingBlock("GetBillboardQuadRotated"); MyUtils.GetBillboardQuadRotated(billboard, ref m_actualPosition, actualRadius, m_actualAngle); MyTransparentGeometry.EndParticleProfilingBlock(); } else if (Type == MyParticleTypeEnum.Line) { if (MyMwcUtils.IsZero(Velocity.LengthSquared())) { Velocity = MyMwcUtils.GetRandomVector3Normalized(); } MyQuad quad = new MyQuad(); MyPolyLine polyLine = new MyPolyLine(); polyLine.LineDirectionNormalized = MyMwcUtils.Normalize(Velocity); if (m_actualAngle > 0) { polyLine.LineDirectionNormalized = Vector3.TransformNormal(polyLine.LineDirectionNormalized, Matrix.CreateRotationY(MathHelper.ToRadians(m_actualAngle))); } polyLine.Point0 = m_actualPosition; polyLine.Point1.X = m_actualPosition.X + polyLine.LineDirectionNormalized.X * actualRadius; polyLine.Point1.Y = m_actualPosition.Y + polyLine.LineDirectionNormalized.Y * actualRadius; polyLine.Point1.Z = m_actualPosition.Z + polyLine.LineDirectionNormalized.Z * actualRadius; if (m_actualAngle > 0) { //centerize polyLine.Point0.X = polyLine.Point0.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f; polyLine.Point0.Y = polyLine.Point0.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f; polyLine.Point0.Z = polyLine.Point0.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f; polyLine.Point1.X = polyLine.Point1.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f; polyLine.Point1.Y = polyLine.Point1.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f; polyLine.Point1.Z = polyLine.Point1.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f; } polyLine.Thickness = Thickness; MyUtils.GetPolyLineQuad(out quad, ref polyLine); if (this.m_generation.AlphaAnisotropic) { float angle = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), polyLine.LineDirectionNormalized)); float alphaCone = (float)Math.Pow(angle, 0.5f); alpha = alphaCone; } billboard.Position0 = quad.Point0; billboard.Position1 = quad.Point1; billboard.Position2 = quad.Point2; billboard.Position3 = quad.Point3; } else if (Type == MyParticleTypeEnum.Trail) { if (Quad.Point0 == Quad.Point2) //not moving particle { return(false); } if (Quad.Point1 == Quad.Point3) //not moving particle was previous one { return(false); } if (Quad.Point0 == Quad.Point3) //not moving particle was previous one { return(false); } billboard.Position0 = Quad.Point0; billboard.Position1 = Quad.Point1; billboard.Position2 = Quad.Point2; billboard.Position3 = Quad.Point3; //if (this.m_generation.AlphaAnisotropic) /* { //Trails are anisotropic by default (nobody wants them to see ugly) * Vector3 lineDir = Vector3.Normalize(Quad.Point1 - Quad.Point0); * float angle = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), lineDir)); * float alphaCone = (float)Math.Pow(angle, 0.3f); * alpha = alphaCone; * }*/ } else { throw new NotSupportedException(Type + " is not supported particle type"); } MyTransparentGeometry.EndParticleProfilingBlock(); MyTransparentGeometry.StartParticleProfilingBlock("Material calculation"); Vector4 color; Color.GetInterpolatedValue <Vector4>(m_normalizedTime, out color); int material1 = (int)MyTransparentMaterialEnum.Test; int material2 = (int)MyTransparentMaterialEnum.Test; float textureBlendRatio = 0; if ((Flags & ParticleFlags.BlendTextures) != 0) { float prevTime, nextTime, difference; Material.GetPreviousValue(m_normalizedTime, out material1, out prevTime); Material.GetNextValue(m_normalizedTime, out material2, out nextTime, out difference); if (prevTime != nextTime) { textureBlendRatio = (m_normalizedTime - prevTime) * difference; } } else { Material.GetInterpolatedValue <int>(m_normalizedTime, out material1); } MyTransparentGeometry.EndParticleProfilingBlock(); //This gets 0.44ms for 2000 particles MyTransparentGeometry.StartParticleProfilingBlock("billboard.Start"); billboard.MaterialEnum = (MyTransparentMaterialEnum)material1; billboard.BlendMaterial = (MyTransparentMaterialEnum)material2; billboard.BlendTextureRatio = textureBlendRatio; billboard.EnableColorize = false; billboard.Color = color * alpha * m_generation.GetEffect().UserColorMultiplier; MyTransparentGeometry.EndParticleProfilingBlock(); return(true); }
/// <summary> /// Updates resource. /// </summary> public override void UpdateBeforeSimulation() { try { MyRender.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation"); //Large ship weapons wont make bots curious if ((!(OwnerEntity is MyLargeShipMissileLauncherBarrel)) && MyMwcUtils.HasValidLength(this.WorldMatrix.Translation - m_previousPosition)) { MyLine line = new MyLine(this.WorldMatrix.Translation, m_previousPosition); MyDangerZones.Instance.Notify(line, OwnerEntity); } if (m_isExploded) { // Create explosion MyExplosion newExplosion = MyExplosions.AddExplosion(); if (newExplosion != null) { float radius = m_ammoProperties.ExplosionRadius; // Explicitly on Marek's request (ticket 4740) bool amplifyRadius = m_collidedEntity != null?MyFactions.GetFactionsRelation(m_collidedEntity.Faction, Faction) != MyFactionRelationEnum.Friend : false; if (amplifyRadius) { radius *= 2; } BoundingSphere explosionSphere = new BoundingSphere(m_collisionPoint.HasValue ? m_collisionPoint.Value : GetPosition(), radius); // Call main explosion starter MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = m_ammoProperties.HealthDamage, Damage = m_ammoProperties.ShipDamage, EmpDamage = m_ammoProperties.EMPDamage, ExplosionType = m_explosionType, ExplosionSphere = explosionSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, ExplosionForceDirection = MyExplosionForceDirection.EXPLOSION, GroupMask = Physics.GroupMask, CascadeLevel = CascadedExplosionLevel, HitEntity = m_collidedEntity, ParticleScale = 1.5f, OwnerEntity = this.OwnerEntity, Direction = WorldMatrix.Forward, VoxelExplosionCenter = explosionSphere.Center + m_ammoProperties.ExplosionRadius * WorldMatrix.Forward * 0.5f, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT, VoxelCutoutScale = amplifyRadius ? 0.5f : 1.0f, PlaySound = true, }; newExplosion.Start(ref info); } if (m_collidedEntity != null && !m_collidedEntity.IsExploded()) { m_collidedEntity.Physics.AddForce( MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, WorldMatrix.Forward * MyMissileConstants.HIT_STRENGTH_IMPULSE, GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 2, MyMissileConstants.HIT_STRENGTH_IMPULSE * MyMwcUtils.GetRandomVector3Normalized()); m_collidedEntity.OnClose -= m_collidedEntity_OnClose; } MarkForClose(); return; } bool firstTargetting = m_elapsedMiliseconds == 0; base.UpdateBeforeSimulation(); m_missileTargetUpdate += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS; if (m_missileTargetUpdate >= MyGuidedMissileConstants.MISSILE_TARGET_UPDATE_INTERVAL_IN_MS || firstTargetting) { m_missileTargetUpdate = 0; switch (m_missileType) { case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Radar_Detection: { MySmallShip targetShip = m_targetEntity as MySmallShip; if (targetShip != null && targetShip.IsRadarJammed()) { m_targetEntity = null; } } break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Engine_Detection: { m_targetEntities.Clear(); Matrix proj = Matrix.CreateOrthographic(MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, 0, 1000); Matrix view = Matrix.CreateLookAt(GetPosition(), GetPosition() + WorldMatrix.Forward, WorldMatrix.Up); m_visualFrustum.Matrix = view * proj; MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities); if (m_targetEntities.Contains(m_targetEntity)) { break; } MyEntity target = null; float closestToMissileDirection = float.MaxValue; foreach (MyEntity entity in m_targetEntities) { if (CanTarget(entity)) { MySmallShip targetShip = entity as MySmallShip; if (targetShip != null) { if ((targetShip.IsEngineTurnedOff())) { continue; } } Vector3 targetPos = entity.GetPosition(); Vector3 missilePos = this.GetPosition(); Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000; Vector3 closestPos = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos); float distance = Vector3.Distance(closestPos, targetPos); if (distance < closestToMissileDirection) { closestToMissileDirection = distance; target = entity; } } } UpdateTarget(target); } break; case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Visual_Detection: { Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_FOV), 1, 10, MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_RANGE); m_visualFrustum.Matrix = Matrix.Invert(WorldMatrix) * projectionMatrix; m_targetEntities.Clear(); MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities); int testsLimit = 8; if (m_targetEntities.Contains(m_targetEntity)) { break; } MyEntity target = null; //looks better if missile gets "lost" float closestToMissileDirection = float.MaxValue; foreach (MyEntity entity in m_targetEntities) { if (!CanTarget(entity)) { continue; } if (testsLimit-- == 0) { break; } if (MyEnemyTargeting.CanSee(this, entity) == null) { Vector3 targetPos = entity.GetPosition(); Vector3 missilePos = this.GetPosition(); Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000; Vector3 closestPos = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos); float distance = Vector3.Distance(closestPos, targetPos); if (distance < closestToMissileDirection) { closestToMissileDirection = distance; target = entity; } } } UpdateTarget(target); } break; } } if ((m_initTime - m_elapsedMiliseconds) > 0) { //simulating missile launch and engine ignition MyEntity owner = OwnerEntity; if (owner != null) { Vector3 transformedInitDir = Vector3.TransformNormal(m_initDir, owner.WorldMatrix); // Vector3 initialVelocity = Vector3.Zero; if (owner.Physics != null) { initialVelocity = owner.Physics.LinearVelocity; } Physics.LinearVelocity = transformedInitDir * m_ammoProperties.InitialSpeed + initialVelocity; } } else { // This will help blend "initial velocity" and "thrust velocity" so at the beginning missile is powered by initiatal velocity only, but later float velocityBlend = MathHelper.Clamp((float)(m_elapsedMiliseconds - m_initTime) / m_blendVelocities, 0, 1); if (velocityBlend == 1.0f) { m_actualSpeed = m_ammoProperties.DesiredSpeed; } else { float initialSpeed = 0.0f; MyEntity owner = OwnerEntity; if (owner != null) { if (owner.Physics != null) { initialSpeed = owner.Physics.LinearVelocity.Length(); } } m_actualSpeed = velocityBlend * m_ammoProperties.DesiredSpeed + ((1.0f - velocityBlend) * (m_ammoProperties.InitialSpeed + initialSpeed)); if (m_missileType != MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_Basic && m_smokeEffect == null) { // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150) { /* * MyParticleEffect startEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_MissileStart); * startEffect.WorldMatrix = WorldMatrix; */ m_smokeEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile); m_smokeEffect.WorldMatrix = WorldMatrix; m_smokeEffect.AutoDelete = false; } } } m_desiredVelocity = GetDesiredVelocity(m_targetEntity); Physics.LinearVelocity = m_desiredVelocity * m_actualSpeed * 1.0f; } Physics.AngularVelocity = Vector3.Zero; if ((m_elapsedMiliseconds > m_missileTimeout) || (Vector3.Distance(GetPosition(), m_origin) >= m_maxTrajectory)) { Explode(); return; } if (m_smokeEffect != null) { Matrix smokeMatrix = Matrix.CreateWorld(WorldMatrix.Translation - 0.5f * WorldMatrix.Forward, WorldMatrix.Forward, WorldMatrix.Up); m_smokeEffect.WorldMatrix = smokeMatrix; } if (m_targetEntity != null) { if (m_targetEntity.Physics != null) { m_targetVelocity = m_targetEntity.Physics.LinearVelocity; } else { m_targetVelocity = Vector3.Zero; } } } finally { MyRender.GetRenderProfiler().EndProfilingBlock(); } }
public static void Update() { /* * foreach (var pair in m_usedCoords) * { * pair.Value.MarkForClose(); * } * * m_usedCoords.Clear(); */ if (!MySector.DebrisProperties.Enabled || !MinerWars.AppCode.Game.Render.MyRenderConstants.RenderQualityProfile.EnableFlyingDebris) { return; } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyDebrisField.Update"); if ((lastDustFieldCountInDirectionHalf != DustFieldCountInDirectionHalf) || (lastDistanceBetween != DistanceBetween)) { lastDistanceBetween = DistanceBetween; lastDustFieldCountInDirectionHalf = DustFieldCountInDirectionHalf; // Fill 3D array with random values from interval <0..1> m_random = new float[DustFieldCountInDirection][][]; for (int x = 0; x < m_random.Length; x++) { m_random[x] = new float[DustFieldCountInDirection][]; for (int y = 0; y < m_random.Length; y++) { m_random[x][y] = new float[DustFieldCountInDirection]; for (int z = 0; z < m_random.Length; z++) { m_random[x][y][z] = MyMwcUtils.GetRandomFloat(0, 1); } } } } // Update helper frustum and then its bounding box m_helperBoundingSphere = new BoundingSphere(MySession.PlayerShip.GetPosition(), MaxDistance); BoundingBox helperBoundingBox = BoundingBox.CreateFromSphere(m_helperBoundingSphere); MyMwcVector3Int minCoord = GetMetersToDustFieldCoord(ref helperBoundingBox.Min); MyMwcVector3Int maxCoord = GetMetersToDustFieldCoord(ref helperBoundingBox.Max); m_entitiesToRemove.Clear(); m_entitiesToRemove.AddRange(m_usedCoords.Keys); BoundingSphere collisionBoundingSphere = new BoundingSphere(MySession.PlayerShip.GetPosition(), MaxDistance / 3); BoundingBox helperCollisionBoundingBox = BoundingBox.CreateFromSphere(m_helperBoundingSphere); MyEntities.GetCollisionsInBoundingBox(ref helperCollisionBoundingBox, m_list); bool newDebrisAllowed = true; foreach (MyRBElement element in m_list) { MyEntity entity = ((MinerWars.AppCode.Game.Physics.MyPhysicsBody)element.GetRigidBody().m_UserData).Entity; if ((entity is MyVoxelMap) || (entity is MinerWars.AppCode.Game.Prefabs.MyPrefabBase)) { newDebrisAllowed = false; } } MyMwcVector3Int tempCoord; for (tempCoord.X = minCoord.X; tempCoord.X <= maxCoord.X; tempCoord.X++) { for (tempCoord.Y = minCoord.Y; tempCoord.Y <= maxCoord.Y; tempCoord.Y++) { for (tempCoord.Z = minCoord.Z; tempCoord.Z <= maxCoord.Z; tempCoord.Z++) { // Position of this particle Vector3 position; position.X = tempCoord.X * DistanceBetween; position.Y = tempCoord.Y * DistanceBetween; position.Z = tempCoord.Z * DistanceBetween; // Get pseudo-random number. It's randomness is based on 3D position, so values don't change between draw calls. float pseudoRandomVariationMod = m_random[Math.Abs(tempCoord.X) % m_random.Length][Math.Abs(tempCoord.Y) % m_random.Length][Math.Abs(tempCoord.Z) % m_random.Length]; // Alter position by randomness position.X += MathHelper.Lerp(-DistanceBetweenHalf, +DistanceBetweenHalf, pseudoRandomVariationMod); position.Y += MathHelper.Lerp(-DistanceBetweenHalf, +DistanceBetweenHalf, pseudoRandomVariationMod); position.Z += MathHelper.Lerp(-DistanceBetweenHalf, +DistanceBetweenHalf, pseudoRandomVariationMod); // Distance to particle float distance; Vector3 center = MySession.PlayerShip.GetPosition(); Vector3.Distance(ref center, ref position, out distance); if (distance > MaxDistance) { continue; } // Pseudo-random color and alpha float pseudoRandomColor = MathHelper.Lerp(0.1f, 0.2f, pseudoRandomVariationMod); //MathHelper.Lerp(0.2f, 0.3f, pseudoRandomVariationMod); //float pseudoRandomAlpha = 0.5f; //0.4f; // 0.2f;// MathHelper.Lerp(0.2f, 0.3f, pseudoRandomVariationMod); //Remove only entities outside distance, not frustum (looks better) m_entitiesToRemove.Remove(tempCoord); if (MyCamera.GetBoundingFrustum().Contains(position) == ContainmentType.Disjoint) { continue; } float alpha = 0; if (distance < FullScaleDistance) { alpha = 1; } else if ((distance >= FullScaleDistance) && (distance < MaxDistance)) { alpha = 1 - MathHelper.Clamp((distance - FullScaleDistance) / (MaxDistance - FullScaleDistance), 0, 1); } else { alpha = 0; } MyEntity entity; m_usedCoords.TryGetValue(tempCoord, out entity); float scale = MathHelper.Lerp(0.2f, 1.0f, alpha); if (entity == null) { if (!newDebrisAllowed) { continue; } if (alpha > 0.2f) { continue; //it would be popping } MinerWars.CommonLIB.AppCode.ObjectBuilders.MyMwcObjectBuilder_Base debrisBuilder = null; if (MyMwcUtils.GetRandomInt(2) % 2 == 0) { entity = MyExplosionDebrisVoxel.Allocate(); if (entity == null) { continue; } int voxelMatEnumIndex = (int)MyMwcUtils.GetRandomShort((short)0, (short)(MySector.DebrisProperties.DebrisVoxelMaterials.Length)); MyMwcVoxelMaterialsEnum voxelMatEnum = (MyMwcVoxelMaterialsEnum)MySector.DebrisProperties.DebrisVoxelMaterials.GetValue(voxelMatEnumIndex); ((MyExplosionDebrisVoxel)entity).Start(position, 1, voxelMatEnum, MyGroupMask.Empty, false); MyEntities.Add(entity); } else { int debrisEnumIndex = (int)MyMwcUtils.GetRandomShort((short)0, (short)(MySector.DebrisProperties.DebrisEnumValues.Length)); MyMwcObjectBuilder_SmallDebris_TypesEnum debrisEnum = (MyMwcObjectBuilder_SmallDebris_TypesEnum)MySector.DebrisProperties.DebrisEnumValues.GetValue(debrisEnumIndex); debrisBuilder = new MyMwcObjectBuilder_SmallDebris(debrisEnum, true, 0); //MyMwcObjectBuilder_SmallDebris debrisBuilder = new MyMwcObjectBuilder_SmallDebris(MyMwcObjectBuilder_SmallDebris_TypesEnum.Debris32_pilot, true, 0); entity = MyEntities.CreateFromObjectBuilderAndAdd(null, debrisBuilder, Matrix.CreateWorld(position, MyMwcUtils.GetRandomVector3Normalized(), MyMwcUtils.GetRandomVector3Normalized())); } entity.Save = false; entity.CastShadows = false; m_usedCoords.Add(tempCoord, entity); } if (entity.Physics != null && entity.Physics.Enabled == true) { entity.Physics.Enabled = false; } /* * if (!(entity is MyExplosionDebrisVoxel) && (distance < FullScaleDistance / 2.0f)) * { * if (entity.Physics == null) * { * entity.InitBoxPhysics(MyMaterialType.METAL, entity.ModelCollision, 500, 0, MyConstants.COLLISION_LAYER_MODEL_DEBRIS, RigidBodyFlag.RBF_DEFAULT); * } * if (entity.Physics.Enabled == false) * { * entity.Physics.Clear(); * entity.Physics.Enabled = true; * } * }*/ /* * else * { * if (entity.Physics != null && entity.Physics.Enabled) * { * entity.Physics.Enabled = false; * } * } */ if (entity is MyExplosionDebrisVoxel) { scale *= 0.08f; } entity.Scale = scale; /* * if (entity.Physics == null && distance < FullScaleDistance / 3) * { * entity.InitBoxPhysics(MyMaterialType.METAL, entity.ModelLod0, 100, MyPhysicsConfig.DefaultAngularDamping, MyConstants.COLLISION_LAYER_ALL, RigidBodyFlag.RBF_DEFAULT); * entity.Physics.Enabled = true; * } */ } } } foreach (MyMwcVector3Int positionToRemove in m_entitiesToRemove) { MyEntity entity = m_usedCoords[positionToRemove]; /* * if (entity.Physics != null && entity.Physics.LinearVelocity.LengthSquared() > 0.1f) * { * // Particles.MyParticleEffect effect = Particles.MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Explosion_Missile); * // effect.WorldMatrix = entity.WorldMatrix; * } */ entity.MarkForClose(); m_usedCoords.Remove(positionToRemove); } MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); }