public override void UpdateBeforeSimulation() { return; base.UpdateBeforeSimulation(); if (m_particleSpawnCounter-- > 0) { return; } var entity = MySession.Static.ControlledEntity as MyEntity; if (entity == null) { return; } var controlledEntity = entity.GetTopMostParent(); if (controlledEntity == null) { return; } try { ProfilerShort.Begin("Grassland.UpdateBeforeSimulation"); m_particleSpawnCounter = (int)Math.Round(m_particleSpawnCounter + m_particleSpawnCounter * m_particleSpawnIntervalRandomness * (MyRandom.Instance.NextFloat() * 2.0f - 1.0f)); if (MyRandom.Instance.FloatNormal() <= m_particleDensity) { return; } var cameraPosition = MySector.MainCamera.Position; MyPlanet nearestPlanet = MyGravityProviderSystem.GetNearestPlanet(cameraPosition); Vector3D naturalGravity = nearestPlanet.GetWorldGravityGrid(MySector.MainCamera.Position); if (naturalGravity.Dot(MySector.DirectionToSunNormalized) > 0) // Only spawn during the day { return; } var velocity = (MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.Entity && MySession.Static.GetCameraControllerEnum() != MyCameraControllerEnum.ThirdPersonSpectator ? Vector3.Zero : controlledEntity.Physics.LinearVelocity); var speed = velocity.Length(); var cameraPositionLocal = Vector3D.Transform(cameraPosition, MatrixD.Invert(nearestPlanet.WorldMatrix)); //Vector3D nearestSurfacePointLocal = nearestPlanet.GetClosestSurfacePointLocal(cameraPosition); // Vector3D nearestSurfacePointWorld = Vector3D.Transform(nearestSurfacePointLocal, nearestPlanet.WorldMatrix); // bool test = nearestPlanet.IsFloraAtPosition(nearestSurfacePointLocal); var currentCharacter = controlledEntity as MyCharacter; float characterFlyingMaxSpeed = (currentCharacter != null) ? currentCharacter.Physics.CharacterProxy.CharacterFlyingMaxLinearVelocity() : MyGridPhysics.ShipMaxLinearVelocity(); Vector3 halfExtents = Vector3.One * m_particleSpawnDistance; if (speed / characterFlyingMaxSpeed > 1.0f) { halfExtents += 10.0f * velocity / characterFlyingMaxSpeed; } var entityTranslation = cameraPosition; var searchPosition = entityTranslation + velocity; MyPhysics.GetPenetrationsBox(ref halfExtents, ref searchPosition, ref Quaternion.Identity, m_bodyCollisions, MyPhysics.CollisionLayers.NotCollideWithStaticLayer); var spawnPosition = default(Vector3D); bool spawnPositionFound = false; foreach (var foundEntity in m_bodyCollisions) { var environmentItems = foundEntity.Body.GetEntity(foundEntity.ShapeKey) as MyEnvironmentItems; if (environmentItems != null) { environmentItems.GetAllItemsInRadius(searchPosition, m_particleSpawnDistance, m_tmpItemInfos); } } if (m_tmpItemInfos.Count != 0) { int selectedTreeIndex = MyRandom.Instance.Next(0, m_tmpItemInfos.Count - 1); spawnPosition = m_tmpItemInfos[selectedTreeIndex].Transform.Position; spawnPositionFound = true; } if (!spawnPositionFound) { return; } var spawnedParticle = Spawn(spawnPosition); if (spawnedParticle == null) { return; } InitializePath(spawnedParticle); } finally { m_bodyCollisions.Clear(); ProfilerShort.End(); } }