/// <summary>
        /// Used when the patch below is more detailed, and we are filling the bottom row
        /// </summary>
        /// <param name="pIndexBuilder"></param>
        /// <param name="hSkip"></param>
        /// <param name="hHalfSkip"></param>
        /// <param name="bLeft"></param>
        /// <param name="bRight"></param>
        private void AddTrianglesBottomRow(IndexBuilder pIndexBuilder,
                                           int nY, int hSkip, int hHalfSkip,
                                           bool bLeft, bool bRight)
        {
            int nStartX = 0, nEndX = _patchSize - 1;

            if (bLeft)
            {
                pIndexBuilder.AddIndex(0, nY + hSkip);
                pIndexBuilder.AddIndex(0, nY + hHalfSkip);
                pIndexBuilder.AddIndex(hHalfSkip, nY + hSkip);
                pIndexBuilder.AddIndex(0, nY);
                pIndexBuilder.AddIndex(hSkip, nY + hSkip);
                pIndexBuilder.AddIndex(hSkip, nY);

                nStartX = hSkip;
            }

            // if right patch is more detailed, don't fill the end block normally
            if (bRight)
            {
                nEndX -= hSkip;
            }

            for (int x = nStartX; x < nEndX; x += hSkip)
            {
                pIndexBuilder.AddIndex(x, nY + hSkip);
                pIndexBuilder.AddIndex(x, nY);
                pIndexBuilder.AddIndex(x + hHalfSkip, nY + hSkip);
                pIndexBuilder.AddIndex(x + hSkip, nY);
                pIndexBuilder.AddIndex(x + hSkip, nY + hSkip);
                if (x != _patchSize - 1 - hSkip)
                {
                    pIndexBuilder.AddLastIndexAgain();
                }
            }

            if (bRight)
            {
                int nRightX = _patchSize - 1 - hSkip;
                pIndexBuilder.AddIndex(nRightX, nY + hSkip);
                pIndexBuilder.AddIndex(nRightX, nY);
                pIndexBuilder.AddIndex(nRightX + hHalfSkip, nY + hSkip);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY + hSkip);
                pIndexBuilder.AddLastIndexAgain();
                pIndexBuilder.AddIndex(nRightX, nY);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY + hHalfSkip);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY);
            }
        }
        private IndexCollection[] BuildIndices(int numLevels, int level)
        {
            // calculate number of vertices
            int nNumVerticesOneSide = GetPowerOfTwo((int)(numLevels - 1 - level)) + 1;
            int nNumVertices        = nNumVerticesOneSide * nNumVerticesOneSide;

            // calculate number of primitives
            int nNumRows = nNumVerticesOneSide - 1;

            // for level 0, we only have set of indices because we never adapt to neighbours
            int nTotalNeighbourCodes = (level == 0) ? 1 : TotalNeighbourCodes;

            IndexCollection[] indices = new IndexCollection[nTotalNeighbourCodes];

            int hSkip     = GetPowerOfTwo(level);
            int hHalfSkip = hSkip / 2;

            for (int j = 0; j < nTotalNeighbourCodes; j++)
            {
                bool bLeft, bRight, bTop, bBottom;
                GetNeighboursBoolean(j, out bLeft, out bRight, out bTop, out bBottom);

                // generate indices
                if (level == numLevels - 1)
                {
                    indices[j] = AddHighestLevelTriangles(hSkip, hHalfSkip, j);
                }
                else
                {
                    IndexBuilder pIndexBuilder = new IndexBuilder(this);
                    for (int y = 0; y < _patchSize - hSkip; y += hSkip)
                    {
                        AddTriangleRow(pIndexBuilder, y, hSkip, hHalfSkip, bLeft, bRight, bTop, bBottom);
                    }
                    indices[j] = pIndexBuilder.Indices;
                }
            }

            return(indices);
        }
        private void AddTriangleRow(IndexBuilder pIndexBuilder,
                                    int nY, int hSkip, int hHalfSkip,
                                    bool bLeft, bool bRight, bool bTop, bool bBottom)
        {
            // special case for top row when patch above is more detailed
            if (bTop && nY == 0)
            {
                AddTrianglesTopRow(pIndexBuilder, hSkip, hHalfSkip, bLeft, bRight);
                return;
            }

            // if this is not the first row, add index for degenerate triangle
            // coming from previous row (this is so that we can keep the triangle list going)
            if (nY != 0)
            {
                pIndexBuilder.AddIndex(0, nY + hSkip);
            }

            // special case for bottom row when patch below is more detailed
            if (bBottom && (nY == _patchSize - 1 - hSkip))
            {
                AddTrianglesBottomRow(pIndexBuilder, nY, hSkip, hHalfSkip, bLeft, bRight);
                return;
            }

            int nStartX = 0, nEndX = _patchSize;

            // special case if left patch (or left and top patch, or left and bottom patch) is more detailed
            if (bLeft)
            {
                pIndexBuilder.AddIndex(0, nY + hSkip);
                pIndexBuilder.AddIndex(0, nY + hHalfSkip);
                pIndexBuilder.AddIndex(hSkip, nY + hSkip);
                pIndexBuilder.AddIndex(0, nY);
                pIndexBuilder.AddIndex(hSkip, nY);
                pIndexBuilder.AddLastIndexAgain();

                // shift starting x pos
                nStartX = hSkip;
            }

            // if right patch is more detailed, don't fill the end block normally
            if (bRight)
            {
                nEndX -= hSkip;
            }

            // standard row filler
            for (int x = nStartX; x < nEndX; x += hSkip)
            {
                pIndexBuilder.AddIndex(x, nY + hSkip);
                pIndexBuilder.AddIndex(x, nY);
            }

            // special case if right patch is more detailed
            if (bRight)
            {
                int nRightX = _patchSize - 1 - hSkip;
                pIndexBuilder.AddIndex(nRightX, nY + hSkip);
                pIndexBuilder.AddLastIndexAgain();
                pIndexBuilder.AddIndex(nRightX + hSkip, nY + hSkip);
                pIndexBuilder.AddIndex(nRightX, nY);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY + hHalfSkip);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY);
            }

            // if this is not last row, add extra index for degenerate triangle
            if (nY != _patchSize - 1 - hSkip)
            {
                pIndexBuilder.AddLastIndexAgain();
            }
        }
