Beispiel #1
0
        public void TessellateBlock(List<VertexPositionColorLighting>[] vertexLists, List<short>[] indexLists, BlockPosition worldBlockPosition, RelativeBlockPosition relativeBlockPosition)
        {
            GetRequiredBlocks(worldBlockPosition);
            BuildLeftQuad(vertexLists[Face.Left], indexLists[Face.Left], relativeBlockPosition);
            BuildRightQuad(vertexLists[Face.Right], indexLists[Face.Right], relativeBlockPosition);
            BuildFrontQuad(vertexLists[Face.Front], indexLists[Face.Front], relativeBlockPosition);
            BuildBackQuad(vertexLists[Face.Back], indexLists[Face.Back], relativeBlockPosition);
            BuildTopQuad(vertexLists[Face.Top], indexLists[Face.Top], relativeBlockPosition);
            BuildBottomQuad(vertexLists[Face.Bottom], indexLists[Face.Bottom], relativeBlockPosition);

            NumberOfBlocksTessellated++;
        }
Beispiel #2
0
        void BuildRightQuad(List<VertexPositionColorLighting> vertexList, List<short> indexList, RelativeBlockPosition relativeBlockPosition)
        {
            if (!rightBlock.CanBeSeenThrough)
            {
                return;
            }

            var topRightFrontIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Up.Right.Front,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(rightBlock, rightUpBlock, rightFrontBlock, rightUpFrontBlock, SideFaceLightingLimit)
            });

            var topRightBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Up.Right,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(rightBlock, rightUpBlock, rightBackBlock, rightUpBackBlock, SideFaceLightingLimit)
            });

            var bottomRightBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Right,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(rightBlock, rightDownBlock, rightBackBlock, rightDownBackBlock, SideFaceLightingLimit)
            });

            var bottomRightFrontIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Right.Front,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(rightBlock, rightDownBlock, rightFrontBlock, rightDownFrontBlock, SideFaceLightingLimit)
            });

            indexList.Add(topRightFrontIndex);
            indexList.Add(topRightBackIndex);
            indexList.Add(bottomRightBackIndex);
            indexList.Add(topRightFrontIndex);
            indexList.Add(bottomRightBackIndex);
            indexList.Add(bottomRightFrontIndex);
        }
Beispiel #3
0
        void BuildTopQuad(List<VertexPositionColorLighting> vertexList, List<short> indexList, RelativeBlockPosition relativeBlockPosition)
        {
            if (!upBlock.CanBeSeenThrough)
            {
                return;
            }

            var topLeftBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Up,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(upBlock, upLeftBlock, upBackBlock, upLeftBackBlock, TopFaceLightingLimit)
            });

            var topRightBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Right.Up,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(upBlock, upRightBlock, upBackBlock, upRightBackBlock, TopFaceLightingLimit)
            });

            var topRightFrontIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Right.Up.Front,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(upBlock, upRightBlock, upFrontBlock, upRightFrontBlock, TopFaceLightingLimit)
            });

            var topLeftFrontIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Up.Front,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(upBlock, upLeftBlock, upFrontBlock, upLeftFrontBlock, TopFaceLightingLimit)
            });

            indexList.Add(topLeftBackIndex);
            indexList.Add(topRightBackIndex);
            indexList.Add(topRightFrontIndex);
            indexList.Add(topLeftBackIndex);
            indexList.Add(topRightFrontIndex);
            indexList.Add(topLeftFrontIndex);
        }
Beispiel #4
0
        void BuildBackQuad(List<VertexPositionColorLighting> vertexList, List<short> indexList, RelativeBlockPosition relativeBlockPosition)
        {
            if (!backBlock.CanBeSeenThrough)
            {
                return;
            }

            var topRightBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Right.Up,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(backBlock, backUpBlock, backRightBlock, backUpRightBlock, SideFaceLightingLimit)
            });

            var topLeftBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Up,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(backBlock, backUpBlock, backLeftBlock, backUpLeftBlock, SideFaceLightingLimit)
            });

            var bottomLeftBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(backBlock, backDownBlock, backLeftBlock, backDownLeftBlock, SideFaceLightingLimit)
            });

            var bottomRightBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Right,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(backBlock, backDownBlock, backRightBlock, backDownRightBlock, SideFaceLightingLimit)
            });

            indexList.Add(topRightBackIndex);
            indexList.Add(topLeftBackIndex);
            indexList.Add(bottomLeftBackIndex);
            indexList.Add(topRightBackIndex);
            indexList.Add(bottomLeftBackIndex);
            indexList.Add(bottomRightBackIndex);
        }
