Пример #1
0
        private void CreateVerticies(Color color)
        {
            Vertices = new ExtendedVertex[RelativeTransforms.Count * 4];

            Vector3 topLeftFront  = new Vector3(-0.5f * Width, 0.5f * Height, 0.0f);
            Vector3 topRightFront = new Vector3(0.5f * Width, 0.5f * Height, 0.0f);
            Vector3 btmLeftFront  = new Vector3(-0.5f * Width, -0.5f * Height, 0.0f);
            Vector3 btmRightFront = new Vector3(0.5f * Width, -0.5f * Height, 0.0f);

            Indexes = new ushort[RelativeTransforms.Count * 6];

            for (int i = 0; i < RelativeTransforms.Count; i++)
            {
                int vertOffset = i * 4;
                Vertices[vertOffset + 0] = new ExtendedVertex(Vector3.Transform(topLeftFront, RelativeTransforms[i]), Tints[i], VertColors[i], UVs.UVs[0], UVs.Bounds);
                Vertices[vertOffset + 1] = new ExtendedVertex(Vector3.Transform(btmLeftFront, RelativeTransforms[i]), Tints[i], VertColors[i], UVs.UVs[1], UVs.Bounds);
                Vertices[vertOffset + 2] = new ExtendedVertex(Vector3.Transform(topRightFront, RelativeTransforms[i]), Tints[i], VertColors[i], UVs.UVs[2], UVs.Bounds);
                Vertices[vertOffset + 3] = new ExtendedVertex(Vector3.Transform(btmRightFront, RelativeTransforms[i]), Tints[i], VertColors[i], UVs.UVs[3], UVs.Bounds);


                int indOffset = i * 6;
                Indexes[indOffset + 0] = (ushort)(vertOffset + 1);
                Indexes[indOffset + 1] = (ushort)(vertOffset + 0);
                Indexes[indOffset + 2] = (ushort)(vertOffset + 2);
                Indexes[indOffset + 3] = (ushort)(vertOffset + 1);
                Indexes[indOffset + 4] = (ushort)(vertOffset + 2);
                Indexes[indOffset + 5] = (ushort)(vertOffset + 3);
            }
        }
        private void CreateVerticies(Color color)
        {
            Vertices = new ExtendedVertex[RelativeTransforms.Count * 4];

            Vector3 topLeftFront  = new Vector3(-0.5f * Width, 0.5f * Height, 0.0f);
            Vector3 topRightFront = new Vector3(0.5f * Width, 0.5f * Height, 0.0f);
            Vector3 btmLeftFront  = new Vector3(-0.5f * Width, -0.5f * Height, 0.0f);
            Vector3 btmRightFront = new Vector3(0.5f * Width, -0.5f * Height, 0.0f);

            short[] indices = new short[RelativeTransforms.Count * 6];

            for (int i = 0; i < RelativeTransforms.Count; i++)
            {
                int vertOffset = i * 4;
                Vertices[vertOffset + 0] = new ExtendedVertex(Vector3.Transform(topLeftFront, RelativeTransforms[i]), Tints[i], UVs.UVs[0], UVs.Bounds);
                Vertices[vertOffset + 1] = new ExtendedVertex(Vector3.Transform(btmLeftFront, RelativeTransforms[i]), Tints[i], UVs.UVs[1], UVs.Bounds);
                Vertices[vertOffset + 2] = new ExtendedVertex(Vector3.Transform(topRightFront, RelativeTransforms[i]), Tints[i], UVs.UVs[2], UVs.Bounds);
                Vertices[vertOffset + 3] = new ExtendedVertex(Vector3.Transform(btmRightFront, RelativeTransforms[i]), Tints[i], UVs.UVs[3], UVs.Bounds);


                int indOffset = i * 6;
                indices[indOffset + 0] = (short)(vertOffset + 1);
                indices[indOffset + 1] = (short)(vertOffset + 0);
                indices[indOffset + 2] = (short)(vertOffset + 2);
                indices[indOffset + 3] = (short)(vertOffset + 1);
                indices[indOffset + 4] = (short)(vertOffset + 2);
                indices[indOffset + 5] = (short)(vertOffset + 3);
            }
            IndexBuffer = new IndexBuffer(GameState.Game.GraphicsDevice, typeof(short), RelativeTransforms.Count * 6, BufferUsage.None);
            IndexBuffer.SetData(indices);
        }
Пример #3
0
        public BillboardPrimitive()
        {
            Vertices = new ExtendedVertex[4];

            Indexes = new ushort[]
            {
                1, 0, 2,
                1, 2, 3
            };
        }
Пример #4
0
        public void SetFrame(SpriteSheet Sheet,
                             Rectangle Rect,
                             float Width,
                             float Height,
                             Color Color,
                             Color VertColor,
                             bool Flipped)
        {
            var texture = Sheet.GetTexture();

            var tileBounds = new Vector4(
                ((float)Rect.X / texture.Width) + 0.001f,
                ((float)Rect.Y / texture.Height) + 0.001f,
                ((float)Rect.Right / texture.Width) - 0.001f,
                ((float)Rect.Bottom / texture.Height) - 0.001f);

            Vertices[0] = new ExtendedVertex(
                new Vector3(-0.5f * Width, 0.5f * Height, 0.0f),
                Color, VertColor,
                new Vector2((float)Rect.Right / texture.Width, (float)Rect.Y / texture.Height),
                tileBounds);

            Vertices[1] = new ExtendedVertex(
                new Vector3(-0.5f * Width, -0.5f * Height, 0.0f),
                Color, VertColor,
                new Vector2((float)Rect.Right / texture.Width, (float)Rect.Bottom / texture.Height),
                tileBounds);

            Vertices[2] = new ExtendedVertex(
                new Vector3(0.5f * Width, 0.5f * Height, 0.0f),
                Color, VertColor,
                new Vector2((float)Rect.X / texture.Width, (float)Rect.Y / texture.Height),
                tileBounds);

            Vertices[3] = new ExtendedVertex(
                new Vector3(0.5f * Width, -0.5f * Height, 0.0f),
                Color, VertColor,
                new Vector2((float)Rect.X / texture.Width, (float)Rect.Bottom / texture.Height),
                tileBounds);

            //GameState.Game.GraphicsDevice.SetVertexBuffer(null);
            if (VertexBuffer == null)
            {
                ResetBuffer(GameState.Game.GraphicsDevice);
            }
            else
            {
                var buffers = GameState.Game.GraphicsDevice.GetVertexBuffers();
                if (buffers.Any(buffer => buffer.VertexBuffer == VertexBuffer))
                {
                    GameState.Game.GraphicsDevice.SetVertexBuffer(null);
                }
                VertexBuffer.SetData(Vertices);
            }
        }
Пример #5
0
        public void AddTriangle(ExtendedVertex A, ExtendedVertex B, ExtendedVertex C)
        {
            var index = (short)VertexCount;

            AddVertex(A);
            AddVertex(B);
            AddVertex(C);
            AddIndex(index);
            AddIndex((short)(index + 1));
            AddIndex((short)(index + 2));
        }
