예제 #1
0
        /// <summary>
        /// Build up renderable geometry from input height neighborhood and material map.
        /// </summary>
        /// <param name="neighbors"></param>
        /// <param name="colorMap"></param>
        /// <returns></returns>
        public bool MakeGeometry(VirtualMap.HeightMapNeighbors heightNeighbors, VirtualMap.ColorMapNeighbors colorNeighbors)
        {
            MakeMinLut(heightNeighbors);

            bool notEmpty = MakeRenderables(heightNeighbors, colorNeighbors);

            CheckIndices(heightNeighbors[(int)VirtualMap.HeightMapNeighbors.Dir.Center].Size);

            return(notEmpty);
        }
예제 #2
0
        /// <summary>
        /// Build up renderable geometry for each possible material. Discard empties.
        /// </summary>
        /// <param name="neighbors"></param>
        /// <param name="colorMap"></param>
        /// <returns></returns>
        private bool MakeRenderables(
            VirtualMap.HeightMapNeighbors heightNeighbors,
            VirtualMap.ColorMapNeighbors colorNeighbors)
        {
            var heightMap = heightNeighbors[VirtualMap.HeightMapNeighbors.Dir.Center];

            VirtualMap.ColorMap colorMap = colorNeighbors[VirtualMap.ColorMapNeighbors.Dir.Center];

            Renderable.PrepareToBuild(heightMap.Size, Min, minLut);

            //Dispose();
            //renderableDict.Clear();

            // Reset number of local vertices in each Renderable
            // since we're about to remake the list.
            ResetAllVertexCounts();


            Vector2 cubeSize = new Vector2(
                heightMap.Scale.X / (float)heightMap.Size.X,
                heightMap.Scale.Y / (float)heightMap.Size.Y);
            Vector2 halfSize = cubeSize * 0.5f;

            Point vert = new Point(0, 0);

            for (vert.X = 0; vert.X < heightMap.Size.X; vert.X += 1)
            {
                for (vert.Y = 0; vert.Y < heightMap.Size.Y; vert.Y += 1)
                {
                    float h = heightMap.GetHeightUnsafe(vert.X, vert.Y);
                    if (h != 0)
                    {
                        ushort color = colorMap[vert.X, vert.Y];

                        //Debug.Assert(TerrainMaterial.IsValid(color, false, true));

                        if (TerrainMaterial.IsValid(color, false, true))
                        {
                            Vector3 pos = new Vector3(
                                (float)vert.X * cubeSize.X + halfSize.X,
                                (float)vert.Y * cubeSize.Y + halfSize.Y,
                                h);

                            Renderable r = GetOrMakeRenderable(colorMap[vert.X, vert.Y]);

                            r.AddVertices(pos, halfSize, vert, heightNeighbors, colorNeighbors);
                        }
                    }
                }
            }

            return(FinishGeometry(cubeSize, halfSize));
        }
