public void Update()
        {
            // check if chunk is not null
            GameObject chunkObject = Engine.PositionToChunk (transform.position);
            if (chunkObject == null) return;

            // get the voxelInfo from the transform's position
            Chunk chunk = chunkObject.GetComponent<Chunk>();
            Index voxelIndex = chunk.PositionToVoxelIndex (transform.position);
            VoxelInfo voxelInfo = new VoxelInfo (voxelIndex, chunk);

            // create a local copy of the collision voxel so we can call functions on it
            GameObject voxelObject = Instantiate ( Engine.GetVoxelGameObject (voxelInfo.GetVoxel()) ) as GameObject;

            VoxelEvents events = voxelObject.GetComponent<VoxelEvents>();
            if (events != null ) {

            // OnEnter
            if ( chunk != LastChunk || voxelIndex.IsEqual(LastIndex) == false) {
                events.OnBlockEnter (this.gameObject, voxelInfo);
            }

            // OnStay
            else {
                events.OnBlockStay(this.gameObject, voxelInfo);
            }
            }

            LastChunk = chunk;
            LastIndex = voxelIndex;

            Destroy(voxelObject);
        }
Exemplo n.º 2
0
        public void InitializeGenerator()
        {
            // load seed if it's not loaded yet
            while (Engine.WorldSeed == 0) {
            Engine.GetSeed();
            }
            seed = Engine.WorldSeed;

            // get chunk component
            chunk = GetComponent<Chunk>();

            // generate data
            GenerateVoxelData ();

            // set empty
            chunk.Empty = true;
            foreach (ushort voxel in chunk.VoxelData) {
            if (voxel != 0) {
                chunk.Empty = false;
                break;
            }
            }

            // flag as done
            chunk.VoxelsDone = true;
        }
Exemplo n.º 3
0
        public VoxelInfo( Index setIndex, Index setAdjacentIndex, Chunk setChunk )
        {
            this.index = setIndex;
            this.adjacentIndex = setAdjacentIndex;

            this.chunk = setChunk;
        }
Exemplo n.º 4
0
        public VoxelInfo( int setX, int setY, int setZ, Chunk setChunk )
        {
            this.index.x = setX;
            this.index.y = setY;
            this.index.z = setZ;

            this.chunk = setChunk;
        }
Exemplo n.º 5
0
        public VoxelInfo( int setX, int setY, int setZ, int setXa, int setYa, int setZa, Chunk setChunk )
        {
            this.index.x = setX;
            this.index.y = setY;
            this.index.z = setZ;

            this.adjacentIndex.x = setXa;
            this.adjacentIndex.y = setYa;
            this.adjacentIndex.z = setZa;

            this.chunk = setChunk;
        }
Exemplo n.º 6
0
        public void Initialize()
        {
            // set variables
            chunk = GetComponent<Chunk>();
            SideLength = chunk.SideLength;

            // make a list for each material (each material is a submesh)
            for (int i=0; i<GetComponent<Renderer>().materials.Length; i++) {
            Faces.Add(new List<int>());
            }

            initialized = true;
        }
Exemplo n.º 7
0
        public static Dictionary<string, string> TempChunkData; // stores chunk's data to write into a region file later

        #endregion Fields

        #region Methods

        public static string CompressData( Chunk chunk )
        {
            // returns the data of chunk in compressed string format

            StringWriter writer = new StringWriter();

            int i = 0;
            int length = chunk.GetDataLength(); // length of VoxelData array

            ushort currentCount = 0; // count of consecutive voxels of the same type
            ushort currentData = 0; // data of the current voxel

            for (i=0; i<length; i++) { // for each voxel

            ushort thisData = chunk.GetVoxelSimple(i); // read raw data at i

            if (thisData != currentData) { // if the data is different from the previous data, write the last block and start a new one

                // write previous block
                if (i != 0) { // (don't write in the first loop iteration, because count would be 0 (no previous blocks))
                    writer.Write ((char)currentCount);
                    writer.Write ((char)currentData);
                }
                // start new block
                currentCount = 1;
                currentData = thisData;
            }

            else { // if the data is the same as the last data, simply add to the count
                currentCount ++;
            }

            if (i == length-1) { // if this is the last iteration of the loop, close and write the current block
                writer.Write ((char)currentCount);
                writer.Write ((char)currentData);
            }

            }

            string compressedData = writer.ToString();
            writer.Flush ();
            writer.Close ();
            return compressedData;
        }
