Ejemplo n.º 1
0
 /// <summary>
 /// If the stitchRenderable is not valid, then throw it away.  A new one will
 /// be generated when needed.
 /// </summary>
 /// <param name="southMetersPerSample"></param>
 /// <param name="eastMetersPerSample"></param>
 public void ValidateStitch(int southMetersPerSample, int eastMetersPerSample)
 {
     if (stitchRenderable != null)
     {
         if (!stitchRenderable.IsValid(numSamples, southMetersPerSample, eastMetersPerSample))
         {
             stitchRenderable.Dispose();
             stitchRenderable = null;
         }
     }
 }
Ejemplo n.º 2
0
        private void DisposeBuffers()
        {
            renderOp.indexData = null;

            if (renderOp.vertexData != null)
            {
                renderOp.vertexData.vertexBufferBinding.GetBuffer(0).Dispose();
                renderOp.vertexData.vertexBufferBinding.SetBinding(0, null);
                renderOp.vertexData = null;
            }
            if (stitchRenderable != null)
            {
                stitchRenderable.Dispose();
                stitchRenderable = null;
            }
        }
        private void DisposeBuffers()
        {
            renderOp.indexData = null;

            if ( renderOp.vertexData != null )
            {
                renderOp.vertexData.vertexBufferBinding.GetBuffer(0).Dispose();
                renderOp.vertexData.vertexBufferBinding.SetBinding(0, null);
                renderOp.vertexData = null;
            }
            if ( stitchRenderable != null )
            {
                stitchRenderable.Dispose();
                stitchRenderable = null;
            }
        }
 /// <summary>
 /// If the stitchRenderable is not valid, then throw it away.  A new one will
 /// be generated when needed.
 /// </summary>
 /// <param name="southMetersPerSample"></param>
 /// <param name="eastMetersPerSample"></param>
 public void ValidateStitch(int southMetersPerSample, int eastMetersPerSample)
 {
     if ( stitchRenderable != null )
     {
         if ( ! stitchRenderable.IsValid(numSamples, southMetersPerSample, eastMetersPerSample) )
         {
             stitchRenderable.Dispose();
             stitchRenderable = null;
         }
     }
 }
        public void Stitch(HeightField south1, HeightField south2, HeightField east1, 
			HeightField east2, HeightField southEast, bool stitchMiddleSouth, bool stitchMiddleEast)
        {
            Debug.Assert( ( south2 == null || south2.metersPerSample == south1.metersPerSample ), "south neighbors have different LOD");
            Debug.Assert( ( east2 == null || east2.metersPerSample == east1.metersPerSample ), "east neighbors have different LOD");

            //
            // Determine the stitch types for south and east direction
            //
            StitchType southStitchType;
            StitchType eastStitchType;

            int southMetersPerSample = 0;

            if ( south1 == null )
            {
                southStitchType = StitchType.None;
            }
            else
            {
                southMetersPerSample = south1.metersPerSample;

                if ( south1.metersPerSample == metersPerSample )
                {
                    southStitchType = StitchType.ToSame;
                }
                else if ( south1.metersPerSample > metersPerSample )
                {
                    Debug.Assert(south1.metersPerSample == ( 2 * metersPerSample ), "stitching:south LOD not half");
                    southStitchType = StitchType.ToLower;
                }
                else
                {
                    Debug.Assert( ( south1.metersPerSample * 2 ) == metersPerSample, "stitching: south LOD not double");
                    southStitchType = StitchType.ToHigher;
                }
            }

            int eastMetersPerSample = 0;

            if ( east1 == null )
            {
                eastStitchType = StitchType.None;
            }
            else
            {
                eastMetersPerSample = east1.metersPerSample;

                if ( east1.metersPerSample == metersPerSample )
                {
                    eastStitchType = StitchType.ToSame;
                }
                else if ( east1.metersPerSample > metersPerSample )
                {
                    Debug.Assert(east1.metersPerSample == ( 2 * metersPerSample ), "stitching:east LOD not half");
                    eastStitchType = StitchType.ToLower;
                }
                else
                {
                    Debug.Assert( ( east1.metersPerSample * 2 ) == metersPerSample, "stitching:east LOD not double");
                    eastStitchType = StitchType.ToHigher;
                }
            }

            if ( stitchRenderable != null )
            {
                if ( stitchRenderable.IsValid(numSamples, southMetersPerSample, eastMetersPerSample) )
                { // existing stitchRenderable is still ok, so just use it
                    return;
                }
                else
                {
                    stitchRenderable.Dispose();
                    stitchRenderable = null;
                }
            }

            //
            // The following combinations are acceptable:
            //  1) both same
            //  2) one same and one lower
            //  3) one same and one higher
            //  4) both lower
            //
            Debug.Assert( ( ( southStitchType == StitchType.ToSame ) || ( eastStitchType == StitchType.ToSame ) ) ||
                ( ( southStitchType == StitchType.ToLower ) && ( eastStitchType == StitchType.ToLower ) ) ||
                ( ( southStitchType == StitchType.None ) && ( eastStitchType == StitchType.None ) ),
                "stitching:invalid stitchType combination");

            bool bothSame = false;
            bool bothLower = false;
            int vertexCount;

            if ( southStitchType == eastStitchType )
            {
                if ( southStitchType == StitchType.ToSame )
                {
                    bothSame = true;
                    vertexCount = numSamples * 4;
                }
                else if ( southStitchType == StitchType.ToLower )
                {
                    bothLower = true;
                    vertexCount = numSamples * 3;
                }
                else
                {
                    // both are StitchType.None, which means we are at the NE corner, so we dont need stitching
                    return;
                }
            }
            else
            {
                if ( ( southStitchType == StitchType.ToLower ) || ( eastStitchType == StitchType.ToLower ) )
                {
                    // one same and one lower
                    vertexCount = numSamples * 3 + ( numSamples / 2 );
                }
                else if ( ( southStitchType == StitchType.ToHigher ) || ( eastStitchType == StitchType.ToHigher ) )
                {
                    // one same and one higher
                    vertexCount = numSamples * 5;
                }
                else
                {
                    // one same and one none
                    vertexCount = numSamples * 2;
                }
            }

            VertexData vertexData = new VertexData();

            vertexData.vertexCount = vertexCount;
            vertexData.vertexStart = 0;

            // set up the vertex declaration
            int vDecOffset = 0;
            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float2);

            // create the hardware vertex buffer and set up the buffer binding
            HardwareVertexBuffer hvBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(
                vertexData.vertexDeclaration.GetVertexSize(0), vertexData.vertexCount,
                BufferUsage.StaticWriteOnly, false);

            vertexData.vertexBufferBinding.SetBinding(0, hvBuffer);

            // lock the vertex buffer
            IntPtr ipBuf = hvBuffer.Lock(BufferLocking.Discard);

            int bufferOff = 0;

            int southSamples = 0;
            int eastSamples = 0;
            int vertOff = 0;

            unsafe
            {
                float* buffer = (float *) ipBuf.ToPointer();

                if ( southStitchType != StitchType.None )
                {
                    //
                    // First the south edge of this tile
                    //
                    fillVerts(this, buffer, vertOff, numSamples, 0, numSamples - 1, 1, 0, 0, 0, tile.Page.Location);
                    vertOff += numSamples;
                }

                if ( eastStitchType != StitchType.None )
                {
                    int adjust = 0;
                    if ( southStitchType == StitchType.None )
                    {
                        // include the inner corner because it wasnt done with the south edge
                        adjust = 1;
                    }
                    //
                    // Now the east edge of the tile
                    //
                    fillVerts(this, buffer, vertOff, numSamples - 1 + adjust, numSamples - 1, numSamples - 2 + adjust, 0, -1, 0, 0, tile.Page.Location);
                    vertOff += ( numSamples - 1 + adjust );
                }

                if ( southStitchType != StitchType.None )
                {
                    //
                    // fill the verts from the south neighbor
                    //
                    southSamples = neighborSamples(southStitchType);

                    if ( south2 == null )
                    { // only one southern neighbor

                        int xStart = 0;
                        int xSampOff = 0;
                        if ( stitchMiddleSouth )
                        {
                            // go from bottom to middle of east tile, rather than middle to top
                            xStart = southSamples;
                            xSampOff = -tile.Size;
                        }

                        fillVerts(south1, buffer, vertOff, southSamples, xStart, 0, 1, 0, xSampOff, tile.Size, tile.Page.Location);
                        vertOff += southSamples;
                    }
                    else
                    { // two southern neighbors
                        int halfSamples = southSamples / 2;
                        fillVerts(south1, buffer, vertOff, halfSamples, 0, 0, 1, 0, 0, tile.Size, tile.Page.Location);
                        vertOff += halfSamples;

                        fillVerts(south2, buffer, vertOff, halfSamples, 0, 0, 1, 0, south1.tile.Size, tile.Size, tile.Page.Location);
                        vertOff += halfSamples;
                    }
                }

                if ( ( southStitchType != StitchType.None ) && ( eastStitchType != StitchType.None ) )
                {
                    //
                    // fill the single sample from the SE neighbor
                    //
                    if ( southEast == east1 )
                    {
                        fillVerts(southEast, buffer, vertOff, 1, 0, neighborSamples(eastStitchType), 0, 0, tile.Size, 0, tile.Page.Location);
                    }
                    else if ( southEast == south1 )
                    {
                        fillVerts(southEast, buffer, vertOff, 1, neighborSamples(southStitchType), 0, 0, 0, 0, tile.Size, tile.Page.Location);
                    }
                    else
                    {
                        fillVerts(southEast, buffer, vertOff, 1, 0, 0, 0, 0, tile.Size, tile.Size, tile.Page.Location);
                    }
                    vertOff++;
                }

                if ( eastStitchType != StitchType.None )
                {
                    //
                    // fill the verts from the east neighbor
                    //
                    eastSamples = neighborSamples(eastStitchType);

                    if ( east2 == null )
                    { // only one eastern neighbor

                        int zStart = eastSamples - 1;
                        int zSampOff = 0;
                        if ( stitchMiddleEast )
                        {
                            // go from bottom to middle of east tile, rather than middle to top
                            zStart = ( eastSamples * 2 ) - 1;
                            zSampOff = -tile.Size;
                        }

                        fillVerts(east1, buffer, vertOff, eastSamples, 0, zStart, 0, -1, tile.Size, zSampOff, tile.Page.Location);
                        vertOff += eastSamples;
                    }
                    else
                    { // two eastern neighbors
                        int halfSamples = eastSamples / 2;

                        fillVerts(east2, buffer, vertOff, halfSamples, 0, halfSamples - 1, 0, -1, tile.Size, east1.tile.Size, tile.Page.Location);
                        vertOff += halfSamples;

                        fillVerts(east1, buffer, vertOff, halfSamples, 0, halfSamples - 1, 0, -1, tile.Size, 0, tile.Page.Location);
                        vertOff += halfSamples;
                    }
                }

                Debug.Assert(vertexCount == vertOff, "stitching: generated incorrect number of vertices");

            }
            hvBuffer.Unlock();

            IndexData indexData = IndexBufferManager.Instance.GetStitchIndexBuffer(numSamples, southSamples, eastSamples);

            stitchRenderable = new StitchRenderable(this, vertexData, indexData, numSamples, southMetersPerSample, eastMetersPerSample);
        }