Пример #6
0
        private void CreateVerticies()
        {
            Indexes        = new ushort[36];
            FlippedIndexes = new ushort[36];
            Vertices       = new ExtendedVertex[NumVertices];

            // Calculate the position of the vertices on the top face.
            Vector3 topLeftFront  = new Vector3(0.0f, Height, 0.0f);
            Vector3 topLeftBack   = new Vector3(0.0f, Height, 1.0f);
            Vector3 topRightFront = new Vector3(Width, Height, 0.0f);
            Vector3 topRightBack  = new Vector3(Width, Height, 1.0f);

            // Calculate the position of the vertices on the bottom face.
            Vector3 btmLeftFront  = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 btmLeftBack   = new Vector3(0.0f, 0.0f, 1.0f);
            Vector3 btmRightFront = new Vector3(Width, 0.0f, 0.0f);
            Vector3 btmRightBack  = new Vector3(Width, 0.0f, 1.0f);

            // Normal vectors for each face (needed for lighting / display)


            // Add the vertices for the FRONT face.
            Vertices[0] = new ExtendedVertex(topLeftFront, Color.White, Color.White, UVs.Uvs[0], UVs.Bounds[0]);
            Vertices[1] = new ExtendedVertex(btmLeftFront, Color.White, Color.White, UVs.Uvs[1], UVs.Bounds[0]);
            Vertices[2] = new ExtendedVertex(btmRightFront, Color.White, Color.White, UVs.Uvs[2], UVs.Bounds[0]);
            Vertices[3] = new ExtendedVertex(topRightFront, Color.White, Color.White, UVs.Uvs[3], UVs.Bounds[0]);

            /*
             *  0 . . . 3
             *  .     . .
             *  .   .   .
             *  . .     .
             *  1 . . . 2
             */
            Indexes[0] = 0;
            Indexes[1] = 1;
            Indexes[2] = 3;
            Indexes[3] = 3;
            Indexes[4] = 1;
            Indexes[5] = 2;

            /*
             *  0 . . . 3
             *  . .     .
             *  .   .   .
             *  .     . .
             *  1 . . . 2
             */
            FlippedIndexes[0] = 0;
            FlippedIndexes[1] = 1;
            FlippedIndexes[2] = 2;
            FlippedIndexes[3] = 3;
            FlippedIndexes[4] = 0;
            FlippedIndexes[5] = 2;

            // Add the vertices for the BACK face.
            Vertices[4] = new ExtendedVertex(topRightBack, Color.White, Color.White, UVs.Uvs[4], UVs.Bounds[1]);
            Vertices[5] = new ExtendedVertex(btmRightBack, Color.White, Color.White, UVs.Uvs[5], UVs.Bounds[1]);
            Vertices[6] = new ExtendedVertex(btmLeftBack, Color.White, Color.White, UVs.Uvs[6], UVs.Bounds[1]);
            Vertices[7] = new ExtendedVertex(topLeftBack, Color.White, Color.White, UVs.Uvs[7], UVs.Bounds[1]);


            /*
             *  4 . . . 7
             *  .     . .
             *  .   .   .
             *  . .     .
             *  5 . . . 6
             */
            Indexes[6]  = 4;
            Indexes[7]  = 5;
            Indexes[8]  = 7;
            Indexes[9]  = 7;
            Indexes[10] = 5;
            Indexes[11] = 6;

            /*
             *  4 . . . 7
             *  . .     .
             *  .   .   .
             *  .     . .
             *  5 . . . 6
             */
            FlippedIndexes[6]  = 4;
            FlippedIndexes[7]  = 5;
            FlippedIndexes[8]  = 6;
            FlippedIndexes[9]  = 6;
            FlippedIndexes[10] = 7;
            FlippedIndexes[11] = 4;

            // Add the vertices for the TOP face.
            Vertices[8]  = new ExtendedVertex(topLeftBack, Color.White, Color.White, UVs.Uvs[8], UVs.Bounds[2]);
            Vertices[9]  = new ExtendedVertex(topLeftFront, Color.White, Color.White, UVs.Uvs[9], UVs.Bounds[2]);
            Vertices[10] = new ExtendedVertex(topRightFront, Color.White, Color.White, UVs.Uvs[10], UVs.Bounds[2]);
            Vertices[11] = new ExtendedVertex(topRightBack, Color.White, Color.White, UVs.Uvs[11], UVs.Bounds[2]);


            /*
             *  8 . . .11
             *  .     . .
             *  .   .   .
             *  .  .    .
             *  9 . . . 10
             */
            Indexes[12] = 8;
            Indexes[13] = 9;
            Indexes[14] = 11;
            Indexes[15] = 10;
            Indexes[16] = 11;
            Indexes[17] = 9;


            /*
             *  8 . . .11
             *  . .     .
             *  .   .   .
             *  .     . .
             *  9 . . .10
             */
            FlippedIndexes[12] = 8;
            FlippedIndexes[13] = 10;
            FlippedIndexes[14] = 11;
            FlippedIndexes[15] = 10;
            FlippedIndexes[16] = 8;
            FlippedIndexes[17] = 9;

            // Add the vertices for the BOTTOM face.
            Vertices[12] = new ExtendedVertex(btmLeftFront, Color.White, Color.White, UVs.Uvs[12], UVs.Bounds[3]);
            Vertices[13] = new ExtendedVertex(btmLeftBack, Color.White, Color.White, UVs.Uvs[13], UVs.Bounds[3]);
            Vertices[14] = new ExtendedVertex(btmRightBack, Color.White, Color.White, UVs.Uvs[14], UVs.Bounds[3]);
            Vertices[15] = new ExtendedVertex(btmRightFront, Color.White, Color.White, UVs.Uvs[15], UVs.Bounds[3]);


            /*
             *  12. . .15
             *  .     . .
             *  .   .   .
             *  .  .    .
             *  13. . .14
             */

            Indexes[18] = 12;
            Indexes[19] = 13;
            Indexes[20] = 15;
            Indexes[21] = 15;
            Indexes[22] = 13;
            Indexes[23] = 14;


            /*
             *  12. . .15
             *  . .     .
             *  .   .   .
             *  .     . .
             *  13. . .14
             */
            FlippedIndexes[18] = 12;
            FlippedIndexes[19] = 13;
            FlippedIndexes[20] = 14;
            FlippedIndexes[21] = 15;
            FlippedIndexes[22] = 12;
            FlippedIndexes[23] = 14;

            // Add the vertices for the LEFT face.
            Vertices[16] = new ExtendedVertex(topLeftBack, Color.White, Color.White, UVs.Uvs[16], UVs.Bounds[4]);
            Vertices[17] = new ExtendedVertex(btmLeftBack, Color.White, Color.White, UVs.Uvs[17], UVs.Bounds[4]);
            Vertices[18] = new ExtendedVertex(btmLeftFront, Color.White, Color.White, UVs.Uvs[18], UVs.Bounds[4]);
            Vertices[19] = new ExtendedVertex(topLeftFront, Color.White, Color.White, UVs.Uvs[19], UVs.Bounds[4]);

            /*
             *  16. . .19
             *  .     . .
             *  .   .   .
             *  .  .    .
             *  17. . .18
             */
            Indexes[24] = 16;
            Indexes[25] = 17;
            Indexes[26] = 19;
            Indexes[27] = 18;
            Indexes[28] = 19;
            Indexes[29] = 17;


            /*
             *  16. . .19
             *  . .     .
             *  .   .   .
             *  .     . .
             *  17. . .18
             */
            FlippedIndexes[24] = 16;
            FlippedIndexes[25] = 17;
            FlippedIndexes[26] = 18;
            FlippedIndexes[27] = 18;
            FlippedIndexes[28] = 19;
            FlippedIndexes[29] = 16;


            // Add the vertices for the RIGHT face.
            Vertices[20] = new ExtendedVertex(topRightFront, Color.White, Color.White, UVs.Uvs[20], UVs.Bounds[5]);
            Vertices[21] = new ExtendedVertex(btmRightFront, Color.White, Color.White, UVs.Uvs[21], UVs.Bounds[5]);
            Vertices[22] = new ExtendedVertex(btmRightBack, Color.White, Color.White, UVs.Uvs[22], UVs.Bounds[5]);
            Vertices[23] = new ExtendedVertex(topRightBack, Color.White, Color.White, UVs.Uvs[23], UVs.Bounds[5]);

            /*
             *  20. . .23
             *  .     . .
             *  .   .   .
             *  .  .    .
             *  21. . .22
             */
            Indexes[30] = 20;
            Indexes[31] = 21;
            Indexes[32] = 23;
            Indexes[33] = 23;
            Indexes[34] = 21;
            Indexes[35] = 22;

            /*
             *  20. . .23
             *  . .     .
             *  .   .   .
             *  .     . .
             *  21. . .22
             */
            FlippedIndexes[30] = 20;
            FlippedIndexes[31] = 21;
            FlippedIndexes[32] = 22;
            FlippedIndexes[33] = 23;
            FlippedIndexes[34] = 20;
            FlippedIndexes[35] = 22;

            try
            {
                IndexBuffer = new DynamicIndexBuffer(GameState.Game.GraphicsDevice, typeof(ushort), Indexes.Length, BufferUsage.WriteOnly);
                IndexBuffer.SetData(Indexes);
            }
            catch (Exception exception)
            {
                IndexBuffer = null;
            }

            Faces = new List <FaceDescriptor>
            {
                new FaceDescriptor
                {
                    Face         = BoxFace.Top,
                    VertexCount  = 4,
                    IndexCount   = 6,
                    IndexOffset  = 12,
                    VertexOffset = 8
                },
                new FaceDescriptor
                {
                    Face         = BoxFace.Bottom,
                    VertexCount  = 4,
                    IndexCount   = 6,
                    IndexOffset  = 18,
                    VertexOffset = 12
                },
                new FaceDescriptor
                {
                    Face         = BoxFace.Left,
                    VertexCount  = 4,
                    IndexCount   = 6,
                    IndexOffset  = 24,
                    VertexOffset = 16
                },
                new FaceDescriptor
                {
                    Face         = BoxFace.Right,
                    VertexCount  = 4,
                    IndexCount   = 6,
                    IndexOffset  = 30,
                    VertexOffset = 20
                },
                new FaceDescriptor
                {
                    Face         = BoxFace.Front,
                    VertexCount  = 4,
                    IndexCount   = 6,
                    IndexOffset  = 0,
                    VertexOffset = 0
                },
                new FaceDescriptor
                {
                    Face         = BoxFace.Back,
                    VertexCount  = 4,
                    IndexCount   = 6,
                    IndexOffset  = 6,
                    VertexOffset = 4
                },
            };
        }
