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

📄 ogrepaginglandscapetile.cpp

📁 使用stl技术,(还没看,是听说的)
💻 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 + -