private TerrainPatch( TerrainPatch parent, TerrainPatchVertices vertices, Point3 origin, Vector3 uAxis, Vector3 vAxis, float patchError, Point2 uv, float uvRes ) { m_Parent = parent; m_Vertices = vertices; m_LocalOrigin = origin; m_LocalUAxis = uAxis; m_LocalVAxis = vAxis; m_Radius = ( uAxis + vAxis ).Length; m_PatchError = patchError; m_IncreaseDetailDistance = float.MaxValue; m_UvRes = uvRes; m_Uv = uv; }
/// <summary> /// Adds patches that cover the side of a cube /// </summary> /// <param name="res">Patch resolution (res*res patches cover the cube side)</param> /// <param name="topLeft">The top left corner of the cube side</param> /// <param name="topRight">The top right corner of the cube side</param> /// <param name="bottomLeft">The bottom left corner of the cube side</param> /// <param name="uvRes">The UV resolution of the cube patch</param> private void AddCubeSidePatches( int res, Point3 topLeft, Point3 topRight, Point3 bottomLeft, float uvRes ) { Vector3 xAxis = ( topRight - topLeft ); Vector3 yAxis = ( bottomLeft - topLeft ); Vector3 xInc = xAxis / res; Vector3 yInc = yAxis / res; Point3 rowStart = topLeft; for ( int row = 0; row < res; ++row ) { Point3 curPos = rowStart; for ( int col = 0; col < res; ++col ) { TerrainPatch newPatch = new TerrainPatch( Vertices, curPos, xInc, yInc, new Point2( 0, 0 ), uvRes ); RootPatches.Add( newPatch ); curPos += xInc; } rowStart += yInc; } }
/// <summary> /// Increases the detail of this paqtch /// </summary> private void IncreaseDetail( ITerrainPatchGenerator generator, IProjectionCamera camera ) { if ( m_CachedChildren != null ) { // Child nodes have already been created - they just need new vertex buffers m_PendingChildren = m_CachedChildren; m_CachedChildren = null; } else { Vector3 uOffset = m_LocalUAxis * 0.5f; Vector3 vOffset = m_LocalVAxis * 0.5f; float error = m_PatchError / 2; // float error = float.MaxValue;// Use this value to force a recalculation of the patch error float uvRes = m_UvRes / 2; Point2 tlUv = m_Uv; Point2 trUv = m_Uv + new Vector2( uvRes, 0 ); Point2 brUv = m_Uv + new Vector2( uvRes, uvRes ); Point2 blUv = m_Uv + new Vector2( 0, uvRes ); TerrainPatch tl = new TerrainPatch( this, m_Vertices, m_LocalOrigin, uOffset, vOffset, error, tlUv,uvRes ); TerrainPatch tr = new TerrainPatch( this, m_Vertices, m_LocalOrigin + uOffset, uOffset, vOffset, error, trUv, uvRes ); TerrainPatch bl = new TerrainPatch( this, m_Vertices, m_LocalOrigin + vOffset, uOffset, vOffset, error, blUv, uvRes ); TerrainPatch br = new TerrainPatch( this, m_Vertices, m_LocalOrigin + uOffset + vOffset, uOffset, vOffset, error, brUv, uvRes ); m_PendingChildren = new TerrainPatch[] { tl, tr, bl, br }; } foreach ( TerrainPatch patch in m_PendingChildren ) { patch.Build( generator, camera ); } }