Exemplo n.º 8
0
        public static void DecompressData( Chunk chunk, string data )
        {
            // decompresses voxel data and loads it into the VoxelData array

            // check if chunk is empty
            if (data.Length == 2 && data[1] == (char)0) {
            chunk.Empty = true;
            }

            StringReader reader = new StringReader (data);

            int i = 0;
            int length = chunk.GetDataLength(); // length of VoxelData array

            try {
            while ( i < length ) { // this loop will stop once the VoxelData array has been populated completely. Iterates once per count-data block.

            ushort currentCount =  (ushort) reader.Read(); // read the count
            ushort currentData = (ushort) reader.Read(); // read the data

            int ii = 0;

            while ( ii < currentCount ) {
                chunk.SetVoxelSimple (i, (ushort)currentData);// write a single voxel for every currentCount
                ii ++;
                i ++;
            }
            }
            }
            catch (System.Exception) {
            Debug.LogError ("Uniblocks: Corrupt chunk data for chunk: " + chunk.ChunkIndex.ToString() + ". Has the data been saved using a different chunk size?");
            reader.Close();
            return;
            }

            reader.Close();
        }
Exemplo n.º 9
0
 public static void RegisterChunk( Chunk chunk )
 {
     // adds a reference to the chunk to the global chunk list
     ChunkManager.Chunks.Add (chunk.ChunkIndex.ToString(), chunk);
 }
Exemplo n.º 10
0
 public static void AddChunkToUpdateQueue( Chunk chunk )
 {
     if (ChunkUpdateQueue.Contains(chunk) == false) {
     ChunkUpdateQueue.Add (chunk);
     }
 }
Exemplo n.º 11
0
 public static void UnregisterChunk( Chunk chunk )
 {
     ChunkManager.Chunks.Remove(chunk.ChunkIndex.ToString());
 }
Exemplo n.º 12
0
        // ==== Voxel updates =====================================================================================
        public void RebuildMesh()
        {
            chunk = GetComponent<Chunk>();

            // destroy additional mesh containers
            foreach (Transform child in transform) {
            Destroy(child.gameObject);
            }

            int x=0,y=0,z=0;

            // Refresh neighbor chunks
            chunk.GetNeighbors();

            // for each voxel in Voxels, check if any of the voxel's faces are exposed, and if so, add their faces to the main mesh arrays (named Vertices and Faces)
            while (x < SideLength) {
            while (y < SideLength) {
                while (z < SideLength) {

                    ushort voxel = chunk.GetVoxel(x,y,z); // the current voxel data
                    if ( voxel != 0 ) { // don't render empty blocks.

                        Voxel voxelType = Engine.GetVoxelType(voxel);
                        if ( voxelType.VCustomMesh == false ) { // if cube

                            //Transparency transparency = Engine.GetVoxelType (chunk.GetVoxel(x,y,z)).VTransparency;
                            Transparency transparency = voxelType.VTransparency;
                            ColliderType colliderType = voxelType.VColliderType;

                            if (CheckAdjacent(x,y,z, Direction.forward, transparency) == true)
                             	CreateFace(voxel, Facing.forward, colliderType, x,y,z);

                            if (CheckAdjacent(x,y,z, Direction.back, transparency) == true)
                                CreateFace(voxel, Facing.back, colliderType, x,y,z);

                            if (CheckAdjacent(x,y,z, Direction.up, transparency) == true)
                                CreateFace(voxel, Facing.up, colliderType, x,y,z);

                            if (CheckAdjacent(x,y,z, Direction.down, transparency) == true)
                                CreateFace(voxel, Facing.down, colliderType, x,y,z);

                            if (CheckAdjacent(x,y,z, Direction.right, transparency) == true)
                                CreateFace(voxel, Facing.right, colliderType, x,y,z);

                            if (CheckAdjacent(x,y,z, Direction.left, transparency) == true)
                                CreateFace(voxel, Facing.left, colliderType, x,y,z);

                            // if no collider, create a trigger cube collider
                            if (colliderType == ColliderType.none && Engine.GenerateColliders) {
                                AddCubeMesh (x,y,z, false);
                            }
                        }
                        else { // if not cube
                            if (CheckAllAdjacent (x,y,z) == false) { // if any adjacent voxel isn't opaque, we render the mesh
                                CreateCustomMesh(voxel, x,y,z, voxelType.VMesh);
                            }
                        }
                    }
                    z += 1;
                }
                z = 0;
                y += 1;

            }
            y = 0;
            x += 1;
            }

            // update mesh using the values from the arrays
            UpdateMesh ( GetComponent<MeshFilter>().mesh );
        }
