📄 naturepatchmanager.cpp
字号:
/*****************************************************************************
File: NaturePatchManager.cpp
Desc:
Date: 2003/02/22
Author: Martin Persson
*****************************************************************************/
#include "NaturePatch.h"
#include "NatureTerrainPatch.h"
#include "NaturePatchManager.h"
namespace Ogre
{
//----------------------------------------------------------------------------
template<> NaturePatchManager* Singleton<NaturePatchManager>::ms_Singleton = 0;
NaturePatchManager* NaturePatchManager::getSingletonPtr(void)
{
return ms_Singleton;
}
NaturePatchManager& NaturePatchManager::getSingleton(void)
{
assert( ms_Singleton ); return ( *ms_Singleton );
}
//----------------------------------------------------------------------------
NaturePatchManager::NaturePatchManager()
: mDataBuffer(0)
{
mInited = false;
mQuadNodeLookup = 0;
mNorthNeighbor = mSouthNeighbor = mWestNeighbor = mEastNeighbor = 0;
mNorthEdgeQuad = mSouthEdgeQuad = mWestEdgeQuad = mEastEdgeQuad = 0;
mIndexBuffer = mVertexLookup = 0;
mMinimumQuality = 10.0f;
mTargetQuality = 5.0f;
for (int i = 0; i < 324; i++)
mPatches[i] = 0;
}
//----------------------------------------------------------------------------
NaturePatchManager::~NaturePatchManager()
{
// delete lookup tables
freeLookupTables();
// delete shared buffers
freeSharedBuffers();
for (int i = 0; i < 324; i++)
{
if (mPatches[i] != 0)
{
mMapLoader->releaseData(mPatches[i]->mData);
delete mPatches[i];
}
}
}
//----------------------------------------------------------------------------
Material *NaturePatchManager::createTerrainMaterial()
{
#if 0
static int count = 0;
// START TEST!!!
Material *mMaterial = mSceneRoot->getCreator()->createMaterial("NatureQuadMaterial" + toString(count++));
#if USE_TEXTURES
TextureUnitState *layer;
layer = mMaterial->addTextureLayer("grass_1024.jpg", 0);
layer->setColourOperation(LBO_REPLACE);
layer = mMaterial->addTextureLayer("terr_dirt-grass.jpg", 0);
layer->setColourOperationEx(LBX_BLEND_DIFFUSE_COLOUR, LBS_TEXTURE, LBS_CURRENT);
layer->setTextureScale(0.5, 0.5);
layer = mMaterial->addTextureLayer("snow_1024.jpg", 0);
layer->setColourOperationEx(LBX_BLEND_DIFFUSE_ALPHA, LBS_TEXTURE, LBS_CURRENT);
layer->setTextureScale(0.5, 0.5);
layer = mMaterial->addTextureLayer("lightmap_test.jpg", 1);
layer->setColourOperationEx(LBX_MODULATE, LBS_TEXTURE, LBS_CURRENT);
/* // test...
layer = mMaterial->addTextureLayer("grass_1024.jpg", 0);
layer = mMaterial->addTextureLayer("grass_blend.png", 0);
layer->setColourOperationEx(LBX_BLEND_TEXTURE_ALPHA, LBS_TEXTURE, LBS_CURRENT);
layer = mMaterial->addTextureLayer("terr_rock6.jpg", 0);
layer->setColourOperationEx(LBX_BLEND_CURRENT_ALPHA, LBS_TEXTURE, LBS_CURRENT);
*/
#endif
#if USE_NORMALS
mMaterial->setLightingEnabled(true);
// mMaterial->setShadingMode(SO_PHONG);
#else
mMaterial->setLightingEnabled(false);
#endif
// mMaterial->setTextureFiltering(TFO_NONE);
return mMaterial;
#endif
return 0;
}
//----------------------------------------------------------------------------
bool NaturePatchManager::initialise(SceneNode *sceneRoot,
NaturePatchLoader *loader)
{
if (!mInited)
{
mSceneRoot = sceneRoot;
mMapLoader = loader;
if (!initLookupTables())
return false;
if (!initSharedBuffers())
{
freeLookupTables();
return false;
}
// get the map and zone size
mMapSize = loader->getMapSize();
mZoneSize = loader->getZoneSize();
mPageSize = 17; // get this from loader
// set to some some large value will force reload of all patches
mCenterPatchX = -10000000;
mCenterPatchY = -10000000;
mInited = true;
}
return true;
}
//----------------------------------------------------------------------------
void NaturePatchManager::freeLookupTables()
{
// delete lookup tables
if (mQuadNodeLookup != 0)
delete[] mQuadNodeLookup;
if (mNorthNeighbor != 0)
delete[] mNorthNeighbor;
if (mSouthNeighbor != 0)
delete[] mSouthNeighbor;
if (mWestNeighbor != 0)
delete[] mWestNeighbor;
if (mEastNeighbor != 0)
delete[] mEastNeighbor;
if (mNorthEdgeQuad != 0)
delete[] mNorthEdgeQuad;
if (mSouthEdgeQuad != 0)
delete[] mSouthEdgeQuad;
if (mWestEdgeQuad != 0)
delete[] mWestEdgeQuad;
if (mEastEdgeQuad != 0)
delete[] mEastEdgeQuad;
// clear the pointers
mQuadNodeLookup = 0;
mNorthNeighbor = mSouthNeighbor = mWestNeighbor = mEastNeighbor = 0;
mNorthEdgeQuad = mSouthEdgeQuad = mWestEdgeQuad = mEastEdgeQuad = 0;
}
//----------------------------------------------------------------------------
bool NaturePatchManager::initLookupTables()
{
// allocate new memory for the lookup tables
mQuadNodeLookup = new short[QUADTREE_SIZE * QUADTREE_SIZE];
mNorthNeighbor = new short[QUADTREE_NODES];
mSouthNeighbor = new short[QUADTREE_NODES];
mWestNeighbor = new short[QUADTREE_NODES];
mEastNeighbor = new short[QUADTREE_NODES];
mSouthEdgeQuad = new short[QUADTREE_NODES];
mNorthEdgeQuad = new short[QUADTREE_NODES];
mWestEdgeQuad = new short[QUADTREE_NODES];
mEastEdgeQuad = new short[QUADTREE_NODES];
if (mQuadNodeLookup == 0 || mNorthNeighbor == 0 ||
mSouthNeighbor == 0 || mWestNeighbor == 0 ||
mEastNeighbor == 0 || mNorthEdgeQuad == 0 ||
mSouthEdgeQuad == 0 || mWestEdgeQuad == 0 ||
mEastEdgeQuad == 0)
{
freeLookupTables();
return false;
}
// clear the quad node lookup table
memset(mQuadNodeLookup, 0, sizeof(short)*QUADTREE_SIZE*QUADTREE_SIZE);
// calculate lookup table for quad nodes
computeQuadLookup(EDGE_LENGTH / 2, EDGE_LENGTH / 2, 0, 0);
// calculate neighbor lookup tables
computeNeighborLookup(EDGE_LENGTH / 2, EDGE_LENGTH / 2, 0, 0);
return true;
}
//----------------------------------------------------------------------------
void NaturePatchManager::freeSharedBuffers()
{
// delete shared buffers
if (mDataBuffer != 0)
delete[] mDataBuffer;
if (mIndexBuffer != 0)
delete[] mIndexBuffer;
if (mVertexLookup != 0)
delete[] mVertexLookup;
// clear the pointers
mDataBuffer = 0;
mIndexBuffer = mVertexLookup = 0;
}
//----------------------------------------------------------------------------
bool NaturePatchManager::initSharedBuffers()
{
// allocate new memory for shared buffers
mDataBuffer = new Real[QUADTREE_SIZE * QUADTREE_SIZE * (3 + 3 + 4)];
mIndexBuffer = new ushort[EDGE_LENGTH * EDGE_LENGTH * 2 * 3];
mVertexLookup = new ushort[QUADTREE_SIZE * QUADTREE_SIZE];
// return false if allocation failed
if (mDataBuffer == 0 || mIndexBuffer == 0 || mVertexLookup == 0)
{
freeSharedBuffers();
return false;
}
return true;
}
//----------------------------------------------------------------------------
void NaturePatchManager::computeQuadLookup(int cx, int cz, int node, int level)
{
// if not at lowest level, descend into children
if (level < (QUADTREE_DEPTH - 1))
{
int w4 = EDGE_LENGTH >> (level + 2);
// northwest child
computeQuadLookup(cx - w4, cz - w4, (node<<2)+1, level+1);
// northeast child
computeQuadLookup(cx + w4, cz - w4, (node<<2)+2, level+1);
// southwest child
computeQuadLookup(cx - w4, cz + w4, (node<<2)+3, level+1);
// southeast child
computeQuadLookup(cx + w4, cz + w4, (node<<2)+4, level+1);
}
mQuadNodeLookup[cz * QUADTREE_SIZE + cx] = node;
}
//----------------------------------------------------------------------------
void NaturePatchManager::computeNeighborLookup(int cx,int cz,int node,int level)
{
int nx, nz, nIdx;
int width = EDGE_LENGTH >> level;
// calculate index of north neighbor
nx = cx;
nz = cz - width;
nIdx = (nz * QUADTREE_SIZE) + nx;
if (nz < 0)
{
nIdx += EDGE_LENGTH * QUADTREE_SIZE;
mNorthNeighbor[node] = -mQuadNodeLookup[nIdx];
mNorthEdgeQuad[cx] = node;
}
else
mNorthNeighbor[node] = mQuadNodeLookup[nIdx];
// calculate index of south neighbor
nx = cx;
nz = cz + width;
nIdx = (nz * QUADTREE_SIZE) + nx;
if (nz > EDGE_LENGTH)
{
nIdx -= EDGE_LENGTH * QUADTREE_SIZE;
mSouthNeighbor[node] = -mQuadNodeLookup[nIdx];
mSouthEdgeQuad[cx] = node;
}
else
mSouthNeighbor[node] = mQuadNodeLookup[nIdx];
// calculate index of west neighbor
nx = cx - width;
nz = cz;
nIdx = (nz * QUADTREE_SIZE) + nx;
if (nx < 0)
{
nIdx += EDGE_LENGTH;
mWestNeighbor[node] = -mQuadNodeLookup[nIdx];
mWestEdgeQuad[cz] = node;
}
else
mWestNeighbor[node] = mQuadNodeLookup[nIdx];
// calculate index of east neighbor
nx = cx + width;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -