Пример #1
0
        public void InitRenderableSlices()
        {
            for (int i = 0; i < NumSlices; ++i)
            {
                ChunkSlice slice = Slices[i];
                if (!slice.IsEmpty)
                {
                    slice.ClearDirtyLight();
                    GameObject newObject = new GameObject("ChunkSlice#" + i);
                    ChunkSliceObjects[i] = newObject;
                    MeshRenderer meshRenderer = newObject.AddComponent(typeof(MeshRenderer)) as MeshRenderer;
                    meshRenderer.material             = WorldBehaviour.BlockMaterial;
                    meshRenderer.material.mainTexture = WorldBehaviour.AtlasTexture;
                    meshRenderer.sharedMaterial       = WorldBehaviour.BlockMaterial;
                    newObject.AddComponent(typeof(MeshFilter));
                    newObject.AddComponent <MeshCollider>();

                    Vector3 pos = new Vector3(ChunkObject.transform.position.x, ChunkObject.transform.position.y + (i * Chunk.SliceHeight), ChunkObject.transform.position.z);
                    if (WorldBehaviour.mode == 3)
                    {
                        pos.x = pos.x * Server.brickWidth;
                        pos.y = pos.y * Server.brickHeight;
                        pos.z = pos.z * Server.brickWidth;
                    }
                    newObject.transform.position = pos;
                    newObject.transform.parent   = ChunkObject.transform;

                    slice.renderer = meshRenderer;
                    slice.CreateBoundsBox(newObject.transform);
                }
            }
        }
Пример #2
0
        public BlockType GetBlockType(int x, int y, int z)
        {
            ChunkSlice slice = Slices[y / Chunk.SliceHeight];

            if (slice == null)
            {
                return(0);
            }
            return((BlockType)slice[x, y & Chunk.SliceHeightLimit, z]);
        }
Пример #3
0
 public void ClearDirtySlices()
 {
     for (int i = 0; i < NumSlices; ++i)
     {
         ChunkSlice slice = Slices[i];
         if (slice != null && !slice.IsEmpty)
         {
             slice.ClearDirtyLight();
         }
     }
 }
Пример #4
0
        public void SetSkylight(int x, int y, int z, byte newLight)
        {
            ChunkSlice slice = Slices[y / Chunk.SliceHeight];

            if (slice == null)
            {
                return;
            }

            slice.SetSkylight(x, y & SliceHeightLimit, z, newLight);
        }
Пример #5
0
        public byte GetSkylight(int x, int y, int z)
        {
            ChunkSlice slice = Slices[y / Chunk.SliceHeight];

            if (slice == null)
            {
                return(0);
            }

            return(slice.GetSkylight(x, y & SliceHeightLimit, z));
        }
Пример #6
0
        public Chunk(int chunkX, int chunkZ, WorldBehaviour world, Color color)
        {
            ChunkColor = color;

            X     = chunkX;
            Z     = chunkZ;
            World = world;

            for (int i = 0; i < NumSlices; ++i)
            {
                Slices[i] = new ChunkSlice(i, this);
            }
        }
Пример #7
0
        public void SetType(int x, int y, int z, BlockType type, bool unused)
        {
            ChunkSlice slice = Slices[y / Chunk.SliceHeight];

            slice[x & 0xF, y & Chunk.SliceHeightLimit, z & 0xF] = (byte)type;
        }