예제 #3
0
        /// <summary>
        /// Generate the minumum lookup table from the height neighborhood.
        /// </summary>
        /// <param name="neighbors"></param>
        private void MakeMinLut(VirtualMap.HeightMapNeighbors neighbors)
        {
            HeightMap heightMap = neighbors[VirtualMap.HeightMapNeighbors.Dir.Center];

            if ((minLut == null) || (minLutSize.X != heightMap.Size.X + 1) || (minLutSize.Y != heightMap.Size.Y + 1))
            {
                minLutSize = new Point(heightMap.Size.X + 1, heightMap.Size.Y + 1);
                minLut     = new Vector2[minLutSize.X, minLutSize.Y];
            }

            float absMax = heightMap.Scale.Z;
            float absMin = 0.0f;

            for (int j = 0; j < minLutSize.Y; ++j)
            {
                for (int i = 0; i < minLutSize.X; ++i)
                {
                    minLut[i, j].X = absMax;
                    minLut[i, j].Y = absMin;
                }
            }

            Debug.Assert(heightMap.Size.X == heightMap.Size.Y);

            int lastPix = heightMap.Size.X - 1;
            int lastLut = lastPix + 1;

            /// Prime the sides from the neighbors.
            HeightMap north = neighbors[VirtualMap.HeightMapNeighbors.Dir.North];

            if (north != null)
            {
                for (int i = 0; i <= lastPix; ++i)
                {
                    float height = north.GetHeight(i, 0);

                    minLut[i, lastLut].X     = Math.Min(minLut[i, lastLut].X, height);
                    minLut[i + 1, lastLut].X = Math.Min(minLut[i + 1, lastLut].X, height);

                    minLut[i, lastLut].Y     = Math.Max(minLut[i, lastLut].Y, height);
                    minLut[i + 1, lastLut].Y = Math.Max(minLut[i + 1, lastLut].Y, height);
                }
            }
            else
            {
                for (int i = 0; i < minLutSize.X; ++i)
                {
                    minLut[i, lastLut].X = absMin;
                    minLut[i, lastLut].Y = absMin;
                }
            }
            HeightMap east = neighbors[VirtualMap.HeightMapNeighbors.Dir.East];

            if (east != null)
            {
                for (int j = 0; j <= lastPix; ++j)
                {
                    float height = east.GetHeight(0, j);

                    minLut[lastLut, j].X     = Math.Min(minLut[lastLut, j].X, height);
                    minLut[lastLut, j + 1].X = Math.Min(minLut[lastLut, j + 1].X, height);

                    minLut[lastLut, j].Y     = Math.Max(minLut[lastLut, j].Y, height);
                    minLut[lastLut, j + 1].Y = Math.Max(minLut[lastLut, j + 1].Y, height);
                }
            }
            else
            {
                for (int j = 0; j < minLutSize.Y; ++j)
                {
                    minLut[lastLut, j].X = absMin;
                    minLut[lastLut, j].Y = absMin;
                }
            }
            HeightMap south = neighbors[VirtualMap.HeightMapNeighbors.Dir.South];

            if (south != null)
            {
                for (int i = 0; i <= lastPix; ++i)
                {
                    float height = south.GetHeight(i, lastPix);

                    minLut[i, 0].X     = Math.Min(minLut[i, 0].X, height);
                    minLut[i + 1, 0].X = Math.Min(minLut[i + 1, 0].X, height);

                    minLut[i, 0].Y     = Math.Max(minLut[i, 0].Y, height);
                    minLut[i + 1, 0].Y = Math.Max(minLut[i + 1, 0].Y, height);
                }
            }
            else
            {
                for (int i = 0; i < minLutSize.X; ++i)
                {
                    minLut[i, 0].X = absMin;
                    minLut[i, 0].Y = absMin;
                }
            }
            HeightMap west = neighbors[VirtualMap.HeightMapNeighbors.Dir.West];

            if (west != null)
            {
                for (int j = 0; j <= lastPix; ++j)
                {
                    float height = west.GetHeight(lastPix, j);

                    minLut[0, j].X     = Math.Min(minLut[0, j].X, height);
                    minLut[0, j + 1].X = Math.Min(minLut[0, j + 1].X, height);

                    minLut[0, j].Y     = Math.Max(minLut[0, j].Y, height);
                    minLut[0, j + 1].Y = Math.Max(minLut[0, j + 1].Y, height);
                }
            }
            else
            {
                for (int j = 0; j < minLutSize.Y; ++j)
                {
                    minLut[0, j].X = absMin;
                    minLut[0, j].Y = absMin;
                }
            }

            for (int i = 0; i < heightMap.Size.X; ++i)
            {
                for (int j = 0; j < heightMap.Size.Y; ++j)
                {
                    float height = heightMap.GetHeight(i, j);

                    minLut[i, j].X         = Math.Min(minLut[i, j].X, height);
                    minLut[i + 1, j].X     = Math.Min(minLut[i + 1, j].X, height);
                    minLut[i, j + 1].X     = Math.Min(minLut[i, j + 1].X, height);
                    minLut[i + 1, j + 1].X = Math.Min(minLut[i + 1, j + 1].X, height);

                    minLut[i, j].Y         = Math.Max(minLut[i, j].Y, height);
                    minLut[i + 1, j].Y     = Math.Max(minLut[i + 1, j].Y, height);
                    minLut[i, j + 1].Y     = Math.Max(minLut[i, j + 1].Y, height);
                    minLut[i + 1, j + 1].Y = Math.Max(minLut[i + 1, j + 1].Y, height);
                }
            }
        }