Beispiel #4
0
        private IndexCollection[] BuildIndices(int numLevels, int level)
        {
            // calculate number of vertices
            int nNumVerticesOneSide = GetPowerOfTwo((int) (numLevels - 1 - level)) + 1;
            int nNumVertices = nNumVerticesOneSide * nNumVerticesOneSide;

            // calculate number of primitives
            int nNumRows = nNumVerticesOneSide - 1;

            // for level 0, we only have set of indices because we never adapt to neighbours
            int nTotalNeighbourCodes = (level == 0) ? 1 : TotalNeighbourCodes;
            IndexCollection[] indices = new IndexCollection[nTotalNeighbourCodes];

            int hSkip = GetPowerOfTwo(level);
            int hHalfSkip = hSkip / 2;

            for (int j = 0; j < nTotalNeighbourCodes; j++)
            {
                bool bLeft, bRight, bTop, bBottom;
                GetNeighboursBoolean(j, out bLeft, out bRight, out bTop, out bBottom);

                // generate indices
                if (level == numLevels - 1)
                {
                    indices[j] = AddHighestLevelTriangles(hSkip, hHalfSkip, j);
                }
                else
                {
                    IndexBuilder pIndexBuilder = new IndexBuilder(this);
                    for (int y = 0; y < _patchSize - hSkip; y += hSkip)
                        AddTriangleRow(pIndexBuilder, y, hSkip, hHalfSkip, bLeft, bRight, bTop, bBottom);
                    indices[j] = pIndexBuilder.Indices;
                }
            }

            return indices;
        }
Beispiel #5
0
        /// <summary>
        /// Used when the patch above is more detailed, and we are filling the top row
        /// </summary>
        /// <param name="pIndexBuilder"></param>
        /// <param name="hSkip"></param>
        /// <param name="hHalfSkip"></param>
        /// <param name="bLeft"></param>
        /// <param name="bRight"></param>
        private void AddTrianglesTopRow(IndexBuilder pIndexBuilder, int hSkip, int hHalfSkip,
			bool bLeft, bool bRight)
        {
            int nStartX = 0, nEndX = _patchSize - 1;

            if (bLeft)
            {
                pIndexBuilder.AddIndex(0, 0);
                pIndexBuilder.AddIndex(hHalfSkip, 0);
                pIndexBuilder.AddIndex(0, hHalfSkip);
                pIndexBuilder.AddIndex(hSkip, 0);
                pIndexBuilder.AddIndex(0, hSkip);
                pIndexBuilder.AddIndex(hSkip, hSkip);

                nStartX = hSkip;
            }

            // if right patch is more detailed, don't fill the end block normally
            if (bRight)
            {
                nEndX -= hSkip;
            }

            for (int x = nStartX; x < nEndX; x += hSkip)
            {
                pIndexBuilder.AddIndex(x, 0);
                pIndexBuilder.AddIndex(x + hHalfSkip, 0);
                pIndexBuilder.AddIndex(x, hSkip);
                pIndexBuilder.AddIndex(x + hSkip, 0);
                pIndexBuilder.AddIndex(x + hSkip, hSkip);
                if (x != _patchSize - 1)
                {
                    pIndexBuilder.AddLastIndexAgain();
                }
                if (x == _patchSize - hSkip - 1)
                {
                    pIndexBuilder.AddLastIndexAgain();
                }
            }

            if (bRight)
            {
                int nRightX = _patchSize - 1 - hSkip;
                pIndexBuilder.AddIndex(nRightX, 0);
                pIndexBuilder.AddLastIndexAgain();
                pIndexBuilder.AddIndex(nRightX, hSkip);
                pIndexBuilder.AddIndex(nRightX + hHalfSkip, 0);
                pIndexBuilder.AddIndex(nRightX + hSkip, 0);
                pIndexBuilder.AddLastIndexAgain();
                pIndexBuilder.AddIndex(nRightX, hSkip);
                pIndexBuilder.AddIndex(nRightX + hSkip, hHalfSkip);
                pIndexBuilder.AddIndex(nRightX + hSkip, hSkip);
            }

            // don't need to add degenerate triangle due to weird indexing
        }