Пример #7
0
        public void InitializeFromChunk(VoxelChunk chunk, GraphicsDevice graphics)
        {
            if (chunk == null)
            {
                return;
            }

            rebuildMutex.WaitOne();
            if (isRebuilding)
            {
                rebuildMutex.ReleaseMutex();
                return;
            }

            isRebuilding = true;
            rebuildMutex.ReleaseMutex();


            accumulatedVertices.Clear();
            accumulatedIndices.Clear();
            faceExists.Clear();
            drawFace.Clear();

            Voxel v           = chunk.MakeVoxel(0, 0, 0);
            Voxel voxelOnFace = chunk.MakeVoxel(0, 0, 0);

            Voxel[] manhattanNeighbors = new Voxel[4];
            for (int x = 0; x < chunk.SizeX; x++)
            {
                for (int y = 0; y < Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY); y++)
                {
                    for (int z = 0; z < chunk.SizeZ; z++)
                    {
                        v.GridPosition = new Vector3(x, y, z);


                        if (v.IsEmpty || !v.IsVisible)
                        {
                            continue;
                        }

                        BoxPrimitive primitive = VoxelLibrary.GetPrimitive(v.Type);

                        if (primitive == null)
                        {
                            continue;
                        }

                        BoxPrimitive.BoxTextureCoords uvs = primitive.UVs;

                        if (v.Type.HasTransitionTextures)
                        {
                            uvs = v.ComputeTransitionTexture(manhattanNeighbors);
                        }


                        Voxel worldVoxel = new Voxel();
                        for (int i = 0; i < 6; i++)
                        {
                            BoxFace face  = (BoxFace)i;
                            Vector3 delta = FaceDeltas[face];
                            faceExists[face] = chunk.IsCellValid(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z);
                            drawFace[face]   = true;

                            if (faceExists[face])
                            {
                                voxelOnFace.GridPosition = new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z);
                                drawFace[face]           = voxelOnFace.IsEmpty || !voxelOnFace.IsVisible || (voxelOnFace.Type.CanRamp && voxelOnFace.RampType != RampType.None && IsSideFace(face) && ShouldDrawFace(face, voxelOnFace.RampType, v.RampType));
                            }
                            else
                            {
                                bool success = chunk.Manager.ChunkData.GetNonNullVoxelAtWorldLocation(new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z) + chunk.Origin, ref worldVoxel);
                                drawFace[face] = !success || worldVoxel.IsEmpty || !worldVoxel.IsVisible || (worldVoxel.Type.CanRamp && worldVoxel.RampType != RampType.None && IsSideFace(face) && ShouldDrawFace(face, worldVoxel.RampType, v.RampType));
                            }
                        }


                        for (int i = 0; i < 6; i++)
                        {
                            BoxFace face = (BoxFace)i;
                            if (!drawFace[face])
                            {
                                continue;
                            }
                            int faceIndex   = 0;
                            int faceCount   = 0;
                            int vertexIndex = 0;
                            int vertexCount = 0;
                            primitive.GetFace(face, uvs, out faceIndex, out faceCount, out vertexIndex, out vertexCount);
                            Vector2 texScale = uvs.Scales[i];

                            int indexOffset = accumulatedVertices.Count;
                            for (int vertOffset = 0; vertOffset < vertexCount; vertOffset++)
                            {
                                ExtendedVertex vert      = primitive.Vertices[vertOffset + vertexIndex];
                                VoxelVertex    bestKey   = VoxelChunk.GetNearestDelta(vert.Position);
                                Color          color     = v.Chunk.Data.GetColor(x, y, z, bestKey);
                                Vector3        offset    = Vector3.Zero;
                                Vector2        texOffset = Vector2.Zero;

                                if (v.Type.CanRamp && ShouldRamp(bestKey, v.RampType))
                                {
                                    offset = new Vector3(0, -v.Type.RampSize, 0);

                                    if (face != BoxFace.Top && face != BoxFace.Bottom)
                                    {
                                        texOffset = new Vector2(0, v.Type.RampSize * (texScale.Y));
                                    }
                                }


                                ExtendedVertex newVertex = new ExtendedVertex((vert.Position + v.Position + VertexNoise.GetNoiseVectorFromRepeatingTexture(vert.Position + v.Position) + offset),
                                                                              color,
                                                                              uvs.Uvs[vertOffset + vertexIndex] + texOffset, uvs.Bounds[faceIndex / 6]);
                                accumulatedVertices.Add(newVertex);
                            }

                            for (int idx = faceIndex; idx < faceCount + faceIndex; idx++)
                            {
                                int vertexOffset = primitive.Indices[idx];
                                accumulatedIndices.Add((short)(indexOffset + (vertexOffset - primitive.Indices[faceIndex])));
                            }
                        }
                    }
                }
            }


            Vertices = new ExtendedVertex[accumulatedVertices.Count];
            accumulatedVertices.CopyTo(Vertices);
            IndexBuffer = new IndexBuffer(graphics, typeof(short), accumulatedIndices.Count, BufferUsage.WriteOnly);
            IndexBuffer.SetData(accumulatedIndices.ToArray());

            ResetBuffer(graphics);
            isRebuilding = false;

            //chunk.PrimitiveMutex.WaitOne();
            chunk.NewPrimitive         = this;
            chunk.NewPrimitiveReceived = true;
            //chunk.PrimitiveMutex.ReleaseMutex();
        }
Пример #8
0
        private void CreateVerticies()
        {
            Indices  = new short[36];
            Vertices = new ExtendedVertex[NumVertices];

            // Calculate the position of the vertices on the top face.
            Vector3 topLeftFront  = new Vector3(0.0f, Height, 0.0f);
            Vector3 topLeftBack   = new Vector3(0.0f, Height, Depth);
            Vector3 topRightFront = new Vector3(Width, Height, 0.0f);
            Vector3 topRightBack  = new Vector3(Width, Height, Depth);


            // Calculate the position of the vertices on the bottom face.
            Vector3 btmLeftFront  = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 btmLeftBack   = new Vector3(0.0f, 0.0f, Depth);
            Vector3 btmRightFront = new Vector3(Width, 0.0f, 0.0f);
            Vector3 btmRightBack  = new Vector3(Width, 0.0f, Depth);

            // Normal vectors for each face (needed for lighting / display)


            // Add the vertices for the FRONT face.
            Vertices[0] = new ExtendedVertex(topLeftFront, Color.White, UVs.Uvs[0], UVs.Bounds[0]);
            Vertices[1] = new ExtendedVertex(btmLeftFront, Color.White, UVs.Uvs[1], UVs.Bounds[0]);
            Vertices[2] = new ExtendedVertex(topRightFront, Color.White, UVs.Uvs[2], UVs.Bounds[0]);
            Vertices[3] = new ExtendedVertex(btmRightFront, Color.White, UVs.Uvs[3], UVs.Bounds[0]);

            Indices[0] = 0;
            Indices[1] = 1;
            Indices[2] = 2;
            Indices[3] = 2;
            Indices[4] = 1;
            Indices[5] = 3;

            // Add the vertices for the BACK face.
            Vertices[4] = new ExtendedVertex(topLeftBack, Color.White, UVs.Uvs[4], UVs.Bounds[1]);
            Vertices[5] = new ExtendedVertex(topRightBack, Color.White, UVs.Uvs[5], UVs.Bounds[1]);
            Vertices[6] = new ExtendedVertex(btmLeftBack, Color.White, UVs.Uvs[6], UVs.Bounds[1]);
            Vertices[7] = new ExtendedVertex(btmRightBack, Color.White, UVs.Uvs[7], UVs.Bounds[1]);

            Indices[6]  = 4;
            Indices[7]  = 5;
            Indices[8]  = 6;
            Indices[9]  = 7;
            Indices[10] = 6;
            Indices[11] = 5;

            // Add the vertices for the TOP face.
            Vertices[8]  = new ExtendedVertex(topLeftFront, Color.White, UVs.Uvs[8], UVs.Bounds[2]);
            Vertices[9]  = new ExtendedVertex(topRightBack, Color.White, UVs.Uvs[9], UVs.Bounds[2]);
            Vertices[10] = new ExtendedVertex(topLeftBack, Color.White, UVs.Uvs[10], UVs.Bounds[2]);
            Vertices[11] = new ExtendedVertex(topRightFront, Color.White, UVs.Uvs[11], UVs.Bounds[2]);

            Indices[12] = 8;
            Indices[13] = 9;
            Indices[14] = 10;
            Indices[15] = 9;
            Indices[16] = 8;
            Indices[17] = 11;

            // Add the vertices for the BOTTOM face.
            Vertices[12] = new ExtendedVertex(btmLeftFront, Color.White, UVs.Uvs[12], UVs.Bounds[3]);
            Vertices[13] = new ExtendedVertex(btmLeftBack, Color.White, UVs.Uvs[13], UVs.Bounds[3]);
            Vertices[14] = new ExtendedVertex(btmRightBack, Color.White, UVs.Uvs[14], UVs.Bounds[3]);
            Vertices[15] = new ExtendedVertex(btmRightFront, Color.White, UVs.Uvs[15], UVs.Bounds[3]);

            Indices[18] = 12;
            Indices[19] = 13;
            Indices[20] = 14;
            Indices[21] = 15;
            Indices[22] = 12;
            Indices[23] = 14;

            // Add the vertices for the LEFT face.
            Vertices[16] = new ExtendedVertex(topLeftFront, Color.White, UVs.Uvs[16], UVs.Bounds[4]);
            Vertices[17] = new ExtendedVertex(btmLeftBack, Color.White, UVs.Uvs[17], UVs.Bounds[4]);
            Vertices[18] = new ExtendedVertex(btmLeftFront, Color.White, UVs.Uvs[18], UVs.Bounds[4]);
            Vertices[19] = new ExtendedVertex(topLeftBack, Color.White, UVs.Uvs[19], UVs.Bounds[4]);

            Indices[24] = 16;
            Indices[25] = 17;
            Indices[26] = 18;
            Indices[27] = 17;
            Indices[28] = 16;
            Indices[29] = 19;

            // Add the vertices for the RIGHT face.
            Vertices[20] = new ExtendedVertex(topRightFront, Color.White, UVs.Uvs[20], UVs.Bounds[5]);
            Vertices[21] = new ExtendedVertex(btmRightFront, Color.White, UVs.Uvs[21], UVs.Bounds[5]);
            Vertices[22] = new ExtendedVertex(btmRightBack, Color.White, UVs.Uvs[22], UVs.Bounds[5]);
            Vertices[23] = new ExtendedVertex(topRightBack, Color.White, UVs.Uvs[23], UVs.Bounds[5]);

            Indices[30] = 20;
            Indices[31] = 21;
            Indices[32] = 22;
            Indices[33] = 23;
            Indices[34] = 20;
            Indices[35] = 22;

            IndexBuffer = new IndexBuffer(GameState.Game.GraphicsDevice, typeof(short), Indices.Length, BufferUsage.WriteOnly);
            IndexBuffer.SetData(Indices);
        }
