/// <summary> /// This quickly checks if a given position is in any natural gravity. /// </summary> /// <param name="position">Position to check</param> /// <param name="sphereSize">Sphere size to test with.</param> /// <returns>True if there is natural gravity at this position, false otherwise.</returns> public static bool IsPositionInNaturalGravity(Vector3D position, double sphereSize = 0) { // Clamp sphere size to be at least 0. sphereSize = MathHelper.Max(sphereSize, 0); for (int i = 0; i < m_planetGenerators.Count; i++) { IMyGravityProvider provider = m_planetGenerators[i]; if (provider == null) { continue; } MyPlanet planet = provider as MyPlanet; if (planet == null) { continue; } //we don't really care which planet's gravity we're in, so return as soon as we find one if (planet.IsPositionInGravityWell(position)) { return(true); } } return(false); }
public override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); if (!MyFakes.ENABLE_PLANET_FIREFLIES) { return; } if (m_particleSpawnCounter-- > 0) { return; } m_particleSpawnCounter = 0; var entity = MySession.Static.ControlledEntity as MyEntity; if (entity == null) { return; } var controlledEntity = entity.GetTopMostParent(); if (controlledEntity == null) { return; } try { ProfilerShort.Begin("Fireflies.Spawn"); m_particleSpawnCounter = (int)Math.Round(m_particleSpawnCounter + m_particleSpawnCounter * m_particleSpawnIntervalRandomness * (MyRandom.Instance.NextFloat() * 2.0f - 1.0f)); float normalVar = (MyRandom.Instance.FloatNormal() + 3.0f) / 6.0f; if (normalVar > m_particleDensity) { return; } var naturalGravity = MyGravityProviderSystem.CalculateNaturalGravityInPoint(MySector.MainCamera.Position); if (naturalGravity.Dot(MySector.DirectionToSunNormalized) <= 0) // Only spawn at night and on planets { return; } var velocity = (MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity && MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.ThirdPersonSpectator ? Vector3.Zero : controlledEntity.Physics.LinearVelocity); var speed = velocity.Length(); var currentCharacter = controlledEntity as MyCharacter; float characterFlyingMaxSpeed = MyGridPhysics.ShipMaxLinearVelocity(); if (currentCharacter != null && currentCharacter.Physics != null && currentCharacter.Physics.CharacterProxy != null) { characterFlyingMaxSpeed = currentCharacter.Physics.CharacterProxy.CharacterFlyingMaxLinearVelocity(); } Vector3 halfExtents = Vector3.One * m_particleSpawnDistance; if (speed / characterFlyingMaxSpeed > 1.0f) { halfExtents += 10.0f * velocity / characterFlyingMaxSpeed; } var entityTranslation = MySector.MainCamera.Position; var searchPosition = entityTranslation + velocity; MyPlanet planet = MyGravityProviderSystem.GetStrongestGravityWell(MySector.MainCamera.Position); if (planet == null || !planet.IsPositionInGravityWell(MySector.MainCamera.Position)) { return; } Vector3D cameraPosition = MySector.MainCamera.Position; var foundEnvironmentItems = planet.GetEnvironmentItemsAtPosition(ref cameraPosition); foreach (var environmentItems in foundEnvironmentItems) { environmentItems.GetAllItemsInRadius(searchPosition, m_particleSpawnDistance, m_tmpItemInfos); } var spawnPosition = default(Vector3D); bool spawnPositionFound = m_tmpItemInfos.Count != 0; if (spawnPositionFound) { int selectedTreeIndex = MyRandom.Instance.Next(0, m_tmpItemInfos.Count - 1); spawnPosition = m_tmpItemInfos[selectedTreeIndex].Transform.Position; spawnPositionFound = true; } else { return; } var spawnedParticle = Spawn(spawnPosition); if (spawnedParticle == null) { return; } InitializePath(spawnedParticle); } finally { m_bodyCollisions.Clear(); m_tmpItemInfos.Clear(); ProfilerShort.End(); } }