📄 ogrepaginglandscapetile.cpp
字号:
/***************************************************************************
OgrePagingLandScapeTile.cpp - description
-------------------
begin : Sun Jun 08 2003
copyright : (C) 2003 by Jose A. Milan
email : spoke2@supercable.es
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
***************************************************************************/
#include "OgreVector3.h"
#include "OgreColourValue.h"
#include "OgreMovableObject.h"
#include "OgreAxisAlignedBox.h"
#include "OgreCamera.h"
#include "OgreStringConverter.h"
#include "OgreSceneNode.h"
#include "OgreSimpleRenderable.h"
#include "OgrePagingLandScapeOptions.h"
#include "OgrePagingLandScapeCamera.h"
#include "OgrePagingLandScapeTileManager.h"
#include "OgrePagingLandScapeTile.h"
#include "OgrePagingLandScapeTileInfo.h"
#include "OgrePagingLandScapeData2DManager.h"
#include "OgrePagingLandScapeData2D.h"
#include "OgrePagingLandScapeRenderableManager.h"
#include "OgrePagingLandScapeRenderable.h"
#include "OgrePagingLandScapeTextureManager.h"
namespace Ogre
{
String PagingLandScapeTile::mType = "PagingLandScapeTile";
//-----------------------------------------------------------------------
PagingLandScapeTile::PagingLandScapeTile( )
{
mInfo = new PagingLandScapeTileInfo();
mTileSceneNode = 0;
mRenderable = 0;
mInit = false;
mLoaded = false;
}
//-----------------------------------------------------------------------
PagingLandScapeTile::~PagingLandScapeTile( )
{
if ( mInfo )
{
delete mInfo;
mInfo = 0;
}
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::release( void )
{
if (mInit)
{
mInit = false;
if ( mLoaded && mRenderable )
{
mRenderable->release();
mRenderable = 0;
mLoaded = false;
}
if (mNeighbors[SOUTH])
mNeighbors[SOUTH]->_setNeighbor (NORTH, 0);
if (mNeighbors[NORTH])
mNeighbors[NORTH]->_setNeighbor (SOUTH, 0);
if (mNeighbors[EAST])
mNeighbors[EAST]->_setNeighbor (WEST, 0);
if (mNeighbors[WEST])
mNeighbors[WEST]->_setNeighbor (EAST, 0);
for ( uint i = 0; i < 4; i++ )
{
mNeighbors[ i ] = 0;
}
if ( mTileSceneNode )
{
//mTileNode->getParent()->removeChild( mTileNode->getName() );
//delete mTileNode;
assert (mTileSceneNode->getParent());
static_cast<SceneNode*>( mTileSceneNode->getParent() )->removeAndDestroyChild( mTileSceneNode->getName() );
mTileSceneNode = 0;
}
PagingLandScapeTileManager::getSingleton().freeTile( this );
}
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::init( SceneNode &ParentSceneNode, const int pageX, const int pageZ, const int tileX, const int tileZ )
{
mInit = true;
Vector3 ParentPos = ParentSceneNode.getWorldPosition();
mInfo->pageX = pageX;
mInfo->pageZ = pageZ;
mInfo->tileX = tileX;
mInfo->tileZ = tileZ;
// Calculate the offset from the parent for this tile
Vector3 scale = PagingLandScapeOptions::getSingleton().scale;
const Real endx = PagingLandScapeOptions::getSingleton().TileSize * scale.x;
const Real endz = PagingLandScapeOptions::getSingleton().TileSize * scale.z;
mInfo->posX = mInfo->tileX * endx;
mInfo->posZ = mInfo->tileZ * endz;
mName = "tile[" + StringConverter::toString( mInfo->pageX ) + "." + StringConverter::toString( mInfo->pageZ ) + "."
+ StringConverter::toString( mInfo->tileX ) + "." + StringConverter::toString( mInfo->tileZ ) + "]";
mTileSceneNode = ParentSceneNode.createChildSceneNode( mName );
// figure out scene node position within parent
mTileSceneNode->setPosition( mInfo->posX, 0, mInfo->posZ );
mTileSceneNode->attachObject( this );
Real MaxHeight = PagingLandScapeData2DManager::getSingleton().getMaxHeight(mInfo->pageX, mInfo->pageZ);
mBounds.setExtents( 0,
0,
0,
(Real)( endx ),
MaxHeight,
(Real)( endz ) );
//Change Zone of this page
mBoundsExt.setExtents( - endx * 0.5f,
- MaxHeight * 0.5f,
- endz * 0.5f,
endx * 1.5f,
MaxHeight * 1.5f ,
endz * 1.5f);
//Change Zone of this page
mWorldBounds.setExtents(mInfo->posX + ParentPos.x ,
0,
mInfo->posZ + ParentPos.z,
(Real)( mInfo->posX + ParentPos.x + endx),
MaxHeight,
(Real)( mInfo->posZ + ParentPos.z + endz) );
for ( uint i = 0; i < 4; i++ )
{
mNeighbors[ i ] = 0;
}
//force update in scene node
mTileSceneNode->_update( true, true );
mLoaded = false;
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::_notifyCurrentCamera( Camera* cam )
{
PagingLandscapeCamera *plsmcam = static_cast<PagingLandscapeCamera*> (cam);
if (mInit && mLoaded && plsmcam->getVisibility (mTileSceneNode->_getWorldAABB ()))
{
setVisible (true);
}
else
{
setVisible (false);
}
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::_notifyAttached(Node* parent)
{
mParentNode = parent;
if ( parent != 0 )
{
mTileSceneNode = static_cast<SceneNode*>( parent->createChild( mName ) );
//mTileNode->setPosition( (Real)mTableX , 0.0, (Real)mTableZ );
if ( mRenderable && mRenderable->isLoaded ())
{
mTileSceneNode->attachObject ( mRenderable );
}
mTileSceneNode->_update( true, true );
}
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::_updateRenderQueue( RenderQueue* queue )
{
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::getWorldTransforms( Matrix4* xform ) const
{
*xform = mParentNode->_getFullTransform();
}
//-----------------------------------------------------------------------
const Quaternion& PagingLandScapeTile::getWorldOrientation(void) const
{
return mParentNode->_getDerivedOrientation();
}
//-----------------------------------------------------------------------
const Vector3& PagingLandScapeTile::getWorldPosition(void) const
{
return mParentNode->_getDerivedPosition();
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::_linkRenderableNeighbor()
{
if (mNeighbors[SOUTH] && mNeighbors[SOUTH]->mLoaded)
{
PagingLandScapeRenderable *n = mNeighbors[SOUTH]->getRenderable();
assert(n);
mRenderable->_setNeighbor (SOUTH, n);
n->_setNeighbor (NORTH, mRenderable);
}
if (mNeighbors[NORTH] && mNeighbors[NORTH]->mLoaded)
{
PagingLandScapeRenderable *n = mNeighbors[NORTH]->getRenderable();
assert(n);
mRenderable->_setNeighbor (NORTH, n);
n->_setNeighbor (SOUTH, mRenderable);
}
if (mNeighbors[EAST] && mNeighbors[EAST]->mLoaded)
{
PagingLandScapeRenderable *n = mNeighbors[EAST]->getRenderable();
assert(n);
mRenderable->_setNeighbor (EAST, n);
n->_setNeighbor (WEST, mRenderable);
}
if (mNeighbors[WEST] && mNeighbors[WEST]->mLoaded)
{
PagingLandScapeRenderable *n = mNeighbors[WEST]->getRenderable();
assert(n);
mRenderable->_setNeighbor (WEST, n);
n->_setNeighbor (EAST, mRenderable);
}
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::_Notify(const Vector3 &pos, PagingLandscapeCamera* Cam)
{
if ((( pos - mTileSceneNode->_getDerivedPosition() ).squaredLength() <=
PagingLandScapeOptions::getSingleton().renderable_factor))
{
if ( mLoaded == false
//&& Cam->getVisibility (mBoundsExt))
&& Cam->getVisibility (mTileSceneNode->_getWorldAABB ()))
{
// Request a renderable
mRenderable = PagingLandScapeRenderableManager::getSingleton().getRenderable();
if ( mRenderable )
{
//TODO: We may remove the PosX and PosZ since it is not necessary
mRenderable->init( mInfo );
// Set the material
const Material *mmat = PagingLandScapeTextureManager::getSingleton().getMaterial( mInfo->pageX, mInfo->pageZ );
if (mmat)
mRenderable->setMaterial( mmat->getName() );
if ( mTileSceneNode )
{
mTileSceneNode->removeAndDestroyAllChildren();
}
//Queue it for loading
PagingLandScapeRenderableManager::getSingleton().queueRenderableLoading( mRenderable, this );
mLoaded = true;
}
}
}
else
{
if ( mRenderable )
{
mLoaded = false;
if ( mTileSceneNode && mRenderable->isLoaded ())
{
mTileSceneNode->detachObject( mRenderable->getName() );
}
mRenderable->release();
mRenderable = 0;
}
}
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::getPagingLandScapeRenderOpsInBox(const AxisAlignedBox& box, std::list<RenderOperation>& opList)
{
if ( box.intersects( mBounds ) )
{
RenderOperation rend;
mRenderable->getRenderOperation( rend );
opList.push_back( rend );
}
}
//-----------------------------------------------------------------------
bool PagingLandScapeTile::intersectSegment( const Vector3 & start,
const Vector3 & dir,
Vector3 * result )
{
Vector3 ray = start;
const Vector3 * corners = mWorldBounds.getAllCorners();
//start with the next one...
ray += dir;
PagingLandScapeData2D *data = PagingLandScapeData2DManager::getSingleton().getData2d (mInfo->pageX, mInfo->pageZ);
if (data == 0)
{
// just go until next tile.
while ( ! ( ( ray.x < corners[ 0 ].x ) ||
( ray.x > corners[ 4 ].x ) ||
( ray.z < corners[ 0 ].z ) ||
( ray.z > corners[ 4 ].z ) ) )
{
ray += dir;
}
}
else
{
Real pageMax;
if (mRenderable && mRenderable->isLoaded ())
pageMax = mRenderable->getMaxHeight ();
else
pageMax = data->getMaxHeight ();
while ( ! ( ( ray.x < corners[ 0 ].x ) ||
( ray.x > corners[ 4 ].x ) ||
( ray.z < corners[ 0 ].z ) ||
( ray.z > corners[ 4 ].z ) ) )
{
if ( ray.y <= pageMax && // until under the max possible for this page/tile
ray.y <= data->getHeightAbsolute( ray.x, ray.z, mInfo )// until under the max
)
{
// Found intersection range
// zone (ray - dir < intersection < ray.y + dir )
// now do a precise check using a normalised Direction
// vector. (that is < 0.1f)
// ray -= dir;
// Vector3 s = PagingLandScapeOptions::getSingleton().scale;
// Vector3 PrecisionDir (dir.x / s.x,
// dir.y / s.y,
// dir.z / s.z);
// while( ray.y >= pageMax &&
// ray.y >= tileMax)
// {
// ray += PrecisionDir;
// }
// // until under the interpolated upon current LOD max
// while( ray.y > PagingLandScapeData2DManager::getSingleton().getRealWorldHeight( ray.x, ray.z ))
// {
// ray += PrecisionDir;
// }
*result = ray;
return true;
}
ray += dir;
}
}
if ( ray.x < corners[ 0 ].x && mNeighbors[ WEST ] != 0 )
return mNeighbors[ WEST ] ->intersectSegment( ray, dir, result );
else if ( ray.z < corners[ 0 ].z && mNeighbors[ NORTH ] != 0 )
return mNeighbors[ NORTH ] ->intersectSegment( ray, dir, result );
else if ( ray.x > corners[ 4 ].x && mNeighbors[ EAST ] != 0 )
return mNeighbors[ EAST ] ->intersectSegment( ray, dir, result );
else if ( ray.z > corners[ 4 ].z && mNeighbors[ SOUTH ] != 0 )
return mNeighbors[ SOUTH ] ->intersectSegment( ray, dir, result );
else
{
if ( result != 0 )
* result = Vector3( -1, -1, -1 );
return false;
}
}
//-----------------------------------------------------------------------
void PagingLandScapeTile::updateTerrain ()
{
assert (mRenderable);
mRenderable->setNeedUpdate ();
};
} //namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -