예제 #1
0
        private void Awake()
        {
            if (dontDestroyOnLoad)
            {
                DontDestroyOnLoad(gameObject);
            }

            // There's a chance there are multiple worlds active currently.
            // If there is, stop here.
            if (Main != null && Main != this)
            {
                return;
            }

            if (!BlockProvider.IsInitialized)
            {
                BlockProvider.Initialize(blockCollection);
            }

            if (!TextureProvider.IsInitialized)
            {
                TextureProvider.Initialize(blockCollection);
            }

            if (!Serialization.IsInitialized)
            {
                Serialization.Initialize(Application.persistentDataPath + "/HertzVox/");
            }

            Texture2D atlas = TextureProvider.GetAtlas();

            mat = new Material(chunkMaterial)
            {
                mainTexture = atlas
            };

            int xSize = atlas.width / blockCollection.TextureSize;
            int ySize = atlas.height / blockCollection.TextureSize;

            mat.SetInt("_AtlasX", xSize);
            mat.SetInt("_AtlasY", ySize);
            mat.SetVector("_AtlasRec", new Vector4(1.0f / xSize, 1.0f / ySize));

            generateJobs = new NativeHashMap <int3, ChunkJobData>(0, Allocator.Persistent);
            renderJobs   = new NativeHashMap <int3, ChunkJobData>(0, Allocator.Persistent);
            colliderJobs = new NativeHashMap <int3, ChunkJobData>(0, Allocator.Persistent);

            renderChunks   = new NativeList <int3>(Allocator.Persistent);
            chunksToRemove = new NativeList <int3>(Allocator.Persistent);

            generator = GetComponent <IVoxGeneration>();

            if (generator == null)
            {
                Debug.LogWarning("There's no voxel generator (IVoxGenerator) attached to Voxel World " + gameObject.name + ". No chunks will show up.");
            }
        }
예제 #2
0
        public JobHandle ScheduleRenderJob()
        {
            UpdatingRenderer = true;
            HasRender        = true;

            vertices = new NativeList <float3>(Allocator.TempJob);
            indicies = new NativeList <int>(Allocator.TempJob);
            uvs      = new NativeList <float4>(Allocator.TempJob);
            colors   = new NativeList <float4>(Allocator.TempJob);
            normals  = new NativeList <float3>(Allocator.TempJob);

            NativeArray <int> northBlocks = world.TryGetChunk(new int3(position.x, position.y, position.z + CHUNK_SIZE), out Chunk northChunk) ?
                                            northChunk.blocks.GetBlocks(Allocator.TempJob) : BlockProvider.GetEmptyBlocks(Allocator.TempJob);

            NativeArray <int> southBlocks = world.TryGetChunk(new int3(position.x, position.y, position.z - CHUNK_SIZE), out Chunk southChunk) ?
                                            southChunk.blocks.GetBlocks(Allocator.TempJob) : BlockProvider.GetEmptyBlocks(Allocator.TempJob);

            NativeArray <int> eastBlocks = world.TryGetChunk(new int3(position.x + CHUNK_SIZE, position.y, position.z), out Chunk eastChunk) ?
                                           eastChunk.blocks.GetBlocks(Allocator.TempJob) : BlockProvider.GetEmptyBlocks(Allocator.TempJob);

            NativeArray <int> westBlocks = world.TryGetChunk(new int3(position.x - CHUNK_SIZE, position.y, position.z), out Chunk westChunk) ?
                                           westChunk.blocks.GetBlocks(Allocator.TempJob) : BlockProvider.GetEmptyBlocks(Allocator.TempJob);

            NativeArray <int> upBlocks = world.TryGetChunk(new int3(position.x, position.y + CHUNK_SIZE, position.z), out Chunk topChunk) ?
                                         topChunk.blocks.GetBlocks(Allocator.TempJob) : BlockProvider.GetEmptyBlocks(Allocator.TempJob);

            NativeArray <int> downBlocks = world.TryGetChunk(new int3(position.x, position.y - CHUNK_SIZE, position.z), out Chunk downChunk) ?
                                           downChunk.blocks.GetBlocks(Allocator.TempJob) : BlockProvider.GetEmptyBlocks(Allocator.TempJob);

            return(new BuildChunkJob()
            {
                chunkSize = CHUNK_SIZE,
                position = position,
                blocks = blocks.GetBlocks(Allocator.TempJob),
                blockMap = BlockProvider.GetBlockMap(),
                textures = TextureProvider.GetTextureMap(),
                vertices = vertices,
                indicies = indicies,
                uvs = uvs,
                colors = colors,
                normals = normals,
                northBlocks = northBlocks,
                southBlocks = southBlocks,
                eastBlocks = eastBlocks,
                westBlocks = westBlocks,
                upBlocks = upBlocks,
                downBlocks = downBlocks
            }.Schedule());
        }
