/// <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; } } }
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); }
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); }