📄 ogrepaginglandscapedata2dmanager.cpp
字号:
localZ = pSize;
// 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 = 1 << Lod;
// find the vertex to the bottom left of the point
int bottom_left_x = ((int)(localX / vertex_spread)) * vertex_spread;
int bottom_left_z = ((int)(localZ / vertex_spread)) * vertex_spread;
// find the 4 heights around the point
PagingLandScapeData2D* data = mData2D[ pageX ][ pageZ ];
float bottom_left_y = data->getHeight(bottom_left_x , bottom_left_z);
float bottom_right_y = data->getHeight(bottom_left_x + vertex_spread, bottom_left_z);
float top_left_y = data->getHeight(bottom_left_x , bottom_left_z + vertex_spread);
float top_right_y = data->getHeight(bottom_left_x + vertex_spread, bottom_left_z + vertex_spread);
float x_pct = (localX - (float)bottom_left_x) / (float)vertex_spread;
float z_pct = (localZ - (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)));
}
}
//-----------------------------------------------------------------------
//JEFF
const float PagingLandScapeData2DManager::getRealWorldHeight(const float x, const float z,
PagingLandScapeTileInfo* info)
{
// figure out which page the point is on
uint dataX = info->pageX;
uint dataZ = info->pageZ;
if ( ! (mData2D[ dataX ][ dataZ ]->isLoaded()))
return 0.0f;
PagingLandScapeTile *t = PagingLandScapePageManager::getSingleton().getPage (dataX, dataZ )->getTile (info->tileX, info->tileZ);
uint Lod = 0;
if (t && t->isLoaded ())
Lod = t->getRenderable ()->mRenderLevel;
return getRealPageHeight (x, z, dataX, dataZ, Lod);
}
//-----------------------------------------------------------------------
//JEFF
const float PagingLandScapeData2DManager::getRealWorldHeight(const float x, const float z)
{
// figure out which page the point is on
const Vector3 pos (x, 0, z);
uint dataX, dataZ;
getPageIndices(pos, dataX, dataZ);
if ( !(mData2D[ dataX ][ dataZ ]->isLoaded()))
return 0.0f;
// figure out which tile the point is on
PagingLandScapeTile *t = PagingLandScapePageManager::getSingleton().getTile (pos, dataX, dataZ);
uint Lod = 0;
if (t && t->isLoaded ())
Lod = t->getRenderable ()->mRenderLevel;
return getRealPageHeight (x, z, dataX, dataZ, Lod);
}
//-----------------------------------------------------------------------
const float PagingLandScapeData2DManager::getHeightAtPage(const uint dataX, const uint dataZ,
const float x, const float z)
{
PagingLandScapeData2D* data = mData2D[ dataX ][ dataZ ];
if ( data->isLoaded() )
{
Real lX = x;
Real lZ = z;
Real pSize = PagingLandScapeOptions::getSingleton().PageSize - 1;
//check if we have to change current page
if ( lX < 0.0f )
{
if ( dataX == 0 )
lX = 0.0f;
else
{
data = mData2D[ dataX - 1 ][ dataZ ];
if ( data->isLoaded() )
{
lX = Real (pSize - 1);
}
else
{
lX = 0.0f;
data = mData2D[ dataX ][ dataZ ];
}
}
}
else if (lX > pSize)
{
if ( dataX == PagingLandScapeOptions::getSingleton().world_width - 1 )
lX = Real (pSize);
else
{
data = mData2D[ dataX + 1 ][ dataZ ];
if ( data->isLoaded() )
{
lX = 0.0f;
}
else
{
lX = Real (pSize);
data = mData2D[ dataX ][ dataZ ];
}
}
}
if ( lZ < 0.0f )
{
if ( dataZ == 0 )
lZ = 0.0f;
else
{
data = mData2D[ dataX ][ dataZ - 1 ];
if ( data->isLoaded() )
{
lZ = Real (pSize);
}
else
{
lZ = 0.0f;
data = mData2D[ dataX ][ dataZ ];
}
}
}
else if (lZ > pSize)
{
if ( dataZ == PagingLandScapeOptions::getSingleton().world_height - 1)
lZ = Real (pSize);
else
{
data = mData2D[ dataX ][ dataZ + 1 ];
if ( data->isLoaded() )
{
lZ = 0.0f;
}
else
{
lZ = Real (pSize);
data = mData2D[ dataX ][ dataZ ];
}
}
}
return data->getHeight (lX, lZ);
}
return 0.0f;
}
//-----------------------------------------------------------------------
const float PagingLandScapeData2DManager::getHeightAtPage(const uint dataX, const uint dataZ,
const int x, const int z)
{
PagingLandScapeData2D* data = mData2D[ dataX ][ dataZ ];
if ( data->isLoaded() )
{
int lX = x;
int lZ = z;
int pSize = PagingLandScapeOptions::getSingleton().PageSize - 1;
//check if we have to change current page
if ( lX < 0 )
{
if ( dataX == 0 )
lX = 0;
else
{
data = mData2D[ dataX - 1 ][ dataZ ];
if ( data->isLoaded() )
{
lX = pSize;
}
else
{
lX = 0;
data = mData2D[ dataX ][ dataZ ];
}
}
}
else if (lX > pSize)
{
if ( dataX == PagingLandScapeOptions::getSingleton().world_width - 1)
lX = pSize;
else
{
data = mData2D[ dataX + 1 ][ dataZ ];
if ( data->isLoaded() )
{
lX = 0;
}
else
{
lX = pSize;
data = mData2D[ dataX ][ dataZ ];
}
}
}
if ( lZ < 0 )
{
if ( dataZ == 0 )
lZ = 0;
else
{
data = mData2D[ dataX ][ dataZ - 1 ];
if ( data->isLoaded() )
{
lZ = pSize;
}
else
{
lZ = 0;
data = mData2D[ dataX ][ dataZ ];
}
}
}
else if (lZ > pSize)
{
if ( dataZ == PagingLandScapeOptions::getSingleton().world_height - 1)
lZ = pSize;
else
{
data = mData2D[ dataX ][ dataZ + 1 ];
if ( data->isLoaded() )
{
lZ = 0;
}
else
{
lZ = pSize;
data = mData2D[ dataX ][ dataZ ];
}
}
}
return data->getHeight (lX, lZ);
}
return 0.0f;
}
//-----------------------------------------------------------------------
const Vector3 PagingLandScapeData2DManager::getNormalAt( const uint dataX, const uint dataZ,
const float x, const float z)
{
PagingLandScapeData2D* data = mData2D[ dataX ][ dataZ ];
if ( data->isLoaded() )
{
#ifdef _LOADEDNORM
// not as precise (rgb normals gives 8 bits precision float)
// and finally nearly as fast.
return data->getNormalAt (x, z);
#else /*_LOADEDNORM*/
{
// First General method : (9 adds and 6 muls + a normalization)
// *---v3--*
// | | |
// | | |
// v1--X--v2
// | | |
// | | |
// *---v4--*
//
// U = v2 - v1;
// V = v4 - v3;
// N = Cross(U, V);
// N.normalise;
//
// BUT IN CASE OF A HEIGHTMAP :
//
// if you do some math by hand before you code,
// you can see that N is immediately given by
// Approximation (2 adds and a normalization)
//
// N = Vector3(z[x-1][y] - z[x+1][y], z[x][y-1] - z[x][y+1], 2);
// N.normalise();
//
// or even using SOBEL operator VERY accurate!
// (14 adds and a normalization)
//
// N = Vector3 (z[x-1][y-1] + z[x-1][y] + z[x-1][y] + z[x-1][y+1] - z[x+1][y-1] - z[x+1][y] - z[x+1][y] - z[x+1][y+1],
// z[x-1][y-1] + z[x][y-1] + z[x][y-1] + z[x+1][y-1] - z[x-1][y+1] - z[x][y+1] - z[x][y+1] - z[x+1][y+1],
// 8);
// N.normalize();
// Fast SOBEL filter
#define gH(a, b) this->getHeightAtPage(dataX, dataZ, a,b)
// Vector3 result (gH(x-1,z-1) + gH (x-1, z) + gH (x-1, z) + gH (x-1, z+1) - gH (x+1, z-1) - gH (x+1, z) - gH (x+1, z) - gH (x+1, z+1),
// 8.0f,
// gH (x-1, z-1) + gH (x, z-1) + gH (x, z-1) + gH (x+1, z-1) - gH (x-1, z+1) - gH (x, z+1) - gH (x, z+1) - gH (x+1, z+1));
Vector3 result (gH (x - 1.0f , z) - gH (x + 1.0f , z),
2.0f,
gH (x, z - 1) - gH (x , z + 1.0f ));
result.normalise ();
return result;
}
#endif //_NOLOAD
}
return Vector3::UNIT_Y;
}
// JEFF
//----------------------------------------------------------------------------
/// method takes an UP vector and determines the indexes for the page the UP vector would be in
void PagingLandScapeData2DManager::getPageIndices(const Vector3& pos, uint& x, uint& z)
{
uint w = PagingLandScapeOptions::getSingleton().world_width;
uint h = PagingLandScapeOptions::getSingleton().world_height;
x = (uint)(pos.x / PagingLandScapeOptions::getSingleton().scale.x / (PagingLandScapeOptions::getSingleton().PageSize - 1.0) + w * 0.5f);
z = (uint)(pos.z / PagingLandScapeOptions::getSingleton().scale.z / (PagingLandScapeOptions::getSingleton().PageSize - 1.0) + h * 0.5f);
// make sure indices are not negative or outside range of number of pages
if (x >= w)
{
x = w - 1;
}
if (z >= h)
{
z = h - 1;
}
}
PagingLandScapeData2D *PagingLandScapeData2DManager::getData2d (const uint x, const uint z)
{
PagingLandScapeData2D *data = mData2D[ x ][ z ];
return ( data->isLoaded() )? data: 0;
}
} //namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -