private static IEnumerable<MyObjectInfo> GetAsteroids(MySectorObjectCounts asteroidCounts, float entityMinimalSize) { var asteroids = asteroidCounts.AllObjects.Where(s => s.SizeInMeters > entityMinimalSize); return asteroids; }
private void AddSectorEntities(MySectorObjectCounts asteroidCounts, MyMwcVector3Int sectorPosition, Random random, float entityMinimalSize, int maxEntityCount, List<MySolarSystemMapEntity> entities, bool onlyStaticAsteroids) { // Space around asteroid should be at least 1.2x - 2x it's size float asteroidSpacingCoeficient = 0.7f; // Asteroid count mean is 40% float asteroidCountMean = 0.4f; Dictionary<int, int> entityCounts = new Dictionary<int, int>(); foreach (MySolarSystemEntityEnum t in Enum.GetValues(typeof(MySolarSystemEntityEnum))) { entityCounts.Add((int)t, 0); } MyDynamicAABBTree prunningStructure = new MyDynamicAABBTree(Vector3.Zero); foreach (BoundingSphere boundingSphere in m_safeAreas) { BoundingBox bb = BoundingBox.CreateFromSphere(boundingSphere); prunningStructure.AddProxy(ref bb, new Render.MyRenderObject(null, null), 0); } // Generate asteroids, check collisions (order asteroids by size) //var asteroids = GetAsteroids(asteroidCounts, entityMinimalSize); var asteroids = GetAsteroids(asteroidCounts, entityMinimalSize); foreach (var info in asteroids) { if (info.EntityType != MySolarSystemEntityEnum.StaticAsteroid && onlyStaticAsteroids) continue; float radius = info.SizeInMeters / 2; float count = info.ObjectCount; float positionOffset = 1.3f; count = (float)Math.Round(count * random.Float(1 - asteroidCountMean, 1 + asteroidCountMean)); if (info.EntityType == MySolarSystemEntityEnum.VoxelAsteroid) { positionOffset = 0.6f; //generate voxels more in center } while (entityCounts[(int)info.EntityType] < count && entityCounts[(int)info.EntityType] < maxEntityCount) { Vector3? pos = FindEntityPosition(prunningStructure, random, radius, positionOffset, asteroidSpacingCoeficient); if (pos.HasValue) { MySolarSystemMapEntity entity = new MySolarSystemMapEntity(sectorPosition, pos.Value, info.SizeInMeters, info.EntityType.ToString(), info.EntityType); entities.Add(entity); if (!MySectorGenerator.IsOutsideSector(pos.Value, radius)) { entityCounts[(int)info.EntityType]++; } BoundingBox bb = new BoundingBox(pos.Value - new Vector3(radius), pos.Value + new Vector3(radius)); prunningStructure.AddProxy(ref bb, new Render.MyRenderObject(null, null), 0); } else entityCounts[(int)info.EntityType]++; } } }
private void EnsureMinimalAsteroidCounts(MySectorObjectCounts asteroidCounts) { foreach (var pair in MySolarSystemConstants.MinimumObjectsProperties.Values) { float value; if (!asteroidCounts.Values.TryGetValue(pair.Key, out value) || value < pair.Value) { asteroidCounts.Values[pair.Key] = pair.Value; } } }
private MySectorObjectCounts ApplyAreaInfluence(MySectorObjectCounts objectCounts, float areaInfluence) { MySectorObjectCounts result = new MySectorObjectCounts(); foreach (var item in objectCounts.Values) { result.Values[item.Key] = item.Value * areaInfluence; } return result; }
public MyMwcObjectBuilder_Sector GenerateObjectBuilders(MyMwcVector3Int sectorPosition, MySectorObjectCounts sectorObjectCounts, bool onlyStaticAsteroids) { Random rnd = new Random(m_seed); List<MySolarSystemMapEntity> entities = new List<MySolarSystemMapEntity>(); AddSectorEntities(sectorObjectCounts, sectorPosition, rnd, 0, int.MaxValue, entities, onlyStaticAsteroids); List<MyMwcObjectBuilder_Base> sectorObjects = new List<MyMwcObjectBuilder_Base>(); MyWeightDictionary<MyMwcVoxelMaterialsEnum> primaryMaterials = new MyWeightDictionary<MyMwcVoxelMaterialsEnum>(MySolarSystemConstants.DefaultAsteroidMaterials); MyWeightDictionary<MyMwcVoxelMaterialsEnum> secondaryMaterials = new MyWeightDictionary<MyMwcVoxelMaterialsEnum>(MySolarSystemConstants.DefaultSecondaryMaterials); GenerateSectorObjectBuildersFromSolarEntities(entities, sectorObjects, rnd, primaryMaterials, secondaryMaterials, sectorObjectCounts.StaticAsteroidTypeset); return new MyMwcObjectBuilder_Sector() { SectorObjects = sectorObjects, }; }
/// <param name="interpolator">1 means use other object</param> public MySectorObjectCounts InterpolateWith(MySectorObjectCounts otherObject, float interpolator) { var result = new MySectorObjectCounts(); // This function assumes that both collection contains all types of objects foreach (var kv in Values) { float currentValue = kv.Value; float otherValue = otherObject.Values[kv.Key]; result.Values[kv.Key] = MathHelper.Lerp(currentValue, otherValue, interpolator); } StaticAsteroidTypeset = interpolator > 0.5f ? StaticAsteroidTypeset : otherObject.StaticAsteroidTypeset; return result; }