public void CreateStructure(BoundsInt bound, IStructureGenerator structureGen) { // Generate all chunks inside bound //Vector3Int min = bound.min / 32; //Vector3Int max = bound.max / 32; //for (int cX = min.x; cX <= max.x; cX++) //{ // for (int cY = min.y; cY <= max.y; cY++) // { // for (int cZ = min.z; cZ <= max.z; cZ++) // { // Vector3Int dest = new Vector3Int(cX, cY, cZ); // if (InsideWorld(dest) && !chunks.ContainsKey(dest)) // { // CreateChunk(dest); // } // } // } //} //structureGen.Generate(bound, this); CustomJobs.CustomJob.TryAddJob(new WorldGen.GenericStructureGeneration(this, structureGen, bound)); }
public GenericStructureGeneration(World world, IStructureGenerator generator, BoundsInt bound) : base (BoundWorldToChunks(world, bound)) { this.generator = generator; this.bound = bound; this.world = world; //Debug.LogError($"StructureJob duplication check in use, heavy"); //if(cache.Contains(bound)) //{ // Debug.LogWarning($"Exact same structure populated at {bound}"); //} cache.Add(bound); isUnique = false; }
// TODO: resolve multiple dependencies public static void DoSeed(Chunk chunk, World world, WorldGen.StructureSeedDescriptor structureSeed, CustomJobs.CustomJob since = null, CustomJobs.CustomJob then = null, FastNoiseLite noise = null) { BoundsInt b; IStructureGenerator sg = null; // Use graph if any if (world.structureGraphs[(int)structureSeed.structureType] != null) { b = world.structureGraphs[(int)structureSeed.structureType].GetBounds(structureSeed.worldPos); sg = world.structureGraphs[(int)structureSeed.structureType].NewGenerator(); } else { #region Fallbacks // Special case, load test graph if (structureSeed.structureType == WorldGen.StructureType.Matryoshka) { #if PROFILE UnityEngine.Profiling.Profiler.BeginSample("StructureSeedPopulationPass: Matryoshka"); #endif // Calculate bounds and schedule the job b = world.matryoshkaGraph.GetBounds(structureSeed.worldPos); sg = world.matryoshkaGraph.NewGenerator(); // Run on main thread // world.matryoshkaGraph.NewGenerator().Generate(b, world); #if PROFILE UnityEngine.Profiling.Profiler.EndSample(); #endif return; } b = new BoundsInt(structureSeed.worldPos - WorldGen.Consts.structureSeedGenerationSizes[(int)structureSeed.structureType].min, WorldGen.Consts.structureSeedGenerationSizes[(int)structureSeed.structureType].size); switch (structureSeed.structureType) { // TODO: Use following pipeline instead: // Seed -> Primitives (readonly to chunks) -> Apply primitives (SingleChunkJob, Worker / GPU) case WorldGen.StructureType.Sphere: sg = new UglySphere(); break; case WorldGen.StructureType.Tree: sg = new TestTree(1, 0.5f); break; case WorldGen.StructureType.HangMushroom: // For test purpose, a single MultipleChunkJob is used first. sg = new HangMushroom_test(); break; // Moonlight Forest case WorldGen.StructureType.MoonForestGiantTree: sg = new TestTree(3, 1.0f) .SetGrowth(UnityEngine.Random.Range(100.0f, 140.0f)) .SetShape(2.35f, 1.3f, 2.1f, 0.5f) .SetColors(0x76573cff, 0x76573cff, 0x96c78cff) .SetLeaf(new TestTree.LeafRenderingSetup() { isNoisy = true, noise = noise, leaf = 0x317d18ff, leafVariant = 0x51991aff, variantRate = 0.3f, noiseScale = 5.0f }); break; case WorldGen.StructureType.MoonForestTree: sg = new TestTree(1, 1.0f) .SetShape(1.75f, 1.0f, 1.35f, 0.15f) .SetGrowth(UnityEngine.Random.Range(24.0f, 64.0f)) .SetColors(0x584a4dff, 0x584a4dff, 0x96c78cff); break; case WorldGen.StructureType.MoonFlower: sg = new UglySphere(); // TODO break; case WorldGen.StructureType.MoonFlowerVine: // TODO : just for test GameObject obj = new GameObject(); Light light = obj.AddComponent <Light>(); light.type = LightType.Point; light.shadows = LightShadows.None; light.transform.position = b.center; break; default: break; } #endregion } if (sg != null) { var job = new WorldGen.GenericStructureGeneration(world, sg, b); // resolve dependencies and schedule the job if (since != null) { job.Depends(since); } job = (WorldGen.GenericStructureGeneration)CustomJobs.CustomJob.TryAddJob(job); then?.Depends(job); } return; }