Пример #9
0
        private void CreateVerticies()
        {
            Vertices = new ExtendedVertex[NumVertices];

            // Calculate the position of the vertices on the top face.
            Vector3 topLeftFront  = new Vector3(0.0f, Height, 0.0f);
            Vector3 topLeftBack   = new Vector3(0.0f, Height, Depth);
            Vector3 topRightFront = new Vector3(Width, Height, 0.0f);
            Vector3 topRightBack  = new Vector3(Width, Height, Depth);


            // Calculate the position of the vertices on the bottom face.
            Vector3 btmLeftFront  = new Vector3(0.0f, 0.0f, 0.0f);
            Vector3 btmLeftBack   = new Vector3(0.0f, 0.0f, Depth);
            Vector3 btmRightFront = new Vector3(Width, 0.0f, 0.0f);
            Vector3 btmRightBack  = new Vector3(Width, 0.0f, Depth);

            // Normal vectors for each face (needed for lighting / display)

            /*
             * Vector3 normalFront = new Vector3(0.0f, 0.0f, 1.0f) * SideLength;
             * Vector3 normalBack = new Vector3(0.0f, 0.0f, -1.0f) * SideLength;
             * Vector3 normalTop = new Vector3(0.0f, 1.0f, 0.0f) * SideLength;
             * Vector3 normalBottom = new Vector3(0.0f, -1.0f, 0.0f) * SideLength;
             * Vector3 normalLeft = new Vector3(-1.0f, 0.0f, 0.0f) * SideLength;
             * Vector3 normalRight = new Vector3(1.0f, 0.0f, 0.0f) * SideLength;
             */


            // Add the vertices for the FRONT face.

            Vertices[0] = new ExtendedVertex(topLeftFront, Color.White, UVs.m_uvs[0], UVs.Bounds[0]);
            Vertices[1] = new ExtendedVertex(btmLeftFront, Color.White, UVs.m_uvs[1], UVs.Bounds[0]);
            Vertices[2] = new ExtendedVertex(topRightFront, Color.White, UVs.m_uvs[2], UVs.Bounds[0]);
            Vertices[3] = new ExtendedVertex(btmLeftFront, Color.White, UVs.m_uvs[3], UVs.Bounds[0]);
            Vertices[4] = new ExtendedVertex(btmRightFront, Color.White, UVs.m_uvs[4], UVs.Bounds[0]);
            Vertices[5] = new ExtendedVertex(topRightFront, Color.White, UVs.m_uvs[5], UVs.Bounds[0]);

            // Add the vertices for the BACK face.
            Vertices[6]  = new ExtendedVertex(topLeftBack, Color.White, UVs.m_uvs[6], UVs.Bounds[1]);
            Vertices[7]  = new ExtendedVertex(topRightBack, Color.White, UVs.m_uvs[7], UVs.Bounds[1]);
            Vertices[8]  = new ExtendedVertex(btmLeftBack, Color.White, UVs.m_uvs[8], UVs.Bounds[1]);
            Vertices[9]  = new ExtendedVertex(btmLeftBack, Color.White, UVs.m_uvs[9], UVs.Bounds[1]);
            Vertices[10] = new ExtendedVertex(topRightBack, Color.White, UVs.m_uvs[10], UVs.Bounds[1]);
            Vertices[11] = new ExtendedVertex(btmRightBack, Color.White, UVs.m_uvs[11], UVs.Bounds[1]);

            // Add the vertices for the TOP face.
            Vertices[12] = new ExtendedVertex(topLeftFront, Color.White, UVs.m_uvs[12], UVs.Bounds[2]);
            Vertices[13] = new ExtendedVertex(topRightBack, Color.White, UVs.m_uvs[13], UVs.Bounds[2]);
            Vertices[14] = new ExtendedVertex(topLeftBack, Color.White, UVs.m_uvs[14], UVs.Bounds[2]);
            Vertices[15] = new ExtendedVertex(topLeftFront, Color.White, UVs.m_uvs[15], UVs.Bounds[2]);
            Vertices[16] = new ExtendedVertex(topRightFront, Color.White, UVs.m_uvs[16], UVs.Bounds[2]);
            Vertices[17] = new ExtendedVertex(topRightBack, Color.White, UVs.m_uvs[17], UVs.Bounds[2]);

            // Add the vertices for the BOTTOM face.
            Vertices[18] = new ExtendedVertex(btmLeftFront, Color.White, UVs.m_uvs[18], UVs.Bounds[3]);
            Vertices[19] = new ExtendedVertex(btmLeftBack, Color.White, UVs.m_uvs[19], UVs.Bounds[3]);
            Vertices[20] = new ExtendedVertex(btmRightBack, Color.White, UVs.m_uvs[20], UVs.Bounds[3]);
            Vertices[21] = new ExtendedVertex(btmLeftFront, Color.White, UVs.m_uvs[21], UVs.Bounds[3]);
            Vertices[22] = new ExtendedVertex(btmRightBack, Color.White, UVs.m_uvs[22], UVs.Bounds[3]);
            Vertices[23] = new ExtendedVertex(btmRightFront, Color.White, UVs.m_uvs[23], UVs.Bounds[3]);

            // Add the vertices for the LEFT face.
            Vertices[24] = new ExtendedVertex(topLeftFront, Color.White, UVs.m_uvs[24], UVs.Bounds[4]);
            Vertices[25] = new ExtendedVertex(btmLeftBack, Color.White, UVs.m_uvs[25], UVs.Bounds[4]);
            Vertices[26] = new ExtendedVertex(btmLeftFront, Color.White, UVs.m_uvs[26], UVs.Bounds[4]);
            Vertices[27] = new ExtendedVertex(topLeftBack, Color.White, UVs.m_uvs[27], UVs.Bounds[4]);
            Vertices[28] = new ExtendedVertex(btmLeftBack, Color.White, UVs.m_uvs[28], UVs.Bounds[4]);
            Vertices[29] = new ExtendedVertex(topLeftFront, Color.White, UVs.m_uvs[29], UVs.Bounds[4]);

            // Add the vertices for the RIGHT face.
            Vertices[30] = new ExtendedVertex(topRightFront, Color.White, UVs.m_uvs[30], UVs.Bounds[5]);
            Vertices[31] = new ExtendedVertex(btmRightFront, Color.White, UVs.m_uvs[31], UVs.Bounds[5]);
            Vertices[32] = new ExtendedVertex(btmRightBack, Color.White, UVs.m_uvs[32], UVs.Bounds[5]);
            Vertices[33] = new ExtendedVertex(topRightBack, Color.White, UVs.m_uvs[33], UVs.Bounds[5]);
            Vertices[34] = new ExtendedVertex(topRightFront, Color.White, UVs.m_uvs[34], UVs.Bounds[5]);
            Vertices[35] = new ExtendedVertex(btmRightBack, Color.White, UVs.m_uvs[35], UVs.Bounds[5]);
        }
