/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2005 The OGRE Team Also see acknowledgements in Readme.html 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt. ----------------------------------------------------------------------------- */ #include "OgreKdTerrainPage.h" #include "OgreKdTerrainRenderable.h" namespace Ogre { //------------------------------------------------------------------------- KdTerrainPage::KdTerrainPage(unsigned short numTiles) { tilesPerPage = numTiles; // Set up an empty array of TerrainRenderable pointers int i, j; for ( i = 0; i < tilesPerPage; i++ ) { tiles.push_back( KdTerrainRow() ); for ( j = 0; j < tilesPerPage; j++ ) { tiles[ i ].push_back( 0 ); } } pageSceneNode = 0; } //------------------------------------------------------------------------- KdTerrainPage::~KdTerrainPage() { KdTerrain2D::iterator i, iend; iend = tiles.end(); for (i = tiles.begin(); i != iend; ++i) { KdTerrainRow::iterator j, jend; jend = i->end(); for (j = i->begin(); j != jend; ++j) { delete *j; *j = 0; } } } //------------------------------------------------------------------------- void KdTerrainPage::linkNeighbours(void) { //setup the neighbor links. for ( size_t j = 0; j < tilesPerPage; j++ ) { for ( size_t i = 0; i < tilesPerPage; i++ ) { if ( j != tilesPerPage - 1 ) { tiles[ i ][ j ] -> _setNeighbor( KdTerrainRenderable::SOUTH, tiles[ i ][ j + 1 ] ); tiles[ i ][ j + 1 ] -> _setNeighbor( KdTerrainRenderable::NORTH, tiles[ i ][ j ] ); } if ( i != tilesPerPage - 1 ) { tiles[ i ][ j ] -> _setNeighbor( KdTerrainRenderable::EAST, tiles[ i + 1 ][ j ] ); tiles[ i + 1 ][ j ] -> _setNeighbor( KdTerrainRenderable::WEST, tiles[ i ][ j ] ); } } } } //------------------------------------------------------------------------- KdTerrainRenderable * KdTerrainPage::getTerrainTile( const Vector3 & pt ) { /* Since we don't know if the terrain is square, or has holes, we use a line trace to find the containing tile... */ KdTerrainRenderable * tile = tiles[ 0 ][ 0 ]; while ( tile != 0 ) { AxisAlignedBox b = tile -> getBoundingBox(); const Vector3 *corners = b.getAllCorners(); if ( pt.x < corners[ 0 ].x ) tile = tile -> _getNeighbor( KdTerrainRenderable::WEST ); else if ( pt.x > corners[ 4 ].x ) tile = tile -> _getNeighbor( KdTerrainRenderable::EAST ); else if ( pt.z < corners[ 0 ].z ) tile = tile -> _getNeighbor( KdTerrainRenderable::NORTH ); else if ( pt.z > corners[ 4 ].z ) tile = tile -> _getNeighbor( KdTerrainRenderable::SOUTH ); else return tile; } return 0; } //------------------------------------------------------------------------- void KdTerrainPage::setRenderQueue(uint8 qid) { for ( size_t j = 0; j < tilesPerPage; j++ ) { for ( size_t i = 0; i < tilesPerPage; i++ ) { if ( j != tilesPerPage - 1 ) { tiles[ i ][ j ]->setRenderQueueGroup(qid); } } } } }