Exemplo n.º 13
0
 //添加块
 public static void RegisterChunk(Chunk chunk)
 { // adds a reference to the chunk to the global chunk list
     ChunkManager.Chunks.Add(chunk.ChunkIndex.ToString(), chunk);
 }
Exemplo n.º 14
0
        private IEnumerator SpawnMissingChunks(int originX, int originY, int originZ, int range)
        {
            int heightRange = Engine.HeightRange;

            ChunkUpdateQueue = new List <Chunk>(); // clear update queue - it will be repopulated again in the correct order in the following loop

            // flag chunks not in range for removal
            ChunksToDestroy = new List <Chunk>();
            foreach (Chunk chunk in Chunks.Values)
            {
                if (Vector2.Distance(new Vector2(chunk.ChunkIndex.x, chunk.ChunkIndex.z), new Vector2(originX, originZ)) > range + Engine.ChunkDespawnDistance)
                {//块和人物的水平距离超过销毁范围,将此块加入销毁队列
                    ChunksToDestroy.Add(chunk);
                }

                else if (Mathf.Abs(chunk.ChunkIndex.y - originY) > range + Engine.ChunkDespawnDistance)
                { // destroy chunks outside of vertical range
                    // 块和人物的垂直距离超过销毁范围,将此块加入销毁队列
                    ChunksToDestroy.Add(chunk);
                }
            }


            // main loop
            for (int currentLoop = 0; currentLoop <= range; currentLoop++)
            {
                for (var x = originX - currentLoop; x <= originX + currentLoop; x++)
                { // iterate through all potential chunk indexes within range
                    for (var y = originY - currentLoop; y <= originY + currentLoop; y++)
                    {
                        for (var z = originZ - currentLoop; z <= originZ + currentLoop; z++)
                        {
                            if (Mathf.Abs(y) <= heightRange)
                            { // skip chunks outside of height range//垂直范围之内
                                if (Mathf.Abs(originX - x) + Mathf.Abs(originZ - z) < range * 2f)
                                /*if (Mathf.Pow(Mathf.Abs(originX-x),2)+ Mathf.Pow(Mathf.Abs(originZ-z),2)< Mathf.Pow(range,2))*/
                                { //1.3f skip corners
                                    // pause loop while the queue is not empty
                                    while (ChunkUpdateQueue.Count > 0)
                                    {
                                        ProcessChunkQueue();
                                        if (frameStopwatch.Elapsed.TotalSeconds >= targetFrameDuration)
                                        {
                                            yield return(new WaitForEndOfFrame());
                                        }
                                    }

                                    Chunk currentChunk = ChunkManager.GetChunkComponent(x, y, z);


                                    // chunks that already exist but haven't had their mesh built yet should be added to the update queue
                                    if (currentChunk != null)
                                    {
                                        // chunks without meshes spawned by server should be changed to regular chunks
                                        if (currentChunk.DisableMesh || currentChunk.EnableTimeout)
                                        {
                                            currentChunk.DisableMesh   = false;
                                            currentChunk.EnableTimeout = false;
                                            currentChunk.Fresh         = true;
                                        }

                                        if (currentChunk.Fresh)
                                        {
                                            // spawn neighbor chunks
                                            for (int d = 0; d < 6; d++)
                                            {
                                                Index      neighborIndex = currentChunk.ChunkIndex.GetAdjacentIndex((Direction)d);
                                                GameObject neighborChunk = GetChunk(neighborIndex);
                                                if (neighborChunk == null)
                                                {
                                                    neighborChunk = Instantiate(ChunkObject, neighborIndex.ToVector3(), transform.rotation) as GameObject;
                                                }
                                                currentChunk.NeighborChunks[d] = neighborChunk.GetComponent <Chunk>(); // always add the neighbor to NeighborChunks, in case it's not there already

                                                // continue loop in next frame if the current frame time is exceeded
                                                if (frameStopwatch.Elapsed.TotalSeconds >= targetFrameDuration)
                                                {
                                                    yield return(new WaitForEndOfFrame());
                                                }
                                                if (StopSpawning)
                                                {
                                                    EndSequence();
                                                    yield break;
                                                }
                                            }

                                            if (currentChunk != null)
                                            {
                                                currentChunk.AddToQueueWhenReady();
                                            }
                                        }
                                    }

                                    else
                                    {                                                                                                           // if chunk doesn't exist, create new chunk (it adds itself to the update queue when its data is ready)
                                        // spawn chunk
                                        GameObject newChunk = Instantiate(ChunkObject, new Vector3(x, y, z), transform.rotation) as GameObject; // Spawn a new chunk.
                                        currentChunk = newChunk.GetComponent <Chunk>();

                                        // spawn neighbor chunks if they're not spawned yet
                                        for (int d = 0; d < 6; d++)
                                        {
                                            Index      neighborIndex = currentChunk.ChunkIndex.GetAdjacentIndex((Direction)d);
                                            GameObject neighborChunk = GetChunk(neighborIndex);
                                            if (neighborChunk == null)
                                            {
                                                neighborChunk = Instantiate(ChunkObject, neighborIndex.ToVector3(), transform.rotation) as GameObject;
                                            }
                                            currentChunk.NeighborChunks[d] = neighborChunk.GetComponent <Chunk>(); // always add the neighbor to NeighborChunks, in case it's not there already

                                            // continue loop in next frame if the current frame time is exceeded
                                            if (frameStopwatch.Elapsed.TotalSeconds >= targetFrameDuration)
                                            {
                                                yield return(new WaitForEndOfFrame());
                                            }
                                            if (StopSpawning)
                                            {
                                                EndSequence();
                                                yield break;
                                            }
                                        }

                                        if (currentChunk != null)
                                        {
                                            currentChunk.AddToQueueWhenReady();
                                        }
                                    }
                                }
                            }



                            // continue loop in next frame if the current frame time is exceeded
                            if (frameStopwatch.Elapsed.TotalSeconds >= targetFrameDuration)
                            {
                                yield return(new WaitForEndOfFrame());
                            }
                            if (StopSpawning)
                            {
                                EndSequence();
                                yield break;
                            }
                        }
                    }
                }
            }

            yield return(new WaitForEndOfFrame());

            EndSequence();
        }
Exemplo n.º 15
0
 //删除块
 public static void UnregisterChunk(Chunk chunk)
 {
     ChunkManager.Chunks.Remove(chunk.ChunkIndex.ToString());
 }
Exemplo n.º 16
0
        public VoxelInfo(Index setIndex, Chunk setChunk)
        {
            this.index = setIndex;

            this.chunk = setChunk;
        }
Exemplo n.º 17
0
        public VoxelInfo(int setX, int setY, int setZ, int setXa, int setYa, int setZa, Chunk setChunk)
        {
            this.index.x = setX;
            this.index.y = setY;
            this.index.z = setZ;

            this.adjacentIndex.x = setXa;
            this.adjacentIndex.y = setYa;
            this.adjacentIndex.z = setZa;

            this.chunk = setChunk;
        }