Пример #10
0
        public void InitializeFromChunk(VoxelChunk chunk, GraphicsDevice graphics)
        {
            //chunk.PrimitiveMutex.WaitOne();
            if (!chunk.IsVisible || IsBuilding)
            {
                // chunk.PrimitiveMutex.ReleaseMutex();
                return;
            }

            IsBuilding = true;
            //chunk.PrimitiveMutex.ReleaseMutex();

            accumulatedVertices.Clear();
            faceExists.Clear();
            drawFace.Clear();

            int[,,] totalDepth = new int[chunk.SizeX, chunk.SizeY, chunk.SizeZ];
            for (int x = 0; x < chunk.SizeX; x++)
            {
                for (int z = 0; z < chunk.SizeZ; z++)
                {
                    bool drynessEncountered = false;
                    int  previousSum        = 0;

                    for (int y = 0; y < chunk.SizeY; y++)
                    {
                        WaterCell cell       = chunk.Data.Water[chunk.Data.IndexAt(x, y, z)];
                        byte      waterLevel = cell.WaterLevel;

                        if (cell.Type != LiqType)
                        {
                            waterLevel = 0;
                        }

                        if (drynessEncountered)
                        {
                            if (waterLevel > 0)
                            {
                                drynessEncountered  = false;
                                previousSum        += waterLevel;
                                totalDepth[x, y, z] = previousSum;
                            }
                        }
                        else
                        {
                            if (waterLevel > 0)
                            {
                                previousSum        += waterLevel;
                                totalDepth[x, y, z] = previousSum;
                            }
                            else
                            {
                                drynessEncountered  = true;
                                previousSum         = 0;
                                totalDepth[x, y, z] = 0;
                            }
                        }
                    }
                }
            }

            int maxY = chunk.SizeY;

            if (chunk.Manager.ChunkData.Slice == ChunkManager.SliceMode.Y)
            {
                maxY = (int)Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY);
            }


            Voxel myVoxel = chunk.MakeVoxel(0, 0, 0);
            Voxel vox     = chunk.MakeVoxel(0, 0, 0);

            for (int x = 0; x < chunk.SizeX; x++)
            {
                for (int y = 0; y < maxY; y++)
                {
                    for (int z = 0; z < chunk.SizeZ; z++)
                    {
                        int index = chunk.Data.IndexAt(x, y, z);
                        if (chunk.Data.Water[index].WaterLevel > 0 && chunk.Data.Water[index].Type == LiqType)
                        {
                            bool isTop = false;

                            myVoxel.GridPosition = new Vector3(x, y, z);

                            for (int i = 0; i < 6; i++)
                            {
                                BoxFace face = (BoxFace)i;
                                if (face == BoxFace.Bottom)
                                {
                                    continue;
                                }

                                Vector3 delta = faceDeltas[face];


                                bool success = chunk.Manager.ChunkData.GetVoxel(chunk, new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z) + chunk.Origin, ref vox);

                                if (success)
                                {
                                    if (face == BoxFace.Top)
                                    {
                                        if (vox.WaterLevel == 0 || y == (int)chunk.Manager.ChunkData.MaxViewingLevel)
                                        {
                                            drawFace[face] = true;
                                        }
                                        else
                                        {
                                            drawFace[face] = false;
                                        }
                                    }
                                    else
                                    {
                                        if (vox.WaterLevel == 0 && vox.IsEmpty)
                                        {
                                            drawFace[face] = true;
                                        }
                                        else
                                        {
                                            drawFace[face] = false;
                                        }

                                        bool gotVox = chunk.Manager.ChunkData.GetVoxel(chunk, new Vector3(x, y + 1, z) + chunk.Origin, ref vox);

                                        isTop = !gotVox || vox.IsEmpty || vox.WaterLevel == 0;
                                    }
                                }
                                else
                                {
                                    drawFace[face] = true;
                                }


                                if (!drawFace[face])
                                {
                                    continue;
                                }

                                IEnumerable <ExtendedVertex> vertices = CreateWaterFace(myVoxel, face, chunk, x, y, z, totalDepth[x, y, z], isTop);


                                foreach (ExtendedVertex newVertex in vertices.Select(vertex => new ExtendedVertex(vertex.Position + VertexNoise.GetRandomNoiseVector(vertex.Position),
                                                                                                                  vertex.Color, vertex.VertColor, vertex.TextureCoordinate, vertex.TextureBounds)))
                                {
                                    accumulatedVertices.Add(newVertex);
                                }
                            }
                        }
                    }
                }
            }


            try
            {
                ExtendedVertex[] vertex = new ExtendedVertex[accumulatedVertices.Count];

                for (int i = 0; i < accumulatedVertices.Count; i++)
                {
                    vertex[i] = accumulatedVertices[i];
                }


                Vertices = vertex;

                chunk.PrimitiveMutex.WaitOne();
                ResetBuffer(graphics);
                chunk.PrimitiveMutex.ReleaseMutex();
            }
            catch (System.Threading.AbandonedMutexException e)
            {
                Console.Error.WriteLine(e.Message);
            }

            IsBuilding = false;
        }
Пример #11
0
        private static IEnumerable <ExtendedVertex> CreateWaterFace(Voxel voxel, BoxFace face, VoxelChunk chunk, int x, int y, int z, int totalDepth, bool top)
        {
            List <ExtendedVertex> toReturn = new List <ExtendedVertex>();
            int idx        = 0;
            int c          = 0;
            int vertOffset = 0;
            int numVerts   = 0;

            m_canconicalPrimitive.GetFace(face, m_canconicalPrimitive.UVs, out idx, out c, out vertOffset, out numVerts);

            for (int i = idx; i < idx + c; i++)
            {
                toReturn.Add(m_canconicalPrimitive.Vertices[m_canconicalPrimitive.Indices[i]]);
            }

            Vector3      origin          = chunk.Origin + new Vector3(x, y, z);
            List <Voxel> neighborsVertex = new List <Voxel>();

            for (int i = 0; i < toReturn.Count; i++)
            {
                VoxelVertex currentVertex = VoxelChunk.GetNearestDelta(toReturn[i].Position);
                chunk.GetNeighborsVertex(currentVertex, voxel, neighborsVertex);
                int   index             = chunk.Data.IndexAt(x, y, z);
                float averageWaterLevel = chunk.Data.Water[index].WaterLevel;
                float count             = 1.0f;
                float emptyNeighbors    = 0.0f;

                foreach (byte level in neighborsVertex.Select(vox => vox.WaterLevel))
                {
                    averageWaterLevel += level;
                    count++;

                    if (level < 1)
                    {
                        emptyNeighbors++;
                    }
                }

                averageWaterLevel = averageWaterLevel / count;

                float   averageWaterHeight = (float)averageWaterLevel / 255.0f;
                float   puddleness         = 0;
                Vector2 uv;

                float foaminess = emptyNeighbors / count;

                if (foaminess <= 0.5f)
                {
                    foaminess = 0.0f;
                }

                if (totalDepth < 5)
                {
                    foaminess  = 0.75f;
                    puddleness = 0;
                    uv         = new Vector2((toReturn[i].Position.X + origin.X) / 80.0f, (toReturn[i].Position.Z + origin.Z) / 80.0f);
                }
                else
                {
                    uv = new Vector2((toReturn[i].Position.X + origin.X) / 80.0f, (toReturn[i].Position.Z + origin.Z) / 80.0f);
                }
                Vector4 bounds = new Vector4(0, 0, 1, 1);

                if (chunk.Data.Water[index].IsFalling || !top)
                {
                    averageWaterHeight = 1.0f;
                }

                if (face == BoxFace.Top)
                {
                    toReturn[i] = new ExtendedVertex(toReturn[i].Position + origin + new Vector3(0, (averageWaterHeight * 0.4f - 1.0f), 0),
                                                     new Color(foaminess, puddleness, (float)totalDepth / 512.0f, 1.0f),
                                                     Color.White,
                                                     uv, bounds);
                }
                else
                {
                    Vector3 offset = Vector3.Zero;
                    switch (face)
                    {
                    case BoxFace.Back:
                    case BoxFace.Front:
                        uv        = new Vector2((Math.Abs(toReturn[i].Position.X + origin.X) / 80.0f), (Math.Abs(toReturn[i].Position.Y + origin.Y) / 80.0f));
                        foaminess = 1.0f;
                        offset    = new Vector3(0, -0.5f, 0);
                        break;

                    case BoxFace.Right:
                    case BoxFace.Left:
                        uv        = new Vector2((Math.Abs(toReturn[i].Position.Z + origin.Z) / 80.0f), (Math.Abs(toReturn[i].Position.Y + origin.Y) / 80.0f));
                        foaminess = 1.0f;
                        offset    = new Vector3(0, -0.5f, 0);
                        break;

                    case BoxFace.Top:
                        offset = new Vector3(0, -0.5f, 0);
                        break;
                    }

                    toReturn[i] = new ExtendedVertex(toReturn[i].Position + origin + offset, new Color(foaminess, 0.0f, 1.0f, 1.0f), Color.White, uv, bounds);
                }
            }

            return(toReturn);
        }
