public MyCompositeNoise(int numNoises,float startFrequency,MyRandom random) { m_numNoises = numNoises; m_noises = new IMyModule[m_numNoises]; m_amplitudeScales = new float[m_numNoises]; m_normalizationFactor = 2.0f - 1.0f / (float)Math.Pow(2, numNoises - 1); float frequency = startFrequency; for (int i = 0; i < m_numNoises; ++i) { m_amplitudeScales[i] = 1.0f / (float)Math.Pow(2.0f, i); m_noises[i] = new MySimplexFast(seed: random.Next(), frequency: frequency); frequency *= 2.01f; } }
private static Vector3 CreateRandomPointOnBox(MyRandom self, float boxSize) { Vector3 result = Vector3.Zero; switch (self.Next() & 6) {// each side of a box case 0: return new Vector3(0f, self.NextFloat(), self.NextFloat()); case 1: return new Vector3(1f, self.NextFloat(), self.NextFloat()); case 2: return new Vector3(self.NextFloat(), 0f, self.NextFloat()); case 3: return new Vector3(self.NextFloat(), 1f, self.NextFloat()); case 4: return new Vector3(self.NextFloat(), self.NextFloat(), 0f); case 5: return new Vector3(self.NextFloat(), self.NextFloat(), 1f); } result *= boxSize; return result; }
private void GenerateObject(MyProceduralCell cell, MyObjectSeed objectSeed, ref int index, MyRandom random, IMyModule densityFunction) { cell.AddObject(objectSeed); switch (objectSeed.Type) { case MyObjectSeedType.Asteroid: m_asteroidSeedCount++; break; case MyObjectSeedType.AsteroidCluster: objectSeed.Type = MyObjectSeedType.Asteroid; m_asteroidSeedCount++; m_tmpClusterBoxes.Add(objectSeed.BoundingVolume); for (int j = 0; j < OBJECT_MAX_IN_CLUSTER; ++j) { var direction = GetRandomDirection(random); var size = GetClusterObjectSize(random.NextDouble()); var distance = MathHelper.Lerp(OBJECT_MIN_DISTANCE_CLUSTER, OBJECT_MAX_DISTANCE_CLUSTER, random.NextDouble()); var clusterObjectPosition = objectSeed.BoundingVolume.Center + direction * (size + objectSeed.BoundingVolume.HalfExtents.Length() * 2 + distance); ProfilerShort.Begin("GetValue"); var value = densityFunction.GetValue(clusterObjectPosition.X, clusterObjectPosition.Y, clusterObjectPosition.Z); ProfilerShort.End(); if (value < OBJECT_DENSITY_CLUSTER) // -1..+1 { var clusterObjectSeed = new MyObjectSeed(cell, clusterObjectPosition, size); clusterObjectSeed.Seed = random.Next(); clusterObjectSeed.Index = index++; clusterObjectSeed.Type = GetClusterSeedType(random.NextDouble()); bool overlaps = false; foreach (var box in m_tmpClusterBoxes) { if (overlaps |= clusterObjectSeed.BoundingVolume.Intersects(box)) { break; } } if (!overlaps) { m_tmpClusterBoxes.Add(clusterObjectSeed.BoundingVolume); GenerateObject(cell, clusterObjectSeed, ref index, random, densityFunction); } } } m_tmpClusterBoxes.Clear(); break; case MyObjectSeedType.EncounterAlone: case MyObjectSeedType.EncounterSingle: case MyObjectSeedType.EncounterMulti: m_encounterSeedCount++; break; default: throw new InvalidBranchException(); break; } }
private void GenerateObject(MyProceduralCell cell, MyObjectSeed objectSeed, ref int index, MyRandom random, IMyModule densityFunctionFilled, IMyModule densityFunctionRemoved) { cell.AddObject(objectSeed); IMyAsteroidFieldDensityFunction func = objectSeed.UserData as IMyAsteroidFieldDensityFunction; if (func != null) { ChildrenAddDensityFunctionRemoved(func); } switch (objectSeed.Type) { case MyObjectSeedType.Moon: break; case MyObjectSeedType.Planet: m_tmpClusterBoxes.Add(objectSeed.BoundingVolume); for (int i = 0; i < MOONS_MAX; ++i) { var direction = GetRandomDirection(random); var size = MathHelper.Lerp(MOON_SIZE_MIN, MOON_SIZE_MAX, random.NextDouble()); var distance = MathHelper.Lerp(MOON_DISTANCE_MIN, MOON_DISTANCE_MAX, random.NextDouble()); var position = objectSeed.BoundingVolume.Center + direction * (size + objectSeed.BoundingVolume.HalfExtents.Length() * 2 + distance); ProfilerShort.Begin("GetValue"); var value = densityFunctionFilled.GetValue(position.X, position.Y, position.Z); ProfilerShort.End(); if (value < MOON_DENSITY) // -1..+1 { var clusterObjectSeed = new MyObjectSeed(cell, position, size); clusterObjectSeed.Seed = random.Next(); clusterObjectSeed.Type = MyObjectSeedType.Moon; clusterObjectSeed.Index = index++; clusterObjectSeed.UserData = new MySphereDensityFunction(position, OBJECT_SEED_RADIUS, OBJECT_SEED_RADIUS); bool overlaps = false; foreach (var box in m_tmpClusterBoxes) { if (overlaps |= clusterObjectSeed.BoundingVolume.Intersects(box)) { break; } } if (!overlaps) { m_tmpClusterBoxes.Add(clusterObjectSeed.BoundingVolume); GenerateObject(cell, clusterObjectSeed, ref index, random, densityFunctionFilled, densityFunctionRemoved); } } } m_tmpClusterBoxes.Clear(); break; case MyObjectSeedType.Empty: break; default: throw new InvalidBranchException(); break; } }
private static MyMaterialLayer[] CreateMaterialLayers(MyPlanetDefinition planetDefinition, bool isHostile, MyRandom random, float averagePlanetRadius, float hillHalfDeviation, float canyonHalfDeviation, ref float outerRadius, ref float innerRadius) { int numLayers = random.Next((int)planetDefinition.NumLayers.Min, (int)planetDefinition.NumLayers.Max); float startHeight = averagePlanetRadius - canyonHalfDeviation; outerRadius = averagePlanetRadius + hillHalfDeviation; innerRadius = averagePlanetRadius - canyonHalfDeviation; int layerOffset = 0; MyMaterialLayer southPoleLayer = CreatePoleLayer(random, planetDefinition.SouthPole, startHeight, outerRadius, ref layerOffset); MyMaterialLayer northPoleLayer = CreatePoleLayer(random, planetDefinition.NorthPole, startHeight, outerRadius, ref layerOffset); MyMaterialLayer[] materialLayers = new MyMaterialLayer[numLayers + layerOffset]; float endAngle = 1; float startAngle = -1; int currentLayer = 0; if (southPoleLayer != null) { materialLayers[currentLayer] = southPoleLayer; endAngle = southPoleLayer.StartAngle; currentLayer++; } if (northPoleLayer != null) { materialLayers[currentLayer] = northPoleLayer; northPoleLayer.EndAngle = northPoleLayer.StartAngle; northPoleLayer.StartAngle = -1.0f; northPoleLayer.AngleEndDeviation = northPoleLayer.AngleStartDeviation; northPoleLayer.AngleStartDeviation = 0.0f; startAngle = northPoleLayer.EndAngle; } float step = (outerRadius - innerRadius) / materialLayers.Length; float organicHeightEnd = random.NextFloat(planetDefinition.OrganicHeightEnd.Min, planetDefinition.OrganicHeightEnd.Max); float metalsHeightEnd = random.NextFloat(planetDefinition.MetalsHeightEndHostile.Min, planetDefinition.MetalsHeightEndHostile.Max); float floraMaterialSpawnProbability = random.NextFloat(planetDefinition.FloraMaterialSpawnProbability.Min, planetDefinition.FloraMaterialSpawnProbability.Max); float metalsSpawnProbability = random.NextFloat(planetDefinition.MetalsSpawnProbability.Min, planetDefinition.MetalsSpawnProbability.Max); float metalsSpawnValue = random.NextFloat(0, 1); for (int i = layerOffset; i < materialLayers.Length; ++i) { float layerHeight = random.NextFloat(0, step); materialLayers[i] = new MyMaterialLayer(); materialLayers[i].StartHeight = startHeight; materialLayers[i].EndHeight = startHeight + layerHeight; materialLayers[i].StartAngle = startAngle; materialLayers[i].EndAngle = endAngle; materialLayers[i].HeightStartDeviation = random.NextFloat(0, 100.0f / (float)(i + 1)); materialLayers[i].AngleStartDeviation = 0; materialLayers[i].HeightEndDeviation = random.NextFloat(0, 100.0f / (float)(i + 1)); materialLayers[i].AngleEndDeviation = 0; MyVoxelMaterialDefinition materialDefinition = null; if (m_materialsByOreType.ContainsKey("Stone") == true) { materialDefinition = m_materialsByOreType["Stone"][random.Next() % m_materialsByOreType["Stone"].Count]; } if (planetDefinition.HasAtmosphere && isHostile == false) { if ((outerRadius - startHeight) > ((outerRadius - innerRadius) * (1 - organicHeightEnd))) { float value = random.NextFloat(0, 1); if (value > floraMaterialSpawnProbability) { materialDefinition = m_organicMaterials[random.Next() % m_organicMaterials.Count]; } else { materialDefinition = m_spawningMaterials[random.Next() % m_spawningMaterials.Count]; } } } else { if (metalsSpawnValue < metalsSpawnProbability) { if ((outerRadius - startHeight) > ((outerRadius - innerRadius) * (1 - metalsHeightEnd))) { MyOreProbability probablity = GetOre(random.NextFloat(0, 1)); if (probablity != null) { materialLayers[i].EndHeight = materialLayers[i].StartHeight - 1; materialLayers[i].HeightStartDeviation *= probablity.Probability; materialLayers[i].HeightEndDeviation *= probablity.Probability; materialDefinition = m_materialsByOreType[probablity.OreName][random.Next() % m_materialsByOreType[probablity.OreName].Count]; } } } } materialLayers[i].MaterialDefinition = materialDefinition; startHeight += layerHeight; } return materialLayers; }
private static MyMaterialLayer CreatePoleLayer(MyRandom random, MyPoleParams poleParams, float startHeight, float outerRadius, ref int layerOffset) { if (m_materialsByOreType.ContainsKey("Ice") == false) { return null; } MyMaterialLayer poleLayer = null; float poleProbability = random.NextFloat(0, 1); if (poleParams != null && poleProbability < poleParams.Probability) { layerOffset++; poleLayer = new MyMaterialLayer(); poleLayer.StartHeight = startHeight; poleLayer.EndHeight = outerRadius; poleLayer.MaterialDefinition = m_materialsByOreType["Ice"][random.Next() % m_materialsByOreType["Ice"].Count]; poleLayer.HeightEndDeviation = 0; poleLayer.HeightStartDeviation = 0; poleLayer.StartAngle = random.NextFloat(poleParams.Angle.Min, poleParams.Angle.Max); poleLayer.EndAngle = 1.0f; poleLayer.AngleStartDeviation = random.NextFloat(poleParams.AngleDeviation.Min, poleParams.AngleDeviation.Max); } return poleLayer; }
private static MyCsgShapePlanetHillAttributes FillValues(MyStructureParams input, MyRandom random) { MyCsgShapePlanetHillAttributes outputValues = new MyCsgShapePlanetHillAttributes(); outputValues.BlendTreshold = random.NextFloat(input.BlendSize.Min, input.BlendSize.Max); outputValues.Treshold = random.NextFloat(input.Treshold.Min, input.Treshold.Max); outputValues.Frequency = random.NextFloat(input.Frequency.Min, input.Frequency.Max); outputValues.SizeRatio = random.NextFloat(input.SizeRatio.Min, input.SizeRatio.Max); outputValues.NumNoises = random.Next((int)input.NumNoises.Min, (int)input.NumNoises.Max); return outputValues; }
public MyPanCakeFieldDesityFunction(MyRandom random, double frequency) { noise = new MySimplexFast(random.Next(), frequency); }
public MyCsgShapePlanet(MyRandom random, Vector3 translation, ref MyCsgShapePlanetShapeAttributes shapeAttributes, ref MyCsgShapePlanetHillAttributes hillAttributes, ref MyCsgShapePlanetHillAttributes canyonAttributes, float deviationFrequency = 0, float detailFrequency = 0) { m_translation = translation; m_random = random; m_shapeAttributes = shapeAttributes; m_hillAttributes = hillAttributes; m_canyonAttributes = canyonAttributes; m_canyonBlendTreshold = m_canyonAttributes.Treshold + m_canyonAttributes.BlendTreshold; m_hillBlendTreshold = m_hillAttributes.Treshold - m_hillAttributes.BlendTreshold; m_shapeAttributes.Radius = (shapeAttributes.Radius/2.0f) * (1 - shapeAttributes.DeviationScale * m_hillAttributes.SizeRatio); m_halfDeviation = (shapeAttributes.Radius / 2.0f) * shapeAttributes.DeviationScale; m_deviationFrequency = deviationFrequency; m_detailFrequency = detailFrequency; m_hillHalfDeviation = m_halfDeviation * m_hillAttributes.SizeRatio; m_canyonHalfDeviation = m_halfDeviation * m_canyonAttributes.SizeRatio; m_enableModulation = true; m_hillModule = new MyCompositeNoise(hillAttributes.NumNoises, hillAttributes.Frequency / m_shapeAttributes.Radius, random); m_canyonModule = new MyCompositeNoise(canyonAttributes.NumNoises, canyonAttributes.Frequency / m_shapeAttributes.Radius, random); m_normalModule = new MySimplexFast(seed: random.Next(), frequency: shapeAttributes.NormalNoiseFrequency / m_shapeAttributes.Radius); ComputeDerivedProperties(); }
public MyInfiniteDensityFunction(MyRandom random, double frequency) { noise = new MySimplexFast(random.Next(), frequency); }