diff -Nauwr Irrlicht/CSceneManager.cpp Irrlicht/CSceneManager.cpp --- Irrlicht/CSceneManager.cpp 2005-08-24 18:01:14.000000000 +0200 +++ Irrlicht/CSceneManager.cpp 2005-09-27 15:50:08.000000000 +0200 @@ -36,6 +36,7 @@ #include "CDummyTransformationSceneNode.h" #include "CWaterSurfaceSceneNode.h" #include "CTerrainSceneNode.h" +#include "CTiledTerrainSceneNodeManager.h" #include "CEmptySceneNode.h" #include "CTextSceneNode.h" @@ -502,6 +502,75 @@ } +//! Adds a terrain scene node to the scene graph. +ITerrainSceneNode* CSceneManager::addTerrainSceneNodeRAW( + const char* heightMapFileName, s32 bitsPerPixel, + ISceneNode* parent, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale, + video::SColor vertexColor, + s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize) +{ + io::IReadFile* file = FileSystem->createAndOpenFile(heightMapFileName); + if (!file) + { + os::Printer::log("Could not load terrain, because file could not be opened.", + heightMapFileName, ELL_ERROR); + return 0; + } + + ITerrainSceneNode* terrain = addTerrainSceneNodeRAW(file, bitsPerPixel, parent, id, + position, rotation, scale, vertexColor, maxLOD, patchSize); + file->drop(); + + return terrain; +} + +//! Adds a terrain scene node to the scene graph. +ITerrainSceneNode* CSceneManager::addTerrainSceneNodeRAW( + io::IReadFile* heightMapFile, s32 bitsPerPixel, + ISceneNode* parent, s32 id, + const core::vector3df& position, + const core::vector3df& rotation, + const core::vector3df& scale, + video::SColor vertexColor, + s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize) +{ + if (!parent) + parent = this; + + CTerrainSceneNode* node = new CTerrainSceneNode(parent, this, id, + maxLOD, patchSize, position, rotation, scale); + + if (!node->loadHeightMapRAW(heightMapFile, bitsPerPixel, vertexColor)) + { + node->remove(); + node->drop(); + return 0; + } + + node->drop(); + return node; +} + + +//! Adds a tiled terrain scene node manager to the scene graph. +ITiledTerrainSceneNodeManager* CSceneManager::addTiledTerrainSceneNodeManager( + s32 tileWidth, s32 xWidth, s32 zWidth, s32 viewableTileDistance, ISceneNode* parent, s32 id, + const core::vector3df& position, const core::vector3df& rotation, + const core::vector3df& scale, video::SColor vertexColor ) +{ + if( !parent ) + parent = this; + + CTiledTerrainSceneNodeManager* manager = new CTiledTerrainSceneNodeManager( parent, this, id, + tileWidth, xWidth, zWidth, viewableTileDistance, position, rotation, scale ); + + return manager; +} + + //! Adds an empty scene node. ISceneNode* CSceneManager::addEmptySceneNode(ISceneNode* parent, s32 id) { diff -Nauwr Irrlicht/CSceneManager.h Irrlicht/CSceneManager.h --- Irrlicht/CSceneManager.h 2005-08-20 22:17:50.000000000 +0200 +++ Irrlicht/CSceneManager.h 2005-09-27 15:46:54.000000000 +0200 @@ -179,6 +177,35 @@ video::SColor vertexColor = video::SColor(255,255,255,255), s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17); + //! Adds a terrain scene node to the scene graph. + virtual ITerrainSceneNode* addTerrainSceneNodeRAW( + const char* heightMapFileName, s32 bitsPerPixel = 16, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17); + + //! Adds a terrain scene node to the scene graph. + virtual ITerrainSceneNode* addTerrainSceneNodeRAW( + io::IReadFile* heightMap, s32 bitsPerPixel = 16, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17); + + //! Adds a tiled terrain scene node manager to the scene graph. + virtual ITiledTerrainSceneNodeManager* addTiledTerrainSceneNodeManager( + s32 tileWidth, s32 xWidth, s32 zWidth, s32 viewableTileDistance = 1, + ISceneNode* parent = 0, s32 id = -1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255) ); + //! Adds a dummy transformation scene node to the scene graph. virtual IDummyTransformationSceneNode* addDummyTransformationSceneNode( ISceneNode* parent=0, s32 id=-1); diff -Nauwr Irrlicht/CTiledTerrainSceneNodeManager.cpp Irrlicht/CTiledTerrainSceneNodeManager.cpp --- Irrlicht/CTiledTerrainSceneNodeManager.cpp 1970-01-01 01:00:00.000000000 +0100 +++ Irrlicht/CTiledTerrainSceneNodeManager.cpp 2005-09-16 10:40:22.000000000 +0200 @@ -0,0 +1,443 @@ +// Copyright (C) 2002-2005 Spintz( Tom Ince ) +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +// The code for the TerrainSceneNode is based on the GeoMipMapSceneNode +// developed by Spinz. He made it available for Irrlicht and allowed it to be +// distributed under this licence. I only modified some parts. A lot of thanks go to him. + +#include "CTiledTerrainSceneNodeManager.h" +#include "CTerrainSceneNode.h" +#include "IVideoDriver.h" +#include "ISceneManager.h" +#include "ICameraSceneNode.h" +#include "SMeshBufferLightMap.h" +#include +#include +#include "os.h" +#include + +namespace irr +{ +namespace scene +{ + + //! constructor + CTiledTerrainSceneNodeManager::CTiledTerrainSceneNodeManager( ISceneNode* parent, ISceneManager* mgr, s32 id, + s32 tileWidth, s32 xWidth, s32 zWidth, s32 viewableTileDistance, const core::vector3df& position, + const core::vector3df& rotation, const core::vector3df& scale ) + : ITiledTerrainSceneNodeManager( parent, mgr, id, position, rotation, scale ) + , m_tileWidth( tileWidth ) + , m_xWidth( xWidth ) + , m_zWidth( zWidth ) + , m_viewableTileDistance( viewableTileDistance ) + { + m_allocatedTiles = xWidth * zWidth; + m_terrainTiles = (ITerrainSceneNode**)malloc( sizeof( ITerrainSceneNode* ) * m_allocatedTiles ); + + for( s32 i = 0; i < m_allocatedTiles; i++ ) + m_terrainTiles[i] = 0; + } + + //! destructor + CTiledTerrainSceneNodeManager::~CTiledTerrainSceneNodeManager ( ) + { + } + + //! Resizes the allocated memory for tiles. At this point in time, you can only increase + //! the size, not decrease. + s32 CTiledTerrainSceneNodeManager::Resize( s32 xWidth, s32 zWidth ) + { + s32 rtnValue = 0; + s32 temp = xWidth * zWidth; + + if( temp < m_allocatedTiles ) + { + rtnValue = -1; + } + else if( temp == m_allocatedTiles ) + { + rtnValue = -2; + } + else + { + m_terrainTiles = (ITerrainSceneNode**)realloc( m_terrainTiles, sizeof( ITerrainSceneNode* ) * m_allocatedTiles ); + + for( s32 i = m_allocatedTiles; i < temp; i++ ) + m_terrainTiles[i] = 0; + + m_allocatedTiles = temp; + + if( !m_terrainTiles ) + rtnValue = 1; + } + + return rtnValue; + } + + //! Loads a tile from a heightmap + bool CTiledTerrainSceneNodeManager::LoadTile( s32 X, s32 Z, const c8* heightmap, + s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, s32 id ) + { + if( !SceneManager ) + return false; + + s32 index = X * m_xWidth + Z; + + if( index > m_allocatedTiles ) + { + return false; + } + + core::vector3df position( RelativeTranslation ); + position.X += (float)X * m_tileWidth; + position.Z += (float)Z * m_tileWidth; + position *= RelativeScale; + + m_terrainTiles[index] = SceneManager->addTerrainSceneNode( heightmap, this, id, + position, RelativeRotation, RelativeScale, + video::SColor( 255,255,255,255 ), maxLOD, patchSize + ); + + return true; + } + + //! Loads a tile from a heightmap + bool CTiledTerrainSceneNodeManager::LoadTileRAW( s32 X, s32 Z, const c8* heightmap, + s32 bitsPerPixel, s32 maxLOD, E_TERRAIN_PATCH_SIZE patchSize, s32 id ) + { + if( !SceneManager ) + return false; + + s32 index = X * m_xWidth + Z; + + if( index > m_allocatedTiles ) + { + return false; + } + + core::vector3df position( RelativeTranslation ); + position.X += (float)X * m_tileWidth; + position.Z += (float)Z * m_tileWidth; + + m_terrainTiles[index] = SceneManager->addTerrainSceneNodeRAW( heightmap, + bitsPerPixel, this, id, position, core::vector3df( 0,0,0 ), + core::vector3df( 1,1,1 ), video::SColor( 255,255,255,255 ), maxLOD, + patchSize + ); + + return true; + } + + //! Gets the pointer to tile terrainSceneNode data + ITerrainSceneNode* CTiledTerrainSceneNodeManager::GetTileNode( s32 X, s32 Z ) + { + s32 index = X * m_xWidth + Z; + + if( index > m_allocatedTiles ) + return 0; + + return m_terrainTiles[index]; + } + + void CTiledTerrainSceneNodeManager::OnPreRender() + { + core::list::Iterator it; + core::list::Iterator endIt; + + it = Children.begin(); + endIt = Children.end(); + for( ; it != endIt; ++it ) + { + ((CTerrainSceneNode*)(*it))->preRenderLODCalculations(); + } + + // Once all tiledterrainnodes have their 1st sweep of LODs determined, we can check the LOD of patches adjacent to + // each other on adjacent tiles. + + // Get the tile that the camera is on. + core::vector3df camPos = SceneManager->getActiveCamera()->getPosition(); + ITerrainSceneNode* activeTile = 0; + s32 activeTileX = -1; + s32 activeTileZ = -1; + + for( s32 x = 0; x < m_xWidth; x++ ) + { + for( s32 z = 0; z < m_zWidth; z++ ) + { + s32 index = x * m_xWidth + z; + + // Need to only check the X and Z edges, not the Y of the bbox + if( m_terrainTiles[index]->isVisible() ) + { + core::aabbox3df bbox = m_terrainTiles[index]->getBoundingBox(); + if( camPos.X >= bbox.MinEdge.X && + camPos.X <= bbox.MaxEdge.X && + camPos.Z >= bbox.MinEdge.Z && + camPos.Z <= bbox.MaxEdge.Z ) + { + activeTile = m_terrainTiles[index]; + activeTileX = x; + activeTileZ = z; + + // breaks both for loops + x = m_xWidth; + z = m_zWidth; + continue; + } + } + } + } + + // We've found the tile that the camera is in. Check seams with all neighbor tiles of this tile only. + //if( activeTile && activeTile->isVisible() ) + if( activeTile ) + { + // Make only my tile, and surrounding tiles visible. + for( s32 x = 0; x < m_xWidth; x++ ) + { + for( s32 z = 0; z < m_zWidth; z++ ) + { + s32 index = x * m_xWidth + z; + + if( m_viewableTileDistance == 0 ) + { + if( x == activeTileX && z == activeTileZ ) + m_terrainTiles[index]->setVisible( true ); + else + m_terrainTiles[index]->setVisible( false ); + } + else + { + if( x >= activeTileX - m_viewableTileDistance && x <= activeTileX + m_viewableTileDistance && + z >= activeTileZ - m_viewableTileDistance && z <= activeTileZ + m_viewableTileDistance ) + { + m_terrainTiles[index]->setVisible( true ); + } + else + { + m_terrainTiles[index]->setVisible( false ); + } + } + } + } + + if( m_viewableTileDistance > 0 ) + { + core::array myLODs; + core::array neighborLODs; + s32 totalPatches = activeTile->getCurrentLODOfPatches( myLODs ); + s32 tilePatchWidth = (s32)sqrt( (f32)totalPatches ); + s32 neighborIndex = 0; + ITerrainSceneNode* neighbor = 0; + + // does the activeTile have a left neighbor? + neighborIndex = (activeTileX - 1) * m_xWidth + activeTileZ; + if( neighborIndex > -1 && neighborIndex < m_allocatedTiles ) + { + neighbor = m_terrainTiles[neighborIndex]; + if( neighbor && neighbor->isVisible() ) + { + // Check the right patches of the neighbor with the left patches of my tile. + neighbor->getCurrentLODOfPatches( neighborLODs ); + + s32 myX = 0; + s32 neighborX = tilePatchWidth - 1; + s32 Z = 0; + for( Z = 0; Z < tilePatchWidth - 1; Z++ ) + { + s32 myIndex = myX * tilePatchWidth + Z; + s32 neighborIndex = neighborX * tilePatchWidth + Z; + if( neighborLODs[neighborIndex] != myLODs[myIndex] ) + neighbor->setLODOfPatch( neighborX, Z, myLODs[myIndex] ); + } + + if( m_viewableTileDistance > 1 ) + { + // Check the left neighbor's top patches with the left neighbor's top neighbor's bottom patches + // Check the left neighbor's bottom patches with the left neighbor's bottom neighor's top patches + } + } + } + + // does the activeTile have a top neighbor? + neighbor = 0; + neighborIndex = activeTileX * m_xWidth + (activeTileZ + 1); + if( neighborIndex > -1 && neighborIndex < m_allocatedTiles ) + { + neighbor = m_terrainTiles[neighborIndex]; + if( neighbor && neighbor->isVisible() ) + { + // check the bottom patches of the neighbor with the top patches of my tile. + neighborLODs.clear(); + neighbor->getCurrentLODOfPatches( neighborLODs ); + + s32 myZ = tilePatchWidth - 1; + s32 neighborZ = 0; + s32 X = 0; + for( X = 0; X < tilePatchWidth - 1; X++ ) + { + s32 myIndex = X * tilePatchWidth + myZ; + s32 neighborIndex = X * tilePatchWidth + neighborZ; + if( neighborLODs[neighborIndex] != myLODs[myIndex] ) + neighbor->setLODOfPatch( X, neighborZ, myLODs[myIndex] ); + } + + if( m_viewableTileDistance > 1 ) + { + // Check the top neighbor's left patches with the top neighbor's left neighbor's right patches + // Check the top neighbor's right patches with the top neighbor's right neighbor's left patches + } + } + } + + // does the activeTile have a bottom neighbor? + neighbor = 0; + neighborIndex = activeTileX * m_xWidth + (activeTileZ - 1); + if( neighborIndex > -1 && neighborIndex < m_allocatedTiles ) + { + neighbor = m_terrainTiles[neighborIndex]; + if( neighbor ) + { + // check the top patches of the neighbor with the bottom patches of my tile. + neighborLODs.clear(); + neighbor->getCurrentLODOfPatches( neighborLODs ); + + s32 myZ = 0; + s32 neighborZ = tilePatchWidth - 1; + s32 X = 0; + for( X = 0; X < tilePatchWidth - 1; X++ ) + { + s32 myIndex = X * tilePatchWidth + myZ; + s32 neighborIndex = X * tilePatchWidth + neighborZ; + if( neighborLODs[neighborIndex] != myLODs[myIndex] ) + neighbor->setLODOfPatch( X, neighborZ, myLODs[myIndex] ); + } + + if( m_viewableTileDistance > 1 ) + { + // Check the bottom neighbor's left patches with the bottom neighbor's left neighbor's right patches + // Check the bottom neighbor's right patches with the bottom neighbor's right neighbor's left patches + } + } + } + + // does the activeTile have a right neighbor? + neighbor = 0; + neighborIndex = (activeTileX + 1 ) * m_xWidth + activeTileZ; + if( neighborIndex > -1 && neighborIndex < m_allocatedTiles ) + { + neighbor = m_terrainTiles[neighborIndex]; + if( neighbor ) + { + // Check the left patches of the neighbor with the right patches of my tile. + neighbor->getCurrentLODOfPatches( neighborLODs ); + + s32 myX = tilePatchWidth - 1; + s32 neighborX = 0; + s32 Z = 0; + for( Z = 0; Z < tilePatchWidth - 1; Z++ ) + { + s32 myIndex = myX * tilePatchWidth + Z; + s32 neighborIndex = neighborX * tilePatchWidth + Z; + if( neighborLODs[neighborIndex] != myLODs[myIndex] ) + neighbor->setLODOfPatch( neighborX, Z, myLODs[myIndex] ); + } + + if( m_viewableTileDistance > 1 ) + { + // Check the right neighbor's top patches with the right neighbor's top neighbor's bottom patches + // Check the right neighbor's bottom patches with the right neighbor's bottom neighbor's top patches + } + } + } + } + } + + it = Children.begin(); + for( ; it != endIt; ++it ) + { + ((CTerrainSceneNode*)(*it))->preRenderIndicesCalculations(); + } + } + + //! Sets the scale for all terrain tiles the terrain manager is managing. + //! \param scale: New scale of all terrain nodes. + void CTiledTerrainSceneNodeManager::setScale( const core::vector3df& scale ) + { + ISceneNode::setScale( scale ); + + for( s32 X = 0; X < m_xWidth; ++X ) + { + for( s32 Z = 0; Z < m_zWidth; ++Z ) + { + s32 index = X * m_xWidth + Z; + + if( index > m_allocatedTiles || !m_terrainTiles[index] ) + { + return; + } + + core::vector3df position( RelativeTranslation ); + position.X += (float)X * m_tileWidth * RelativeScale.X; + position.Z += (float)Z * m_tileWidth * RelativeScale.Z; + + m_terrainTiles[index]->setPosition( position ); + m_terrainTiles[index]->setScale( RelativeScale ); + } + } + } + + //! Sets the rotation for all terrain tiles the terrain manager is managing. + //! \param scale: New rotation of all terrain nodes. + void CTiledTerrainSceneNodeManager::setRotation( const core::vector3df& rotation ) + { + ISceneNode::setRotation( rotation ); + + for( s32 X = 0; X < m_xWidth; ++X ) + { + for( s32 Z = 0; Z < m_zWidth; ++Z ) + { + s32 index = X * m_xWidth + Z; + + if( index > m_allocatedTiles || !m_terrainTiles[index] ) + { + return; + } + + m_terrainTiles[index]->setRotationPivot( RelativeTranslation ); + m_terrainTiles[index]->setRotation( RelativeRotation ); + } + } + } + + //! Sets the position for the first terrain tile the terrain manager is managing. + //! All other tiles will react to this change in position, if any. + //! \param scale: New position of the terrain manager. + void CTiledTerrainSceneNodeManager::setPosition( const core::vector3df& position ) + { + ISceneNode::setPosition( position ); + + for( s32 X = 0; X < m_xWidth; ++X ) + { + for( s32 Z = 0; Z < m_zWidth; ++Z ) + { + s32 index = X * m_xWidth + Z; + + if( index > m_allocatedTiles || !m_terrainTiles[index] ) + { + return; + } + + core::vector3df position( RelativeTranslation ); + position.X += (float)X * m_tileWidth * RelativeScale.X; + position.Z += (float)Z * m_tileWidth * RelativeScale.Z; + + m_terrainTiles[index]->setPosition( position ); + } + } + } + +} // end namespace scene +} // end namespace irr + diff -Nauwr Irrlicht/CTiledTerrainSceneNodeManager.h Irrlicht/CTiledTerrainSceneNodeManager.h --- Irrlicht/CTiledTerrainSceneNodeManager.h 1970-01-01 01:00:00.000000000 +0100 +++ Irrlicht/CTiledTerrainSceneNodeManager.h 2005-09-16 10:43:26.000000000 +0200 @@ -0,0 +1,105 @@ +// Copyright (C) 2002-2005 Spintz( Tom Ince ) +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +// The code for the TerrainSceneNode is based on the GeoMipMapSceneNode +// developed by Spinz. He made it available for Irrlicht and allowed it to be +// distributed under this licence. I only modified some parts. A lot of thanks go to him. + +// TODO : Match the LOD of seams of tiles for all visible tiles, not just the active tiles, +// immediate x and z neighbors. ( should it only be the active tiles neighbors +// including x, z and diagonal or should it be all visible tiles, maybe make a flag? ) +// TODO : If the camera is not above a tile, for activeTile determination, select the tile +// nearest to the camera as the activeTile. + +#ifndef __C_TILED_TERRAIN_SCENE_NODE_MANAGER_H__ +#define __C_TILED_TERRAIN_SCENE_NODE_MANAGER_H__ + +#include "ITiledTerrainSceneNodeManager.h" +#include "ITerrainSceneNode.h" + +namespace irr +{ +namespace scene +{ + //! A scene node for displaying tiled terrain, with each tile being a ITerrainSceneNode. + /** You cannot, or rather should not, modify the position, scale or rotation of the terrain tiles + * directly. If you wish to change the position, scale or rotation of the terrain tiles that are + * used by the tile manager, use the set functions for the tile manager. It will apply the proper + * changes to all tiles it is managing. + **/ + + class CTiledTerrainSceneNodeManager : public ITiledTerrainSceneNodeManager + { + public: + + //! constructor + CTiledTerrainSceneNodeManager( ISceneNode* parent, ISceneManager* mgr, s32 id, + s32 tileWidth = 0, s32 xWidth = 0, s32 zWidth = 0, s32 viewableTileDistance = 1, + const core::vector3df& position = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& rotation = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f) ); + + //! destructor + virtual ~CTiledTerrainSceneNodeManager(); + + //! Sets the viewable tile distance, or the depth of tiles to set as viewable based on the + //! active tile( the tile the camera is hovering in. + virtual void SetViewableTileDistance( s32 viewableTileDistance ) { m_viewableTileDistance = viewableTileDistance; } + + //! Resizes the allocated memory for tiles. At this point in time, you can only increase + //! the size, not decrease. + virtual s32 Resize( s32 xWidth, s32 zWidth ); + + //! Loads a tile from a heightmap + virtual bool LoadTile( s32 X, s32 Z, const c8* heightmap, + s32 maxLOD = 5, E_TERRAIN_PATCH_SIZE patchSize = ETPS_33, s32 id = -1 ); + + //! Loads a tile from a heightmap + virtual bool LoadTileRAW( s32 X, s32 Z, const c8* heightmap, s32 bitsPerPixel = 16, + s32 maxLOD = 5, E_TERRAIN_PATCH_SIZE patchSize = ETPS_33, s32 id = -1 ); + + //! Gets the pointer to tile terrainSceneNode data + virtual ITerrainSceneNode* GetTileNode( s32 X, s32 Z ); + + virtual void OnPreRender(); + + //! Returns the axis aligned, not transformed bounding box of this node. + //! This means that if this node is a animated 3d character, moving in a room, + //! the bounding box will always be around the origin. To get the box in + //! real world coordinates, just transform it with the matrix you receive with + //! getAbsoluteTransformation() or simply use getTransformedBoundingBox(), + //! which does the same. + virtual const core::aabbox3d& getBoundingBox() const { return m_bbox; } + + //! Sets the scale for all terrain tiles the terrain manager is managing. + //! \param scale: New scale of all terrain nodes. + virtual void setScale( const core::vector3df& scale ); + + //! Sets the rotation for all terrain tiles the terrain manager is managing. + //! \param scale: New rotation of all terrain nodes. + virtual void setRotation( const core::vector3df& scale ); + + //! Sets the position for the first terrain tile the terrain manager is managing. + //! All other tiles will react to this change in position, if any. + //! \param scale: New position of the terrain manager. + virtual void setPosition( const core::vector3df& scale ); + + protected: + + ITerrainSceneNode** m_terrainTiles; + core::aabbox3d m_bbox; + + s32 m_allocatedTiles; + s32 m_xWidth; + s32 m_zWidth; + s32 m_tileWidth; + s32 m_viewableTileDistance; + }; + +} // end namespace scene +} // end namespace irr + + +#endif // __C_TILED_TERRAIN_SCENE_NODE_MANAGER_H__ + diff -Nauwr Irrlicht/include/irrlicht.h Irrlicht/include/irrlicht.h --- Irrlicht/include/irrlicht.h 2005-08-20 22:46:48.000000000 +0200 +++ Irrlicht/include/irrlicht.h 2005-09-28 10:14:26.000000000 +0200 @@ -87,6 +87,7 @@ #include "IShaderConstantSetCallBack.h" #include "IParticleSystemSceneNode.h" #include "ITerrainSceneNode.h" +#include "ITiledTerrainSceneNodeManager.h" #include "ITextSceneNode.h" #include "IParticleEmitter.h" #include "IParticleAffector.h" diff -Nauwr Irrlicht/include/ISceneManager.h Irrlicht/include/ISceneManager.h --- Irrlicht/include/ISceneManager.h 2005-08-23 18:51:58.000000000 +0200 +++ Irrlicht/include/ISceneManager.h 2005-09-27 15:46:10.000000000 +0200 @@ -162,6 +168,7 @@ class IMetaTriangleSelector; class IMeshManipulator; class ITextSceneNode; + class ITiledTerrainSceneNodeManager; //! The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff. /** All Scene nodes can be created only here. There is a always growing list of scene @@ -638,6 +644,39 @@ video::SColor vertexColor = video::SColor(255,255,255,255), s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17) = 0; + //! Just like the addTerrainSceneNode() method, but takes a RAW file as + //! input parameter for the heightmap. For more informations take a look + //! add the other overload. + virtual ITerrainSceneNode* addTerrainSceneNodeRAW( + const char* heightMapFileName, s32 bitsPerPixel = 16, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17) = 0; + + //! Just like the other addTerrainSceneNodeRAW() method, but takes an IReadFile + //! pointer as parameter for the heightmap. For more informations take a look + //! add the other overload. + virtual ITerrainSceneNode* addTerrainSceneNodeRAW( + io::IReadFile* heightMapFile, s32 bitsPerPixel = 16, + ISceneNode* parent=0, s32 id=-1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255), + s32 maxLOD=5, E_TERRAIN_PATCH_SIZE patchSize=ETPS_17) = 0; + + //! Adds a tiled terrain scene node manager to the scene graph. + virtual ITiledTerrainSceneNodeManager* addTiledTerrainSceneNodeManager( + s32 tileWidth, s32 xWidth, s32 zWidth, s32 viewableTileDistance = 1, + ISceneNode* parent = 0, s32 id = -1, + const core::vector3df& position = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& rotation = core::vector3df(0.0f,0.0f,0.0f), + const core::vector3df& scale = core::vector3df(1.0f,1.0f,1.0f), + video::SColor vertexColor = video::SColor(255,255,255,255) ) = 0; + //! Adds an empty scene node to the scene graph. /** Can be used for doing advanced transformations or structuring the scene graph. diff -Nauwr Irrlicht/include/ITiledTerrainSceneNodeManager.h Irrlicht/include/ITiledTerrainSceneNodeManager.h --- Irrlicht/include/ITiledTerrainSceneNodeManager.h 1970-01-01 01:00:00.000000000 +0100 +++ Irrlicht/include/ITiledTerrainSceneNodeManager.h 2005-09-16 10:43:36.000000000 +0200 @@ -0,0 +1,77 @@ +// Copyright (C) 2002-2005 Nikolaus Gebhardt +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +// The code for the TerrainSceneNode is based on the terrain renderer by Soconne and +// the GeoMipMapSceneNode developed by Spinz. They made their code available for Irrlicht +// and allowed it to be distributed under this licence. I only modified some parts. +// A lot of thanks go to them. + +#ifndef __I_TILED_TERRAIN_SCENE_NODE_MANAGER_H__ +#define __I_TILED_TERRAIN_SCENE_NODE_MANAGER_H__ + +#include "ISceneNode.h" +#include "ITerrainSceneNode.h" + +namespace irr +{ +namespace scene +{ + class ISceneManager; + + //! A scene node for displaying tiled terrain, with each tile being a ITerrainSceneNode. + /** You cannot, or rather should not, modify the position, scale or rotation of the terrain tiles + * directly. If you wish to change the position, scale or rotation of the terrain tiles that are + * used by the tile manager, use the set functions for the tile manager. It will apply the proper + * changes to all tiles it is managing. + **/ + class ITiledTerrainSceneNodeManager : public ISceneNode + { + public: + + //! constructor + ITiledTerrainSceneNodeManager( ISceneNode* parent, ISceneManager* mgr, s32 id, + const core::vector3df& position = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& rotation = core::vector3df(0.0f, 0.0f, 0.0f), + const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f) ) + : ISceneNode (parent, mgr, id, position, rotation, scale) {} + + //! destructor + virtual ~ITiledTerrainSceneNodeManager() {}; + + //! Sets the viewable tile distance, or the depth of tiles to set as viewable based on the + //! active tile( the tile the camera is hovering in. + virtual void SetViewableTileDistance( s32 viewableTileDistance ) = 0; + + //! Resizes the allocated memory for tiles. At this point in time, you can only increase + //! the size, not decrease. + virtual s32 Resize( s32 xWidth, s32 zWidth ) = 0; + + //! Loads a tile from a heightmap + virtual bool LoadTile( s32 X, s32 Z, const c8* heightmap, s32 maxLOD = 5, + E_TERRAIN_PATCH_SIZE patchSize = ETPS_33, s32 id = -1 ) = 0; + + //! Loads a tile from a heightmap + virtual bool LoadTileRAW( s32 X, s32 Z, const c8* heightmap, s32 bitsPerPixel = 16, + s32 maxLOD = 5, E_TERRAIN_PATCH_SIZE patchSize = ETPS_33, s32 id = -1 ) = 0; + + //! Gets the pointer to tile terrainSceneNode data + virtual ITerrainSceneNode* GetTileNode( s32 X, s32 Z ) = 0; + + //! Renders the node. + virtual void render() {} + + //! Returns the axis aligned, not transformed bounding box of this node. + //! This means that if this node is a animated 3d character, moving in a room, + //! the bounding box will always be around the origin. To get the box in + //! real world coordinates, just transform it with the matrix you receive with + //! getAbsoluteTransformation() or simply use getTransformedBoundingBox(), + //! which does the same. + virtual const core::aabbox3d& getBoundingBox() const = 0; + }; + +} // end namespace scene +} // end namespace irr + + +#endif // __I_TILED_TERRAIN_SCENE_NODE_MANAGER_H__ diff -Nauwr Irrlicht/include/ITerrainSceneNode.h Irrlicht/include/ITerrainSceneNode.h --- Irrlicht/include/ITerrainSceneNode.h 2005-08-20 22:17:46.000000000 +0200 +++ Irrlicht/include/ITerrainSceneNode.h 2005-09-16 10:33:02.000000000 +0200 @@ -142,6 +148,11 @@ to the same values as in the first set. If this is another value than zero, it will scale the second texture coordinate set by this value. */ virtual void scaleTexture(f32 scale = 1.0f, f32 scale2 = 0.0f) = 0; + + //! Sets the pivot point for rotation of this node. This is useful for the TiledTerrainManager to + //! rotate all terrain tiles around a global world point. + //! NOTE: The default for the RotationPivot will be the center of the individual tile. + virtual void setRotationPivot( const core::vector3df& pivot ) = 0; }; } // end namespace scene