예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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;
        }
예제 #4
0
        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;
        }
예제 #5
0
        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;
        }