public void Finish() { chunk.UnlockLocalGroupForMeshing(); chunk.UpdateMeshLight(colors); int lightFlags = lightBFS.Dequeue(); Chunk downdown = chunk.neighbors[Dirs.DOWN].neighbors[Dirs.DOWN]; if (downdown != null) { while (lightBFS_U.Count > 0) { downdown.sunBFS.Enqueue(lightBFS_U.Dequeue()); } while (lightRBFS_U.Count > 0) { downdown.sunRBFS.Enqueue(lightRBFS_U.Dequeue()); } } Pools.c32N.Return(colors); Pools.intQN.Return(lightBFS); Pools.intQN.Return(lightBFS_U); Pools.lrnQN.Return(lightRBFS); Pools.lrnQN.Return(lightRBFS_U); // notify neighbors whom should update based on set light flags LightCalculator.CheckNeighborLightUpdate(chunk, lightFlags); }
public void Execute() { lights.flags = 0; LightCalculator.ProcessSunlight(ref lights, ref blocks, blockData, lightBFS, lightBFS_U, lightRBFS, lightRBFS_U); LightCalculator.LightUpdate(ref lights, faces, colors); lightBFS.Enqueue(lights.flags); }
// decode given byte array into nativearray for chunk static void DecodeChunk(byte[] buffer, int bytes, Chunk chunk) { var blocks = chunk.blocks; var lights = chunk.lights; // just resetting this here reader.Start(buffer, 0, uintBuffer, bytes); chunk.builtStructures = reader.ReadBool(); #if ENABLE_UNITY_COLLECTIONS_CHECKS var bh = AtomicSafetyHandle.Create(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref blocks, bh); var lh = AtomicSafetyHandle.Create(); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref lights, bh); #endif int i = 0; while (i < blocks.Length) { byte type = reader.ReadByte(); byte run = reader.ReadByte(); while (run-- > 0) { blocks[i++] = new Block { type = type }; } } LightCalculator.InitializeLights(lights, chunk.GetWorldPos()); #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.Release(bh); AtomicSafetyHandle.Release(lh); #endif }
public void Execute() { LightCalculator.LightUpdate(ref lights, faces, colors); }
public void Finish() { chunk.UnlockLocalGroupForMeshing(); chunk.UpdateMesh(vertices, normals, uvs, uv2s, colors, triangles); #if GEN_COLLIDERS if (chunk.needNewCollider) { chunk.UpdateColliderNative(colliderVerts, colliderTris); } Pools.v3Pool.Return(colliderVerts); Pools.intPool.Return(colliderTris); #endif int lightFlags = lightBFS.Dequeue(); // add unfinished sunlight nodes to downdown neighbor // then in update they check if any nodes in that queue and trigger a new type of light job update if so // can skip down neighbor because that was already fully propagated from this job so start with his down neighbor instead Chunk downdown = chunk.neighbors[Dirs.DOWN].neighbors[Dirs.DOWN]; if (downdown != null) { while (lightBFS_U.Count > 0) { downdown.sunBFS.Enqueue(lightBFS_U.Dequeue()); } while (lightRBFS_U.Count > 0) { downdown.sunRBFS.Enqueue(lightRBFS_U.Dequeue()); } } #if _DEBUG if (lightBFS.Count > 0) { if (tracking) { totalsIters++; //initLightTime += lightBFS.Dequeue(); //processLightTime += lightBFS.Dequeue(); //meshingTime += lightBFS.Dequeue(); //colliderTime += lightBFS.Dequeue(); //string output = string.Format("initLight:{0:0.0}, lighting:{1:0.0}, meshing:{2:0.0}, collider:{3:0.0}", // initLightTime / (float)totalsIters, // processLightTime / (float)totalsIters, // meshingTime / (float)totalsIters, // colliderTime / (float)totalsIters); initLightTime = lightBFS.Dequeue(); processLightTime = lightBFS.Dequeue(); meshingTime = lightBFS.Dequeue(); colliderTime = lightBFS.Dequeue(); string output = string.Format("initLight:{0:0.0}, lighting:{1:0.0}, meshing:{2:0.0}, collider:{3:0.0}", initLightTime, processLightTime, meshingTime, colliderTime); Debug.Log(output); } } #endif Pools.tloLN.Return(lightOps); Pools.intQN.Return(lightBFS); Pools.intQN.Return(lightBFS_U); Pools.lrnQN.Return(lightRBFS); Pools.lrnQN.Return(lightRBFS_U); // notify neighbors whom should update based on set light flags LightCalculator.CheckNeighborLightUpdate(chunk, lightFlags); }
// also record list of who needs to update after this (if u edit their light) public void Execute() { #if _DEBUG long initLightTime = 0; long processLightTime = 0; long meshingTime = 0; long colliderTime = 0; System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Restart(); UnityEngine.Profiling.Profiler.BeginSample("Lighting"); #endif //LightCalculator.AddSunlightRemovals(ref lights, lightOps, lightRBFS); // if chunk hasnt been rendered before then check each block to see if it has any lights if (calcInitialLight) { LightCalculator.CalcInitialLightOps(blocks.c, blockData, lightOps); #if _DEBUG initLightTime = watch.ElapsedMilliseconds; watch.Restart(); #endif LightCalculator.CalcInitialSunLight(blocks.c, blockData, lights.c, lights.u, lightBFS, upRendered, chunkWorldPos); } // always call this incase lightBFS comes with some data in it already LightCalculator.ProcessSunlight(ref lights, ref blocks, blockData, lightBFS, lightBFS_U, lightRBFS, lightRBFS_U); Assert.IsTrue(lightBFS.Count == 0 && lightRBFS.Count == 0); LightCalculator.ProcessTorchLightOpsOptimal(ref lights, ref blocks, blockData, lightOps, lightBFS, lightRBFS); Assert.IsTrue(lightBFS.Count == 0 && lightRBFS.Count == 0); int torchLightFlags = lights.flags; // add this so job controller can see after jobs done lightBFS.Enqueue(torchLightFlags); // also here maybe add nodes that weren't finished due to hitting bottom of chunks #if _DEBUG UnityEngine.Profiling.Profiler.EndSample(); processLightTime = watch.ElapsedMilliseconds; watch.Restart(); UnityEngine.Profiling.Profiler.BeginSample("Meshing"); #endif NativeMeshData meshData = new NativeMeshData(vertices, normals, uvs, uv2s, colors, triangles, faces); // add faces to this MeshBuilder.BuildNaive(ref meshData, ref blocks, ref lights, blockData); #if _DEBUG meshingTime = watch.ElapsedMilliseconds; watch.Restart(); UnityEngine.Profiling.Profiler.EndSample(); #endif #if GEN_COLLIDERS #if _DEBUG UnityEngine.Profiling.Profiler.BeginSample("Collider"); #endif if (genCollider) { MeshBuilder.BuildGreedyCollider(ref blocks, colliderVerts, colliderTris); } #if _DEBUG colliderTime = watch.ElapsedMilliseconds; UnityEngine.Profiling.Profiler.EndSample(); #endif #endif #if _DEBUG lightBFS.Enqueue((int)initLightTime); lightBFS.Enqueue((int)processLightTime); lightBFS.Enqueue((int)meshingTime); lightBFS.Enqueue((int)colliderTime); #endif }
static void AddBlockFaces(int x, int y, int z, ref NativeMeshData data, ref NativeArray3x3 <Block> blocks, ref NativeArray3x3 <Light> lights, NativeArray <BlockData> blockData) { bool isLight = LightCalculator.GetIsLight(lights.Get(x, y, z).torch); if (!BlockData.RenderSolid(blockData, blocks.Get(x - 1, y, z), Dir.east)) { AddWestFace(x, y, z, ref data); AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.west, isLight); data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x - 1, y, z))); data.AddFaceNormal(Dirs.norm3f[Dirs.WEST]); data.faces.Add(new Face { pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.west }); } if (!BlockData.RenderSolid(blockData, blocks.Get(x, y - 1, z), Dir.up)) { AddDownFace(x, y, z, ref data); AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.down, isLight); data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x, y - 1, z))); data.AddFaceNormal(Dirs.norm3f[Dirs.DOWN]); data.faces.Add(new Face { pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.down }); } if (!BlockData.RenderSolid(blockData, blocks.Get(x, y, z - 1), Dir.north)) { AddSouthFace(x, y, z, ref data); AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.south, isLight); data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x, y, z - 1))); data.AddFaceNormal(Dirs.norm3f[Dirs.SOUTH]); data.faces.Add(new Face { pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.south }); } if (!BlockData.RenderSolid(blockData, blocks.Get(x + 1, y, z), Dir.west)) { AddEastFace(x, y, z, ref data); AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.east, isLight); data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x + 1, y, z))); data.AddFaceNormal(Dirs.norm3f[Dirs.EAST]); data.faces.Add(new Face { pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.east }); } if (!BlockData.RenderSolid(blockData, blocks.Get(x, y + 1, z), Dir.down)) { AddUpFace(x, y, z, ref data); AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.up, isLight); data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x, y + 1, z))); data.AddFaceNormal(Dirs.norm3f[Dirs.UP]); data.faces.Add(new Face { pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.up }); } if (!BlockData.RenderSolid(blockData, blocks.Get(x, y, z + 1), Dir.south)) { AddNorthFace(x, y, z, ref data); AddUVs(x, y, z, ref data, ref blocks, blockData, Dir.north, isLight); data.AddFaceColor(LightCalculator.GetColorFromLight(lights.Get(x, y, z + 1))); data.AddFaceNormal(Dirs.norm3f[Dirs.NORTH]); data.faces.Add(new Face { pos = (ushort)(x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE), dir = Dir.north }); } }
public static void Run() { passes = 0; failures = 0; { TestEqual(Dirs.Opp(Dir.west), Dir.east, "DirTest1"); TestEqual(Dirs.Opp(Dir.down), Dir.up, "DirTest2"); TestEqual(Dirs.Opp(Dir.south), Dir.north, "DirTest3"); TestEqual(Dirs.Opp(Dir.east), Dir.west, "DirTest4"); TestEqual(Dirs.Opp(Dir.up), Dir.down, "DirTest5"); TestEqual(Dirs.Opp(Dir.north), Dir.south, "DirTest6"); } { TestEqual(WorldUtils.GetRegionCoord(new Vector3i(0, 0, 0)), new Vector3i(0, 0, 0), "RegionCoordTest1"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(1, 0, 0)), new Vector3i(0, 0, 0), "RegionCoordTest2"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(5, 5, 5)), new Vector3i(0, 0, 0), "RegionCoordTest3"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(15, 15, 15)), new Vector3i(0, 0, 0), "RegionCoordTest4"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(16, 16, 16)), new Vector3i(1, 1, 1), "RegionCoordTest5"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(18, 5, 5)), new Vector3i(1, 0, 0), "RegionCoordTest6"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(-1, 0, 0)), new Vector3i(-1, 0, 0), "RegionCoordTest7"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(0, -1, 0)), new Vector3i(0, -1, 0), "RegionCoordTest8"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(0, 0, -1)), new Vector3i(0, 0, -1), "RegionCoordTest9"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(0, 0, -1)), new Vector3i(0, 0, -1), "RegionCoordTest10"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(14, 15, 15)), new Vector3i(0, 0, 0), "RegionCoordTest11"); TestEqual(WorldUtils.GetRegionCoord(new Vector3i(17, 15, 15)), new Vector3i(1, 0, 0), "RegionCoordTest12"); } { // written assuming 2 blocks per unit TestEqual(WorldUtils.GetChunkPosFromWorldPos(new Vector3(0, 0, 0)), new Vector3i(0, 0, 0), "ChunkPos1"); TestEqual(WorldUtils.GetChunkPosFromWorldPos(new Vector3(-1.0f, 0, 0)), new Vector3i(-1, 0, 0), "ChunkPos2"); TestEqual(WorldUtils.GetChunkPosFromWorldPos(new Vector3(-16.01f, 0, 0)), new Vector3i(-2, 0, 0), "ChunkPos3"); TestEqual(WorldUtils.GetChunkPosFromWorldPos(new Vector3(25, 35, -5)), new Vector3i(1, 2, -1), "ChunkPos4"); } { TestEqual(WorldUtils.GetChunkPosFromBlockPos(0, 13, 0), new Vector3i(0, 0, 0), "GCPFBP1"); TestEqual(WorldUtils.GetChunkPosFromBlockPos(32, 34, 0), new Vector3i(1, 1, 0), "GCPFBP2"); TestEqual(WorldUtils.GetChunkPosFromBlockPos(0, -1, 0), new Vector3i(0, -1, 0), "GCPFBP3"); TestEqual(WorldUtils.GetChunkPosFromBlockPos(-15, 0, 0), new Vector3i(-1, 0, 0), "GCPFBP4"); TestEqual(WorldUtils.GetChunkPosFromBlockPos(-16, 0, 0), new Vector3i(-1, 0, 0), "GCPFBP5"); TestEqual(WorldUtils.GetChunkPosFromBlockPos(-31, 0, 0), new Vector3i(-1, 0, 0), "GCPFBP6"); TestEqual(WorldUtils.GetChunkPosFromBlockPos(-32, 0, 0), new Vector3i(-1, 0, 0), "GCPFBP7"); TestEqual(WorldUtils.GetChunkPosFromBlockPos(-33, 0, 0), new Vector3i(-2, 0, 0), "GCPFBP8"); TestEqual(WorldUtils.GetChunkPosFromBlockPos(-33, 0, 40), new Vector3i(-2, 0, 1), "GCPFBP9"); } { TestEqual(Serialization.GetTablePos(new Vector3i(0, 0, 0)), 0, "LookUpPos1"); TestEqual(Serialization.GetTablePos(new Vector3i(1, 0, 0)), 4, "LookUpPos2"); TestEqual(Serialization.GetTablePos(new Vector3i(0, 1, 0)), 1024, "LookUpPos3"); TestEqual(Serialization.GetTablePos(new Vector3i(-1, 0, 0)), 60, "LookUpPos4"); } { TestEqual(Mth.Mod16(0), 0, "Mod16_1"); TestEqual(Mth.Mod16(15), 15, "Mod16_2"); TestEqual(Mth.Mod16(16), 0, "Mod16_3"); TestEqual(Mth.Mod16(35), 3, "Mod16_4"); TestEqual(Mth.Mod16(-1), 15, "Mod16_5"); TestEqual(Mth.Mod16(-16), 0, "Mod16_6"); TestEqual(Mth.Mod16(-5), 11, "Mod16_7"); } { int b = 0; b |= 0x1; TestEqual(b & 0x1, 1, "bit1"); TestEqual(0x1, 1, "hex0"); TestEqual(0x2, 2, "hex1"); TestEqual(0x4, 4, "hex2"); TestEqual(0x8, 8, "hex3"); TestEqual(0x10, 16, "hex4"); TestEqual(0x20, 32, "hex5"); TestEqual(0x40, 64, "hex6"); TestEqual(0x80, 128, "hex7"); TestEqual(0x100, 256, "hex8"); TestEqual(0x200, 512, "hex9"); TestEqual(0x400, 1024, "hex10"); TestEqual(0x800, 2048, "hex11"); TestEqual(0x1000, 4096, "hex12"); } { // U RRRRR GGGGG BBBBB ushort torch = 0b0_00010_00110_10011; TestEqual(LightCalculator.GetRed(torch), 2, "torch1"); TestEqual(LightCalculator.GetGreen(torch), 6, "torch2"); TestEqual(LightCalculator.GetBlue(torch), 19, "torch3"); TestEqual(LightCalculator.GetIsLight(torch), false, "torchb1"); torch = 0b0_11111_00000_11111; TestEqual(LightCalculator.GetRed(torch), 31, "torch4"); TestEqual(LightCalculator.GetGreen(torch), 0, "torch5"); TestEqual(LightCalculator.GetBlue(torch), 31, "torch6"); torch = LightCalculator.SetIsLight(torch, true); TestEqual(LightCalculator.GetIsLight(torch), true, "torchb1"); torch = 0b0_10000_00100_01010; TestEqual(LightCalculator.GetRed(torch), 16, "torch7"); TestEqual(LightCalculator.GetGreen(torch), 4, "torch8"); TestEqual(LightCalculator.GetBlue(torch), 10, "torch9"); torch = LightCalculator.SetRed(torch, 8); TestEqual(torch, (ushort)0b0_01000_00100_01010, "torch10"); torch = LightCalculator.SetBlue(torch, 23); TestEqual(torch, (ushort)0b0_01000_00100_10111, "torch11"); torch = LightCalculator.SetGreen(torch, 0); TestEqual(torch, (ushort)0b0_01000_00000_10111, "torch12"); torch = LightCalculator.SetIsLight(torch, true); TestEqual(LightCalculator.GetIsLight(torch), true, "torchb1"); torch = LightCalculator.SetIsLight(torch, false); TestEqual(LightCalculator.GetIsLight(torch), false, "torchb1"); int c = LightCalculator.GetColor(31, 31, 31); TestEqual(LightCalculator.GetRed(c), 31, "torch13"); TestEqual(LightCalculator.GetGreen(c), 31, "torch14"); TestEqual(LightCalculator.GetBlue(c), 31, "torch15"); c = LightCalculator.GetColor(1, 7, 30); TestEqual(LightCalculator.GetRed(c), 1, "torch16"); TestEqual(LightCalculator.GetGreen(c), 7, "torch17"); TestEqual(LightCalculator.GetBlue(c), 30, "torch18"); c = LightCalculator.GetColor(0, 0, 0); TestEqual(LightCalculator.GetRed(c), 0, "torch19"); TestEqual(LightCalculator.GetGreen(c), 0, "torch20"); TestEqual(LightCalculator.GetBlue(c), 0, "torch21"); torch = 0b0_00010_00110_10011; TestEqual(LightCalculator.GetChannel(torch, 2), 2, "torch1"); TestEqual(LightCalculator.GetChannel(torch, 1), 6, "torch2"); TestEqual(LightCalculator.GetChannel(torch, 0), 19, "torch3"); TestEqual(LightCalculator.GetIsLight(torch), false, "torchb1"); torch = 0b1_11111_00000_11111; TestEqual(LightCalculator.GetIsLight(torch), true, "torchb1"); TestEqual(LightCalculator.GetChannel(torch, 2), 31, "torch4"); TestEqual(LightCalculator.GetChannel(torch, 1), 0, "torch5"); TestEqual(LightCalculator.GetChannel(torch, 0), 31, "torch6"); TestEqual(LightCalculator.GetIsLight(torch), true, "torchb1"); torch = 0b1_10000_00100_01010; TestEqual(LightCalculator.GetChannel(torch, 2), 16, "torch7"); TestEqual(LightCalculator.GetChannel(torch, 1), 4, "torch8"); TestEqual(LightCalculator.GetChannel(torch, 0), 10, "torch9"); torch = LightCalculator.SetChannel(torch, 2, 8); TestEqual(torch, (ushort)0b1_01000_00100_01010, "torch10"); torch = LightCalculator.SetChannel(torch, 0, 23); TestEqual(torch, (ushort)0b1_01000_00100_10111, "torch11"); torch = LightCalculator.SetChannel(torch, 1, 0); TestEqual(torch, (ushort)0b1_01000_00000_10111, "torch12"); TestEqual(LightCalculator.GetIsLight(torch), true, "torchb1"); c = LightCalculator.GetColor(31, 31, 31); TestEqual(LightCalculator.GetChannel(c, 2), 31, "torch13"); TestEqual(LightCalculator.GetChannel(c, 1), 31, "torch14"); TestEqual(LightCalculator.GetChannel(c, 0), 31, "torch15"); c = LightCalculator.GetColor(1, 7, 30); TestEqual(LightCalculator.GetChannel(c, 2), 1, "torch16"); TestEqual(LightCalculator.GetChannel(c, 1), 7, "torch17"); TestEqual(LightCalculator.GetChannel(c, 0), 30, "torch18"); c = LightCalculator.GetColor(0, 0, 0); TestEqual(LightCalculator.GetChannel(c, 2), 0, "torch19"); TestEqual(LightCalculator.GetChannel(c, 1), 0, "torch20"); TestEqual(LightCalculator.GetChannel(c, 0), 0, "torch21"); TestEqual(LightCalculator.GetIsLight(torch), true, "torchb1"); } { BlockData test = new BlockData(0) { colliderSolid = 0, }; TestEqual(test.texture, 0, "bd1"); TestEqual(test.light, (ushort)0, "bd2"); TestEqual(test.renderType, (byte)1, "bd3"); TestEqual(test.colliderSolid, (byte)0, "bd4"); TestEqual(test.renderSolid, (byte)1, "bd5"); } { TestStruct t; t.member = 0; TestEqual(t.member, 0, "struct1"); t.IncMember(); TestEqual(t.member, 1, "struct2"); } string msg = string.Format("{0}/{1} tests passed", passes, passes + failures); if (failures == 0) { Debug.Log(string.Format("<color=#00FF00><b>{0}</b></color>", msg)); } else { Debug.Log(msg); } }
// inits BlockData[] array for managed and also // returns a NativeArray version for jobs public static NativeArray <BlockData> InitBlockData() { data = new BlockData[] { new BlockData(0) // AIR { renderType = 0, renderSolid = 0, colliderSolid = 0, lightReduction = 0, }, new BlockData(0) // STONE { texture = -1, renderType = 2, }, new BlockData(0) // GRASS { texture = -1, // figured out dynamically renderType = 2, }, new BlockData(0) // PINE { texture = -1, renderType = 2, }, new BlockData(0) // PINELEAF { renderSolid = 0, renderType = 2, texture = 6, lightReduction = 4, }, new BlockData(0) // TORCH { light = LightCalculator.GetColor(31, 31, 31), texture = 7, }, new BlockData(0) // TORCH R { light = LightCalculator.GetColor(31, 0, 0), texture = 7, }, new BlockData(0) // TORCH B { light = LightCalculator.GetColor(0, 31, 0), texture = 7, }, new BlockData(0) // TORCH G { light = LightCalculator.GetColor(0, 0, 31), texture = 7, }, new BlockData(0) // TORCH M { light = LightCalculator.GetColor(31, 0, 31), texture = 7, }, new BlockData(0) // TORCH Y { light = LightCalculator.GetColor(31, 31, 0), texture = 7, }, new BlockData(0) // TORCH O { light = LightCalculator.GetColor(31, 15, 0), texture = 7, }, new BlockData(0) // TORCH W { light = LightCalculator.GetColor(10, 10, 10), texture = 7, }, new BlockData(0) // COAL { texture = 7, renderType = 2, }, new BlockData(0) // RUBY { texture = 8, renderType = 2, light = LightCalculator.GetColor(20, 0, 0), }, new BlockData(0) // EMERALD { texture = 9, renderType = 2, light = LightCalculator.GetColor(0, 20, 0), }, new BlockData(0) // SAPPHIRE { texture = 10, renderType = 2, light = LightCalculator.GetColor(0, 0, 20), } }; return(new NativeArray <BlockData>(data, Allocator.Persistent)); }
public static void Generate(Vector3 chunkWorldPos, NativeArray <Block> blocks, NativeArray <Light> lights) { // make this single loop instead and calculate x,y,z from index i for (int y = 0; y < Chunk.SIZE; ++y) { for (int z = 0; z < Chunk.SIZE; ++z) { for (int x = 0; x < Chunk.SIZE; ++x) { Vector3 wp = new Vector3(x, y, z) / Chunk.BPU + chunkWorldPos + new Vector3(55.0f, 12.4f, 87.5f); float n = 0.0f; // experiment with catlike coding noise some more //NoiseSample samp = Noise.Sum(Noise.Simplex3D, wp, 0.015f, 5, 2.0f, 0.5f); //float n = samp.value * 3.0f; // TODO: convert shapes.cginc into c# equiv, and or get gen going on multiple thread (try job system!!!) // this is adding a flat ground plane density at low strength, so as you go lower will slowly become solid n -= Vector3.Dot(wp, Vector3.up) * 0.03f; //n += Fractal(wp, 5, 0.01f); float4 ng = Mth.FractalGrad(wp, 5, 0.01f); n += ng.x; Block b = Blocks.AIR; if (n > 0.25f) { b = Blocks.STONE; } else if (n > 0.15f) { b = Blocks.STONE; // todo switch to using math.dot if (Vector3.Dot(Vector3.up, new Vector3(ng.y, ng.z, ng.w).normalized) < .7f) { b = Blocks.GRASS; } // trying to make grass not spawn on cliff edge... //if (Mathf.Abs(samp.derivative.normalized.y) < 0.4f) { // chunk.SetBlock(x, y, z, new BlockGrass()); //} else { // chunk.SetBlock(x, y, z, new Block()); //} } if (b == Blocks.STONE) { float coal = Mth.Billow(wp + new Vector3(1000, 722, 255), 2, 0.04f, 1, 0.6f); if (coal > 0.0f) { b = Blocks.COAL; } } // add caves if (b != Blocks.AIR) { // octaves of 5 and 0.015 was pretty good too n = Mth.Ridged(wp + new Vector3(500, -5000, 1000), 4, 0.01f); if (n > 0.75f - math.abs(wp.y) * 0.001f) // as you go deeper caves open up is the idea here { b = Blocks.AIR; } } // for testing singular blocks //if (b != Blocks.COAL) { // b = Blocks.AIR; //} blocks[x + z * Chunk.SIZE + y * Chunk.SIZE * Chunk.SIZE] = b; } } } LightCalculator.InitializeLights(lights, chunkWorldPos); }