public static VoxelTerrain LoadFrom(string filename) { List<BlockData> blocks = new List<BlockData>(); using (StreamReader input = new StreamReader(File.OpenRead(filename))) { string buffer; while ((buffer = input.ReadLine()) != null) { string[] data = buffer.Split(','); BlockData block = new BlockData() { x = Int32.Parse(data[0]), y = Int32.Parse(data[1]), z = Int32.Parse(data[2]), type = Byte.Parse(data[3]) }; blocks.Add(block); } } return new VoxelTerrain(blocks); }
/// <summary> /// Draw the current voxel terrain /// </summary> private void DrawVoxelTerrain() { #region Terrain Rendering Setup //Stop if no terrain to render if (voxelTerrain == null || voxelPlaceHolderModel == null) return; //init bones if (instancedModelBones == null) //TODO: move to loadModels when implemented { instancedModelBones = new Matrix[voxelPlaceHolderModel.Bones.Count]; voxelPlaceHolderModel.CopyAbsoluteBoneTransformsTo(instancedModelBones); } //Setup camera float aspectRatio = GraphicsDevice.Viewport.AspectRatio; float rotation = (float)timer.Elapsed.TotalSeconds; //float rotation = 1.5f; Matrix world = Matrix.CreateRotationY(0);//rotation); //Populate instances here to find max length for camera int maxDist = 0; int maxSize = Math.Min(1048574, voxelTerrain.blocks.Count); Array.Resize(ref instanceTransforms, maxSize); Vector3 position = new Vector3(); BlockData block = new BlockData(); Matrix transform = new Matrix(); float scale = 2; if (doubleSpaceBlocks) //inverted because dividing by scale scale = 1; int maxX, maxY, maxZ; maxX = maxY = maxZ = 0; int minX, minY, minZ; minX = minY = minZ = int.MaxValue; for (long i = 0; i < maxSize; i++) { block = voxelTerrain.blocks[(int)i]; position.X = block.x / scale; //TODO: fix hardcoded scaling position.Y = block.y / scale; position.Z = block.z / scale; maxX = Math.Max(maxX, (int)position.X); maxY = Math.Max(maxY, (int)position.Y); maxZ = Math.Max(maxZ, (int)position.Z); minX = Math.Min(minX, (int)position.X); minY = Math.Min(minY, (int)position.Y); minZ = Math.Min(minZ, (int)position.Z); //find distance from origin int distFromZero = (int)position.Length(); //update maxDist if bigger if (distFromZero > maxDist) maxDist = distFromZero; transform = Matrix.CreateTranslation(position); instanceTransforms[(instanceTransforms.Length - (i /*- currentDrawIndex*/)) - 1] = transform * world; //TODO: remove backwards test } //Debug.WriteLine("{0}", voxelTerrain.blocks[65000]); //currentDrawIndex = ((currentDrawIndex + maxSize) > voxelTerrain.blocks.Count) ? 0 : currentDrawIndex + maxSize; //Continue camera setup //Vector3 eyePosition = Vector3.Zero; //float nearClip = maxDist / 50.0f; //float farClip = maxDist * 50; //Matrix view = Matrix.CreateLookAt(new Vector3(40, 300, 30), new Vector3(0, 0, 0), Vector3.Up); //Matrix projection = Matrix.CreatePerspectiveFieldOfView((float)(Math.PI / 2), aspectRatio, // nearClip, farClip); modelCenter = new Vector3((minX + maxX) / 2, (minY + maxY)/2, (minZ + maxZ) / 2); Vector3 eyePosition = Vector3.Zero; eyePosition.Z = maxZ + 20;// maxZ + 1; eyePosition.X = maxX - 5;// maxX + 1; eyePosition.Y = maxY + 20; Debug.WriteLine("Max = ({0},{1},{2})", maxX, maxY, maxZ); Debug.WriteLine("Min = ({0},{1},{2})", minX, minY, minZ); Debug.WriteLine("EyePosition = ({0},{1},{2})", eyePosition.X, eyePosition.Y, eyePosition.Z); Debug.WriteLine("ModelCenter = ({0},{1},{2})", modelCenter.X, modelCenter.Y, modelCenter.Z); aspectRatio = GraphicsDevice.Viewport.AspectRatio; float nearClip = 128 / 100f; float farClip = 128 * 100; world = Matrix.CreateRotationY(rotation); Matrix view = Matrix.CreateLookAt(eyePosition, modelCenter, Vector3.Up); Matrix projection = Matrix.CreatePerspectiveFieldOfView(1, aspectRatio, nearClip, farClip); #endregion DrawModelHardwareInstancing(voxelPlaceHolderModel, instancedModelBones, instanceTransforms, view, projection); }
private static byte[, ,] unflattenBlockArray(int length, int width, int height, byte[] blockArray) { byte[, ,] unflattenedBlockArray = new byte[height, length, width]; short y, z, x; x = y = z = 0; BlockData blockData = new BlockData(); for (int i = 0; i < blockArray.Length; i++) { if (blockArray[i] != 0) //ignore air blocks { blockData.x = x; blockData.y = y; blockData.z = z; unflattenedBlockArray[y, z, x] = blockArray[i]; //blocks.Add(new TerrainBlockInstance(x * 0.5f, y * 0.5f, z * 0.5f, BlockType.Stone)); //TODO: fix hardcoded scaling } //simulate 3D array x++; if (x == width) { x = 0; z++; if (z == length) { z = 0; y++; //y is leftmost index so it won't need to cycle } } } return unflattenedBlockArray; }
public static List<BlockData> GenerateBlocks(List<Chunk> chunkList, bool ignoreAir = true) { List<BlockData> blocks = new List<BlockData>(); short width; if (fileType == FileType.FILE_MCR) width = 128; else width = 256; short length = 16; foreach (Chunk chunk in chunkList) { if (fileType == FileType.FILE_MCR) { byte[] blockArray = chunk.ByteArray.GetByteArray(); if (blockArray == null) { //TODO:show error reading file return new List<BlockData>(); } makeHollow(length, width, 16, blockArray); //can only use this for mcr right now, mca doesnt use same array //variables used in loop short y, z, x; x = y = z = 0; BlockData blockData = new BlockData(); for (int i = 0; i < blockArray.Length; i++) { if (!ignoreAir || blockArray[i] != 0) { blockData.x = y + ((int)chunk.Position.X * 16); //Swapping axis so that the chunk appears right side up blockData.y = x; blockData.z = z + ((int)chunk.Position.Y * 16); //Working to add the chunk position to the block array blockData.type = blockArray[i]; if (blockData.y > 30) blocks.Add(blockData); } //simulate 3D array x++; if (x == width) { x = 0; z++; if (z == length) { z = 0; y++; } } } } else { byte[, ,] blockArray = (byte[,,]) chunk.ByteArray.Payload; makeHollow(length, width, 16, blockArray); BlockData blockData = new BlockData(); for(int x = 0; x < 16; x++) for(int y = 0; y < 256; y++) for(int z = 0; z < 16; z++) { if (blockArray[x, y, z] != 0) { blockData.x = x + ((int)chunk.Position.X * 16); //Swapping axis so that the chunk appears right side up blockData.y = y; blockData.z = z + ((int)chunk.Position.Y * 16); //Working to add the chunk position to the block array blockData.type = blockArray[x, y, z]; blocks.Add(blockData); } } } } return blocks; }
public static List<BlockData> GenerateBlocks(List<Chunk> chunkList, bool ignoreAir = true) { List<BlockData> blocks = new List<BlockData>(); int temp = 0; foreach (Chunk chunk in chunkList) { byte[] blockArray = chunk.ByteArray.GetByteArray(); //if (temp++ > 2) break; short width = 128; short length = 16; makeHollow(length, width, 16, blockArray); if (blockArray == null) { //TODO:show error reading file return new List<BlockData>(); } //variables used in loop short y, z, x; x = y = z = 0; BlockData blockData = new BlockData(); for (int i = 0; i < blockArray.Length; i++) { if (!ignoreAir || blockArray[i] != 0) { blockData.x = y + ((int)chunk.Position.X * 16); //Swapping axis so that the chunk appears right side up blockData.y = x; blockData.z = z + ((int)chunk.Position.Y * 16); //Working to add the chunk position to the block array blockData.type = blockArray[i]; if(blockData.y > 30) blocks.Add(blockData); } //simulate 3D array x++; if (x == width) { x = 0; z++; if (z == length) { z = 0; y++; } } } } return blocks; }