void Start() { BanditCampBuilder b = new BanditCampBuilder(new BanditCamp(new Vec2i(0,0), new Vec2i(4,4))); b.Generate(new GenerationRandom(0)); List<ChunkData> chunks = b.ToChunkData(); Chunks = new ChunkData[20, 20]; foreach (ChunkData c in chunks) { Chunks[c.X, c.Z] = c; } foreach (ChunkData cd in Chunks) { if (cd == null) continue; PreLoadedChunk plc = GeneratePreLoadedChunk(cd); CreateChunk(plc); } Player player = new Player(); PlayerManager.Instance.SetPlayer(player); }
private void Start() { int Size = 8; int seed = System.DateTime.Now.Millisecond; Debug.Log(seed); GenerationRandom genRan = new GenerationRandom(seed); TestBuildingBuilder tbb = new TestBuildingBuilder(new Vec2i(0, 0), new Vec2i(Size, Size)); for (int x = 0; x < Size / 2; x++) { for (int z = 0; z < Size / 2; z++) { // if (x != 0 || z != 0) // continue; int xP = x * World.ChunkSize * 2; int zP = z * World.ChunkSize * 2; } } /* * Building b = BuildingGenerator.CreateBuilding(genRan, out BuildingVoxels vox, Building.HOUSE); * Building b1 = BuildingGenerator.CreateBuilding(genRan, out BuildingVoxels vox1, Building.BLACKSMITH); * * Building b2 = BuildingGenerator.CreateBuilding(genRan, out BuildingVoxels vox2, Building.HOUSE); * Building b3 = BuildingGenerator.CreateBuilding(genRan, out BuildingVoxels vox3, Building.HOUSE); * Building b4 = BuildingGenerator.CreateBuilding(genRan, out BuildingVoxels vox4, Building.HOUSE); * * //tbb.AddBuilding(b, vox, new Vec2i(10, 10)); * tbb.AddBuilding(b1, vox1, new Vec2i(40, 40)); * tbb.AddBuilding(b2, vox2, new Vec2i(60, 60)); * tbb.AddBuilding(b3, vox3, new Vec2i(60, 40)); * tbb.AddBuilding(b4, vox4, new Vec2i(40, 60)); */ List <ChunkData> chunks = tbb.ToChunkData(); Chunks = new ChunkData[Size, Size]; foreach (ChunkData cd in chunks) { Chunks[cd.X, cd.Z] = cd; } foreach (ChunkData cd in Chunks) { PreLoadedChunk plc = GeneratePreLoadedChunk(cd); CreateChunk(plc, cd); } for (int x = 0; x < 20; x++) { //Debug.Log(tbb.GetVoxelNode(x,1,15); } }
/// <summary> /// Takes a 'preloadedchunk' and forms a loaded chunk /// This must be called from the main thread. /// </summary> /// <param name="pChunk"></param> /// <returns></returns> private LoadedChunk2 CreateChunk(PreLoadedChunk pChunk, ChunkData cd) { GameObject cObj = Instantiate(ChunkPrefab); cObj.transform.parent = ChunkHolder.transform; cObj.transform.position = pChunk.Position.AsVector3() * World.ChunkSize; cObj.name = "chunk_" + pChunk.Position; LoadedChunk2 loaded = cObj.GetComponent <LoadedChunk2>(); MeshFilter mf = loaded.GetComponent <MeshFilter>(); //Create the terrain mesh mf.mesh = PreLoadedChunk.CreateMesh(pChunk.TerrainMesh); mf.mesh.RecalculateNormals(); MeshCollider mc = loaded.GetComponent <MeshCollider>(); mc.sharedMesh = mf.mesh; //Iterate all voxels foreach (Voxel v in MiscUtils.GetValues <Voxel>()) { if (v == Voxel.none) { continue; } if (pChunk.VoxelMesh.TryGetValue(v, out PreMesh pmesh)) { GameObject voxelObj = Instantiate(ChunkVoxelPrefab); MeshFilter voxelMf = voxelObj.GetComponent <MeshFilter>(); voxelMf.mesh = PreLoadedChunk.CreateMesh(pmesh); Material voxMat = ResourceManager.GetVoxelMaterial(v); //Debug.Log(voxMat + " vox mat"); voxelObj.GetComponent <MeshRenderer>().material = voxMat; MeshCollider voxelMc = voxelObj.GetComponent <MeshCollider>(); voxelMc.sharedMesh = voxelMf.mesh; voxelObj.transform.parent = cObj.transform; voxelObj.transform.localPosition = Vector3.zero; voxelMf.mesh.RecalculateNormals(); } } if (cd.WorldObjects != null) { foreach (WorldObjectData objDat in cd.WorldObjects) { WorldObject obj = WorldObject.CreateWorldObject(objDat, cObj.transform, 0.7f); //if(objDat.AutoHeight) // obj.AdjustHeight(); //obj.transform.position = objDat.Position; //obj.transform.localPosition = objDat.Position.Mod(World.ChunkSize); } } loaded.SetChunk(pChunk.ChunkData); return(loaded); }
private LoadedChunk2 CreateChunk(PreLoadedChunk pChunk) { GameObject cObj = Instantiate(ChunkPrefab); cObj.transform.parent = transform; cObj.name = "chunk_" + pChunk.Position; LoadedChunk2 loaded = cObj.GetComponent<LoadedChunk2>(); MeshFilter mf = loaded.GetComponent<MeshFilter>(); //Create the terrain mesh mf.mesh = PreLoadedChunk.CreateMesh(pChunk.TerrainMesh); mf.mesh.RecalculateNormals(); MeshCollider mc = loaded.GetComponent<MeshCollider>(); mc.sharedMesh = mf.mesh; //Iterate all voxels foreach (Voxel v in MiscUtils.GetValues<Voxel>()) { if (v == Voxel.none) continue; if (pChunk.VoxelMesh.TryGetValue(v, out PreMesh pmesh)) { GameObject voxelObj = Instantiate(ChunkVoxelPrefab); MeshFilter voxelMf = voxelObj.GetComponent<MeshFilter>(); MeshRenderer voxelMr = voxelObj.GetComponent<MeshRenderer>(); voxelMr.material = ResourceManager.GetVoxelMaterial(v); voxelMf.mesh = PreLoadedChunk.CreateMesh(pmesh); MeshCollider voxelMc = voxelObj.GetComponent<MeshCollider>(); voxelMc.sharedMesh = voxelMf.mesh; voxelObj.transform.parent = cObj.transform; voxelObj.transform.localPosition = Vector3.up * (pChunk.ChunkData.BaseHeight + 0.7f); voxelMf.mesh.RecalculateNormals(); } } cObj.transform.position = pChunk.Position.AsVector3() * World.ChunkSize; loaded.SetChunk(pChunk.ChunkData); if (pChunk.ChunkData.WorldObjects != null) { foreach (WorldObjectData objData in pChunk.ChunkData.WorldObjects) { Vec2i localPos = Vec2i.FromVector3(objData.Position.Mod(World.ChunkSize)); float off = loaded.Chunk.GetHeight(localPos); WorldObject obj = WorldObject.CreateWorldObject(objData, loaded.transform, off + 0.7f); obj.AdjustHeight(); } } return loaded; }
// Start is called before the first frame update void Start() { for (int i = 0; i < 0; i++) { Debug.Log("TETSTETSTHSIBFM<DB NVGA>"); } int seed = 0; SubworldBuilder setB = new CaveDungeonBuilder(new Vec2i(2, 2), new Vec2i(8, 8)); setB.Generate(new GenerationRandom(seed)); List <ChunkData> chunks = setB.ToChunkData(); Chunks = new ChunkData[20, 20]; foreach (ChunkData c in chunks) { Chunks[c.X, c.Z] = c; } foreach (ChunkData cd in Chunks) { if (cd == null) { continue; } PreLoadedChunk plc = GeneratePreLoadedChunk(cd); CreateChunk(plc, cd); } Player player = new Player(); PlayerManager.Instance.SetPlayer(player); HeadLight.transform.parent = player.GetLoadedEntity().transform; }
/// <summary> /// Creates a pre loaded chunk from chunk data. /// This entire function is run in a thread /// </summary> /// <param name="cData"></param> /// <returns></returns> private PreLoadedChunk GeneratePreLoadedChunk(ChunkData chunk, int lod = 1) { //We create a thread safe mesh for the terrain // PreMesh terrainMesh = GenerateMarchingCubesTerrain(chunk); PreMesh terrainMesh = GenerateSmoothTerrain(chunk); Debug.Log("[ChunkLoader] Terrain mesh for " + chunk + " created - " + CurrentVerticies.Count + " verticies", Debug.CHUNK_LOADING); //Create the base pre-loaded chunk PreLoadedChunk preChunk = new PreLoadedChunk(new Vec2i(chunk.X, chunk.Z), terrainMesh, chunk); //if we have no voxel data, return just the terrain map if (chunk.VoxelData == null) { return(preChunk); } foreach (Voxel v in MiscUtils.GetValues <Voxel>()) { if (v == Voxel.none) { continue; } //If the chunk has this type of voxel in it if (chunk.VoxelData.VoxelTypeBounds.TryGetValue(v, out VoxelBounds vb)) { //Clear all lists to prepair CurrentVerticies.Clear(); CurrentTriangles.Clear(); CurrentColours.Clear(); CurrentUVs.Clear(); //Generate the voxel mesh //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize+1, World.ChunkHeight+1, World.ChunkSize+1, CurrentVerticies, CurrentTriangles); //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); MarchingCubes.Generate(chunk.VoxelData.AllVoxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); PreMesh voxelMesh = new PreMesh(); voxelMesh.Verticies = CurrentVerticies.ToArray(); voxelMesh.Triangles = CurrentTriangles.ToArray(); voxelMesh.UV = CreateUV(voxelMesh); //Add it the the pre loaded chunk preChunk.VoxelMesh.Add(v, voxelMesh); } } if (chunk.WorldObjects != null) { /*lock (ObjectsToLoadLock) * { * Debug.Log("[ChunkLoader] Chunk " + chunk.X + "," + chunk.Z + " has " + chunk.WorldObjects.Count + " objects to load", Debug.CHUNK_LOADING); * * ObjectsToLoad.AddRange(chunk.WorldObjects); * }*/ } return(preChunk); }
private PreLoadedChunk GeneratePreLoadedChunk(ChunkData chunk) { //Null till we integrate fully //ChunkData2[] neighbors = null; ChunkData[] neighbors = GetNeighbors(new Vec2i(chunk.X, chunk.Z)); float[] cube = new float[(World.ChunkSize + 1) * (World.ChunkSize + 1) * (World.ChunkHeight + 1)]; Color[,] colourMap = new Color[World.ChunkSize + 1, World.ChunkSize + 1]; //We iterate through the whole chunk, and create a cub map and colour map based on the //height map and tile map for (int x = 0; x < World.ChunkSize + 1; x++) { for (int z = 0; z < World.ChunkSize + 1; z++) { float height = chunk.BaseHeight; if (x == World.ChunkSize && z == World.ChunkSize) { if (neighbors != null && neighbors[1] != null) { height = neighbors[1].BaseHeight; if (neighbors[1].Heights != null) { height = neighbors[1].Heights[0, 0]; } colourMap[x, z] = neighbors[1].GetTile(0, 0).GetColor(); } else { height = chunk.Heights != null ? chunk.Heights[x - 1, z - 1] : height; colourMap[x, z] = chunk.GetTile(x - 1, z - 1).GetColor(); } } else if (x == World.ChunkSize) { if (neighbors != null && neighbors[2] != null) { height = neighbors[2].BaseHeight; if (neighbors[2].Heights != null) { height = neighbors[2].Heights[0, z]; } colourMap[x, z] = neighbors[2].GetTile(0, z).GetColor(); } else { height = chunk.Heights != null ? chunk.Heights[x - 1, z] : height; colourMap[x, z] = chunk.GetTile(x - 1, z).GetColor(); } } else if (z == World.ChunkSize) { if (neighbors != null && neighbors[0] != null) { height = neighbors[0].BaseHeight; if (neighbors[0].Heights != null) { height = neighbors[0].Heights[x, 0]; } colourMap[x, z] = neighbors[0].GetTile(x, 0).GetColor(); } else { height = chunk.Heights != null ? chunk.Heights[x, z - 1] : height; colourMap[x, z] = chunk.GetTile(x, z - 1).GetColor(); } } else { if (chunk.Heights != null) { height = chunk.Heights[x, z]; } colourMap[x, z] = chunk.GetTile(x, z).GetColor(); } for (int y = 0; y < height + 1; y++) { int idx = x + y * (World.ChunkSize + 1) + z * (World.ChunkHeight + 1) * (World.ChunkSize + 1); cube[idx] = -2; } } } CurrentVerticies.Clear(); CurrentTriangles.Clear(); CurrentColours.Clear(); //March the terrain map MarchingCubes.Generate(cube, World.ChunkSize + 1, World.ChunkHeight + 1, World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); /*for (int i = 0; i < CurrentTriangles.Count; i += 3) * { * int tri1 = CurrentTriangles[i]; * int tri2 = CurrentTriangles[i + 1]; * int tri3 = CurrentTriangles[i + 2]; * * //We find the average/mid point of this triangle * Vector3 mid = (CurrentVerticies[tri1] + CurrentVerticies[tri2] + CurrentVerticies[tri3]) / 3; * Vec2i tMid = Vec2i.FromVector3(mid); * Color c = colourMap[tMid.x, tMid.z]; * * CurrentColours.Add(c); * CurrentColours.Add(c); * CurrentColours.Add(c); * }*/ for (int i = 0; i < CurrentVerticies.Count; i++) { int x = (int)CurrentVerticies[i].x; int z = (int)CurrentVerticies[i].z; CurrentColours.Add(colourMap[x, z]); } //We create a thread safe mesh for the terrain PreMesh terrainMesh = new PreMesh(); terrainMesh.Verticies = CurrentVerticies.ToArray(); terrainMesh.Triangles = CurrentTriangles.ToArray(); terrainMesh.Colours = CurrentColours.ToArray(); terrainMesh.UV = CreateUV(terrainMesh); //Debug.Log("[ChunkLoader] Terrain mesh for " + chunk + " created - " + CurrentVerticies.Count + " verticies"); //Create the base pre-loaded chunk PreLoadedChunk preChunk = new PreLoadedChunk(new Vec2i(chunk.X, chunk.Z), terrainMesh, chunk); Debug.Log("Pre loaded chunk started, now for voxels"); //if we have no voxel data, return just the terrain map if (chunk.VoxelData == null) { Debug.Log("Chunk has no voxels"); return(preChunk); } foreach (Voxel v in MiscUtils.GetValues <Voxel>()) { if (v == Voxel.none) { continue; } if (!chunk.VoxelData.HasVoxel(v)) { // Debug.Log("Chunk " + chunk + " does not have the voxel " + v); continue; } CurrentVerticies.Clear(); CurrentTriangles.Clear(); CurrentColours.Clear(); CurrentUVs.Clear(); // Debug.Log("starting march"); //Generate the voxel mesh MarchingCubes.Generate(chunk.VoxelData.Voxels, null, v, World.ChunkSize + 1, World.ChunkHeight + 1, World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); PreMesh voxelMesh = new PreMesh(); voxelMesh.Verticies = CurrentVerticies.ToArray(); voxelMesh.Triangles = CurrentTriangles.ToArray(); voxelMesh.UV = CreateUV(voxelMesh); //Add it the the pre loaded chunk preChunk.VoxelMesh.Add(v, voxelMesh); /* * //If the chunk has this type of voxel in it * if (chunk.VoxelData.VoxelTypeBounds.TryGetValue(v, out VoxelBounds vb)) * { * //Clear all lists to prepair * CurrentVerticies.Clear(); * CurrentTriangles.Clear(); * CurrentColours.Clear(); * CurrentUVs.Clear(); * Debug.Log("starting march"); * * //Generate the voxel mesh * MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize+1, World.ChunkHeight+1, World.ChunkSize+1, CurrentVerticies, CurrentTriangles); * PreMesh voxelMesh = new PreMesh(); * voxelMesh.Verticies = CurrentVerticies.ToArray(); * voxelMesh.Triangles = CurrentTriangles.ToArray(); * voxelMesh.UV = CreateUV(voxelMesh); * //Add it the the pre loaded chunk * preChunk.VoxelMesh.Add(v, voxelMesh); * }*/ } return(preChunk); }
/// <summary> /// Creates a pre loaded chunk from chunk data. /// This entire function is run in a thread /// </summary> /// <param name="cData"></param> /// <returns></returns> private PreLoadedChunk GeneratePreLoadedChunk(ChunkData chunk, int lod = 1) { //We create a thread safe mesh for the terrain // PreMesh terrainMesh = GenerateMarchingCubesTerrain(chunk); ChunkData[] neighbors = ChunkRegionManager.GetNeighbors(new Vec2i(chunk.X, chunk.Z)); PreMesh terrainMesh = GenerateSmoothTerrain(chunk, neighbors, lod); terrainMesh.RecalculateNormals(); Debug.Log("[ChunkLoader] Terrain mesh for " + chunk + " created - " + CurrentVerticies.Count + " verticies", Debug.CHUNK_LOADING); //Create the base pre-loaded chunk PreLoadedChunk preChunk = new PreLoadedChunk(new Vec2i(chunk.X, chunk.Z), terrainMesh, chunk); //if we have no voxel data, return just the terrain map if (chunk.VoxelData == null) { return(preChunk); } int maxHeight = 0; if (neighbors != null) { foreach (ChunkData cd in neighbors) { if (cd != null && cd.VoxelData != null) { if (maxHeight < cd.VoxelData.TotalHeight()) { maxHeight = cd.VoxelData.TotalHeight(); } } } } //If the chunk hasn't had its boundry points defined, we do it now if (!chunk.VoxelData.HasBoundryVoxels) { for (int y = 0; y < maxHeight; y++) { for (int i = 0; i < World.ChunkSize; i++) { if (neighbors[0] != null && neighbors[0].VoxelData != null) { VoxelNode node = neighbors[0].VoxelData.GetVoxelNode(i, y, 0); if (node.IsNode) { chunk.VoxelData.SetVoxelNode(i, y, World.ChunkSize, node); } } if (neighbors[2] != null && neighbors[2].VoxelData != null) { VoxelNode node = neighbors[2].VoxelData.GetVoxelNode(0, y, i); if (node.IsNode) { chunk.VoxelData.SetVoxelNode(World.ChunkSize, y, i, node); } } } if (neighbors[1] != null && neighbors[1].VoxelData != null) { VoxelNode node = neighbors[1].VoxelData.GetVoxelNode(0, y, 0); if (node.IsNode) { chunk.VoxelData.SetVoxelNode(World.ChunkSize, y, World.ChunkSize, node); } } } chunk.VoxelData.HasBoundryVoxels = true; } //Next we generate all relevent voxel meshes foreach (Voxel v in MiscUtils.GetValues <Voxel>()) { if (v == Voxel.none) { continue; } //If the chunk has this type of voxel in it if (chunk.VoxelData.VoxelTypeBounds.TryGetValue(v, out VoxelBounds vb)) { //Clear all lists to prepair CurrentVerticies.Clear(); CurrentTriangles.Clear(); CurrentColours.Clear(); CurrentUVs.Clear(); //Generate the voxel mesh //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize+1, World.ChunkHeight+1, World.ChunkSize+1, CurrentVerticies, CurrentTriangles); //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); //MarchingCubes.Generate(chunk.VoxelData.AllVoxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); MarchingCubes.Generate(chunk.VoxelData.AllVoxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); PreMesh voxelMesh = new PreMesh(); voxelMesh.Verticies = CurrentVerticies.ToArray(); voxelMesh.Triangles = CurrentTriangles.ToArray(); voxelMesh.UV = CreateUV(voxelMesh); voxelMesh.RecalculateNormals(); //Add it the the pre loaded chunk preChunk.VoxelMesh.Add(v, voxelMesh); } } /* * if(chunk.WorldObjects != null) * { * * lock (ObjectsToLoadLock) * { * Debug.Log("[ChunkLoader] Chunk " + chunk.X + "," + chunk.Z + " has " + chunk.WorldObjects.Count + " objects to load", Debug.CHUNK_LOADING); * ObjectsToLoad.AddRange(chunk.WorldObjects); * } * * }*/ return(preChunk); }
/// <summary> /// Called to get the main thread to start generating chunks. /// </summary> private void InternalThreadLoop() { bool shouldLive = true; LoadedChunk2 toLoad; Vec2i position; //Form loop that lasts while we generate all chunks while (shouldLive) { UnityEngine.Profiling.Profiler.BeginSample("chunk_pre_load"); Debug.BeginDeepProfile("chunk_pre_load"); //thread safety lock (ChunkToLoadLock) { //If the count is 0, then the thread has finished for now. //Debug.Log("Chunks To Load: " + ChunksToLoad2.Count); if (ChunksToLoad2.Count == 0) { return; } toLoad = ChunksToLoad2.Dequeue(); position = toLoad.Position; } Debug.Log("[ChunkLoader] Chunk Loader starting to generate chunk " + toLoad.Position, Debug.CHUNK_LOADING); //Create pre-generated chunk PreLoadedChunk preLoaded = GeneratePreLoadedChunk(toLoad.Chunk, toLoad.LOD); preLoaded.SetLoadedChunk(toLoad); Debug.Log("[ChunkLoader] Finished creating PreChunk: " + toLoad.Position, Debug.CHUNK_LOADING); //Thread safe add the preloaded chunk lock (PreLoadedChunkLock) { PreLoadedChunks.Add(preLoaded); } Debug.EndDeepProfile("chunk_pre_load"); UnityEngine.Profiling.Profiler.EndSample(); //If we have requested a force load, we exit the thread. if (ForceLoad) { Debug.Log("[ChunkLoader] Force load is starting, need to finish loading chunk " + toLoad.Position, Debug.CHUNK_LOADING); return; } } /* * bool shouldLive = true; * ChunkData toLoad; * Vec2i position; * //Form loop that lasts while we generate all chunks * while (shouldLive) * { * UnityEngine.Profiling.Profiler.BeginSample("chunk_pre_load"); * Debug.BeginDeepProfile("chunk_pre_load"); * //thread safety * lock (ChunkToLoadLock) * { * * //If the count is 0, then the thread has finished for now. * if (ChunksToLoad.Count == 0) * return; * //otherwise, we set the object * toLoad = ChunksToLoad[0]; * ChunksToLoad.RemoveAt(0); * //We get the lowest priority chunk * * * * position = new Vec2i(toLoad.X, toLoad.Z); * } * Debug.Log("[ChunkLoader] Chunk Loader starting to generate chunk " + toLoad, Debug.CHUNK_LOADING); * * //Create pre-generated chunk * PreLoadedChunk preLoaded = GeneratePreLoadedChunk(toLoad); * Debug.Log("[ChunkLoader] Finished creating PreChunk: " + toLoad, Debug.CHUNK_LOADING); * * //Thread safe add the preloaded chunk * lock (PreLoadedChunkLock) * { * PreLoadedChunks.Add(preLoaded); * } * * Debug.EndDeepProfile("chunk_pre_load"); * UnityEngine.Profiling.Profiler.EndSample(); * * //If we have requested a force load, we exit the thread. * if (ForceLoad) * { * Debug.Log("[ChunkLoader] Force load is starting, need to finish loading chunk " + new Vec2i(toLoad.X, toLoad.Z), Debug.CHUNK_LOADING); * return; * } * * } */ }
/// <summary> /// Takes a 'preloadedchunk' and forms a loaded chunk /// This must be called from the main thread. /// </summary> /// <param name="pChunk"></param> /// <returns></returns> private LoadedChunk2 CreateChunk(PreLoadedChunk pChunk) { GameObject cObj = pChunk.LoadedChunk.gameObject; cObj.transform.parent = transform; cObj.name = "chunk_" + pChunk.Position; LoadedChunk2 loaded = pChunk.LoadedChunk; loaded.SetPreLoadedChunk(pChunk); loaded.gameObject.SetActive(true); MeshFilter mf = loaded.GetComponent <MeshFilter>(); //Create the terrain mesh mf.mesh = PreLoadedChunk.CreateMesh(pChunk.TerrainMesh); /*try * { * mf.mesh.RecalculateNormals(); * }catch(System.Exception e) * { * Debug.Log(e); * }*/ if (pChunk.LoadedChunk.LOD == 1) { MeshCollider mc = loaded.GetComponent <MeshCollider>(); mc.sharedMesh = mf.mesh; mc.enabled = true; } else { MeshCollider mc = loaded.GetComponent <MeshCollider>(); mc.sharedMesh = null; mc.enabled = false; } if (loaded.PreLoaded.VoxelMesh != null) { loaded.SetHasGeneratedVoxels(true); } if (loaded.LOD < 4 && loaded.HasGeneratedVoxels) { //loaded.SetHasGeneratedVoxels(true); //Iterate all voxels foreach (Voxel v in MiscUtils.GetValues <Voxel>()) { if (v == Voxel.none) { continue; } if (pChunk.VoxelMesh.TryGetValue(v, out PreMesh pmesh)) { GameObject voxelObj = Instantiate(ChunkVoxelPrefab); MeshFilter voxelMf = voxelObj.GetComponent <MeshFilter>(); MeshRenderer voxelMr = voxelObj.GetComponent <MeshRenderer>(); voxelMr.material = ResourceManager.GetVoxelMaterial(v); voxelMf.mesh = PreLoadedChunk.CreateMesh(pmesh); MeshCollider voxelMc = voxelObj.GetComponent <MeshCollider>(); voxelMc.sharedMesh = voxelMf.mesh; voxelObj.transform.parent = cObj.transform; voxelObj.transform.localPosition = Vector3.zero; // voxelMf.mesh.RecalculateNormals(); } } } cObj.transform.position = pChunk.Position.AsVector3() * World.ChunkSize; if (loaded.LOD < 3 && !loaded.HasLoadedWorldObjects) { loaded.SetHasLoadedWorldObjects(true); //loaded.SetChunk(pChunk.ChunkData); lock (ObjectsToLoadLock) { if (pChunk.ChunkData.WorldObjects != null) { ObjectsToLoad.AddRange(pChunk.ChunkData.WorldObjects); } } } return(loaded); }
/// <summary> /// Main update loop. /// We check if any pre-loaded chunks are ready. /// if so, we create a new loaded mesh as required. /// </summary> void Update() { for (int i = 0; i < MAX_CHUNK_LOADS_PER_FRAME; i++) { PreLoadedChunk toCreate = null; //Attempt to get a pre-loaded chunk so we can add it to the world. lock (PreLoadedChunkLock) { if (PreLoadedChunks.Count != 0) { toCreate = PreLoadedChunks[0]; PreLoadedChunks.RemoveAt(0); } } if (toCreate != null) { CreateChunk(toCreate); //ChunkRegionManager.LoadedChunks.Add(lc.Position, lc); //After this chunk has finished loading, we remove its position from the list of currently being generated chunks lock (ChunkToLoadLock) { ChunksToLoadPositions.Remove(toCreate.LoadedChunk.Position); } } } for (int i = 0; i < MAX_LOAD_PER_FRAME; i++) { if (ObjectsToLoad.Count > 0) { //Debug.Log("[ChunkLoader] " + ObjectsToLoad.Count + " objects to load in"); LoadSingleObject(); } } /* * PreLoadedChunk toCreate=null; * //Attempt to get a pre-loaded chunk so we can add it to the world. * lock (PreLoadedChunkLock) * { * if(PreLoadedChunks.Count != 0) * { * toCreate = PreLoadedChunks[0]; * PreLoadedChunks.RemoveAt(0); * } * } * * if(toCreate != null) * { * LoadedChunk2 lc = CreateChunk(toCreate); * ChunkRegionManager.LoadedChunks.Add(lc.Position, lc); * //After this chunk has finished loading, we remove its position from the list of currently being generated chunks * lock (ChunkToLoadLock) * { * ChunksToLoadPositions.Remove(lc.Position); * } * } * for(int i=0; i< MAX_LOAD_PER_FRAME; i++) * { * if (ObjectsToLoad.Count > 0) * { * //Debug.Log("[ChunkLoader] " + ObjectsToLoad.Count + " objects to load in"); * LoadSingleObject(); * } * } */ }
/// <summary> /// Calling this function forces the chunk loader to load all chunks currently in its list. /// This must be called from the main thread. /// </summary> public void ForceLoadAll() { ForceLoad = true; //Wait for the thread to finish MainThread?.Join(); Debug.BeginDeepProfile("force_chunk_load"); //All threads have stopped now, so we are not required to be thread safe. //TODO - add some thread generation here to improve performance? Debug.Log("[ChunkLoader] Force load starting - " + ChunksToLoad.Count + " chunks to load", Debug.CHUNK_LOADING); foreach (KeyValuePair <LoadedChunk2, float> kvp in ChunksToLoad2.GetAllElements()) { PreLoadedChunk plc = GeneratePreLoadedChunk(kvp.Key.Chunk, kvp.Key.LOD); plc.SetLoadedChunk(kvp.Key); PreLoadedChunks.Add(plc); } ChunksToLoad2.ClearQue(); ChunksToLoad.Clear(); Debug.Log("[ChunkLoader] Force load - " + PreLoadedChunks.Count + " chunks to create", Debug.CHUNK_LOADING); foreach (PreLoadedChunk plc in PreLoadedChunks) { //If for some reason this has already been generated, don't bother if (ChunkRegionManager.LoadedChunks.ContainsKey(plc.Position)) { Debug.Log("[ChunkLoader] Loaded chunk at position " + plc.Position + " has already generated", Debug.CHUNK_LOADING); continue; } CreateChunk(plc); //ChunkRegionManager.LoadedChunks.Add(lc.Position, lc); } PreLoadedChunks.Clear(); ChunksToLoadPositions.Clear(); ForceLoad = false; Debug.EndDeepProfile("force_chunk_load"); AstarPath.active.Scan(); /* * //We set the force load variable to true. * //this forces the chunk loader thread to stop when it can * ForceLoad = true; * //Wait for the thread to finish * MainThread?.Join(); * * Debug.BeginDeepProfile("force_chunk_load"); * //All threads have stopped now, so we are not required to be thread safe. * //TODO - add some thread generation here to improve performance? * Debug.Log("[ChunkLoader] Force load starting - " + ChunksToLoad.Count + " chunks to load", Debug.CHUNK_LOADING); * foreach(ChunkData cd in ChunksToLoad) * { * PreLoadedChunks.Add(GeneratePreLoadedChunk(cd)); * * } * ChunksToLoad.Clear(); * Debug.Log("[ChunkLoader] Force load - " + PreLoadedChunks.Count + " chunks to create", Debug.CHUNK_LOADING); * * foreach (PreLoadedChunk plc in PreLoadedChunks) * { * //If for some reason this has already been generated, don't bother * if (ChunkRegionManager.LoadedChunks.ContainsKey(plc.Position)) * { * Debug.Log("[ChunkLoader] Loaded chunk at position " + plc.Position + " has already generated", Debug.CHUNK_LOADING); * continue; * } * * LoadedChunk2 lc = CreateChunk(plc); * ChunkRegionManager.LoadedChunks.Add(lc.Position, lc); * } * PreLoadedChunks.Clear(); * ChunksToLoadPositions.Clear(); * ForceLoad = false; * Debug.EndDeepProfile("force_chunk_load"); * AstarPath.active.Scan(); */ }
public void SetPreLoadedChunk(PreLoadedChunk prc) { PreLoaded = prc; }