⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 naturepatchmanager.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************

	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 + -