Ejemplo n.º 6
0
        public void Stitch(HeightField south1, HeightField south2, HeightField east1,
                           HeightField east2, HeightField southEast, bool stitchMiddleSouth, bool stitchMiddleEast)
        {
            Debug.Assert((south2 == null || south2.metersPerSample == south1.metersPerSample), "south neighbors have different LOD");
            Debug.Assert((east2 == null || east2.metersPerSample == east1.metersPerSample), "east neighbors have different LOD");

            //
            // Determine the stitch types for south and east direction
            //
            StitchType southStitchType;
            StitchType eastStitchType;

            int southMetersPerSample = 0;

            if (south1 == null)
            {
                southStitchType = StitchType.None;
            }
            else
            {
                southMetersPerSample = south1.metersPerSample;

                if (south1.metersPerSample == metersPerSample)
                {
                    southStitchType = StitchType.ToSame;
                }
                else if (south1.metersPerSample > metersPerSample)
                {
                    Debug.Assert(south1.metersPerSample == (2 * metersPerSample), "stitching:south LOD not half");
                    southStitchType = StitchType.ToLower;
                }
                else
                {
                    Debug.Assert((south1.metersPerSample * 2) == metersPerSample, "stitching: south LOD not double");
                    southStitchType = StitchType.ToHigher;
                }
            }

            int eastMetersPerSample = 0;

            if (east1 == null)
            {
                eastStitchType = StitchType.None;
            }
            else
            {
                eastMetersPerSample = east1.metersPerSample;

                if (east1.metersPerSample == metersPerSample)
                {
                    eastStitchType = StitchType.ToSame;
                }
                else if (east1.metersPerSample > metersPerSample)
                {
                    Debug.Assert(east1.metersPerSample == (2 * metersPerSample), "stitching:east LOD not half");
                    eastStitchType = StitchType.ToLower;
                }
                else
                {
                    Debug.Assert((east1.metersPerSample * 2) == metersPerSample, "stitching:east LOD not double");
                    eastStitchType = StitchType.ToHigher;
                }
            }

            if (stitchRenderable != null)
            {
                if (stitchRenderable.IsValid(numSamples, southMetersPerSample, eastMetersPerSample))
                {                 // existing stitchRenderable is still ok, so just use it
                    return;
                }
                else
                {
                    stitchRenderable.Dispose();
                    stitchRenderable = null;
                }
            }

            //
            // The following combinations are acceptable:
            //  1) both same
            //  2) one same and one lower
            //  3) one same and one higher
            //  4) both lower
            //
            Debug.Assert(((southStitchType == StitchType.ToSame) || (eastStitchType == StitchType.ToSame)) ||
                         ((southStitchType == StitchType.ToLower) && (eastStitchType == StitchType.ToLower)) ||
                         ((southStitchType == StitchType.None) && (eastStitchType == StitchType.None)),
                         "stitching:invalid stitchType combination");

            bool bothSame  = false;
            bool bothLower = false;
            int  vertexCount;

            if (southStitchType == eastStitchType)
            {
                if (southStitchType == StitchType.ToSame)
                {
                    bothSame    = true;
                    vertexCount = numSamples * 4;
                }
                else if (southStitchType == StitchType.ToLower)
                {
                    bothLower   = true;
                    vertexCount = numSamples * 3;
                }
                else
                {
                    // both are StitchType.None, which means we are at the NE corner, so we dont need stitching
                    return;
                }
            }
            else
            {
                if ((southStitchType == StitchType.ToLower) || (eastStitchType == StitchType.ToLower))
                {
                    // one same and one lower
                    vertexCount = numSamples * 3 + (numSamples / 2);
                }
                else if ((southStitchType == StitchType.ToHigher) || (eastStitchType == StitchType.ToHigher))
                {
                    // one same and one higher
                    vertexCount = numSamples * 5;
                }
                else
                {
                    // one same and one none
                    vertexCount = numSamples * 2;
                }
            }

            VertexData vertexData = new VertexData();

            vertexData.vertexCount = vertexCount;
            vertexData.vertexStart = 0;

            // set up the vertex declaration
            int vDecOffset = 0;

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Position);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float3, VertexElementSemantic.Normal);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float3);

            vertexData.vertexDeclaration.AddElement(0, vDecOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords);
            vDecOffset += VertexElement.GetTypeSize(VertexElementType.Float2);

            // create the hardware vertex buffer and set up the buffer binding
            HardwareVertexBuffer hvBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(
                vertexData.vertexDeclaration.GetVertexSize(0), vertexData.vertexCount,
                BufferUsage.StaticWriteOnly, false);

            vertexData.vertexBufferBinding.SetBinding(0, hvBuffer);

            // lock the vertex buffer
            IntPtr ipBuf = hvBuffer.Lock(BufferLocking.Discard);

            int bufferOff = 0;

            int southSamples = 0;
            int eastSamples  = 0;
            int vertOff      = 0;

            unsafe
            {
                float *buffer = (float *)ipBuf.ToPointer();

                if (southStitchType != StitchType.None)
                {
                    //
                    // First the south edge of this tile
                    //
                    fillVerts(this, buffer, vertOff, numSamples, 0, numSamples - 1, 1, 0, 0, 0, tile.Page.Location);
                    vertOff += numSamples;
                }

                if (eastStitchType != StitchType.None)
                {
                    int adjust = 0;
                    if (southStitchType == StitchType.None)
                    {
                        // include the inner corner because it wasnt done with the south edge
                        adjust = 1;
                    }
                    //
                    // Now the east edge of the tile
                    //
                    fillVerts(this, buffer, vertOff, numSamples - 1 + adjust, numSamples - 1, numSamples - 2 + adjust, 0, -1, 0, 0, tile.Page.Location);
                    vertOff += (numSamples - 1 + adjust);
                }

                if (southStitchType != StitchType.None)
                {
                    //
                    // fill the verts from the south neighbor
                    //
                    southSamples = neighborSamples(southStitchType);

                    if (south2 == null)
                    {                     // only one southern neighbor
                        int xStart   = 0;
                        int xSampOff = 0;
                        if (stitchMiddleSouth)
                        {
                            // go from bottom to middle of east tile, rather than middle to top
                            xStart   = southSamples;
                            xSampOff = -tile.Size;
                        }

                        fillVerts(south1, buffer, vertOff, southSamples, xStart, 0, 1, 0, xSampOff, tile.Size, tile.Page.Location);
                        vertOff += southSamples;
                    }
                    else
                    {                     // two southern neighbors
                        int halfSamples = southSamples / 2;
                        fillVerts(south1, buffer, vertOff, halfSamples, 0, 0, 1, 0, 0, tile.Size, tile.Page.Location);
                        vertOff += halfSamples;

                        fillVerts(south2, buffer, vertOff, halfSamples, 0, 0, 1, 0, south1.tile.Size, tile.Size, tile.Page.Location);
                        vertOff += halfSamples;
                    }
                }

                if ((southStitchType != StitchType.None) && (eastStitchType != StitchType.None))
                {
                    //
                    // fill the single sample from the SE neighbor
                    //
                    if (southEast == east1)
                    {
                        fillVerts(southEast, buffer, vertOff, 1, 0, neighborSamples(eastStitchType), 0, 0, tile.Size, 0, tile.Page.Location);
                    }
                    else if (southEast == south1)
                    {
                        fillVerts(southEast, buffer, vertOff, 1, neighborSamples(southStitchType), 0, 0, 0, 0, tile.Size, tile.Page.Location);
                    }
                    else
                    {
                        fillVerts(southEast, buffer, vertOff, 1, 0, 0, 0, 0, tile.Size, tile.Size, tile.Page.Location);
                    }
                    vertOff++;
                }

                if (eastStitchType != StitchType.None)
                {
                    //
                    // fill the verts from the east neighbor
                    //
                    eastSamples = neighborSamples(eastStitchType);

                    if (east2 == null)
                    {                     // only one eastern neighbor
                        int zStart   = eastSamples - 1;
                        int zSampOff = 0;
                        if (stitchMiddleEast)
                        {
                            // go from bottom to middle of east tile, rather than middle to top
                            zStart   = (eastSamples * 2) - 1;
                            zSampOff = -tile.Size;
                        }

                        fillVerts(east1, buffer, vertOff, eastSamples, 0, zStart, 0, -1, tile.Size, zSampOff, tile.Page.Location);
                        vertOff += eastSamples;
                    }
                    else
                    {                     // two eastern neighbors
                        int halfSamples = eastSamples / 2;

                        fillVerts(east2, buffer, vertOff, halfSamples, 0, halfSamples - 1, 0, -1, tile.Size, east1.tile.Size, tile.Page.Location);
                        vertOff += halfSamples;

                        fillVerts(east1, buffer, vertOff, halfSamples, 0, halfSamples - 1, 0, -1, tile.Size, 0, tile.Page.Location);
                        vertOff += halfSamples;
                    }
                }

                Debug.Assert(vertexCount == vertOff, "stitching: generated incorrect number of vertices");
            }
            hvBuffer.Unlock();

            IndexData indexData = IndexBufferManager.Instance.GetStitchIndexBuffer(numSamples, southSamples, eastSamples);

            stitchRenderable = new StitchRenderable(this, vertexData, indexData, numSamples, southMetersPerSample, eastMetersPerSample);
        }