Пример #12
0
 public void AddVertex(ExtendedVertex Vertex)
 {
     EnsureSpace(ref Vertices, VertexCount);
     Vertices[VertexCount] = Vertex;
     VertexCount          += 1;
 }
Пример #13
0
        // This will loop through the whole world and draw out all liquid primatives that are handed to the function.
        public static void InitializePrimativesFromChunk(VoxelChunk chunk, List <LiquidPrimitive> primitivesToInit)
        {
            LiquidPrimitive[] lps = new LiquidPrimitive[(int)LiquidType.Count];

            if (!AddCaches(primitivesToInit, ref lps))
            {
                return;
            }

            LiquidType      curLiqType   = LiquidType.None;
            LiquidPrimitive curPrimitive = null;

            ExtendedVertex[] curVertices = null;
            ushort[]         curIndexes  = null;
            int[]            maxVertices = new int[lps.Length];
            int[]            maxIndexes  = new int[lps.Length];

            int  maxVertex  = 0;
            int  maxIndex   = 0;
            int  totalFaces = 6;
            bool fogOfWar   = GameSettings.Current.FogofWar;

            for (int globalY = chunk.Origin.Y; globalY < Math.Min(chunk.Manager.World.Renderer.PersistentSettings.MaxViewingLevel + 1, chunk.Origin.Y + VoxelConstants.ChunkSizeY); globalY++)
            {
                var y = globalY - chunk.Origin.Y;
                if (chunk.Data.LiquidPresent[y] == 0)
                {
                    continue;
                }

                for (int x = 0; x < VoxelConstants.ChunkSizeX; x++)
                {
                    for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++)
                    {
                        var voxel = VoxelHandle.UnsafeCreateLocalHandle(chunk, new LocalVoxelCoordinate(x, y, z));
                        if (fogOfWar && !voxel.IsExplored)
                        {
                            continue;
                        }

                        if (voxel.LiquidLevel > 0)
                        {
                            var liqType = voxel.LiquidType;

                            // We need to see if we changed types and should change the data we are writing to.
                            if (liqType != curLiqType)
                            {
                                LiquidPrimitive newPrimitive = lps[(int)liqType];
                                // We weren't passed a LiquidPrimitive object to work with for this type so we'll skip it.
                                if (newPrimitive == null)
                                {
                                    continue;
                                }

                                maxVertices[(int)curLiqType] = maxVertex;
                                maxIndexes[(int)curLiqType]  = maxIndex;

                                curVertices = newPrimitive.Vertices;
                                curIndexes  = newPrimitive.Indexes;

                                curLiqType   = liqType;
                                curPrimitive = newPrimitive;
                                maxVertex    = maxVertices[(int)liqType];
                                maxIndex     = maxIndexes[(int)liqType];
                            }

                            int facesToDraw = 0;
                            for (int i = 0; i < totalFaces; i++)
                            {
                                BoxFace face = (BoxFace)i;
                                // We won't draw the bottom face.  This might be needed down the line if we add transparent tiles like glass.
                                if (face == BoxFace.Bottom)
                                {
                                    continue;
                                }

                                var delta = faceDeltas[(int)face];

                                // Pull the current neighbor DestinationVoxel based on the face it would be touching.

                                var vox = VoxelHelpers.GetNeighbor(voxel, delta);

                                if (vox.IsValid)
                                {
                                    if (face == BoxFace.Top)
                                    {
                                        if (!(vox.LiquidLevel == 0 || y == (int)chunk.Manager.World.Renderer.PersistentSettings.MaxViewingLevel))
                                        {
                                            cache.drawFace[(int)face] = false;
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        if (vox.LiquidLevel != 0 || !vox.IsEmpty)
                                        {
                                            cache.drawFace[(int)face] = false;
                                            continue;
                                        }
                                    }
                                }
                                else
                                {
                                    cache.drawFace[(int)face] = false;
                                    continue;
                                }

                                cache.drawFace[(int)face] = true;
                                facesToDraw++;
                            }

                            // There's no faces to draw on this voxel.  Let's go to the next one.
                            if (facesToDraw == 0)
                            {
                                continue;
                            }

                            // Now we check to see if we need to resize the current Vertex array.
                            int vertexSizeIncrease = facesToDraw * 4;
                            int indexSizeIncrease  = facesToDraw * 6;

                            lock (curPrimitive.VertexLock)
                            {
                                // Check vertex array size
                                if (curVertices == null)
                                {
                                    curVertices           = new ExtendedVertex[256];
                                    curPrimitive.Vertices = curVertices;
                                }
                                else if (curVertices.Length <= maxVertex + vertexSizeIncrease)
                                {
                                    ExtendedVertex[] newVerts = new ExtendedVertex[MathFunctions.NearestPowerOf2(maxVertex + vertexSizeIncrease)];

                                    curVertices.CopyTo(newVerts, 0);
                                    curVertices           = newVerts;
                                    curPrimitive.Vertices = curVertices;
                                }

                                // Check index array size
                                if (curIndexes == null)
                                {
                                    curIndexes           = new ushort[256];
                                    curPrimitive.Indexes = curIndexes;
                                }
                                else if (curIndexes.Length <= maxIndex + indexSizeIncrease)
                                {
                                    ushort[] newIdxs = new ushort[MathFunctions.NearestPowerOf2(maxIndex + indexSizeIncrease)];

                                    curIndexes.CopyTo(newIdxs, 0);
                                    curIndexes           = newIdxs;
                                    curPrimitive.Indexes = curIndexes;
                                }
                            }

                            // Now we have a list of all the faces that will need to be drawn.  Let's draw  them.
                            CreateWaterFaces(voxel, chunk, x, y, z, curVertices, curIndexes, maxVertex, maxIndex);

                            // Finally increase the size so we can move on.
                            maxVertex += vertexSizeIncrease;
                            maxIndex  += indexSizeIncrease;
                        }
                    }
                }
            }

            // The last thing we need to do is make sure we set the current primative's maxVertices to the right value.
            maxVertices[(int)curLiqType] = maxVertex;
            maxIndexes[(int)curLiqType]  = maxIndex;

            // Now actually force the VertexBuffer to be recreated in each primative we worked with.
            for (int i = 0; i < lps.Length; i++)
            {
                LiquidPrimitive updatedPrimative = lps[i];
                if (updatedPrimative == null)
                {
                    continue;
                }

                maxVertex = maxVertices[i];
                maxIndex  = maxIndexes[i];

                if (maxVertex > 0)
                {
                    try
                    {
                        lock (updatedPrimative.VertexLock)
                        {
                            updatedPrimative.VertexCount  = maxVertex;
                            updatedPrimative.IndexCount   = maxIndex;
                            updatedPrimative.VertexBuffer = null;
                            updatedPrimative.IndexBuffer  = null;
                        }
                    }
                    catch (global::System.Threading.AbandonedMutexException e)
                    {
                        Console.Error.WriteLine(e.Message);
                    }
                }
                else
                {
                    try
                    {
                        lock (updatedPrimative.VertexLock)
                        {
                            updatedPrimative.VertexBuffer = null;
                            updatedPrimative.Vertices     = null;
                            updatedPrimative.IndexBuffer  = null;
                            updatedPrimative.Indexes      = null;
                            updatedPrimative.VertexCount  = 0;
                            updatedPrimative.IndexCount   = 0;
                        }
                    }
                    catch (global::System.Threading.AbandonedMutexException e)
                    {
                        Console.Error.WriteLine(e.Message);
                    }
                }
                updatedPrimative.IsBuilding = false;
            }

            cache.inUse = false;
            cache       = null;
        }
