📄 ogrepaginglandscaperenderable.cpp
字号:
//-----------------------------------------------------------------------
const LightList& PagingLandScapeRenderable::getLights(void) const
{
return mParentNode->getLights();
}
//-----------------------------------------------------------------------
void PagingLandScapeRenderable::update( bool Top, bool Right, bool Down, bool Left )
{
if ( mTop != Top || mRight != Right || mDown != Down || mLeft != Left )
{
mRend.indexData = PagingLandScapeIndexBuffer::getSingleton().getIndex( Top, Right, Down, Left );
mTop = Top;
mRight = Right;
mDown = Down;
mLeft = Left;
}
}
//-----------------------------------------------------------------------
void PagingLandScapeRenderable::_getNormalAt( int x, int z, Vector3 * result )
{
// TODO: Interpolate the normal between pages.
Vector3 left, bottom, top, right;
float y = mPageData2D->getHeight( x, z );
float page_end = PagingLandScapeOptions::getSingleton().PageSize - 1;
// left vertex
if ( x > 0 )
{
left.y = mPageData2D->getHeight( x - 1, z );
}
else // a fake left vertex at the same slope as center - right
{
left.y = y * 2 - mPageData2D->getHeight( 1, z );
}
left.x = -1;
left.z = 0;
// right vertex
if ( x < page_end)
{
right.y = mPageData2D->getHeight( x + 1, z );
}
else // a fake right vertex at the same slope as left - center
{
right.y = y * 2 - mPageData2D->getHeight( page_end - 1, z );
}
right.x = 1;
right.z = 0;
// Bottom Vertex
if ( z > 0 )
{
bottom.y = mPageData2D -> getHeight( x, z - 1 );
}
else // a fake bottom vertex at the same slope as center - top
{
bottom.y = y * 2 - mPageData2D -> getHeight( x, 1 );
}
bottom.z = -1;
bottom.x = 0;
// Top Vertex
if ( z < page_end)
{
top.y = mPageData2D -> getHeight( x, z + 1 );
}
else // a fake top vertex at the same slope as bottom - center
{
top.y = y * 2 - mPageData2D -> getHeight( x, page_end - 1);
}
top.z = 1;
top.x = 0;
Vector3 normal = Vector3(0,0,0);
normal.x -= (top.y - left.y) * (top.z + left.z);
normal.y -= (top.z - left.z) * (top.x + left.x);
normal.z -= (top.x - left.x) * (top.y + left.y);
normal.x -= (left.y - bottom.y) * (left.z + bottom.z);
normal.y -= (left.z - bottom.z) * (left.x + bottom.x);
normal.z -= (left.x - bottom.x) * (left.y + bottom.y);
normal.x -= (bottom.y - right.y) * (bottom.z + right.z);
normal.y -= (bottom.z - right.z) * (bottom.x + right.x);
normal.z -= (bottom.x - right.x) * (bottom.y + right.y);
normal.x -= (right.y - top.y) * (right.z + top.z);
normal.y -= (right.z - top.z) * (right.x + top.x);
normal.z -= (right.x - top.x) * (right.y + top.y);
normal.normalise();
*result = normal;
}
//-----------------------------------------------------------------------
void PagingLandScapeRenderable::Morph( )
{
if ( mInUse == true )
{
if ( mMorphStatus == MORPHING )
{
// Lock the Vertices
HardwareVertexBufferSharedPtr vVertices = mRend.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
Real *pVertices = static_cast<Real*>( vVertices->lock( HardwareBuffer::HBL_NORMAL ) );
pVertices[ 19 ] += mMorphStep[ 0 ];
pVertices[ 22 ] += mMorphStep[ 1 ];
pVertices[ 25 ] += mMorphStep[ 2 ];
pVertices[ 34 ] += mMorphStep[ 3 ];
pVertices[ 40 ] += mMorphStep[ 4 ];
pVertices[ 49 ] += mMorphStep[ 5 ];
pVertices[ 52 ] += mMorphStep[ 6 ];
pVertices[ 55 ] += mMorphStep[ 7 ];
// pVertices[ 4 ] += mMorphStep[ 8 ];
// pVertices[ 10 ] += mMorphStep[ 9 ];
// pVertices[ 16 ] += mMorphStep[ 10 ];
// pVertices[ 28 ] += mMorphStep[ 11 ];
// pVertices[ 46 ] += mMorphStep[ 12 ];
// pVertices[ 58 ] += mMorphStep[ 13 ];
// pVertices[ 64 ] += mMorphStep[ 14 ];
// pVertices[ 70 ] += mMorphStep[ 15 ];
// Unlock the vertices
vVertices->unlock();
mNumMorph += 1;
if ( mNumMorph < mMaxMorphSteps )
{
PagingLandScapeRenderableManager::getSingleton().needMorph( this );
}
else
{
mMorphStatus = MORPHED;
}
}
else if ( mMorphStatus == DEMORPHING )
{
// Lock the Vertices
HardwareVertexBufferSharedPtr vVertices = mRend.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
Real *pVertices = static_cast<Real*>( vVertices->lock( HardwareBuffer::HBL_NORMAL ) );
pVertices[ 19 ] -= mMorphStep[ 0 ];
pVertices[ 22 ] -= mMorphStep[ 1 ];
pVertices[ 25 ] -= mMorphStep[ 2 ];
pVertices[ 34 ] -= mMorphStep[ 3 ];
pVertices[ 40 ] -= mMorphStep[ 4 ];
pVertices[ 49 ] -= mMorphStep[ 5 ];
pVertices[ 52 ] -= mMorphStep[ 6 ];
pVertices[ 55 ] -= mMorphStep[ 7 ];
// pVertices[ 4 ] -= mMorphStep[ 8 ];
// pVertices[ 10 ] -= mMorphStep[ 9 ];
// pVertices[ 16 ] -= mMorphStep[ 10 ];
// pVertices[ 28 ] -= mMorphStep[ 11 ];
// pVertices[ 46 ] -= mMorphStep[ 12 ];
// pVertices[ 58 ] -= mMorphStep[ 13 ];
// pVertices[ 64 ] -= mMorphStep[ 14 ];
// pVertices[ 70 ] -= mMorphStep[ 15 ];
// Unlock the vertices
vVertices->unlock();
mNumMorph -= 1;
if ( mNumMorph > 0 )
{
PagingLandScapeRenderableManager::getSingleton().needDeMorph( this );
}
else
{
mMorphStatus = DEMORPHED;
}
}
}
}
//-----------------------------------------------------------------------
void PagingLandScapeRenderable::StartMorphing()
{
// Lock the Vertices
HardwareVertexBufferSharedPtr vVertices = mRend.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
Real *pVertices = static_cast<Real*>( vVertices->lock( HardwareBuffer::HBL_NORMAL ) );
// Start the Morphin data
_buildMorph( pVertices, 0, 19, 1, 37 );
_buildMorph( pVertices, 1, 22, 7, 37 );
_buildMorph( pVertices, 2, 25, 7, 43 );
_buildMorph( pVertices, 3, 34, 31, 37 );
_buildMorph( pVertices, 4, 40, 37, 43 );
_buildMorph( pVertices, 5, 49, 31, 67 );
_buildMorph( pVertices, 6, 52, 37, 67 );
_buildMorph( pVertices, 7, 55, 37, 73 );
// _buildMorph( pVertices, 8, 4, 1, 7 );
// _buildMorph( pVertices, 9, 10, 7, 13 );
// _buildMorph( pVertices, 10, 16, 1, 31 );
// _buildMorph( pVertices, 11, 28, 13, 43 );
// _buildMorph( pVertices, 12, 46, 31, 61 );
// _buildMorph( pVertices, 13, 58, 43, 73 );
// _buildMorph( pVertices, 14, 64, 61, 67 );
// _buildMorph( pVertices, 15, 70, 67, 73 );
// Unlock the vertices
vVertices->unlock();
setMorphStatus( MORPHING );
}
//-----------------------------------------------------------------------
void PagingLandScapeRenderable::_buildMorph( Real *pVertices, int index, int vert, int vert1, int vert2 )
{
if (mMaxMorphSteps != 0)
{
Real l_Ini, l_End;
l_End = pVertices[ vert ];
if ( pVertices[ vert1 ] > pVertices[ vert2 ] )
{
l_Ini = pVertices[ vert2 ] + ( pVertices[ vert1 ] - pVertices[ vert2 ] ) / 2;
}
else
{
l_Ini = pVertices[ vert1 ] + ( pVertices[ vert2 ] - pVertices[ vert1 ] ) /2;
}
mMorphStep[ index ] = ( l_End - l_Ini ) / mMaxMorphSteps;
pVertices[ vert ] = l_Ini;
}
else
{
mMorphStep[ index ] = 0;
}
}
//-----------------------------------------------------------------------
PagingLandScapeRenderable::eMorphStatus PagingLandScapeRenderable::getMorphStatus()
{
return mMorphStatus;
}
//-----------------------------------------------------------------------
void PagingLandScapeRenderable::setMorphStatus( PagingLandScapeRenderable::eMorphStatus e )
{
if ( e == MORPHING )
{
if ( mNivel <= 3 )
{
mMorphStatus = e;
mNumMorph = 0;
// Add this renderable to the Morphing Queue
PagingLandScapeRenderableManager::getSingleton().needMorph( this );
}
else
{
mMorphStatus = MORPHED;
}
}
else
{
if ( e == DEMORPHING )
{
if ( mNivel <= 3 )
{
mMorphStatus = e;
mNumMorph = mMaxMorphSteps;
// Add this renderable to the Morphing Queue
PagingLandScapeRenderableManager::getSingleton().needDeMorph( this );
}
else
{
mMorphStatus = DEMORPHED;
}
}
}
}
//-----------------------------------------------------------------------
//JEFF
float PagingLandScapeRenderable::getRealWorldHeight(PagingLandScapePageData2D* Data, float x, float z, int render_size)
{
// find the 4 vertices that surround the point
// use LOD info to determine vertex spacing - this is passed into the method
// determine vertices on left and right of point and top and bottom
// don't access VBO since a big performance hit when only 4 vertices are needed
int vertex_spread = render_size / 4;
// find the vertex to the bottom left of the point
int bottom_left_x = ((int)(x / vertex_spread)) * vertex_spread;
int bottom_left_z = ((int)(z / vertex_spread)) * vertex_spread;
// find the 4 heights around the point
float bottom_left_y = (float)(Data -> getHeight(bottom_left_x, bottom_left_z));
float bottom_right_y = (float)(Data -> getHeight(bottom_left_x + vertex_spread, bottom_left_z));
float top_left_y = (float)(Data -> getHeight(bottom_left_x, bottom_left_z + vertex_spread));
float top_right_y = (float)(Data -> getHeight(bottom_left_x + vertex_spread, bottom_left_z + vertex_spread));
float x_pct = (x - (float)bottom_left_x) / (float)vertex_spread;
float z_pct = (z - (float)bottom_left_z) / (float)vertex_spread;
//bilinear interpolate to find the height.
// figure out which 3 vertices are closest to the point and use those to form triangle plane for intersection
// Triangle strip has diagonal going from bottom left to top right
if ((x_pct - z_pct) >= 0)
{
return (bottom_left_y + (bottom_right_y - bottom_left_y ) * x_pct + (top_right_y - bottom_right_y) * z_pct);
}
else
{
return (top_left_y + (top_right_y - top_left_y ) * x_pct + (bottom_left_y - top_left_y) * (1 - z_pct));
}
}
//-----------------------------------------------------------------------
const float PagingLandScapeRenderable::getError()
{
return mError;
}
//-----------------------------------------------------------------------
void PagingLandScapeRenderable::_buildError( const float offSetX, const float offSetZ, const int step )
{
int midStep = step / 2;
Real diff;
mError = 0;
for ( int k = offSetZ; k < offSetZ + step * 3; k += step )
{
for ( int i = offSetX; i < offSetX + step * 3; i += step )
{
diff = mPageData2D->getError( i, k, i + step, k + step ) * mScale.y;
if ( mError < diff )
{
mError = diff;
}
}
}
}
} //namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -