Ejemplo n.º 1
0
 public BoxPrimitive(GraphicsDevice device, float width, float height, float depth, BoxTextureCoords uvs)
 {
     Width  = width;
     Height = height;
     Depth  = depth;
     Deltas = new VoxelVertex[NumVertices];
     UVs    = uvs;
     CreateVerticies();
     BoundingBox = new BoundingBox(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(width, height, depth));
     for (int i = 0; i < NumVertices; i++)
     {
         Deltas[i] = VoxelChunk.GetNearestDelta(Vertices[i].Position);
     }
 }
Ejemplo n.º 2
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();
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        private static void CreateWaterFace(Voxel voxel,
                                            BoxFace face,
                                            VoxelChunk chunk,
                                            int x, int y, int z,
                                            bool top,
                                            ExtendedVertex[] vertices,
                                            int startVertex)
        {
            int idx         = 0;
            int vertexCount = 0;
            int vertOffset  = 0;
            int numVerts    = 0;

            primitive.GetFace(face, primitive.UVs, out idx, out vertexCount, out vertOffset, out numVerts);

            for (int i = idx; i < idx + vertexCount; i++)
            {
                vertices[i + startVertex - idx] = primitive.Vertices[primitive.Indexes[i]];
            }

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

            for (int i = 0; i < vertexCount; i++)
            {
                VoxelVertex currentVertex = VoxelChunk.GetNearestDelta(vertices[i + startVertex].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 / 8.0f;
                float foaminess          = emptyNeighbors / count;

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

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

                Vector3 pos = vertices[i + startVertex].Position;
                pos.Y *= averageWaterHeight;
                pos   += origin;

                switch (face)
                {
                case BoxFace.Back:
                case BoxFace.Front:
                    vertices[i + startVertex].Set(pos,
                                                  new Color(foaminess, 0.0f, 1.0f, 1.0f),
                                                  Color.White,
                                                  new Vector2(pos.X, pos.Y),
                                                  new Vector4(0, 0, 1, 1));
                    break;

                case BoxFace.Right:
                case BoxFace.Left:
                    vertices[i + startVertex].Set(pos,
                                                  new Color(foaminess, 0.0f, 1.0f, 1.0f),
                                                  Color.White,
                                                  new Vector2(pos.Z, pos.Y),
                                                  new Vector4(0, 0, 1, 1));
                    break;

                case BoxFace.Top:
                    vertices[i + startVertex].Set(pos,
                                                  new Color(foaminess, 0.0f, 1.0f, 1.0f),
                                                  Color.White,
                                                  new Vector2(pos.X, pos.Z),
                                                  new Vector4(0, 0, 1, 1));
                    break;
                }
            }
        }