Пример #8
0
        public void RenderChunk(Chunk chunk)
        {
            WorldBehaviour world = chunk.World;

            /*	Stopwatch watch = new Stopwatch();
             *      watch.Start();
             */

            int minSliceIndex = chunk.MinSliceIndex;
            int lowestY       = chunk.LowestY;

            Chunk frontChunk = world.GetChunk(chunk.X, chunk.Z - 1);
            Chunk backChunk  = world.GetChunk(chunk.X, chunk.Z + 1);
            Chunk leftChunk  = world.GetChunk(chunk.X - 1, chunk.Z);
            Chunk rightChunk = world.GetChunk(chunk.X + 1, chunk.Z);

            if (frontChunk != null && frontChunk.MinSliceIndex < minSliceIndex)
            {
                minSliceIndex = frontChunk.MinSliceIndex;
                lowestY       = frontChunk.LowestY;
            }

            if (backChunk != null && backChunk.MinSliceIndex < minSliceIndex)
            {
                minSliceIndex = backChunk.MinSliceIndex;
                lowestY       = backChunk.LowestY;
            }

            if (leftChunk != null && leftChunk.MinSliceIndex < minSliceIndex)
            {
                minSliceIndex = leftChunk.MinSliceIndex;
                lowestY       = leftChunk.MinSliceIndex;
            }

            if (rightChunk != null && rightChunk.MinSliceIndex < minSliceIndex)
            {
                minSliceIndex = rightChunk.MinSliceIndex;
                lowestY       = rightChunk.MinSliceIndex;
            }


            for (int i = Chunk.NumSlices - 1; i >= 0; --i)
            {
                ChunkSlice chunkSlice = chunk.Slices[i];

                if (i < minSliceIndex)
                {
                    for (int index = i; index >= 0; --index)
                    {
                        indexesToDelete.Add(index);
                    }
                    break;
                }

                if (chunkSlice.IsEmpty)
                {
                    indexesToDelete.Add(i);
                    continue;
                }

                float epsilon = 0.00f;

                /*watch.Reset();
                *  watch.Start();*/

                int minHeight = chunk.MinSliceIndex == chunkSlice.Index ? (chunk.LowestY & Chunk.SliceHeightLimit) : 0;

                for (int x = 0; x < 16; x++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        for (int y = Chunk.SliceHeight - 1; y >= 0 && y >= minHeight; --y)
                        {
                            byte block = chunkSlice[x, y, z];
                            int  light = 0;
                            byte top;

                            if (block == 0)
                            {
                                continue;
                            }

                            if (y + 1 > Chunk.SliceHeightLimit)
                            {
                                if (i + 1 > Chunk.MaxSliceIndex)
                                {
                                    top = 0;
                                }
                                else
                                {
                                    ChunkSlice topSlice = chunk.Slices[i + 1];
                                    top   = topSlice[x, (y + 1) & Chunk.SliceHeightLimit, z];
                                    light = topSlice.GetSkylight(x, (y + 1) & Chunk.SliceHeightLimit, z);
                                }
                            }
                            else
                            {
                                top   = chunkSlice[x, y + 1, z];
                                light = chunkSlice.GetSkylight(x, y + 1, z);
                            }

                            // we are checking the top face of the block, so see if the top is exposed
                            if (top == 0)
                            {
                                if (WorldBehaviour.mode == 2)
                                {
                                    spawnBrick(block, new Vector3(x, y, z));
                                }
                                else if (WorldBehaviour.mode == 3)
                                {
                                    addBrickFace("top", block, x, y, z);
                                }
                                else
                                {
                                    int vertexIndex = vertices.Count;
                                    vertices.Add(new Vector3(x, y + 1, z));
                                    vertices.Add(new Vector3(x, y + 1, z + 1));
                                    vertices.Add(new Vector3(x + 1, y + 1, z + 1));
                                    vertices.Add(new Vector3(x + 1, y + 1, z));

                                    triangles.Add(vertexIndex);
                                    triangles.Add(vertexIndex + 1);
                                    triangles.Add(vertexIndex + 2);

                                    triangles.Add(vertexIndex + 2);
                                    triangles.Add(vertexIndex + 3);
                                    triangles.Add(vertexIndex);


                                    float attenuation = (light / 15.0f);
                                    Color withLight   = new Color(topColor.r * attenuation, topColor.g * attenuation, topColor.b * attenuation, 1);
                                    colors.Add(withLight);
                                    colors.Add(withLight);
                                    colors.Add(withLight);
                                    colors.Add(withLight);

                                    Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Top);

                                    float yMax = coords.y + coords.height - epsilon;
                                    float xMax = coords.x + coords.width - epsilon;
                                    float xMin = coords.x + epsilon;
                                    float yMin = coords.y + epsilon;

                                    uvs.Add(new Vector2(xMin, yMax));
                                    uvs.Add(new Vector2(xMin, yMin));
                                    uvs.Add(new Vector2(xMax, yMin));
                                    uvs.Add(new Vector2(xMax, yMax));
                                }
                            }

                            int front;
                            if (z - 1 < 0)
                            {
                                int worldX = (chunk.X << 4) + x;
                                int worldZ = (chunk.Z << 4) - 1;
                                int worldY = (chunkSlice.Index * ChunkSlice.SizeY) + y;

                                front = (byte)world.GetBlockType(worldX, worldY, worldZ);
                            }
                            else
                            {
                                front = chunkSlice[x, y, z - 1];
                            }

                            if (front == 0)
                            {
                                if (WorldBehaviour.mode == 2)
                                {
                                    spawnBrick(block, new Vector3(x, y, z));
                                }
                                else if (WorldBehaviour.mode == 3)
                                {
                                    addBrickFace("front", block, x, y, z);
                                }
                                else
                                {
                                    int vertexIndex = vertices.Count;
                                    vertices.Add(new Vector3(x, y, z));
                                    vertices.Add(new Vector3(x, y + 1, z));
                                    vertices.Add(new Vector3(x + 1, y + 1, z));
                                    vertices.Add(new Vector3(x + 1, y, z));

                                    triangles.Add(vertexIndex);
                                    triangles.Add(vertexIndex + 1);
                                    triangles.Add(vertexIndex + 2);

                                    triangles.Add(vertexIndex + 2);
                                    triangles.Add(vertexIndex + 3);
                                    triangles.Add(vertexIndex);

                                    colors.Add(firstSideColor);
                                    colors.Add(firstSideColor);
                                    colors.Add(firstSideColor);
                                    colors.Add(firstSideColor);

                                    Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Side);

                                    float yMax = coords.y + coords.height - epsilon;
                                    float xMax = coords.x + coords.width - epsilon;
                                    float xMin = coords.x + epsilon;
                                    float yMin = coords.y + epsilon;

                                    uvs.Add(new Vector2(xMin, yMin));
                                    uvs.Add(new Vector2(xMin, yMax));
                                    uvs.Add(new Vector2(xMax, yMax));
                                    uvs.Add(new Vector2(xMax, yMin));
                                }
                            }

                            int right;

                            if (x + 1 > 15)
                            {
                                int worldX = (chunk.X << 4) + 16;
                                int worldZ = (chunk.Z << 4) + z;
                                int worldY = (chunkSlice.Index * ChunkSlice.SizeY) + y;

                                right = (byte)world.GetBlockType(worldX, worldY, worldZ);
                            }
                            else
                            {
                                right = chunkSlice[x + 1, y, z];
                            }

                            if (right == 0)
                            {
                                if (WorldBehaviour.mode == 2)
                                {
                                    spawnBrick(block, new Vector3(x, y, z));
                                }
                                else if (WorldBehaviour.mode == 3)
                                {
                                    addBrickFace("right", block, x, y, z);
                                }
                                else
                                {
                                    int vertexIndex = vertices.Count;
                                    vertices.Add(new Vector3(x + 1, y, z));
                                    vertices.Add(new Vector3(x + 1, y + 1, z));
                                    vertices.Add(new Vector3(x + 1, y + 1, z + 1));
                                    vertices.Add(new Vector3(x + 1, y, z + 1));

                                    triangles.Add(vertexIndex);
                                    triangles.Add(vertexIndex + 1);
                                    triangles.Add(vertexIndex + 2);

                                    triangles.Add(vertexIndex + 2);
                                    triangles.Add(vertexIndex + 3);
                                    triangles.Add(vertexIndex);

                                    colors.Add(secondSideColor);
                                    colors.Add(secondSideColor);
                                    colors.Add(secondSideColor);
                                    colors.Add(secondSideColor);

                                    Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Side);

                                    float yMax = coords.y + coords.height - epsilon;
                                    float xMax = coords.x + coords.width - epsilon;
                                    float xMin = coords.x + epsilon;
                                    float yMin = coords.y + epsilon;

                                    uvs.Add(new Vector2(xMin, yMin));
                                    uvs.Add(new Vector2(xMin, yMax));
                                    uvs.Add(new Vector2(xMax, yMax));
                                    uvs.Add(new Vector2(xMax, yMin));
                                }
                            }

                            int back;

                            if (z + 1 > 15)
                            {
                                int worldX = (chunk.X << 4) + x;
                                int worldZ = (chunk.Z << 4) + 16;
                                int worldY = (chunkSlice.Index * ChunkSlice.SizeY) + y;

                                back = (byte)world.GetBlockType(worldX, worldY, worldZ);
                            }
                            else
                            {
                                back = chunkSlice[x, y, z + 1];
                            }

                            if (back == 0)
                            {
                                if (WorldBehaviour.mode == 2)
                                {
                                    spawnBrick(block, new Vector3(x, y, z));
                                }
                                else if (WorldBehaviour.mode == 3)
                                {
                                    addBrickFace("back", block, x, y, z);
                                }
                                else
                                {
                                    int vertexIndex = vertices.Count;
                                    vertices.Add(new Vector3(x + 1, y, z + 1));
                                    vertices.Add(new Vector3(x + 1, y + 1, z + 1));
                                    vertices.Add(new Vector3(x, y + 1, z + 1));
                                    vertices.Add(new Vector3(x, y, z + 1));

                                    triangles.Add(vertexIndex);
                                    triangles.Add(vertexIndex + 1);
                                    triangles.Add(vertexIndex + 2);

                                    triangles.Add(vertexIndex + 2);
                                    triangles.Add(vertexIndex + 3);
                                    triangles.Add(vertexIndex);

                                    colors.Add(firstSideColor);
                                    colors.Add(firstSideColor);
                                    colors.Add(firstSideColor);
                                    colors.Add(firstSideColor);

                                    Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Side);

                                    float yMax = coords.y + coords.height - epsilon;
                                    float xMax = coords.x + coords.width - epsilon;
                                    float xMin = coords.x + epsilon;
                                    float yMin = coords.y + epsilon;

                                    uvs.Add(new Vector2(xMin, yMin));
                                    uvs.Add(new Vector2(xMin, yMax));
                                    uvs.Add(new Vector2(xMax, yMax));
                                    uvs.Add(new Vector2(xMax, yMin));
                                }
                            }

                            int left;

                            if (x - 1 < 0)
                            {
                                int worldX = (chunk.X << 4) - 1;
                                int worldZ = (chunk.Z << 4) + z;
                                int worldY = (chunkSlice.Index * ChunkSlice.SizeY) + y;

                                left = (byte)world.GetBlockType(worldX, worldY, worldZ);
                            }
                            else
                            {
                                left = chunkSlice[x - 1, y, z];
                            }

                            if (left == 0)
                            {
                                if (WorldBehaviour.mode == 2)
                                {
                                    spawnBrick(block, new Vector3(x, y, z));
                                }
                                else if (WorldBehaviour.mode == 3)
                                {
                                    addBrickFace("left", block, x, y, z);
                                }
                                else
                                {
                                    int vertexIndex = vertices.Count;
                                    vertices.Add(new Vector3(x, y, z + 1));
                                    vertices.Add(new Vector3(x, y + 1, z + 1));
                                    vertices.Add(new Vector3(x, y + 1, z));
                                    vertices.Add(new Vector3(x, y, z));

                                    triangles.Add(vertexIndex);
                                    triangles.Add(vertexIndex + 1);
                                    triangles.Add(vertexIndex + 2);

                                    triangles.Add(vertexIndex + 2);
                                    triangles.Add(vertexIndex + 3);
                                    triangles.Add(vertexIndex);

                                    colors.Add(secondSideColor);
                                    colors.Add(secondSideColor);
                                    colors.Add(secondSideColor);
                                    colors.Add(secondSideColor);

                                    Rect coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Side);

                                    float yMax = coords.y + coords.height - epsilon;
                                    float xMax = coords.x + coords.width - epsilon;
                                    float xMin = coords.x + epsilon;
                                    float yMin = coords.y + epsilon;

                                    uvs.Add(new Vector2(xMin, yMin));
                                    uvs.Add(new Vector2(xMin, yMax));
                                    uvs.Add(new Vector2(xMax, yMax));
                                    uvs.Add(new Vector2(xMax, yMin));
                                }
                            }

                            byte bottom;

                            if (y - 1 < 0)
                            {
                                bottom = 1;
                            }
                            else
                            {
                                bottom = chunkSlice[x, y - 1, z];
                            }

                            if (bottom == 0)
                            {
                                if (WorldBehaviour.mode == 2)
                                {
                                    spawnBrick(block, new Vector3(x, y, z));
                                }
                                else if (WorldBehaviour.mode == 3)
                                {
                                    addBrickFace("bottom", block, x, y, z);
                                }
                                else
                                {
                                    int vertexIndex = vertices.Count;
                                    vertices.Add(new Vector3(x, y, z + 1));
                                    vertices.Add(new Vector3(x, y, z));
                                    vertices.Add(new Vector3(x + 1, y, z));
                                    vertices.Add(new Vector3(x + 1, y, z + 1));

                                    triangles.Add(vertexIndex);
                                    triangles.Add(vertexIndex + 1);
                                    triangles.Add(vertexIndex + 2);

                                    triangles.Add(vertexIndex + 2);
                                    triangles.Add(vertexIndex + 3);
                                    triangles.Add(vertexIndex);

                                    colors.Add(bottomColor);
                                    colors.Add(bottomColor);
                                    colors.Add(bottomColor);
                                    colors.Add(bottomColor);

                                    Rect  coords = BlockUVs.GetUVFromTypeAndFace((BlockType)block, BlockFace.Bottom);
                                    float yMax   = coords.y + coords.height - epsilon;
                                    float xMax   = coords.x + coords.width - epsilon;
                                    float xMin   = coords.x + epsilon;
                                    float yMin   = coords.y + epsilon;

                                    uvs.Add(new Vector2(xMin, yMin));
                                    uvs.Add(new Vector2(xMin, yMax));
                                    uvs.Add(new Vector2(xMax, yMax));
                                    uvs.Add(new Vector2(xMax, yMin));
                                }
                            }
                        }
                    }
                }

                /*watch.Stop();
                 * long elapsedPreMesh = watch.ElapsedMilliseconds;
                 * watch.Start();*/


                ChunkSliceBuildEntry chunkEntry = new ChunkSliceBuildEntry();
                chunkEntry.Vertices    = vertices.ToArray();
                chunkEntry.Triangles   = triangles.ToArray();
                chunkEntry.Colors      = colors.ToArray();
                chunkEntry.Uvs         = uvs.ToArray();
                chunkEntry.ParentChunk = chunk;
                chunkEntry.SliceIndex  = i;

                chunkEntry.ColliderVertices  = colliderVertices.ToArray();
                chunkEntry.ColliderTriangles = colliderTriangles.ToArray();

                if (WorldBehaviour.mode == 2)
                {
                    Dictionary <byte, Vector3[]> meshList = new Dictionary <byte, Vector3[]>();
                    foreach (byte block in meshes.Keys)
                    {
                        meshList.Add(block, meshes[block].ToArray());
                    }

                    chunkEntry.meshes = meshList;
                }

                vertices.Clear();
                triangles.Clear();
                colors.Clear();
                uvs.Clear();
                meshes.Clear();
                added.Clear();

                colliderVertices.Clear();
                colliderTriangles.Clear();

                lock (WorldBehaviour.ChunkQueueLock)
                    WorldBehaviour.ChunkSlicesToBuild.Enqueue(chunkEntry);

                //watch.Stop();
                //elapsedPostSet = watch.ElapsedMilliseconds;

                /*UnityEngine.Debug.Log("Elapsed Mesh Prepare " + elapsedPreMesh + "ms");
                 * UnityEngine.Debug.Log("Elapsed Mesh Build " + (elapsedPostMesh - elapsedPreMesh) + "ms");
                 * UnityEngine.Debug.Log("Elapsed Mesh Set " + (elapsedPostSet - elapsedPostMesh) + "ms");
                 * UnityEngine.Debug.Log("Total Elapsed " + (elapsedPostSet));*/
            }
            if (indexesToDelete.Count > 0)
            {
                lock (WorldBehaviour.SliceLock)
                {
                    ChunkSlicesDeleteEntry chunkSliceEntry = new ChunkSlicesDeleteEntry();
                    chunkSliceEntry.indexesToDelete = indexesToDelete.ToArray();
                    chunkSliceEntry.parentChunk     = chunk;

                    WorldBehaviour.SlicesToDelete.Enqueue(chunkSliceEntry);
                }
            }
            //watch.Stop();
            //UnityEngine.Debug.Log ("Total Elapsed " + ((double)watch.ElapsedTicks / (double)Stopwatch.Frequency) + "ms");
        }