public MyCsgShapeExcludedSphere(VRageMath.Vector3 translation, float radius, float exclusionRadius, float halfDeviation = 0, float deviationFrequency = 0, float detailFrequency = 0) { m_translation = translation; m_radius = radius; m_halfDeviation = halfDeviation; m_deviationFrequency = deviationFrequency; m_detailFrequency = detailFrequency; m_sphere = new MyCsgSphere(translation, radius, halfDeviation, deviationFrequency, detailFrequency); m_exclusionSphere = new MyCsgSphere(translation, exclusionRadius, halfDeviation, deviationFrequency, detailFrequency); }
public MyCsgShapeExcludedSphere(VRageMath.Vector3 translation, float radius,float exclusionRadius, float halfDeviation = 0, float deviationFrequency = 0, float detailFrequency = 0) { m_translation = translation; m_radius = radius; m_halfDeviation = halfDeviation; m_deviationFrequency = deviationFrequency; m_detailFrequency = detailFrequency; m_sphere = new MyCsgSphere(translation, radius, halfDeviation, deviationFrequency, detailFrequency); m_exclusionSphere = new MyCsgSphere(translation, exclusionRadius, halfDeviation, deviationFrequency, detailFrequency); }
private static void Generator(int version, int seed, float size, out MyCompositeShapeGeneratedData data) { var random = MyRandom.Instance; using (var stateToken = random.PushSeed(seed)) { data = new MyCompositeShapeGeneratedData(); data.FilledShapes = new MyCsgShapeBase[2]; data.RemovedShapes = new MyCsgShapeBase[2]; data.MacroModule = new MySimplexFast(seed: seed, frequency: 7f / size); switch (random.Next() & 0x1) { case 0: data.DetailModule = new MyRidgedMultifractalFast( seed: seed, quality: MyNoiseQuality.Low, frequency: random.NextFloat() * 0.09f + 0.11f, layerCount: 1); break; case 1: default: data.DetailModule = new MyBillowFast( seed: seed, quality: MyNoiseQuality.Low, frequency: random.NextFloat() * 0.07f + 0.13f, layerCount: 1); break; } float halfSize = size * 0.5f; float storageSize = VRageMath.MathHelper.GetNearestBiggerPowerOfTwo(size); float halfStorageSize = storageSize * 0.5f; float storageOffset = halfStorageSize - halfSize; MyCsgShapeBase primaryShape; { // determine primary shape var primaryType = random.Next() % 3; switch (primaryType) { case 0: //ShapeType.Torus { var secondaryRadius = (random.NextFloat() * 0.05f + 0.1f) * size; var torus = new MyCsgTorus( translation: new Vector3(halfStorageSize), invRotation: CreateRandomRotation(random), primaryRadius: (random.NextFloat() * 0.1f + 0.2f) * size, secondaryRadius: secondaryRadius, secondaryHalfDeviation: (random.NextFloat() * 0.4f + 0.4f) * secondaryRadius, deviationFrequency: random.NextFloat() * 0.8f + 0.2f, detailFrequency: random.NextFloat() * 0.6f + 0.4f); primaryShape = torus; } break; case 1: //ShapeType.Sphere default: { var sphere = new MyCsgSphere( translation: new Vector3(halfStorageSize), radius: (random.NextFloat() * 0.1f + 0.35f) * size, halfDeviation: (random.NextFloat() * 0.05f + 0.05f) * size + 1f, deviationFrequency: random.NextFloat() * 0.8f + 0.2f, detailFrequency: random.NextFloat() * 0.6f + 0.4f); primaryShape = sphere; } break; } } { // add some additional shapes int filledShapeCount = 0; data.FilledShapes[filledShapeCount++] = primaryShape; while (filledShapeCount < data.FilledShapes.Length) { var fromBorders = size * (random.NextFloat() * 0.2f + 0.1f) + 2f; var fromBorders2 = 2f * fromBorders; var sizeMinusFromBorders2 = size - fromBorders2; var shapeType = random.Next() % 3; switch (shapeType) { case 0: //ShapeType.Sphere { Vector3 center = CreateRandomPointOnBox(random, sizeMinusFromBorders2) + fromBorders; float radius = fromBorders * (random.NextFloat() * 0.4f + 0.35f); MyCsgSphere sphere = new MyCsgSphere( translation: center + storageOffset, radius: radius, halfDeviation: radius * (random.NextFloat() * 0.1f + 0.1f), deviationFrequency: random.NextFloat() * 0.8f + 0.2f, detailFrequency: random.NextFloat() * 0.6f + 0.4f); data.FilledShapes[filledShapeCount++] = sphere; } break; case 1: //ShapeType.Capsule { var start = CreateRandomPointOnBox(random, sizeMinusFromBorders2) + fromBorders; var end = new Vector3(size) - start; if ((random.Next() % 2) == 0) MyUtils.Swap(ref start.X, ref end.X); if ((random.Next() % 2) == 0) MyUtils.Swap(ref start.Y, ref end.Y); if ((random.Next() % 2) == 0) MyUtils.Swap(ref start.Z, ref end.Z); float radius = (random.NextFloat() * 0.25f + 0.5f) * fromBorders; MyCsgCapsule capsule = new MyCsgCapsule( pointA: start + storageOffset, pointB: end + storageOffset, radius: radius, halfDeviation: (random.NextFloat() * 0.25f + 0.5f) * radius, deviationFrequency: (random.NextFloat() * 0.4f + 0.4f), detailFrequency: (random.NextFloat() * 0.6f + 0.4f)); data.FilledShapes[filledShapeCount++] = capsule; } break; case 2: //ShapeType.Torus { Vector3 center = CreateRandomPointInBox(random, sizeMinusFromBorders2) + fromBorders; var rotation = CreateRandomRotation(random); var borderDistance = ComputeBoxSideDistance(center, size); var secondaryRadius = (random.NextFloat() * 0.15f + 0.1f) * borderDistance; var torus = new MyCsgTorus( translation: center + storageOffset, invRotation: rotation, primaryRadius: (random.NextFloat() * 0.2f + 0.5f) * borderDistance, secondaryRadius: secondaryRadius, secondaryHalfDeviation: (random.NextFloat() * 0.25f + 0.2f) * secondaryRadius, deviationFrequency: random.NextFloat() * 0.8f + 0.2f, detailFrequency: random.NextFloat() * 0.6f + 0.4f); data.FilledShapes[filledShapeCount++] = torus; } break; } } } { // make some holes int removedShapesCount = 0; while (removedShapesCount < data.RemovedShapes.Length) { var fromBorders = size * (random.NextFloat() * 0.2f + 0.1f) + 2f; var fromBorders2 = 2f * fromBorders; var sizeMinusFromBorders2 = size - fromBorders2; var shapeType = random.Next() % 7; switch (shapeType) { // Sphere case 0: { Vector3 center = CreateRandomPointInBox(random, sizeMinusFromBorders2) + fromBorders; float borderDistance = ComputeBoxSideDistance(center, size); float radius = (random.NextFloat() * 0.4f + 0.3f) * borderDistance; MyCsgSphere sphere = new MyCsgSphere( translation: center + storageOffset, radius: radius, halfDeviation: (random.NextFloat() * 0.3f + 0.35f) * radius, deviationFrequency: (random.NextFloat() * 0.8f + 0.2f), detailFrequency: (random.NextFloat() * 0.6f + 0.4f)); data.RemovedShapes[removedShapesCount++] = sphere; break; } // Torus case 1: case 2: case 3: { Vector3 center = CreateRandomPointInBox(random, sizeMinusFromBorders2) + fromBorders; var rotation = CreateRandomRotation(random); var borderDistance = ComputeBoxSideDistance(center, size); var secondaryRadius = (random.NextFloat() * 0.15f + 0.1f) * borderDistance; var torus = new MyCsgTorus( translation: center + storageOffset, invRotation: rotation, primaryRadius: (random.NextFloat() * 0.2f + 0.5f) * borderDistance, secondaryRadius: secondaryRadius, secondaryHalfDeviation: (random.NextFloat() * 0.25f + 0.2f) * secondaryRadius, deviationFrequency: random.NextFloat() * 0.8f + 0.2f, detailFrequency: random.NextFloat() * 0.6f + 0.4f); data.RemovedShapes[removedShapesCount++] = torus; } break; // Capsule default: { var start = CreateRandomPointOnBox(random, sizeMinusFromBorders2) + fromBorders; var end = new Vector3(size) - start; if ((random.Next() % 2) == 0) MyUtils.Swap(ref start.X, ref end.X); if ((random.Next() % 2) == 0) MyUtils.Swap(ref start.Y, ref end.Y); if ((random.Next() % 2) == 0) MyUtils.Swap(ref start.Z, ref end.Z); float radius = (random.NextFloat() * 0.25f + 0.5f) * fromBorders; MyCsgCapsule capsule = new MyCsgCapsule( pointA: start + storageOffset, pointB: end + storageOffset, radius: radius, halfDeviation: (random.NextFloat() * 0.25f + 0.5f) * radius, deviationFrequency: random.NextFloat() * 0.4f + 0.4f, detailFrequency: random.NextFloat() * 0.6f + 0.4f); data.RemovedShapes[removedShapesCount++] = capsule; } break; } } } { // generating materials // What to do when we (or mods) change the number of materials? Same seed will then produce different results. FillMaterials(version); Action<List<MyVoxelMaterialDefinition>> shuffleMaterials = (list) => { int n = list.Count; while (n > 1) { int k = (int)random.Next() % n; n--; var value = list[k]; list[k] = list[n]; list[n] = value; } }; shuffleMaterials(m_depositMaterials); if (m_surfaceMaterials.Count == 0) { if (m_depositMaterials.Count == 0) { data.DefaultMaterial = m_coreMaterials[(int)random.Next() % m_coreMaterials.Count]; } else { data.DefaultMaterial = m_depositMaterials[(int)random.Next() % m_depositMaterials.Count]; } } else { data.DefaultMaterial = m_surfaceMaterials[(int)random.Next() % m_surfaceMaterials.Count]; } if (false) { data.Deposits = new MyCompositeShapeOreDeposit[data.FilledShapes.Length]; int currentMaterial = 0; int depositCount = 0; data.Deposits[depositCount] = new MyCompositeShapeOreDeposit(data.FilledShapes[depositCount].DeepCopy(), m_coreMaterials[(int)random.Next() % m_coreMaterials.Count]); data.Deposits[depositCount].Shape.ShrinkTo(random.NextFloat() * 0.15f + 0.6f); ++depositCount; while (depositCount < data.FilledShapes.Length) { data.Deposits[depositCount] = new MyCompositeShapeOreDeposit(data.FilledShapes[depositCount].DeepCopy(), m_depositMaterials[currentMaterial++]); data.Deposits[depositCount].Shape.ShrinkTo(random.NextFloat() * 0.15f + 0.6f); ++depositCount; if (currentMaterial == m_depositMaterials.Count) { currentMaterial = 0; shuffleMaterials(m_depositMaterials); } } } else { int depositCount = Math.Max((int)Math.Log(size), data.FilledShapes.Length); data.Deposits = new MyCompositeShapeOreDeposit[depositCount]; var depositSize = size / 10f; int currentMaterial = 0; for (int i = 0; i < data.FilledShapes.Length; ++i) { MyVoxelMaterialDefinition material; if (i == 0) { if (m_coreMaterials.Count == 0) { if (m_depositMaterials.Count == 0) { material = m_surfaceMaterials[(int)random.Next() % m_surfaceMaterials.Count]; } else { material = m_depositMaterials[currentMaterial++]; } } else { material = m_coreMaterials[(int)random.Next() % m_coreMaterials.Count]; } } else { if (m_depositMaterials.Count == 0) { material = m_surfaceMaterials[(int)random.Next() % m_surfaceMaterials.Count]; } else { material = m_depositMaterials[currentMaterial++]; } } data.Deposits[i] = new MyCompositeShapeOreDeposit(data.FilledShapes[i].DeepCopy(), material); data.Deposits[i].Shape.ShrinkTo(random.NextFloat() * 0.15f + 0.6f); if (currentMaterial == m_depositMaterials.Count) { currentMaterial = 0; shuffleMaterials(m_depositMaterials); } } for (int i = data.FilledShapes.Length; i < depositCount; ++i) { var center = CreateRandomPointInBox(random, size * 0.7f) + storageOffset + size * 0.15f; var radius = random.NextFloat() * depositSize + 8f; random.NextFloat();random.NextFloat();//backwards compatibility MyCsgShapeBase shape = new MyCsgSphere(center, radius); MyVoxelMaterialDefinition material; if (m_depositMaterials.Count == 0) { material = m_surfaceMaterials[currentMaterial++]; } else { material = m_depositMaterials[currentMaterial++]; } data.Deposits[i] = new MyCompositeShapeOreDeposit(shape, material); if (m_depositMaterials.Count == 0) { if (currentMaterial == m_surfaceMaterials.Count) { currentMaterial = 0; shuffleMaterials(m_surfaceMaterials); } } else { if (currentMaterial == m_depositMaterials.Count) { currentMaterial = 0; shuffleMaterials(m_depositMaterials); } } } } m_surfaceMaterials.Clear(); m_coreMaterials.Clear(); m_depositMaterials.Clear(); } } }