Beispiel #6
0
        /// <summary>
        /// Used when the patch below is more detailed, and we are filling the bottom row
        /// </summary>
        /// <param name="pIndexBuilder"></param>
        /// <param name="hSkip"></param>
        /// <param name="hHalfSkip"></param>
        /// <param name="bLeft"></param>
        /// <param name="bRight"></param>
        private void AddTrianglesBottomRow(IndexBuilder pIndexBuilder,
			int nY, int hSkip, int hHalfSkip,
			bool bLeft, bool bRight)
        {
            int nStartX = 0, nEndX = _patchSize - 1;

            if (bLeft)
            {
                pIndexBuilder.AddIndex(0, nY + hSkip);
                pIndexBuilder.AddIndex(0, nY + hHalfSkip);
                pIndexBuilder.AddIndex(hHalfSkip, nY + hSkip);
                pIndexBuilder.AddIndex(0, nY);
                pIndexBuilder.AddIndex(hSkip, nY + hSkip);
                pIndexBuilder.AddIndex(hSkip, nY);

                nStartX = hSkip;
            }

            // if right patch is more detailed, don't fill the end block normally
            if (bRight)
            {
                nEndX -= hSkip;
            }

            for (int x = nStartX; x < nEndX; x += hSkip)
            {
                pIndexBuilder.AddIndex(x, nY + hSkip);
                pIndexBuilder.AddIndex(x, nY);
                pIndexBuilder.AddIndex(x + hHalfSkip, nY + hSkip);
                pIndexBuilder.AddIndex(x + hSkip, nY);
                pIndexBuilder.AddIndex(x + hSkip, nY + hSkip);
                if (x != _patchSize - 1 - hSkip)
                {
                    pIndexBuilder.AddLastIndexAgain();
                }
            }

            if (bRight)
            {
                int nRightX = _patchSize - 1 - hSkip;
                pIndexBuilder.AddIndex(nRightX, nY + hSkip);
                pIndexBuilder.AddIndex(nRightX, nY);
                pIndexBuilder.AddIndex(nRightX + hHalfSkip, nY + hSkip);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY + hSkip);
                pIndexBuilder.AddLastIndexAgain();
                pIndexBuilder.AddIndex(nRightX, nY);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY + hHalfSkip);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY);
            }
        }
Beispiel #7
0
        private void AddTriangleRow(IndexBuilder pIndexBuilder,
			int nY, int hSkip, int hHalfSkip,
			bool bLeft, bool bRight, bool bTop, bool bBottom)
        {
            // special case for top row when patch above is more detailed
            if (bTop && nY == 0)
            {
                AddTrianglesTopRow(pIndexBuilder, hSkip, hHalfSkip, bLeft, bRight);
                return;
            }

            // if this is not the first row, add index for degenerate triangle
            // coming from previous row (this is so that we can keep the triangle list going)
            if (nY != 0)
            {
                pIndexBuilder.AddIndex(0, nY + hSkip);
            }

            // special case for bottom row when patch below is more detailed
            if (bBottom && (nY == _patchSize - 1 - hSkip))
            {
                AddTrianglesBottomRow(pIndexBuilder, nY, hSkip, hHalfSkip, bLeft, bRight);
                return;
            }

            int nStartX = 0, nEndX = _patchSize;

            // special case if left patch (or left and top patch, or left and bottom patch) is more detailed
            if (bLeft)
            {
                pIndexBuilder.AddIndex(0, nY + hSkip);
                pIndexBuilder.AddIndex(0, nY + hHalfSkip);
                pIndexBuilder.AddIndex(hSkip, nY + hSkip);
                pIndexBuilder.AddIndex(0, nY);
                pIndexBuilder.AddIndex(hSkip, nY);
                pIndexBuilder.AddLastIndexAgain();

                // shift starting x pos
                nStartX = hSkip;
            }

            // if right patch is more detailed, don't fill the end block normally
            if (bRight)
            {
                nEndX -= hSkip;
            }

            // standard row filler
            for (int x = nStartX; x < nEndX; x += hSkip)
            {
                pIndexBuilder.AddIndex(x, nY + hSkip);
                pIndexBuilder.AddIndex(x, nY);
            }

            // special case if right patch is more detailed
            if (bRight)
            {
                int nRightX = _patchSize - 1 - hSkip;
                pIndexBuilder.AddIndex(nRightX, nY + hSkip);
                pIndexBuilder.AddLastIndexAgain();
                pIndexBuilder.AddIndex(nRightX + hSkip, nY + hSkip);
                pIndexBuilder.AddIndex(nRightX, nY);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY + hHalfSkip);
                pIndexBuilder.AddIndex(nRightX + hSkip, nY);
            }

            // if this is not last row, add extra index for degenerate triangle
            if (nY != _patchSize - 1 - hSkip)
            {
                pIndexBuilder.AddLastIndexAgain();
            }
        }