Пример #14
0
        public void InitializeFromChunk(VoxelChunk chunk, GraphicsDevice graphics)
        {
            if (chunk == null)
            {
                return;
            }

            rebuildMutex.WaitOne();
            if (isRebuilding)
            {
                rebuildMutex.ReleaseMutex();
                return;
            }

            isRebuilding = true;
            rebuildMutex.ReleaseMutex();
            int[] ambientValues = new int[4];
            int   maxIndex      = 0;
            int   maxVertex     = 0;
            Voxel v             = chunk.MakeVoxel(0, 0, 0);
            Voxel voxelOnFace   = chunk.MakeVoxel(0, 0, 0);

            Voxel[]      manhattanNeighbors = new Voxel[4];
            BoxPrimitive bedrockModel       = VoxelLibrary.GetPrimitive("Bedrock");
            Voxel        worldVoxel         = new Voxel();

            if (Vertices == null)
            {
                Vertices = new ExtendedVertex[1024];
            }

            if (Indexes == null)
            {
                Indexes = new ushort[512];
            }

            for (int y = 0; y < Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY); y++)
            {
                for (int x = 0; x < chunk.SizeX; x++)
                {
                    for (int z = 0; z < chunk.SizeZ; z++)
                    {
                        v.GridPosition = new Vector3(x, y, z);


                        if ((v.IsExplored && v.IsEmpty) || !v.IsVisible)
                        {
                            continue;
                        }

                        BoxPrimitive primitive = VoxelLibrary.GetPrimitive(v.Type);
                        if (v.IsExplored && primitive == null)
                        {
                            continue;
                        }
                        if (!v.IsExplored)
                        {
                            primitive = bedrockModel;
                        }

                        Color tint = v.Type.Tint;
                        BoxPrimitive.BoxTextureCoords uvs = primitive.UVs;

                        if (v.Type.HasTransitionTextures && v.IsExplored)
                        {
                            uvs = v.ComputeTransitionTexture(manhattanNeighbors);
                        }

                        for (int i = 0; i < 6; i++)
                        {
                            BoxFace face  = (BoxFace)i;
                            Vector3 delta = FaceDeltas[(int)face];
                            faceExists[(int)face] = chunk.IsCellValid(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z);
                            drawFace[(int)face]   = true;

                            if (faceExists[(int)face])
                            {
                                voxelOnFace.GridPosition = new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z);
                                drawFace[(int)face]      = (voxelOnFace.IsExplored && voxelOnFace.IsEmpty) || !voxelOnFace.IsVisible ||
                                                           (voxelOnFace.Type.CanRamp && voxelOnFace.RampType != RampType.None && IsSideFace(face) &&
                                                            ShouldDrawFace(face, voxelOnFace.RampType, v.RampType));
                            }
                            else
                            {
                                bool success = chunk.Manager.ChunkData.GetNonNullVoxelAtWorldLocation(new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z) + chunk.Origin, ref worldVoxel);
                                drawFace[(int)face] = !success || (worldVoxel.IsExplored && worldVoxel.IsEmpty) || !worldVoxel.IsVisible ||
                                                      (worldVoxel.Type.CanRamp && worldVoxel.RampType != RampType.None &&
                                                       IsSideFace(face) &&
                                                       ShouldDrawFace(face, worldVoxel.RampType, v.RampType));
                            }
                        }


                        for (int i = 0; i < 6; i++)
                        {
                            BoxFace face = (BoxFace)i;
                            if (!drawFace[(int)face])
                            {
                                continue;
                            }


                            int faceIndex   = 0;
                            int faceCount   = 0;
                            int vertexIndex = 0;
                            int vertexCount = 0;
                            primitive.GetFace(face, uvs, out faceIndex, out faceCount, out vertexIndex, out vertexCount);
                            Vector2 texScale = uvs.Scales[i];

                            int indexOffset = maxVertex;
                            for (int vertOffset = 0; vertOffset < vertexCount; vertOffset++)
                            {
                                ExtendedVertex vert    = primitive.Vertices[vertOffset + vertexIndex];
                                VoxelVertex    bestKey = primitive.Deltas[vertOffset + vertexIndex];
                                Color          color   = v.Chunk.Data.GetColor(x, y, z, bestKey);
                                ambientValues[vertOffset] = color.G;
                                Vector3 offset    = Vector3.Zero;
                                Vector2 texOffset = Vector2.Zero;

                                if (v.Type.CanRamp && ShouldRamp(bestKey, v.RampType))
                                {
                                    offset = new Vector3(0, -v.Type.RampSize, 0);

                                    if (face != BoxFace.Top && face != BoxFace.Bottom)
                                    {
                                        texOffset = new Vector2(0, v.Type.RampSize * (texScale.Y));
                                    }
                                }

                                if (maxVertex >= Vertices.Length)
                                {
                                    ExtendedVertex[] newVertices = new ExtendedVertex[Vertices.Length * 2];
                                    Vertices.CopyTo(newVertices, 0);
                                    Vertices = newVertices;
                                }

                                Vertices[maxVertex] = new ExtendedVertex(vert.Position + v.Position +
                                                                         VertexNoise.GetNoiseVectorFromRepeatingTexture(
                                                                             vert.Position + v.Position) + offset,
                                                                         color,
                                                                         tint,
                                                                         uvs.Uvs[vertOffset + vertexIndex] + texOffset,
                                                                         uvs.Bounds[faceIndex / 6]);
                                maxVertex++;
                            }

                            bool flippedQuad = ambientValues[0] + ambientValues[2] >
                                               ambientValues[1] + ambientValues[3];
                            for (int idx = faceIndex; idx < faceCount + faceIndex; idx++)
                            {
                                if (maxIndex >= Indexes.Length)
                                {
                                    ushort[] indexes = new ushort[Indexes.Length * 2];
                                    Indexes.CopyTo(indexes, 0);
                                    Indexes = indexes;
                                }

                                ushort vertexOffset  = flippedQuad ? primitive.FlippedIndexes[idx] : primitive.Indexes[idx];
                                ushort vertexOffset0 = flippedQuad? primitive.FlippedIndexes[faceIndex] : primitive.Indexes[faceIndex];
                                Indexes[maxIndex] =
                                    (ushort)((int)indexOffset + (int)((int)vertexOffset - (int)vertexOffset0));
                                maxIndex++;
                            }
                        }
                    }
                }
            }
            MaxIndex  = maxIndex;
            MaxVertex = maxVertex;
            GenerateLightmap(chunk.Manager.ChunkData.Tilemap.Bounds);
            isRebuilding = false;

            //chunk.PrimitiveMutex.WaitOne();
            chunk.NewPrimitive         = this;
            chunk.NewPrimitiveReceived = true;
            //chunk.PrimitiveMutex.ReleaseMutex();
        }
