#include "Terrain.h"
TerrainBlock* TerrainBlock::mCenterBlock = NULL;
TerrainBlock::TerrainBlock(const NxString& name, const NxOgre::Pose& pose, Shape* shape,
Scene* scene, const NodeRenderableParams& visualParams, const ActorParams& params)
: Actor(name, scene, shape, pose, params)
{
mLowPolyMesh = NULL;
mHighPolyMesh = NULL;
mNorthBlock = NULL;
mEastBlock = NULL;
mSouthBlock = NULL;
mWestBlock = NULL;
mTypeHash = 004;
mStringType = "TerrainBlock";
mScene = scene;
// Create the NodeRenderable based on the Params. The outcome is
// based on the Renderer used (specified in the Scene).
mRenderable = mOwner->getSceneRenderer()->createNodeRenderable(visualParams);
mNodeRenderable = static_cast(mRenderable);
mVoidPointer->RenderPtr = this;
setRenderMode(RM_Interpolate);
// You can use the NodeRenderable functions to mirror most or if
// not all of the actual RenderSystem's NodeRenderable functions
// but in some instances you can't. But you can cast it into another,
// if you have to.
if (mNodeRenderable->getHashType() == NxOgreClass_OgreNodeRenderable)
mOgreNodeRenderable = static_cast(mNodeRenderable);
mOwner->getSceneRenderer()->registerSource(this);
this->setActive( false );
mOgreNodeRenderable->removeEntity( this->getName() );
}
TerrainBlock::TerrainBlock(const VisualIdentifier& vi, const NxOgre::Pose& pose, Shape* shape,
Scene* scene, const ActorParams& params)
: Actor(vi.getIdentifier(), scene, shape, pose, params)
{
mLowPolyMesh = NULL;
mHighPolyMesh = NULL;
mNorthBlock = NULL;
mEastBlock = NULL;
mSouthBlock = NULL;
mWestBlock = NULL;
mTypeHash = 004;
mStringType = "TerrainBlock";
mScene = scene;
NodeRenderableParams renderParams;
renderParams.setToDefault();
renderParams.mGraphicsModel = vi.getVisualIdentifier();
renderParams.mGraphicsModelScale = NxVec3(1, 1, 1);
renderParams.mIdentifier = vi.getIdentifier();
renderParams.mIdentifierUsage = renderParams.IU_Use;
renderParams.mMode = RenderableSource::RM_Interpolate;
mRenderable = mOwner->getSceneRenderer()->createNodeRenderable( renderParams );
mNodeRenderable = static_cast(mRenderable);
mVoidPointer->RenderPtr = this;
setRenderMode(RM_Absolute);
if (mNodeRenderable->getHashType() == NxOgreClass_OgreNodeRenderable)
mOgreNodeRenderable = static_cast(mNodeRenderable);
mOwner->getSceneRenderer()->registerSource(this);
this->setActive( false );
mOgreNodeRenderable->removeEntity( this->getName() );
}
TerrainBlock::~TerrainBlock()
{
mOgreNodeRenderable->getNode()->removeAndDestroyAllChildren();
if( mLowPolyMesh )
{
delete mLowPolyMesh;
mLowPolyMesh = 0;
}
if( mHighPolyMesh )
{
delete mHighPolyMesh;
mHighPolyMesh = 0;
}
mOwner->getSceneRenderer()->unregisterSource(this);
if (mRenderable)
{
delete mRenderable;
mRenderable = 0;
}
//destroyed in GameActorFactory via SharedList
mNorthBlock = 0;
mSouthBlock = 0;
mEastBlock = 0;
mWestBlock = 0;
mCenterBlock = 0;
//destroyed in main app
mSceneMgr = 0;
mScene = 0;
}
void TerrainBlock::initialize( String north, String east, String south, String west )
{
mNorthBlockName = north;
mEastBlockName = east;
mSouthBlockName = south;
mWestBlockName = west;
}
void TerrainBlock::connectTheBlocks()
{
if( mNorthBlockName != "" )
{
mNorthBlock = (TerrainBlock*)mScene->getActor( mNorthBlockName );
if( mNorthBlock == NULL )
{
LogManager::getSingleton().logMessage( "[Error]TerrainBlock '" + getName()
+ "' tried to connect north to invalid actor name: " + mNorthBlockName );
}
}
if( mEastBlockName != "" )
{
mEastBlock = (TerrainBlock*)mScene->getActor( mEastBlockName );
if( mEastBlock == NULL )
{
LogManager::getSingleton().logMessage( "[Error]TerrainBlock '" + getName()
+ "' tried to connect east to invalid actor name: " + mEastBlockName );
}
}
if( mSouthBlockName != "" )
{
mSouthBlock = (TerrainBlock*)mScene->getActor( mSouthBlockName );
if( mSouthBlock == NULL )
{
LogManager::getSingleton().logMessage( "[Error]TerrainBlock '" + getName()
+ "' tried to connect south to invalid actor name: " + mSouthBlockName );
}
}
if( mWestBlockName != "" )
{
mWestBlock = (TerrainBlock*)mScene->getActor( mWestBlockName );
if( mWestBlock == NULL )
{
LogManager::getSingleton().logMessage( "[Error]TerrainBlock '" + getName()
+ "' tried to connect west to invalid actor name: " + mWestBlockName );
}
}
}
NxOgre::Pose TerrainBlock::getSourcePose(const NxOgre::TimeStep&) const
{
return getGlobalPose();
}
NxShortHashIdentifier TerrainBlock::getType()
{
return mTypeHash;
}
NxString TerrainBlock::getStringType()
{
return mStringType;
}
void TerrainBlock::setType( NxShortHashIdentifier newHash )
{
mTypeHash = newHash;
}
void TerrainBlock::setStringType( NxString newStringType )
{
mStringType = newStringType;
}
void TerrainBlock::setLowPolyMesh( Entity* newLowPolyMesh )
{
if( newLowPolyMesh != NULL )
{
if( mLowPolyMesh != NULL )
{
mOgreNodeRenderable->destroyEntity( mLowPolyMesh );
}
mLowPolyMesh = newLowPolyMesh;
if( !mHighPolyMesh->isAttached() )
{
mOgreNodeRenderable->addEntity( mLowPolyMesh );
}
}
}
void TerrainBlock::setHighPolyMesh( Entity* newHighPolyMesh )
{
if( newHighPolyMesh != NULL )
{
if( mHighPolyMesh != NULL )
{
mOgreNodeRenderable->destroyEntity( mHighPolyMesh );
}
mHighPolyMesh = newHighPolyMesh;
if(( mLowPolyMesh != NULL && !mLowPolyMesh->isAttached()) || mLowPolyMesh == NULL )
{
mOgreNodeRenderable->addEntity( mHighPolyMesh );
}
}
}
void TerrainBlock::setActive( bool isActive )
{
mIsActive = isActive;
//Low poly meshes are optional for each block
if( !mIsActive )
{
if( mLowPolyMesh != NULL && !mLowPolyMesh->isAttached() )
{
this->mOgreNodeRenderable->addEntity( mLowPolyMesh );
this->mOgreNodeRenderable->removeEntity( mHighPolyMesh );
}
}
else
{
if( mLowPolyMesh != NULL && !mLowPolyMesh->isAttached() )
{
this->mOgreNodeRenderable->addEntity( mHighPolyMesh );
this->mOgreNodeRenderable->removeEntity( mLowPolyMesh );
}
}
}
bool TerrainBlock::isCenter()
{
bool isCenter = false;
if( this == mCenterBlock )
{
isCenter = true;
}
return isCenter;
}
bool TerrainBlock::getActive()
{
return mIsActive;
}
void TerrainBlock::disableDirection( TerrainBlock* block, OrdinalDirections direction )
{
//Warning: this function is recursive. Be careful if you mess with the anchor.
if( block != NULL )
{
block->setActive( false );
switch( direction )
{
case DIR_NORTH:
if( block->mNorthBlock != NULL && block->mNorthBlock->getActive() )
{
disableDirection( block->mNorthBlock, DIR_NORTH );
block->mNorthBlock->setActive( false );
}
if( block->mEastBlock != NULL && block->mEastBlock->getActive() )
{
disableDirection( block->mEastBlock, DIR_NORTH );
block->mEastBlock->setActive( false );
}
if( block->mWestBlock != NULL && block->mWestBlock->getActive() )
{
disableDirection( block->mWestBlock, DIR_NORTH );
block->mWestBlock->setActive( false );
}
break;
case DIR_EAST:
if( block->mEastBlock != NULL && block->mEastBlock->getActive() )
{
disableDirection( block->mEastBlock, DIR_EAST );
block->mEastBlock->setActive( false );
}
if( block->mNorthBlock != NULL && block->mNorthBlock->getActive() )
{
disableDirection( block->mNorthBlock, DIR_EAST );
block->mNorthBlock->setActive( false );
}
if( block->mSouthBlock != NULL && block->mSouthBlock->getActive() )
{
disableDirection( block->mSouthBlock, DIR_EAST );
block->mSouthBlock->setActive( false );
}
break;
case DIR_SOUTH:
if( block->mSouthBlock != NULL && block->mSouthBlock->getActive() )
{
disableDirection( block->mSouthBlock, DIR_SOUTH );
block->mSouthBlock->setActive( false );
}
if( block->mEastBlock != NULL && block->mEastBlock->getActive() )
{
disableDirection( block->mEastBlock, DIR_SOUTH );
block->mEastBlock->setActive( false );
}
if( block->mWestBlock != NULL && block->mWestBlock->getActive() )
{
disableDirection( block->mWestBlock, DIR_SOUTH );
block->mWestBlock->setActive( false );
}
break;
case DIR_WEST:
if( block->mWestBlock != NULL && block->mWestBlock->getActive() )
{
disableDirection( block->mWestBlock, DIR_WEST );
block->mWestBlock->setActive( false );
}
if( block->mNorthBlock != NULL && block->mNorthBlock->getActive() )
{
disableDirection( block->mNorthBlock, DIR_WEST );
block->mNorthBlock->setActive( false );
}
if( block->mSouthBlock != NULL && block->mSouthBlock->getActive() )
{
disableDirection( block->mSouthBlock, DIR_WEST );
block->mSouthBlock->setActive( false );
}
break;
}
}
}
void TerrainBlock::centerOnThisBlock()
{
if( mCenterBlock != NULL )
{
int direction = -1;
if( mCenterBlock->mNorthBlock == this )
{
direction = DIR_NORTH;
}
else if( mCenterBlock->mEastBlock == this )
{
direction = DIR_EAST;
}
else if( mCenterBlock->mSouthBlock == this )
{
direction = DIR_SOUTH;
}
else if( mCenterBlock->mWestBlock == this )
{
direction = DIR_WEST;
}
if( direction >= 0 )
{
LogManager::getSingleton().logMessage( "**TerrainBlock re-centering on: "
+ this->getName() );
switch( direction )
{
case DIR_NORTH:
if( mCenterBlock->mSouthBlock != NULL )
{
disableDirection( mCenterBlock->mSouthBlock, DIR_SOUTH );
if( mCenterBlock->mEastBlock !=NULL
&& mCenterBlock->mEastBlock->mSouthBlock != NULL )
{
disableDirection( mCenterBlock->mEastBlock->mSouthBlock, DIR_SOUTH );
}
if( mCenterBlock->mWestBlock !=NULL
&& mCenterBlock->mWestBlock->mSouthBlock != NULL )
{
disableDirection( mCenterBlock->mWestBlock->mSouthBlock, DIR_SOUTH );
}
}
if( this->mNorthBlock != NULL )
{
this->mNorthBlock->setActive( true );
if( this->mNorthBlock->mEastBlock != NULL )
{
this->mNorthBlock->mEastBlock->setActive( true );
}
if( this->mNorthBlock->mWestBlock != NULL )
{
this->mNorthBlock->mWestBlock->setActive( true );
}
}
else
{
if( this->mEastBlock != NULL && this->mEastBlock->mNorthBlock != NULL )
{
this->mEastBlock->mNorthBlock->setActive( true );
}
if( this->mWestBlock != NULL && this->mWestBlock->mNorthBlock != NULL )
{
this->mWestBlock->mNorthBlock->setActive( true );
}
}
break;
case DIR_EAST:
if( mCenterBlock->mWestBlock != NULL )
{
disableDirection( mCenterBlock->mWestBlock, DIR_WEST );
if( mCenterBlock->mNorthBlock !=NULL
&& mCenterBlock->mNorthBlock->mWestBlock != NULL )
{
disableDirection( mCenterBlock->mNorthBlock->mWestBlock, DIR_WEST );
}
if( mCenterBlock->mSouthBlock !=NULL
&& mCenterBlock->mSouthBlock->mWestBlock != NULL )
{
disableDirection( mCenterBlock->mSouthBlock->mWestBlock, DIR_WEST );
}
}
if( this->mEastBlock != NULL )
{
this->mEastBlock->setActive( true );
if( this->mEastBlock->mNorthBlock != NULL )
{
this->mEastBlock->mNorthBlock->setActive( true );
}
if( this->mEastBlock->mSouthBlock != NULL )
{
this->mEastBlock->mSouthBlock->setActive( true );
}
}
else
{
if( this->mNorthBlock != NULL && this->mNorthBlock->mEastBlock != NULL )
{
this->mNorthBlock->mEastBlock->setActive( true );
}
if( this->mSouthBlock != NULL && this->mSouthBlock->mEastBlock != NULL )
{
this->mSouthBlock->mEastBlock->setActive( true );
}
}
break;
case DIR_SOUTH:
if( mCenterBlock->mSouthBlock != NULL )
{
disableDirection( mCenterBlock->mNorthBlock, DIR_NORTH );
if( mCenterBlock->mEastBlock !=NULL
&& mCenterBlock->mEastBlock->mNorthBlock != NULL )
{
disableDirection( mCenterBlock->mEastBlock->mNorthBlock, DIR_NORTH );
}
if( mCenterBlock->mWestBlock !=NULL
&& mCenterBlock->mWestBlock->mNorthBlock != NULL )
{
disableDirection( mCenterBlock->mWestBlock->mNorthBlock, DIR_NORTH );
}
}
if( this->mSouthBlock != NULL )
{
this->mSouthBlock->setActive( true );
if( this->mSouthBlock->mEastBlock != NULL )
{
this->mSouthBlock->mEastBlock->setActive( true );
}
if( this->mSouthBlock->mWestBlock != NULL )
{
this->mSouthBlock->mWestBlock->setActive( true );
}
}
else
{
if( this->mEastBlock != NULL && this->mEastBlock->mSouthBlock != NULL )
{
this->mEastBlock->mSouthBlock->setActive( true );
}
if( this->mWestBlock != NULL && this->mWestBlock->mSouthBlock != NULL )
{
this->mWestBlock->mSouthBlock->setActive( true );
}
}
break;
case DIR_WEST:
if( mCenterBlock->mWestBlock != NULL )
{
disableDirection( mCenterBlock->mEastBlock, DIR_EAST );
if( mCenterBlock->mNorthBlock !=NULL
&& mCenterBlock->mNorthBlock->mEastBlock != NULL )
{
disableDirection( mCenterBlock->mNorthBlock->mEastBlock, DIR_EAST );
}
if( mCenterBlock->mSouthBlock !=NULL
&& mCenterBlock->mSouthBlock->mEastBlock != NULL )
{
disableDirection( mCenterBlock->mSouthBlock->mEastBlock, DIR_EAST );
}
}
if( this->mWestBlock != NULL )
{
this->mWestBlock->setActive( true );
if( this->mWestBlock->mNorthBlock != NULL )
{
this->mWestBlock->mNorthBlock->setActive( true );
}
if( this->mWestBlock->mSouthBlock != NULL )
{
this->mWestBlock->mSouthBlock->setActive( true );
}
}
else
{
if( this->mNorthBlock != NULL && this->mNorthBlock->mWestBlock != NULL )
{
this->mNorthBlock->mWestBlock->setActive( true );
}
if( this->mSouthBlock != NULL && this->mSouthBlock->mWestBlock != NULL )
{
this->mSouthBlock->mWestBlock->setActive( true );
}
}
break;
}
mCenterBlock = this;
LogManager::getSingleton().logMessage( "**TerrainBlock re-centered on: "
+ mCenterBlock->getName() );
}
else
{
//This might happen if the player is somehow thrown across a level, or jumps to a
// block diagonal (jumping to adjacent blocks shouldn't trigger this)
//
//As long as at least one of the old blocks are still touching the new set they should
// be cleaned by the directional deactivation function which is recursive.
LogManager::getSingleton().logMessage( "**TerrainBlock center lost - used to be: "
+ mCenterBlock->getName() + " -- currently creating new center at: "
+ this->getName() );
createNewCenter();
}
}
else
{
LogManager::getSingleton().logMessage(
"Center doesn't exist == Activating blocks surrounding player as new center" );
createNewCenter();
}
}
void TerrainBlock::createNewCenter()
{
mCenterBlock = this;
this->setActive( true );
if( this->mNorthBlock != NULL )
{
this->mNorthBlock->setActive( true );
if( this->mNorthBlock->mEastBlock != NULL )
{
this->mNorthBlock->mEastBlock->setActive( true );
}
if( this->mNorthBlock->mWestBlock != NULL )
{
this->mNorthBlock->mWestBlock->setActive( true );
}
}
else
{
if( this->mEastBlock != NULL && this->mEastBlock->mNorthBlock != NULL )
{
this->mEastBlock->mNorthBlock->setActive( true );
}
if( this->mWestBlock != NULL && this->mWestBlock->mNorthBlock != NULL )
{
this->mWestBlock->mNorthBlock->setActive( true );
}
}
if( this->mEastBlock != NULL )
{
this->mEastBlock->setActive( true );
if( this->mEastBlock->mNorthBlock != NULL )
{
this->mEastBlock->mNorthBlock->setActive( true );
}
if( this->mEastBlock->mSouthBlock != NULL )
{
this->mEastBlock->mSouthBlock->setActive( true );
}
}
else
{
if( this->mNorthBlock != NULL && this->mNorthBlock->mEastBlock != NULL )
{
this->mNorthBlock->mEastBlock->setActive( true );
}
if( this->mSouthBlock != NULL && this->mSouthBlock->mEastBlock != NULL )
{
this->mSouthBlock->mEastBlock->setActive( true );
}
}
if( this->mSouthBlock != NULL )
{
this->mSouthBlock->setActive( true );
if( this->mSouthBlock->mEastBlock != NULL )
{
this->mSouthBlock->mEastBlock->setActive( true );
}
if( this->mSouthBlock->mWestBlock != NULL )
{
this->mSouthBlock->mWestBlock->setActive( true );
}
}
else
{
if( this->mEastBlock != NULL && this->mEastBlock->mSouthBlock != NULL )
{
this->mEastBlock->mSouthBlock->setActive( true );
}
if( this->mWestBlock != NULL && this->mWestBlock->mSouthBlock != NULL )
{
this->mWestBlock->mSouthBlock->setActive( true );
}
}
if( this->mWestBlock != NULL )
{
this->mWestBlock->setActive( true );
if( this->mWestBlock->mNorthBlock != NULL )
{
this->mWestBlock->mNorthBlock->setActive( true );
}
if( this->mWestBlock->mSouthBlock != NULL )
{
this->mWestBlock->mSouthBlock->setActive( true );
}
}
else
{
if( this->mNorthBlock != NULL && this->mNorthBlock->mWestBlock != NULL )
{
this->mNorthBlock->mWestBlock->setActive( true );
}
if( this->mSouthBlock != NULL && this->mSouthBlock->mWestBlock != NULL )
{
this->mSouthBlock->mWestBlock->setActive( true );
}
}
}