예제 #3
0
        public Block GetBlock(int3 position)
        {
            int3 chunkPos = Helpers.ContainingChunkPosition(position);

            if (chunks.TryGetValue(chunkPos, out Chunk chunk))
            {
                int xx = Helpers.Mod(position.x, Chunk.CHUNK_SIZE);
                int yy = Helpers.Mod(position.y, Chunk.CHUNK_SIZE);
                int zz = Helpers.Mod(position.z, Chunk.CHUNK_SIZE);

                return(chunk.GetBlock(xx, yy, zz));
            }

            return(BlockProvider.GetBlock("air"));
        }
예제 #4
0
        /// <summary>
        /// Gets a block from the world.
        /// </summary>
        /// <param name="position">The world position.</param>
        /// <param name="world">The world you want to get the block from. If null, the current active world will be used.</param>
        /// <returns>The block at the given position.</returns>
        public static Block GetBlock(int3 position, VoxelWorld world = null)
        {
            if (world == null)
            {
                world = VoxelWorld.Main;

                if (world == null)
                {
                    Debug.LogError("There's no world to get a block from.");
                    return(BlockProvider.GetBlock(BlockProvider.AIR_TYPE));
                }
            }

            return(world.GetBlock(position));
        }
예제 #5
0
        public static VoxelJsonData GetJsonData(VoxelWorld world, bool ignoreEmptyChunks = false)
        {
            VoxelJsonData data = new VoxelJsonData(BlockProvider.GetBlockPalette());

            List <Chunk> chunks = LoadAllChunks(world, ignoreEmptyChunks);

            VoxelJsonChunkData[] chunkData = new VoxelJsonChunkData[chunks.Count];

            for (int i = 0; i < chunks.Count; i++)
            {
                chunkData[i] = new VoxelJsonChunkData(chunks[i]);
            }

            data.chunks = chunkData;

            for (int i = 0; i < chunks.Count; i++)
            {
                chunks[i].Dispose(true);
            }

            return(data);
        }
예제 #6
0
        private void OnDestroy()
        {
            // Make sure only the active world disposes of things.
            if (Main != null && Main != this)
            {
                return;
            }

            if (generatingChunks)
            {
                FinishGeneratingChunks();
            }

            DisposeJobList(generateJobs);
            DisposeJobList(renderJobs);
            DisposeJobList(colliderJobs);

            foreach (Chunk chunk in chunks.Values)
            {
                chunk.Dispose(true);
            }

            TextureProvider.Dispose();
            BlockProvider.Dispose();

            Destroy(mat);

            generateJobs.Dispose();
            renderJobs.Dispose();
            colliderJobs.Dispose();

            renderChunks.Dispose();
            chunksToRemove.Dispose();

            if (clearTempOnDestroy)
            {
                Serialization.ClearTemp();
            }
        }
예제 #7
0
        internal void DecompressAndApply(NativeList <int2> list, Dictionary <int, string> palette)
        {
            int index = 0;

            for (int i = 0; i < list.Length; i++)
            {
                if (!BlockProvider.TryGetBlock(palette[list[i].x], out Block block))
                {
#if DEBUG
                    UnityEngine.Debug.LogWarning("Couldn't find block with ID '" + palette[list[i].x] + "' when decompressing. Replacing it with air.");
#endif
                    block = BlockProvider.GetBlock(BlockProvider.AIR_TYPE_ID);
                }

                for (int j = 0; j < list[i].y; j++)
                {
                    blocks[index] = block.id;
                    index++;
                }
            }

            list.Dispose();
        }
예제 #8
0
 public Block Get(int index)
 {
     return(BlockProvider.GetBlock(blocks[index]));
 }
예제 #9
0
 public Block Get(int x, int y, int z)
 {
     return(BlockProvider.GetBlock(blocks[Helpers.GetIndex1DFrom3D(x, y, z, Chunk.CHUNK_SIZE)]));
 }