public void AddChunkMeshes(Chunk chunk) { for (int i = 0; i < chunk.Meshes.Count; i++) { AddMesh(chunk.Meshes[i]); } }
public bool Contains(ref ChunkCoordinate coords, out Chunk chunk) { int x = coords.X & _dimMask; int z = coords.Z & _dimMask; chunk = Chunks[x, z]; return (chunk != null) ? chunk.Coords.Equals(ref coords) : false; }
public void Store(Chunk chunk, ChunkManager manager) { int x = chunk.Coords.X & _dimMask; int z = chunk.Coords.Z & _dimMask; if (Chunks[x, z] != null) { LoadedChunks.Remove(Chunks[x, z]); manager.PrepareChunkForUnload(Chunks[x, z]); } Chunks[x, z] = chunk; LoadedChunks.Add(chunk); ChunksAddedSinceSort = true; }
public void RemoveChunkMeshes(Chunk chunk) { for (int i = 0; i < chunk.Meshes.Count; i++) { RemoveMesh(chunk.Meshes[i]); } }
public bool Contains(Chunk chunk) { return LoadedChunks.Contains(chunk); }
public void ConsolidateFlags(Chunk chunk, byte neighbors) { if (chunk.State >= ChunkState.Loading) NeighborsInMemoryFlag |= neighbors; if (chunk.State >= ChunkState.Loaded) LightDependenciesFlag |= neighbors; if (chunk.State >= ChunkState.PendingBuild) BuildDependenciesFlag |= neighbors; }
public void NeighborChangedStateCallback(ChunkManager manager, Chunk chunk, ChunkState state) { switch (state) { case ChunkState.Loaded: { LightDependenciesFlag |= Coords.Neighbors(ref chunk.Coords); break; } case ChunkState.PendingLight: break; case ChunkState.Lighting: break; case ChunkState.PendingBuild: { BuildDependenciesFlag |= Coords.Neighbors(ref chunk.Coords); break; } case ChunkState.Built: break; case ChunkState.PendingRebuild: break; case ChunkState.Unloading: { byte val = Coords.Neighbors(ref chunk.Coords); if((NeighborsInMemoryFlag & val) == val) NeighborsInMemoryFlag -= val; if((LightDependenciesFlag & val) == val) LightDependenciesFlag -= val; if((BuildDependenciesFlag & val) == val) BuildDependenciesFlag -= val; StateChanged -= chunk.NeighborChangedStateCallback; chunk.StateChanged -= NeighborChangedStateCallback; break; } } }
//WARN: When load dist is a power of 2 chunks constantly ask to load more chunks. public void QueueNeighbors(Chunk chunk) { Chunk neighborchunk; ChunkCoordinate neighborcoords; Vector3 newpos; bool contains; //+x //Get new chunkcoords chunk.Coords.Add(1, 0, out neighborcoords); contains = ChunkStorage.Contains(ref neighborcoords, out neighborchunk); if ((chunk.NeighborsInMemoryFlag & 1) != 1) { if (!contains) { //Shift this chunks position to get the new chunks relative position newpos.X = chunk.Position.X + Chunk.WIDTH; newpos.Y = chunk.Position.Y; newpos.Z = chunk.Position.Z; //Create a new chunk neighborchunk = new Chunk(this, ref neighborcoords, ref newpos); //Update flag and connect event chain to neighbor chunk.NeighborsInMemoryFlag |= 1; neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; //Add new chunk to manager AddChunk(neighborchunk); } else if (contains)//Chunk is already in memory connect to it { //Update flag and connect event chain to neighbor chunk.ConsolidateFlags(neighborchunk, 1); neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; } } //-x //Get new chunkcoords chunk.Coords.Add(-1, 0, out neighborcoords); contains = ChunkStorage.Contains(ref neighborcoords, out neighborchunk); if ((chunk.NeighborsInMemoryFlag & 2) != 2) { if (!contains) { //Shift this chunks position to get the new chunks relative position newpos.X = chunk.Position.X - Chunk.WIDTH; newpos.Y = chunk.Position.Y; newpos.Z = chunk.Position.Z; //Create a new chunk neighborchunk = new Chunk(this, ref neighborcoords, ref newpos); //Update flag and connect event chain to neighbor chunk.NeighborsInMemoryFlag |= 2; neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; //Add new chunk to manager AddChunk(neighborchunk); } else if (contains)//Chunk is already in memory connect to it { //Update flag and connect event chain to neighbor chunk.ConsolidateFlags(neighborchunk, 2); neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; } } //+z //Get new chunkcoords chunk.Coords.Add(0, 1, out neighborcoords); contains = ChunkStorage.Contains(ref neighborcoords, out neighborchunk); if ((chunk.NeighborsInMemoryFlag & 4) != 4) { if (!contains) { //Shift this chunks position to get the new chunks relative position newpos.X = chunk.Position.X; newpos.Y = chunk.Position.Y; newpos.Z = chunk.Position.Z + Chunk.WIDTH; //Create a new chunk neighborchunk = new Chunk(this, ref neighborcoords, ref newpos); //Update flag and connect event chain to neighbor chunk.NeighborsInMemoryFlag |= 4; neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; //Add new chunk to manager AddChunk(neighborchunk); } else if (contains)//Chunk is already in memory connect to it { //Update flag and connect event chain to neighbor chunk.ConsolidateFlags(neighborchunk, 4); neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; } } //-z //Get new chunkcoords chunk.Coords.Add(0, -1, out neighborcoords); contains = ChunkStorage.Contains(ref neighborcoords, out neighborchunk); if ((chunk.NeighborsInMemoryFlag & 8) != 8) { if (!contains) { //Shift this chunks position to get the new chunks relative position newpos.X = chunk.Position.X; newpos.Y = chunk.Position.Y; newpos.Z = chunk.Position.Z - Chunk.WIDTH; //Create a new chunk neighborchunk = new Chunk(this, ref neighborcoords, ref newpos); //Update flag and connect event chain to neighbor chunk.NeighborsInMemoryFlag |= 8; neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; //Add new chunk to manager AddChunk(neighborchunk); } else if (contains)//Chunk is already in memory connect to it { //Update flag and connect event chain to neighbor chunk.ConsolidateFlags(neighborchunk, 8); neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; } } //+x +z //Get new chunkcoords chunk.Coords.Add(1, 1, out neighborcoords); contains = ChunkStorage.Contains(ref neighborcoords, out neighborchunk); if ((chunk.NeighborsInMemoryFlag & 16) != 16) { if (!contains) { //Shift this chunks position to get the new chunks relative position newpos.X = chunk.Position.X + Chunk.WIDTH; newpos.Y = chunk.Position.Y; newpos.Z = chunk.Position.Z + Chunk.WIDTH; //Create a new chunk neighborchunk = new Chunk(this, ref neighborcoords, ref newpos); //Update flag and connect event chain to neighbor chunk.NeighborsInMemoryFlag |= 16; neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; //Add new chunk to manager AddChunk(neighborchunk); } else if (contains)//Chunk is already in memory connect to it { //Update flag and connect event chain to neighbor chunk.ConsolidateFlags(neighborchunk, 16); neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; } } //-x +z //Get new chunkcoords chunk.Coords.Add(-1, 1, out neighborcoords); contains = ChunkStorage.Contains(ref neighborcoords, out neighborchunk); if ((chunk.NeighborsInMemoryFlag & 32) != 32) { if (!contains) { //Shift this chunks position to get the new chunks relative position newpos.X = chunk.Position.X - Chunk.WIDTH; newpos.Y = chunk.Position.Y; newpos.Z = chunk.Position.Z + Chunk.WIDTH; //Create a new chunk neighborchunk = new Chunk(this, ref neighborcoords, ref newpos); //Update flag and connect event chain to neighbor chunk.NeighborsInMemoryFlag |= 32; neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; //Add new chunk to manager AddChunk(neighborchunk); } else if (contains)//Chunk is already in memory connect to it { //Update flag and connect event chain to neighbor chunk.ConsolidateFlags(neighborchunk, 32); neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; } } //+x -z //Get new chunkcoords chunk.Coords.Add(1, -1, out neighborcoords); contains = ChunkStorage.Contains(ref neighborcoords, out neighborchunk); if ((chunk.NeighborsInMemoryFlag & 64) != 64) { if (!contains) { //Shift this chunks position to get the new chunks relative position newpos.X = chunk.Position.X + Chunk.WIDTH; newpos.Y = chunk.Position.Y; newpos.Z = chunk.Position.Z - Chunk.WIDTH; //Create a new chunk neighborchunk = new Chunk(this, ref neighborcoords, ref newpos); //Update flag and connect event chain to neighbor chunk.NeighborsInMemoryFlag |= 64; neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; //Add new chunk to manager AddChunk(neighborchunk); } else if (contains)//Chunk is already in memory connect to it { //Update flag and connect event chain to neighbor chunk.ConsolidateFlags(neighborchunk, 64); neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; } } //-x -z //Get new chunkcoords chunk.Coords.Add(-1, -1, out neighborcoords); contains = ChunkStorage.Contains(ref neighborcoords, out neighborchunk); if ((chunk.NeighborsInMemoryFlag & 128) != 128) { if (!contains) { //Shift this chunks position to get the new chunks relative position newpos.X = chunk.Position.X - Chunk.WIDTH; newpos.Y = chunk.Position.Y; newpos.Z = chunk.Position.Z - Chunk.WIDTH; //Create a new chunk neighborchunk = new Chunk(this, ref neighborcoords, ref newpos); //Update flag and connect event chain to neighbor chunk.NeighborsInMemoryFlag |= 128; neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; //Add new chunk to manager AddChunk(neighborchunk); } else if (contains) //Chunk is already in memory connect to it { //Update flag and connect event chain to neighbor chunk.ConsolidateFlags(neighborchunk, 128); neighborchunk.StateChanged += chunk.NeighborChangedStateCallback; chunk.StateChanged += neighborchunk.NeighborChangedStateCallback; } } }
public void Reload() { ChunkStorage.UnloadAll(this); Vector3 positionInChunk = -Vector3.Up * Chunk.HEIGHT * 0.9f; ChunkCoordinate chunkPlayerIsIn = new ChunkCoordinate(0, 0, 8000); Chunk seed = new Chunk(this, ref chunkPlayerIsIn, ref positionInChunk); ChunkStorage.Store(seed, this); _loadQueue.TryAdd(seed); Monitor.Pulse(_loadQueue); }
public void PrepareChunkForUnload(Chunk chunk) { chunk.ChangeState(this, ChunkState.Unloading); DrawList.Remove(chunk); ChunkRenderer.RemoveChunkMeshes(chunk); }
public void AddChunk(Chunk chunk) { if (chunk == null) throw new NullReferenceException("Chunk cannot be null."); ChunkStorage.Store(chunk, this); _loadQueue.TryAdd(chunk); _chunksQueuedThisFrame++; }
public ChunkManager(Game game, ChunkCoordinate chunkPlayerIsIn, Vector3 positionInChunk, bool useThreading) { _graphics = game.GraphicsDevice; ChunkRenderer = new ChunkMeshRenderer(game); UseThreading = useThreading; int width = 1; while (width < 2*CHUNK_LOAD_DIST) width *= 2; ChunkStorage = new ChunkStorage(width); //WARN: When load dist is a power of 2 queue chunks infinitely adds delegates to the ChunkStateChange event resulting in an eventual //out of memory exception. CHUNK_LOAD_DIST = width / 2-1; CHUNK_LIGHT_DIST = CHUNK_LOAD_DIST;// -1; CHUNK_BUILD_DIST = CHUNK_LIGHT_DIST;// -1; width *= Chunk.WIDTH; CubeStorage = new CubeStorage(width, Chunk.HEIGHT, width); _loadQueue = new ConcurrentSerialQueue<Chunk>(); _vertexBuffer = new CubeVertex[1000]; LightQueue = new ConcurrentSerialQueue<Chunk>(); BuildQueue = new ConcurrentSerialQueue<Chunk>(); RebuildQueue = new Queue<Chunk>(); UnloadQueue = new ConcurrentSerialQueue<Chunk>(); DrawList = new List<Chunk>(); _timeSinceQueue = TIME_BETWEEN_QUEUES; _timeSinceLoad = TIME_BETWEEN_LOADS; _timeSinceLight = TIME_BETWEEN_LIGHTS * 0.5f; _timeSinceBuild = 0.0f; _running = true; _running = true; _running = true; _running = true; watch1 = new Stopwatch(); watch2 = new Stopwatch(); Thread thread = new Thread(LoadChunks); thread.IsBackground = true; thread.SetApartmentState(ApartmentState.MTA); thread.Name = "LoadThread1"; thread.Priority = ThreadPriority.Lowest; thread.Start(); //thread = new Thread(LoadChunks); //thread.IsBackground = true; //thread.SetApartmentState(ApartmentState.MTA); //thread.Name = "LoadThread2"; //thread.Priority = ThreadPriority.Lowest; //thread.Start(); thread = new Thread(LightChunks); thread.IsBackground = true; thread.SetApartmentState(ApartmentState.MTA); thread.Name = "LightThread"; thread.Priority = ThreadPriority.Lowest; thread.Start(); thread = new Thread(BuildChunkVertices); thread.IsBackground = true; thread.SetApartmentState(ApartmentState.MTA); thread.Name = "BuildThread"; thread.Priority = ThreadPriority.Lowest; thread.Start(); //Initialize chunk loading. positionInChunk = -positionInChunk; Chunk seed = new Chunk(this, ref chunkPlayerIsIn, ref positionInChunk); _loadQueue.TryAdd(seed); ChunkStorage.Store(seed, this); }
public void BuildVertices(CubeVertex[] vertexBuffer, GraphicsDevice graphics, Chunk parent, CubeStorage store) { if (SideCountNeeded) CollectSubmeshStats(parent, store); if (vertexBuffer.Length < SidesRenderable * 6f) vertexBuffer = new CubeVertex[(int)(SidesRenderable * 6.1f)]; Cube current; Cube n0; Cube n1; Cube n2; Cube n3; Cube n4; Cube n5; Cube n6; Cube n7; Cube n8; Vector3 offset; Vector3 posNNN; Vector3 posNNP; Vector3 posNPN; Vector3 posNPP; Vector3 posPNN; Vector3 posPNP; Vector3 posPPN; Vector3 posPPP; int ind = 0; int worldX = 0; int worldZ = 0; int reg=0; //int vert1light = 0; //int vert2light = 0; //int vert3light = 0; //int vert4light = 0; int maxY = Chunk.HEIGHT - 1; for (int x = 0; x < Chunk.WIDTH; x++) { worldX = x + parent.Coords.X * Chunk.WIDTH; for (int z = 0; z < Chunk.WIDTH; z++) { worldZ = z + parent.Coords.Z * Chunk.WIDTH; for (int y = _yStartIndex; y <= _yEndIndex; y++) { store.GetCube(worldX, y, worldZ, out current); //log.Write("worldCoords", "{" + worldX.ToString() + "," + y.ToString() + "," + worldZ.ToString() + "}", ""); if (!current.IsRenderable) continue; offset.X = x; offset.Y = y - _yStartIndex; offset.Z = z; Vector3.Add(ref CubeVertex.CORNER_NNN, ref offset, out posNNN); Vector3.Add(ref CubeVertex.CORNER_NNP, ref offset, out posNNP); Vector3.Add(ref CubeVertex.CORNER_NPN, ref offset, out posNPN); Vector3.Add(ref CubeVertex.CORNER_NPP, ref offset, out posNPP); Vector3.Add(ref CubeVertex.CORNER_PNN, ref offset, out posPNN); Vector3.Add(ref CubeVertex.CORNER_PNP, ref offset, out posPNP); Vector3.Add(ref CubeVertex.CORNER_PPN, ref offset, out posPPN); Vector3.Add(ref CubeVertex.CORNER_PPP, ref offset, out posPPP); //-x reg = worldX - 1; store.GetCube(reg, y, worldZ, out n0); if (n0.IsTransparent) { store.CheckYGetCube(reg, y + 1, worldZ, out n1); store.CheckYGetCube(reg, y + 1, worldZ + 1, out n2); store.GetCube(reg, y, worldZ + 1, out n3); store.CheckYGetCube(reg, y - 1, worldZ + 1, out n4); store.CheckYGetCube(reg, y - 1, worldZ, out n5); store.CheckYGetCube(reg, y - 1, worldZ - 1, out n6); store.GetCube(reg, y, worldZ - 1, out n7); store.CheckYGetCube(reg, y + 1, worldZ - 1, out n8); vertexBuffer[ind++] = new CubeVertex(ref posNPN, ref CubeVertex.N_NEG_X, ref CubeVertex.TC00, ref current, ref n0, ref n1, ref n7, ref n8); vertexBuffer[ind++] = new CubeVertex(ref posNPP, ref CubeVertex.N_NEG_X, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n2, ref n3); vertexBuffer[ind++] = new CubeVertex(ref posNNN, ref CubeVertex.N_NEG_X, ref CubeVertex.TC01, ref current, ref n0, ref n5, ref n6, ref n7); vertexBuffer[ind++] = new CubeVertex(ref posNNN, ref CubeVertex.N_NEG_X, ref CubeVertex.TC01, ref current, ref n0, ref n5, ref n6, ref n7); vertexBuffer[ind++] = new CubeVertex(ref posNPP, ref CubeVertex.N_NEG_X, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n2, ref n3); vertexBuffer[ind++] = new CubeVertex(ref posNNP, ref CubeVertex.N_NEG_X, ref CubeVertex.TC11, ref current, ref n0, ref n3, ref n4, ref n5); } //+x reg = worldX + 1; store.GetCube(reg, y, worldZ, out n0); if (n0.IsTransparent) { store.CheckYGetCube(reg, y + 1, worldZ, out n1); store.CheckYGetCube(reg, y + 1, worldZ + 1, out n2); store.GetCube(reg, y, worldZ + 1, out n3); store.CheckYGetCube(reg, y - 1, worldZ + 1, out n4); store.CheckYGetCube(reg, y - 1, worldZ, out n5); store.CheckYGetCube(reg, y - 1, worldZ - 1, out n6); store.GetCube(reg, y, worldZ - 1, out n7); store.CheckYGetCube(reg, y + 1, worldZ - 1, out n8); vertexBuffer[ind++] = new CubeVertex(ref posPPP, ref CubeVertex.N_POS_X, ref CubeVertex.TC00, ref current, ref n0, ref n1, ref n2, ref n3); vertexBuffer[ind++] = new CubeVertex(ref posPPN, ref CubeVertex.N_POS_X, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n7, ref n8); vertexBuffer[ind++] = new CubeVertex(ref posPNP, ref CubeVertex.N_POS_X, ref CubeVertex.TC01, ref current, ref n0, ref n3, ref n4, ref n5); vertexBuffer[ind++] = new CubeVertex(ref posPNP, ref CubeVertex.N_POS_X, ref CubeVertex.TC01, ref current, ref n0, ref n3, ref n4, ref n5); vertexBuffer[ind++] = new CubeVertex(ref posPPN, ref CubeVertex.N_POS_X, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n7, ref n8); vertexBuffer[ind++] = new CubeVertex(ref posPNN, ref CubeVertex.N_POS_X, ref CubeVertex.TC11, ref current, ref n0, ref n5, ref n6, ref n7); } //-y reg = y - 1; if (y != 0) store.GetCube(worldX, reg, worldZ, out n0); else n0 = Cube.NULL; if (n0.IsTransparent && n0.Material != CubeMaterial.None) { store.GetCube(worldX + 1, reg, worldZ, out n1); store.GetCube(worldX + 1, reg, worldZ + 1, out n2); store.GetCube(worldX, reg, worldZ + 1, out n3); store.GetCube(worldX - 1, reg, worldZ + 1, out n4); store.GetCube(worldX - 1, reg, worldZ, out n5); store.GetCube(worldX - 1, reg, worldZ - 1, out n6); store.GetCube(worldX, reg, worldZ - 1, out n7); store.GetCube(worldX + 1, reg, worldZ - 1, out n8); vertexBuffer[ind++] = new CubeVertex(ref posNNP, ref CubeVertex.N_NEG_Y, ref CubeVertex.TC00, ref current, ref n0, ref n3, ref n4, ref n5); vertexBuffer[ind++] = new CubeVertex(ref posPNP, ref CubeVertex.N_NEG_Y, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n2, ref n3); vertexBuffer[ind++] = new CubeVertex(ref posNNN, ref CubeVertex.N_NEG_Y, ref CubeVertex.TC01, ref current, ref n0, ref n5, ref n6, ref n7); vertexBuffer[ind++] = new CubeVertex(ref posNNN, ref CubeVertex.N_NEG_Y, ref CubeVertex.TC01, ref current, ref n0, ref n5, ref n6, ref n7); vertexBuffer[ind++] = new CubeVertex(ref posPNP, ref CubeVertex.N_NEG_Y, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n2, ref n3); vertexBuffer[ind++] = new CubeVertex(ref posPNN, ref CubeVertex.N_NEG_Y, ref CubeVertex.TC11, ref current, ref n0, ref n1, ref n7, ref n8); } //+y reg = y + 1; if (y != maxY) store.GetCube(worldX, reg, worldZ, out n0); else n0 = Cube.NULL; if (n0.IsTransparent && n0.Material != CubeMaterial.None) { store.GetCube(worldX + 1, reg, worldZ, out n1); store.GetCube(worldX + 1, reg, worldZ + 1, out n2); store.GetCube(worldX, reg, worldZ + 1, out n3); store.GetCube(worldX - 1, reg, worldZ + 1, out n4); store.GetCube(worldX - 1, reg, worldZ, out n5); store.GetCube(worldX - 1, reg, worldZ - 1, out n6); store.GetCube(worldX, reg, worldZ - 1, out n7); store.GetCube(worldX + 1, reg, worldZ - 1, out n8); vertexBuffer[ind++] = new CubeVertex(ref posNPN, ref CubeVertex.N_POS_Y, ref CubeVertex.TC00, ref current, ref n0, ref n5, ref n6, ref n7); vertexBuffer[ind++] = new CubeVertex(ref posPPN, ref CubeVertex.N_POS_Y, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n7, ref n8); vertexBuffer[ind++] = new CubeVertex(ref posNPP, ref CubeVertex.N_POS_Y, ref CubeVertex.TC01, ref current, ref n0, ref n3, ref n4, ref n5); vertexBuffer[ind++] = new CubeVertex(ref posNPP, ref CubeVertex.N_POS_Y, ref CubeVertex.TC01, ref current, ref n0, ref n3, ref n4, ref n5); vertexBuffer[ind++] = new CubeVertex(ref posPPN, ref CubeVertex.N_POS_Y, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n7, ref n8); vertexBuffer[ind++] = new CubeVertex(ref posPPP, ref CubeVertex.N_POS_Y, ref CubeVertex.TC11, ref current, ref n0, ref n1, ref n2, ref n3); } //-z reg = worldZ - 1; store.GetCube(worldX, y, reg, out n0); if (n0.IsTransparent) { store.GetCube(worldX + 1, y, reg, out n1); store.CheckYGetCube(worldX + 1, y + 1, reg, out n2); store.CheckYGetCube(worldX, y + 1, reg, out n3); store.CheckYGetCube(worldX - 1, y + 1, reg, out n4); store.GetCube(worldX - 1, y, reg, out n5); store.CheckYGetCube(worldX - 1, y - 1, reg, out n6); store.CheckYGetCube(worldX, y - 1, reg, out n7); store.CheckYGetCube(worldX + 1, y - 1, reg, out n8); vertexBuffer[ind++] = new CubeVertex(ref posPPN, ref CubeVertex.N_NEG_Z, ref CubeVertex.TC00, ref current, ref n0, ref n1, ref n2, ref n3); vertexBuffer[ind++] = new CubeVertex(ref posNPN, ref CubeVertex.N_NEG_Z, ref CubeVertex.TC10, ref current, ref n0, ref n3, ref n4, ref n5); vertexBuffer[ind++] = new CubeVertex(ref posPNN, ref CubeVertex.N_NEG_Z, ref CubeVertex.TC01, ref current, ref n0, ref n1, ref n7, ref n8); vertexBuffer[ind++] = new CubeVertex(ref posPNN, ref CubeVertex.N_NEG_Z, ref CubeVertex.TC01, ref current, ref n0, ref n1, ref n7, ref n8); vertexBuffer[ind++] = new CubeVertex(ref posNPN, ref CubeVertex.N_NEG_Z, ref CubeVertex.TC10, ref current, ref n0, ref n3, ref n4, ref n5); vertexBuffer[ind++] = new CubeVertex(ref posNNN, ref CubeVertex.N_NEG_Z, ref CubeVertex.TC11, ref current, ref n0, ref n5, ref n6, ref n7); } //+z reg = worldZ + 1; store.GetCube(worldX, y, reg, out n0); if (n0.IsTransparent) { store.GetCube(worldX + 1, y, reg, out n1); store.CheckYGetCube(worldX + 1, y + 1, reg, out n2); store.CheckYGetCube(worldX, y + 1, reg, out n3); store.CheckYGetCube(worldX - 1, y + 1, reg, out n4); store.GetCube(worldX - 1, y, reg, out n5); store.CheckYGetCube(worldX - 1, y - 1, reg, out n6); store.CheckYGetCube(worldX, y - 1, reg, out n7); store.CheckYGetCube(worldX + 1, y - 1, reg, out n8); vertexBuffer[ind++] = new CubeVertex(ref posNPP, ref CubeVertex.N_POS_Z, ref CubeVertex.TC00, ref current, ref n0, ref n3, ref n4, ref n5); vertexBuffer[ind++] = new CubeVertex(ref posPPP, ref CubeVertex.N_POS_Z, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n2, ref n3); vertexBuffer[ind++] = new CubeVertex(ref posNNP, ref CubeVertex.N_POS_Z, ref CubeVertex.TC01, ref current, ref n0, ref n5, ref n6, ref n7); vertexBuffer[ind++] = new CubeVertex(ref posNNP, ref CubeVertex.N_POS_Z, ref CubeVertex.TC01, ref current, ref n0, ref n5, ref n6, ref n7); vertexBuffer[ind++] = new CubeVertex(ref posPPP, ref CubeVertex.N_POS_Z, ref CubeVertex.TC10, ref current, ref n0, ref n1, ref n2, ref n3); vertexBuffer[ind++] = new CubeVertex(ref posPNP, ref CubeVertex.N_POS_Z, ref CubeVertex.TC11, ref current, ref n0, ref n1, ref n7, ref n8); } } } } if (ind > 0) { VertexBuffer = new VertexBuffer(graphics, typeof(CubeVertex), ind, BufferUsage.None); VertexBuffer.SetData<CubeVertex>(vertexBuffer,0,ind); Empty = false; } else Empty = true; }
public void CollectSubmeshStats(Chunk parent, CubeStorage store) { Cube current; Cube neighbor; int worldX = 0; int worldZ = 0; int maxY = Chunk.HEIGHT - 1; for (int x = 0; x < Chunk.WIDTH; x++) { worldX = x + parent.Coords.X * Chunk.WIDTH; for (int z = 0; z < Chunk.WIDTH; z++) { worldZ = z + parent.Coords.Z * Chunk.WIDTH; for (int y = _yStartIndex; y <= _yEndIndex; y++) { store.GetCube(worldX, y, worldZ, out current); if (!current.IsRenderable) continue; RenderableBlocks += 1; //-x store.GetCube(worldX - 1, y, worldZ, out neighbor); if (neighbor.IsTransparent) SidesRenderable++; //+x store.GetCube(worldX + 1, y, worldZ, out neighbor); if (neighbor.IsTransparent) SidesRenderable++; //-y if (y != 0) store.GetCube(worldX, y - 1, worldZ, out neighbor); else neighbor = Cube.NULL; if (neighbor.IsTransparent && neighbor.Material != CubeMaterial.None) SidesRenderable++; //+y if (y != maxY) store.GetCube(worldX, y + 1, worldZ, out neighbor); else neighbor = Cube.NULL; if (neighbor.IsTransparent && neighbor.Material != CubeMaterial.None) SidesRenderable++; //-z store.GetCube(worldX, y, worldZ - 1, out neighbor); if (neighbor.IsTransparent) SidesRenderable++; //+z store.GetCube(worldX, y, worldZ + 1, out neighbor); if (neighbor.IsTransparent) SidesRenderable++; } } } }