Пример #15
0
        // This will loop through the whole world and draw out all liquid primatives that are handed to the function.
        public static void InitializePrimativesFromChunk(VoxelChunk chunk, List <LiquidPrimitive> primitivesToInit)
        {
            LiquidPrimitive[] lps = new LiquidPrimitive[(int)LiquidType.Count];

            // We are going to first set up the internal array.
            foreach (LiquidPrimitive lp in primitivesToInit)
            {
                if (lp != null)
                {
                    lps[(int)lp.LiqType] = lp;
                }
            }

            // We are going to lock around the IsBuilding check/set to avoid the situation where two threads could both pass through
            // if they both checked IsBuilding at the same time before either of them set IsBuilding.
            lock (caches)
            {
                // We check all parts of the array before setting any to avoid somehow setting a few then leaving before we can unset them.
                for (int i = 0; i < lps.Length; i++)
                {
                    if (lps[i] != null && lps[i].IsBuilding)
                    {
                        return;
                    }
                }

                // Now we know we are safe so we can set IsBuilding.
                for (int i = 0; i < lps.Length; i++)
                {
                    if (lps[i] != null)
                    {
                        lps[i].IsBuilding = true;
                    }
                }

                // Now we have to get a valid cache object.
                bool cacheSet = false;
                for (int i = 0; i < caches.Count; i++)
                {
                    if (!caches[i].inUse)
                    {
                        cache       = caches[i];
                        cache.inUse = true;
                        cacheSet    = true;
                    }
                }
                if (!cacheSet)
                {
                    cache       = new LiquidRebuildCache();
                    cache.inUse = true;
                    caches.Add(cache);
                }
            }

            LiquidType      curLiqType   = LiquidType.None;
            LiquidPrimitive curPrimative = null;

            ExtendedVertex[] curVertices = null;
            int[]            maxVertices = new int[lps.Length];
            int maxY = (int)Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY);

            Voxel myVoxel   = chunk.MakeVoxel(0, 0, 0);
            Voxel vox       = chunk.MakeVoxel(0, 0, 0);
            int   maxVertex = 0;
            bool  fogOfWar  = GameSettings.Default.FogofWar;

            for (int x = 0; x < chunk.SizeX; x++)
            {
                for (int y = 0; y < maxY; y++)
                {
                    for (int z = 0; z < chunk.SizeZ; z++)
                    {
                        int index = chunk.Data.IndexAt(x, y, z);
                        if (fogOfWar && !chunk.Data.IsExplored[index])
                        {
                            continue;
                        }

                        if (chunk.Data.Water[index].WaterLevel > 0)
                        {
                            LiquidType liqType = chunk.Data.Water[index].Type;

                            // We need to see if we changed types and should change the data we are writing to.
                            if (liqType != curLiqType)
                            {
                                LiquidPrimitive newPrimitive = lps[(int)liqType];
                                // We weren't passed a LiquidPrimitive object to work with for this type so we'll skip it.
                                if (newPrimitive == null)
                                {
                                    continue;
                                }

                                maxVertices[(int)curLiqType] = maxVertex;

                                curVertices  = newPrimitive.Vertices;
                                curLiqType   = liqType;
                                curPrimative = newPrimitive;
                                maxVertex    = maxVertices[(int)liqType];
                            }

                            myVoxel.GridPosition = new Vector3(x, y, z);

                            int facesToDraw = 0;
                            for (int i = 0; i < 6; i++)
                            {
                                BoxFace face = (BoxFace)i;
                                // We won't draw the bottom face.  This might be needed down the line if we add transparent tiles like glass.
                                if (face == BoxFace.Bottom)
                                {
                                    continue;
                                }

                                Vector3 delta = faceDeltas[(int)face];

                                // Pull the current neighbor Voxel based on the face it would be touching.
                                bool success = myVoxel.GetNeighborBySuccessor(delta, ref vox, false);

                                if (success)
                                {
                                    if (face == BoxFace.Top)
                                    {
                                        if (!(vox.WaterLevel == 0 || y == (int)chunk.Manager.ChunkData.MaxViewingLevel))
                                        {
                                            cache.drawFace[(int)face] = false;
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        if (vox.WaterLevel != 0 || !vox.IsEmpty)
                                        {
                                            cache.drawFace[(int)face] = false;
                                            continue;
                                        }
                                    }
                                }

                                cache.drawFace[(int)face] = true;
                                facesToDraw++;
                            }

                            // There's no faces to draw on this voxel.  Let's go to the next one.
                            if (facesToDraw == 0)
                            {
                                continue;
                            }

                            // Now we check to see if we need to resize the current Vertex array.
                            int vertexSizeIncrease = facesToDraw * 6;
                            if (curVertices == null)
                            {
                                curVertices           = new ExtendedVertex[256];
                                curPrimative.Vertices = curVertices;
                            }
                            else if (curVertices.Length <= maxVertex + vertexSizeIncrease)
                            {
                                ExtendedVertex[] newVerts = new ExtendedVertex[curVertices.Length * 2];
                                curVertices.CopyTo(newVerts, 0);
                                curVertices           = newVerts;
                                curPrimative.Vertices = curVertices;
                            }

                            // Now we have a list of all the faces that will need to be drawn.  Let's draw them.
                            CreateWaterFaces(myVoxel, chunk, x, y, z, curVertices, maxVertex);

                            // Finally increase the size so we can move on.
                            maxVertex += vertexSizeIncrease;
                        }
                    }
                }
            }

            // The last thing we need to do is make sure we set the current primative's maxVertices to the right value.
            maxVertices[(int)curLiqType] = maxVertex;

            // Now actually force the VertexBuffer to be recreated in each primative we worked with.
            for (int i = 0; i < lps.Length; i++)
            {
                LiquidPrimitive updatedPrimative = lps[i];
                if (updatedPrimative == null)
                {
                    continue;
                }

                maxVertex = maxVertices[i];
                if (maxVertex > 0)
                {
                    try
                    {
                        lock (updatedPrimative.VertexLock)
                        {
                            updatedPrimative.MaxVertex    = maxVertex;
                            updatedPrimative.VertexBuffer = null;
                        }
                    }
                    catch (System.Threading.AbandonedMutexException e)
                    {
                        Console.Error.WriteLine(e.Message);
                    }
                }
                else
                {
                    try
                    {
                        lock (updatedPrimative.VertexLock)
                        {
                            updatedPrimative.VertexBuffer = null;
                            updatedPrimative.Vertices     = null;
                            updatedPrimative.Indexes      = null;
                            updatedPrimative.MaxVertex    = 0;
                            updatedPrimative.MaxIndex     = 0;
                        }
                    }
                    catch (System.Threading.AbandonedMutexException e)
                    {
                        Console.Error.WriteLine(e.Message);
                    }
                }
                updatedPrimative.IsBuilding = false;
            }

            cache.inUse = false;
            cache       = null;
        }
Пример #16
0
        public void InitializeFromChunk(VoxelChunk chunk)
        {
            if (IsBuilding)
            {
                return;
            }

            IsBuilding = true;

            int maxY = (int)Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY);


            Voxel myVoxel   = chunk.MakeVoxel(0, 0, 0);
            Voxel vox       = chunk.MakeVoxel(0, 0, 0);
            int   maxVertex = 0;

            for (int x = 0; x < chunk.SizeX; x++)
            {
                for (int y = 0; y < maxY; y++)
                {
                    for (int z = 0; z < chunk.SizeZ; z++)
                    {
                        int index = chunk.Data.IndexAt(x, y, z);
                        if (GameSettings.Default.FogofWar && !chunk.Data.IsExplored[index])
                        {
                            continue;
                        }

                        if (chunk.Data.Water[index].WaterLevel > 0 && chunk.Data.Water[index].Type == LiqType)
                        {
                            bool isTop = false;

                            myVoxel.GridPosition = new Vector3(x, y, z);

                            for (int i = 0; i < 6; i++)
                            {
                                if (Vertices == null)
                                {
                                    Vertices = new ExtendedVertex[256];
                                }
                                else if (Vertices.Length <= maxVertex + 6)
                                {
                                    ExtendedVertex[] newVerts = new ExtendedVertex[Vertices.Length * 2];
                                    Vertices.CopyTo(newVerts, 0);
                                    Vertices = newVerts;
                                }

                                BoxFace face = (BoxFace)i;
                                if (face == BoxFace.Bottom)
                                {
                                    continue;
                                }

                                Vector3 delta = faceDeltas[(int)face];


                                bool success = chunk.Manager.ChunkData.GetVoxel(chunk,
                                                                                new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z) + chunk.Origin, ref vox);

                                if (success)
                                {
                                    if (face == BoxFace.Top)
                                    {
                                        if (vox.WaterLevel == 0 || y == (int)chunk.Manager.ChunkData.MaxViewingLevel)
                                        {
                                            drawFace[(int)face] = true;
                                        }
                                        else
                                        {
                                            drawFace[(int)face] = false;
                                        }
                                    }
                                    else
                                    {
                                        if (vox.WaterLevel == 0 && vox.IsEmpty)
                                        {
                                            drawFace[(int)face] = true;
                                        }
                                        else
                                        {
                                            drawFace[(int)face] = false;
                                        }

                                        bool gotVox = chunk.Manager.ChunkData.GetVoxel(chunk, new Vector3(x, y + 1, z) + chunk.Origin, ref vox);

                                        isTop = !gotVox || vox.IsEmpty || vox.WaterLevel == 0;
                                    }
                                }
                                else
                                {
                                    drawFace[(int)face] = true;
                                }


                                if (!drawFace[(int)face])
                                {
                                    continue;
                                }

                                CreateWaterFace(myVoxel, face, chunk, x, y, z, isTop, Vertices, maxVertex);
                                maxVertex += 6;
                            }
                        }
                    }
                }
            }

            if (maxVertex > 0)
            {
                try
                {
                    lock (VertexLock)
                    {
                        MaxVertex    = maxVertex;
                        VertexBuffer = null;
                    }
                }
                catch (System.Threading.AbandonedMutexException e)
                {
                    Console.Error.WriteLine(e.Message);
                }
            }
            else
            {
                try
                {
                    lock (VertexLock)
                    {
                        VertexBuffer = null;
                        Vertices     = null;
                        Indexes      = null;
                        MaxVertex    = 0;
                        MaxIndex     = 0;
                    }
                }
                catch (System.Threading.AbandonedMutexException e)
                {
                    Console.Error.WriteLine(e.Message);
                }
            }
            IsBuilding = false;
        }