Axiom.Components.Terrain.TerrainQuadTreeNode.CreateTriangleStripBuffer C# (CSharp) Method

CreateTriangleStripBuffer() protected method

protected CreateTriangleStripBuffer ( ushort batchSize, IndexData destData ) : void
batchSize ushort
destData Axiom.Graphics.IndexData
return void
        protected void CreateTriangleStripBuffer(ushort batchSize, IndexData destData)
        {
            /* For even / odd tri strip rows, triangles are this shape:
		    6---7---8
		    | \ | \ |
		    3---4---5
		    | / | / |
		    0---1---2
		    Note how vertex rows count upwards. In order to match up the anti-clockwise
		    winding and this upward transitioning list, we need to start from the
		    right hand side. So we get (2,5,1,4,0,3) etc on even lines (right-left)
		    and (3,6,4,7,5,8) etc on odd lines (left-right). At the turn, we emit the end index 
		    twice, this forms a degenerate triangle, which lets us turn without any artefacts. 
		    So the full list in this simple case is (2,5,1,4,0,3,3,6,4,7,5,8)

		    Skirts are part of the same strip, so after finishing on 8, where sX is
		     the skirt vertex corresponding to main vertex X, we go
		     anticlockwise around the edge, (s8,7,s7,6,s6) to do the top skirt, 
		    then (3,s3,0,s0),(1,s1,2,s2),(5,s5,8,s8) to finish the left, bottom, and
		     right skirts respectively.
		    */

            // to issue a complete row, it takes issuing the upper and lower row
            // and one extra index, which is the degenerate triangle and also turning
            // around the winding
            VertexDataRecord vdr = this.VertextDataRecord;
            int mainIndexPerRow = batchSize * 2 + 1;
            int numRows = batchSize - 1;
            int mainIndexCount = mainIndexPerRow * numRows;
            // skirts share edges, so they take 1 less row per side than batchSize, 
            // but with 2 extra at the end (repeated) to finish the strip
            // * 2 for the vertical line, * 4 for the sides, +2 to finish
            int skirtIndexCount = (batchSize - 1) * 2 * 4 + 2;

            destData.indexStart = 0;
            destData.indexCount = mainIndexCount + skirtIndexCount;
            destData.indexBuffer = HardwareBufferManager.Instance.CreateIndexBuffer(IndexType.Size16, destData.indexCount, BufferUsage.Static,false);

#warning IndexBuffer.Bind(DefaultHardwareIndexBuffer);
            unsafe
            {
                ushort* pI = (ushort*)(destData.indexBuffer.Lock(BufferLocking.Discard));
                ushort* basepI = pI;

                // Ratio of the main terrain resolution in relation to this vertex data resolution
                int resolutionRatio = (mTerrain.Size - 1) / (vdr.Resolution - 1);
                // At what frequency do we sample the vertex data we're using?
                // mSize is the coverage in terms of the original terrain data (not split to fit in 16-bit)
                int vertexIncrement = ( mSize -1 )/ (batchSize -1);
                // however, the vertex data we're referencing may not be at the full resolution anyway
                vertexIncrement /= resolutionRatio;
                int rowSize = vdr.Size * vertexIncrement;
                
                // Start on the right
                ushort currentVertex = (ushort)((batchSize - 1) * vertexIncrement);
                // but, our quad area might not start at 0 in this vertex data
                // offsets are at main terrain resolution, remember
                ushort columnStart = (ushort)((mOffsetX - mNodeWithVertexData.mOffsetX) / resolutionRatio);
                ushort rowStart = (ushort)((mOffsetY - mNodeWithVertexData.mOffsetY) / resolutionRatio);
                currentVertex +=(ushort)((rowStart * vdr.Size) + columnStart);
                bool rightToLeft = true;
                for (ushort r = 0; r < (ushort)numRows; ++r)
                {

                    for (ushort c = 0; c < batchSize; ++c)
                    {
                        *pI++ = currentVertex;
                        *pI++ = (ushort)(currentVertex + rowSize);

                        // don't increment / decrement at a border, keep this vertex for next
                        // row as we 'snake' across the tile
                        if (c + 1 < batchSize)
                        {
                            currentVertex = rightToLeft ?
                                (ushort)(currentVertex - vertexIncrement) : (ushort)(currentVertex + vertexIncrement);
                        }
                    }
                    rightToLeft = !rightToLeft;
                    currentVertex += (ushort)rowSize;
                    // issue one extra index to turn winding around
                    *pI++ = currentVertex;

                }

                 // Skirts
                 for (ushort s = 0; s < 4; ++s)
                 {
                     // edgeIncrement is the index offset from one original edge vertex to the next
                     // in this row or column. Columns skip based on a row size here
                     // skirtIncrement is the index offset from one skirt vertex to the next, 
                     // because skirts are packed in rows/cols then there is no row multiplier for
                     // processing columns
                     int edgeIncrement = 0, skirtIncrement = 0;
                     switch (s)
                     {
                         case 0: //top
                             edgeIncrement = -(int)vertexIncrement;
                             skirtIncrement = -(int)vertexIncrement;
                             break;
                         case 1:// left
                             edgeIncrement = -(int)rowSize;
                             skirtIncrement = -(int)vertexIncrement;
                             break;
                         case 2://bottom
                             edgeIncrement = (int)vertexIncrement;
                             skirtIncrement = (int)vertexIncrement;
                             break;
                         case 3://right
                             edgeIncrement = (int)rowSize;
                             skirtIncrement = (int)vertexIncrement;
                             break;
                     }
                     // Skirts are stored in contiguous rows / columns (rows 0/2, cols 1/3)
                    ushort skirtIndex = CalcSkirtVertexIndex(currentVertex, (s % 2) != 0);

                     for (ushort c = 0; c < (ushort)(batchSize - 1); ++c)
                     {
                         *pI++ = currentVertex;
                         *pI++ = skirtIndex;

                         currentVertex += (ushort)edgeIncrement;
                         skirtIndex += (ushort)skirtIncrement;
                     }
                     if (s == 3)
                     {
                         // we issue an extra 2 indices to finish the skirt off
                         *pI++ = currentVertex;
                         *pI++ = skirtIndex;
                         currentVertex += (ushort)edgeIncrement;
                         skirtIndex += (ushort)skirtIncrement;
                     }
                 }//end for
                ushort val = (ushort)(pI - basepI);
                //Debug.Assert(val == (ushort)destData.indexCount, "wrong indices");
            }//end unsafe
        }
        /// <summary>