Beispiel #5
0
        void BuildBottomQuad(List<VertexPositionColorLighting> vertexList, List<short> indexList, RelativeBlockPosition relativeBlockPosition)
        {
            if (!downBlock.CanBeSeenThrough)
            {
                return;
            }

            var bottomLeftFrontIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Front,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(downBlock, downLeftBlock, downFrontBlock, downLeftFrontBlock, BottomFaceLightingLimit)
            });

            var bottomRightFrontIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Right.Front,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(downBlock, downRightBlock, downFrontBlock, downRightFrontBlock, BottomFaceLightingLimit)
            });

            var bottomRightBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition.Right,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(downBlock, downRightBlock, downBackBlock, downRightBackBlock, BottomFaceLightingLimit)
            });

            var bottomLeftBackIndex = (short)vertexList.Count;
            vertexList.Add(new VertexPositionColorLighting
            {
                Position = relativeBlockPosition,
                Color = Color.LightGray,
                Lighting = AverageLightingOver(downBlock, downLeftBlock, downBackBlock, downLeftBackBlock, BottomFaceLightingLimit)
            });

            indexList.Add(bottomLeftFrontIndex);
            indexList.Add(bottomRightFrontIndex);
            indexList.Add(bottomRightBackIndex);
            indexList.Add(bottomLeftFrontIndex);
            indexList.Add(bottomRightBackIndex);
            indexList.Add(bottomLeftBackIndex);
        }
Beispiel #6
0
 public void SetLightLevel(RelativeBlockPosition position, byte lightLevel)
 {
     lightArray[position.X, position.Y, position.Z] = lightLevel;
 }
Beispiel #7
0
        public void Tessellate()
        {
            // TODO: I guess DX9 can be CPU-bound by the number of draw calls so we might
            // want to switch back to a single VB/IB per chunk.
            var vertexLists = new List<VertexPositionColorLighting>[6];
            var indexLists = new List<short>[6];
            for (int x = 0; x < 6; x++)
            {
                // You'd think that setting a largeish initial capacity would save us some time growing
                // the lists, but it turns out to be the exact opposite in practice.  Not sure why.
                vertexLists[x] = new List<VertexPositionColorLighting>();
                indexLists[x] = new List<short>();
            }

            // We save iteration by only doing a slice of the chunk bounded at the top
            // by the highest solid block and at the bottom by the lowest non-solid block in the
            // neighborhood minus one. Anything above or below that isnt going to have geometry.
            // TODO: If we want to burn extra memory in order to optimize this even more aggressively,
            // we could keep track of lowest/highest for each colum in the chunk.

            var lowerTesselationLimit = Math.Max(lowestInvisibleBlock - 1, 0);
            var tessellator = new Tessellator(world);
            for (int x = 0; x < XDimension; x++)
            {
                for (int y = lowerTesselationLimit; y <= highestVisibleBlock; y++)
                {
                    for (int z = 0; z < ZDimension; z++)
                    {
                        var position = new RelativeBlockPosition(x, y, z);
                        var prototype = GetBlockPrototype(position);
                        if (prototype.CanBeSeen)
                        {
                            var worldBlockPosition = new BlockPosition(Position, position);
                            tessellator.TessellateBlock(vertexLists, indexLists, worldBlockPosition, position);
                        }
                    }
                }
            }

            // TODO: is the conversion causing extra work here?
            renderer.Initialize((Vector3)OriginInWorld, vertexLists, indexLists);
        }
Beispiel #8
0
        public void SetBlockPrototype(RelativeBlockPosition position, BlockPrototype prototype)
        {
            blockArray[position.X, position.Y, position.Z] = prototype;

            if (prototype.CanBeSeen && position.Y > highestVisibleBlock)
            {
                highestVisibleBlock = position.Y;
            }

            if (!prototype.CanBeSeen && position.Y < lowestInvisibleBlock)
            {
                lowestInvisibleBlock = position.Y;
            }
        }
Beispiel #9
0
 public byte GetLightLevel(RelativeBlockPosition position)
 {
     return lightArray[position.X, position.Y, position.Z];
 }
Beispiel #10
0
 public BlockPrototype GetBlockPrototype(RelativeBlockPosition position)
 {
     return blockArray[position.X, position.Y, position.Z];
 }
Beispiel #11
0
        // TODO: we should only calculate lighting once all neighbor chunks have geometry
        // and have sunlight casted
        public void CalculateLighting()
        {
            var calculationLimit = GetHighestVisibleBlockInNeighborhood();
            var propagator = new LightPropagator();

            for (int x = 0; x < XDimension; x++)
            {
                for (int y = lowestSunlitBlock; y <= calculationLimit; y++)
                {
                    for (int z = 0; z < ZDimension; z++)
                    {
                        // TODO: For now we can propogate only if the light is full strength,
                        // but that won't work for light sources that are less than full strength.  Maybe have a source
                        // and destination light map so we don't have to deal with half-calculated data?
                        if (NeedsPropogation(x, y, z))
                        {
                            propagator.NumberOfRecursions = 0;
                            var relativeBlockPosition = new RelativeBlockPosition(x, y, z);
                            if (GetLightLevel(relativeBlockPosition) == World.MaximumLightLevel)
                            {
                                // TODO: because the propagator will happily move into neighboring chunks to do its work, we need to
                                // think about the implications for multi-threading and race conditions.
                                propagator.PropagateSunlightFromBlock(world, new BlockPosition(Position, relativeBlockPosition));
                                NumberOfLightPropagations++;
                            }
                        }
                    }
                }
            }
        }
Beispiel #12
0
 public BlockPosition(ChunkPosition chunkPosition, RelativeBlockPosition relativeBlockPosition)
 {
     X = chunkPosition.X * Chunk.XDimension + relativeBlockPosition.X;
     Y = relativeBlockPosition.Y;
     Z = chunkPosition.Z * Chunk.XDimension + relativeBlockPosition.Z;
 }