./components/ogre/AttributeObserver.cpp

       1  //
          // C++ Implementation: AttributeObserver
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik.hjortsberg@iteam.se>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifdef HAVE_CONFIG_H
          #include "config.h"
          #endif
          
          #include "AttributeObserver.h"
          #include <Eris/Entity.h>
          #include "services/logging/LoggingService.h"
          
          namespace EmberOgre {
          
      33  AttributeObserver::AttributeObserver(  Eris::Entity* entity,   const std::string& attributeName )
          : mSlot(  sigc::mem_fun(  *this,   &AttributeObserver::attributeChanged ) )
          {
           if (  entity ) {
           entity->observe(  attributeName,   mSlot );
           } else {
           S_LOG_WARNING(  "Tried to observer the attribute " << attributeName << " or a null entity." );
           }
          }
          
      43  AttributeObserver::~AttributeObserver(   )
          {
           mSlot.disconnect(   );
          }
          
      48  void AttributeObserver::attributeChanged(  const Atlas::Message::Element& attributeValue )
          {
           EventChanged.emit(  attributeValue );
          }
          
          
          }

./components/ogre/AttributeObserver.h

       1  //
          // C++ Interface: AttributeObserver
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik.hjortsberg@iteam.se>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREATTRIBUTEOBSERVER_H
          #define EMBEROGREATTRIBUTEOBSERVER_H
          
          #include <sigc++/trackable.h>
          #include <Eris/Entity.h>
          
          
          namespace Eris {
      31  class Entity;
          }
          
          namespace EmberOgre {
          
          /**
           Observes changes to a specific attribute and emits a signal.
           @author Erik Hjortsberg <erik.hjortsberg@iteam.se>
          */
      40  class AttributeObserver : public sigc::trackable
          {
          public:
          
      44   AttributeObserver(  Eris::Entity* entity,   const std::string& attributeName );
      45   ~AttributeObserver(   );
          
      47   sigc::signal<void,   const Atlas::Message::Element&> EventChanged;
          
          protected:
      50   Eris::Entity::AttrChangedSlot mSlot;
          
      52   void attributeChanged(  const Atlas::Message::Element& attributeValue );
          };
          
          }
          
          #endif

./components/ogre/Avatar.cpp

       1  /*
           Avatar.cpp by Erik Hjortsberg
           Copyright (  C ) 2002 Miguel Guzman,   Erik Hjortsberg & The Worldforge
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          
          #include "Avatar.h"
          
          #ifdef HAVE_CONFIG_H
          #include "config.h"
          #endif
          #include <typeinfo>
          
          
          #include "services/EmberServices.h"
          #include "services/server/ServerService.h"
          #include "services/config/ConfigService.h"
          // #include "services/sound/SoundService.h"
          
          
          #include "EmberEntity.h"
          #include "EmberPhysicalEntity.h"
          #include "AvatarController.h"
          #include "AvatarCamera.h"
          
          #include "AvatarEmberEntity.h"
          #include "model/Model.h"
          #include "model/SubModel.h"
          #include "EmberOgre.h"
          #include "MathConverter.h"
          #include "input/Input.h"
          
          #include <Eris/Avatar.h>
          #include <Eris/Connection.h>
          #include <Eris/TypeInfo.h>
          
          namespace EmberOgre {
          
          
      54  Avatar::Avatar(   )
          : mErisAvatarEntity(  0 ),   mHasChangedLocation(  false )
          {
           mTimeSinceLastServerMessage = 0;
           setMinIntervalOfRotationChanges(  1000 ); //milliseconds
           mAccumulatedHorizontalRotation = 0;
           mThresholdDegreesOfYawForAvatarRotation = 100;
          
          
           ///these are the defaults,   but if anything is set in the config file that will override these values as updateFromConfig is called
           mWalkSpeed = 2.47;
           mRunSpeed = 5; ///5 seems to be the max speed in cyphesis
          
          
           /// Create the Avatar tree of nodes,   with a base entity
           /// and attach all the needed cameras
          
           createAvatar(   );
          
           Ogre::Root::getSingleton(   ).addFrameListener(  this );
          
           Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->EventChangedConfigItem.connect(  sigc::mem_fun(  *this,   &Avatar::ConfigService_EventChangedConfigItem ) );
          
           ///update values from the config
           updateFromConfig(   );
          
          }
          
      82  Avatar::~Avatar(   )
          {
          
          }
          
      87  void Avatar::setMinIntervalOfRotationChanges(  Ogre::Real milliseconds )
          {
           mMinIntervalOfRotationChanges = milliseconds;
          }
          
      92  void Avatar::createAvatar(   )
          {
           // The avatar itself
           mAvatarNode = static_cast<Ogre::SceneNode*>(  EmberOgre::getSingleton(   ).getSceneManager(   )->getRootSceneNode(   )->createChild(   ) );
           mAvatarNode->setPosition(  Ogre::Vector3(  0,  0,  0 ) );
           //mAvatarNode->setOrientation(  0,  1,  0,  0 );
           //mAvatarNode->setScale(  Ogre::Vector3(  0.01,  0.01,  0.01 ) );
          
          /* // Model Node and Entity for display
           // TODO: do also the scaling here! That way the other nodes can be positioned in their real places
           mAvatarModelNode = static_cast<Ogre::SceneNode*>(  mAvatarNode->createChild(  "AvatarModelNode" ) );
          
           Model* model = new Model(  "AvatarEntity" );
           model->create(  "settler" );
          
          // Model* model = Model::Create(  "spider.modeldef.xml",   "AvatarEntity" );
           //Model::Create(  "malebuilder.modeldef.xml",   "AvatarEntity1" );
          
          
           mAvatarModel = model;
          
           mAvatarModelNode->attachObject(  mAvatarModel );
           mAvatarModelNode->rotate(  Ogre::Vector3::UNIT_Y,  (  Ogre::Degree )90 );*/
          
          
          /* Ogre::Light* light = mSceneMgr->createLight(  "AvatarLight__" );
           light->setType(  Ogre::Light::LT_POINT );
           light->setCastShadows(  true );
           light->setDiffuseColour(  0.6,  0.6,  0.6 );
           //light->setSpecularColour(  1,   1,   1 );
           light->setAttenuation(  50,  1,  0.0005,  0 );
           mAvatarModelNode->attachObject(  light );*/
          //
          // mAvatarModelNode->showBoundingBox(  true );
          
          }
          
     129  bool Avatar::frameStarted(  const Ogre::FrameEvent & event )
          {
          
           if (  mEntitiesToBeAddedToInventory.size(   ) > 0 ) {
           std::set<Eris::Entity*>::iterator I = mEntitiesToBeAddedToInventory.begin(   );
           std::set<Eris::Entity*>::iterator I_end = mEntitiesToBeAddedToInventory.end(   );
          
           for (  ; I != I_end; ++I ) {
           //no need to do dynamic cast here
           EmberEntity* emberEntity = static_cast<EmberEntity*>(  *I );
           EventAddedEntityToInventory.emit(  emberEntity );
           }
          
           mEntitiesToBeAddedToInventory.clear(   );
           }
          
          
          /* if (  mEntitiesToBeRemovedFromInventory.size(   ) > 0 ) {
           std::set<Eris::Entity*>::iterator J = mEntitiesToBeRemovedFromInventory.begin(   );
           std::set<Eris::Entity*>::iterator J_end = mEntitiesToBeRemovedFromInventory.end(   );
          
           for (  ; J != J_end; ++J ) {
           EmberEntity* emberEntity = dynamic_cast<EmberEntity*>(  *J );
           if (  emberEntity )
           EventRemovedEntityFromInventory.emit(  emberEntity );
           }
          
           mEntitiesToBeRemovedFromInventory.clear(   );
           }*/
           return true;
          }
          
          
          
     163  void Avatar::updateFrame(  AvatarControllerMovement& movement )
          {
          
           ///for now we'll just rotate without notifying the server
           ///except when moving!
           attemptRotate(  movement );
          
          
           ///this next method will however send send stuff to the server
           attemptMove(  movement );
          
           ///only adjust if there is actual movement. If we adjust when there's only rotation we'll get a strange jerky effect (  some bug I guess )
           if (  movement.isMoving ) {
           adjustAvatarToNewPosition(  &movement );
           }
          
          }
          
     181  void Avatar::attemptMove(  AvatarControllerMovement& movement )
          {
           Ogre::Vector3 move = movement.movementDirection;
           bool isRunning = movement.mode == AvatarMovementMode::MM_RUN;
           Ogre::Real timeSlice = movement.timeSlice;
           float speed = isRunning ? mRunSpeed : mWalkSpeed;
           Ogre::Vector3 rawVelocity = move * speed;
          
          
           ///first we'll register the current state in newMovementState and compare to mCurrentMovementState
           ///that way we'll only send stuff to the server if our movement changes
           AvatarMovementState newMovementState;
           newMovementState.orientation = mAvatarNode->getOrientation(   );
           newMovementState.velocity = rawVelocity;// * newMovementState.orientation.xAxis(   );
          
           if (  move != Ogre::Vector3::ZERO ) {
           newMovementState.isMoving = true;
           newMovementState.isRunning = isRunning;
           } else {
           newMovementState.isMoving = false;
           newMovementState.isRunning = false;
           }
           bool sendToServer = false;
          
           //first we check if we are already moving
           if (  !mCurrentMovementState.isMoving ) {
           //we are not moving. Should we start to move?
           if (  newMovementState.isMoving ) {
           //we'll start moving
           //let's send the movement command to the server
           sendToServer = true;
          
           } else if (  !(  newMovementState.orientation == mMovementStateAtLastServerMessage.orientation ) ) {
           //we have rotated since last server update
           //let's see if it's ok to send server message
           //if not we have to wait some more frames until we'll send an update
           if (  isOkayToSendRotationMovementChangeToServer(   ) ) {
           sendToServer = true;
           }
           }
           } else {
           //we are already moving
           //let's see if we've changed speed or direction or even stopped
           if (  !newMovementState.isMoving ) {
           S_LOG_VERBOSE(   "Avatar stopped moving." );
           //we have stopped; we must alert the server
           sendToServer = true;
           } else if (  newMovementState.velocity != mCurrentMovementState.velocity || !(  newMovementState.orientation == mCurrentMovementState.orientation ) ){
           //either the speed or the direction has changed
           sendToServer = true;
           }
           }
          
          
           if (  sendToServer ) {
           S_LOG_VERBOSE(  "Sending move op to server." );
           mMovementStateAtBeginningOfMovement = newMovementState;
           mMovementStateAtLastServerMessage = newMovementState;
           mTimeSinceLastServerMessage = 0;
          
          
           //for now we'll only send velocity
           Ember::EmberServices::getSingletonPtr(   )->getServerService(   )->moveInDirection(  Ogre2Atlas_Vector3(  newMovementState.orientation * newMovementState.velocity ),   Ogre2Atlas(  newMovementState.orientation ) );
          
          // Ember::EmberServices::getSingletonPtr(   )->getServerService(   )->moveInDirection(  Ogre2Atlas(  mCurrentMovementState.velocity ),   Ogre2Atlas(  mCurrentMovementState.orientation ) );
          
           } else {
           mTimeSinceLastServerMessage += timeSlice * 1000;
           }
          
           if (  newMovementState.isMoving ) {
           //do the actual movement of the avatar node
           mAvatarNode->translate(  mAvatarNode->getOrientation(   ) * (  rawVelocity * timeSlice ) );
           }
           mCurrentMovementState = newMovementState;
          
          }
          
     259  void Avatar::adjustAvatarToNewPosition(  AvatarControllerMovement* movement )
          {
           ///allow the eris entity to adjust to the containing node
           if (  mErisAvatarEntity ) {
           mErisAvatarEntity->adjustPosition(   );
           }
          // MotionManager::getSingleton(   ).adjustHeightPositionForNode(  mAvatarNode );
          }
          
          
     269  void Avatar::attemptJump(   ) {}
          
          
     272  void Avatar::attemptRotate(  AvatarControllerMovement& movement )
          {
           //TODO: remove the direct references to AvatarCamera
          /* float degHoriz = movement.rotationDegHoriz;
           float degVert = movement.rotationDegVert;
           Ogre::Real timeSlice = movement.timeSlice;*/
          
          // mAccumulatedHorizontalRotation += (  degHoriz * timeSlice );
          
           //if we're moving we must sync the rotation with messages sent to the server
           if (  !movement.isMoving && fabs(  getAvatarCamera(   )->getYaw(   ).valueDegrees(   ) ) > mThresholdDegreesOfYawForAvatarRotation ) {
          // mAvatarNode->setOrientation(  movement.cameraOrientation );
           mAvatarNode->rotate(  Ogre::Vector3::UNIT_Y,  getAvatarCamera(   )->getYaw(   ) );
           Ogre::Degree yaw = getAvatarCamera(   )->getYaw(   );
           getAvatarCamera(   )->yaw(  -yaw );
          // mAccumulatedHorizontalRotation = 0;
           } else if (  isOkayToSendRotationMovementChangeToServer(   ) && (  getAvatarCamera(   )->getYaw(   ).valueDegrees(   ) ) ) {
           // rotate the Avatar Node only in X position (  no vertical rotation )
          // mAvatarNode->setOrientation(  movement.cameraOrientation );
           mAvatarNode->rotate(  Ogre::Vector3::UNIT_Y,  getAvatarCamera(   )->getYaw(   ) );
           Ogre::Degree yaw = getAvatarCamera(   )->getYaw(   );
           getAvatarCamera(   )->yaw(  -yaw );
          
          // mAvatarNode->rotate(  Ogre::Vector3::UNIT_Y,  mAccumulatedHorizontalRotation );
          // mAccumulatedHorizontalRotation = 0;
           }
          
          }
          
     301  bool Avatar::isOkayToSendRotationMovementChangeToServer(   )
          {
           return mTimeSinceLastServerMessage > mMinIntervalOfRotationChanges;
          
          }
          
     307  AvatarCamera* Avatar::getAvatarCamera(   ) const
          {
           return mAvatarController->getAvatarCamera(   );
          }
          
     312  AvatarEmberEntity* Avatar::getAvatarEmberEntity(   )
          {
           return mErisAvatarEntity;
          }
          
          
     318  void Avatar::setAvatarController(  AvatarController* avatarController )
          {
           mAvatarController = avatarController;
          }
          
     323  void Avatar::movedInWorld(   )
          {
           ///only snap the avatar to the postiion and orientation sent from the server if we're not moving or if we're not recently changed location
           ///The main reason when moving is that we don't want to have the avatar snapping back in the case of lag
           ///However,   if we've just recently changed location,   we need to also update the orientation to work with the new location.
           if (  !mCurrentMovementState.isMoving || mHasChangedLocation )
           {
           mAvatarNode->setPosition(  Atlas2Ogre(  mErisAvatarEntity->getPosition(   ) ) );
           const WFMath::Quaternion& orient = mErisAvatarEntity->getOrientation(   );
           mAvatarNode->setOrientation(  Atlas2Ogre(  orient ) );
           ///we must set this,   else ember will think that we've rotated the avatar ourselves and try to send an update to the server
           mMovementStateAtLastServerMessage.orientation = mAvatarNode->getOrientation(   );
           mHasChangedLocation = false;
           }
          
          /*
           Ember::SoundService* mySoundService = Ember::EmberServices::getSingleton(   ).getSoundService(   );
           {
           mySoundService->updateAvatarSourcePosition(  
           mErisAvatarEntity->getPosition(   ),  
           mErisAvatarEntity>getOrientation(   ) );
           mySoundService->playAvatarSound(   );
           }
          */
          }
          
     349  void Avatar::avatar_LocationChanged(  Eris::Entity* entity )
          {
           ///if we've changed location,   we need to update the orientation. This is done on the next onMoved event,   which is why we must honour the updated values on next onMoved event,   even though we might be moving.
           mHasChangedLocation = true;
          }
          
          
     356  void Avatar::createdAvatarEmberEntity(  AvatarEmberEntity *emberEntity )
          {
           Ogre::SceneNode* oldAvatar = mAvatarNode;
          
           ///check if the user is of type "creator" and thus an admin
           Eris::TypeService* typeService = emberEntity->getErisAvatar(   )->getConnection(   )->getTypeService(   );
           if (  emberEntity->getType(   )->isA(  typeService->getTypeByName(  "creator" ) ) ) {
           mIsAdmin = true;
           } else {
           mIsAdmin = false;
           }
          
           //mAvatarNode->getParent(   )->removeChild(  mAvatarNode->getName(   ) );
          
           //HACK!!! DEBUG!!
           //mAvatarNode->getParent(   )->removeChild(  mAvatarNode->getName(   ) );
           //EmberEntity->getSceneNode(   )->addChild(  mAvatarNode );
          // mSceneMgr->getRootSceneNode(   )->addChild(  mAvatarNode );
           //HACK!!! DEBUG!!
          
           mAvatarNode = emberEntity->getSceneNode(   );
           mAvatarModel = emberEntity->getModel(   );
          
           mErisAvatarEntity = emberEntity;
           emberEntity->setAvatar(  this );
          
          
          
           mAvatarController->createAvatarCameras(  emberEntity->getSceneNode(   ) );
          
           EmberOgre::getSingleton(   ).getSceneManager(   )->destroySceneNode(  oldAvatar->getName(   ) );
           Input::getSingleton(   ).setMovementModeEnabled(  true );
          
           mErisAvatarEntity->LocationChanged.connect(  sigc::mem_fun(  *this,   &Avatar::avatar_LocationChanged ) );
          
          }
          
     393  void Avatar::ConfigService_EventChangedConfigItem(  const std::string& section,   const std::string& key )
          {
           if (  section == "general" ) {
           if (  key == "avatarrotationupdatefrequency"  ) {
           updateFromConfig(   );
           }
           } else if (  section == "input" ) {
           if (  key == "walkspeed"  ) {
           updateFromConfig(   );
           }
           } else if (  section == "input" ) {
           if (  key == "runspeed"  ) {
           updateFromConfig(   );
           }
           }
          }
          
     410  void Avatar::updateFromConfig(   )
          {
           if (  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->itemExists(  "general",   "avatarrotationupdatefrequency" ) ) {
           double frequency = static_cast<double>(  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getValue(  "general",   "avatarrotationupdatefrequency" ) );
           setMinIntervalOfRotationChanges(  static_cast<Ogre::Real>(  frequency ) );
           }
           if (  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->itemExists(  "input",   "walkspeed" ) ) {
           mWalkSpeed = static_cast<double>(  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getValue(  "input",   "walkspeed" ) );
           }
           if (  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->itemExists(  "input",   "runspeed" ) ) {
           mRunSpeed = static_cast<double>(  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getValue(  "input",   "runspeed" ) );
           }
          
          }
          
          
          // void Avatar::touch(  EmberEntity* entity )
          // {
          // Ember::EmberServices::getSingletonPtr(   )->getServerService(   )->touch(  entity );
          // }
          
          /*
          Ogre::Camera* Avatar::getCamera(   ) const
          {
           return mAvatarController->getCamera(   );
          }
          */
          }
          
          

./components/ogre/Avatar.h

       1  /*
           Avatar.h by Miguel Guzman (  Aglanor )
           Copyright (  C ) 2002 Miguel Guzman & The Viewforge Project
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef AVATAR_H
          #define AVATAR_H
          #include "EmberOgrePrerequisites.h"
          
          #include <sigc++/trackable.h>
          #include <sigc++/signal.h>
          
          
          #include "framework/Singleton.h"
          
          namespace Eris {
      32   class Entity;
          }
          
          
          namespace EmberOgre {
          
          namespace Model {
      39   class Model;
          }
          
          class EmberEntity;
      43  class AvatarCamera;
      44  class AvatarController;
      45  class AvatarEmberEntity;
          struct AvatarControllerMovement;
          
          struct AvatarMovementState
          {
          public:
           bool isMoving;
           bool isRunning;
           Ogre::Vector3 velocity;
           Ogre::Quaternion orientation;
          };
          
          /**
           * This class holds the Avatar. In general it recieves instructions from mainly
           * AvatarController to attempt to move or rotate the avatar. After checking
           * with the world rules if such a thing is allowed,   the world node is manipulated.
           * If it's a movement it has to be animated.
           *
           */
      64  class Avatar :
      65  public sigc::trackable,  
      66  public Ogre::FrameListener
          {
      68   friend class AvatarController;
      69   friend class AvatarEmberEntity;
          
           public:
          
      73   Avatar(   );
      74   virtual ~Avatar(   );
          
          
           /**
           * Gets the avatar camera.
           * @return
           */
      81   AvatarCamera* getAvatarCamera(   ) const;
          
           /**
           * Gets the scene node which the avatar is attached to.
           * @return
           */
      87   inline Ogre::SceneNode* getAvatarSceneNode(   ) const;
          
           /**
           * Called each frame.
           * @param event
           * @return
           */
      94   virtual bool frameStarted(  const Ogre::FrameEvent & event );
          
           /**
           * Call this when the Eris::Entity representing the avatar has been created.
           * @param EmberEntity
           */
     100   void createdAvatarEmberEntity(  AvatarEmberEntity *EmberEntity );
          
           /**
           * Call this when the avatar entity has moved in the world.
           */
     105   void movedInWorld(   );
          
          
           /**
           * Called each frame.
           * @param movement
           */
     112   void updateFrame(  AvatarControllerMovement& movement );
          
           /**
           * Sets the controller object responsible for controlling the avatar.
           * @param avatarController
           */
     118   void setAvatarController(  AvatarController* avatarController );
          
           /**
           * Access for the Eris::Entity which represents the Avatar.
           * @return
           */
     124   AvatarEmberEntity* getAvatarEmberEntity(   );
          
          
           /**
           * sets the minimum interval to wait before sending new rotation changes to the server
           * this is not done instantly to prevent swamping of data to the server
           * set this lower if you experience too jerky game play
           * @param milliseconds
           */
     133   void setMinIntervalOfRotationChanges(  Ogre::Real milliseconds );
          
           /**
           Emitted when an entity is added to the inventory.
           */
     138   sigc::signal<void,   EmberEntity* > EventAddedEntityToInventory;
          
           /**
           Emitted when an entity is removed from the inventory.
           */
     143   sigc::signal<void,   EmberEntity* > EventRemovedEntityFromInventory;
          
           /**
           True if the current user have admin rights,   i.e. is a "creator".
           */
     148   inline bool isAdmin(   ) const;
          
          protected:
          
           /**
           * adjust the avatar to the new position in the terrain
           * for now this means setting the correct heigth
           * accoring to mercator terrain,   but it will probably
           * be extended to also include stuff as positioning the avatars feet
           * right
           */
     159   void adjustAvatarToNewPosition(  AvatarControllerMovement* movement );
          
           /**
           * This method will determine if it's ok to send a small movement change,   such as
           * a small deviation direction during an already begun movement to the server.
           */
     165   bool isOkayToSendRotationMovementChangeToServer(   );
          
           /**
           Time in milliseconds since we last sent an movement update to the server.
           */
     170   Ogre::Real mTimeSinceLastServerMessage;
          
           /**
           In milliseconds,   the minimum time we must wait between sending updates to the server. Set this higher to avoid spamming the server.
           */
     175   Ogre::Real mMinIntervalOfRotationChanges;
          
           /**
           In degrees the minimum amount of degrees we can yaw the camera until we need to send an update to the server of our new position.
           */
     180   Ogre::Real mThresholdDegreesOfYawForAvatarRotation;
          
           /**
           In degrees the accumulated yaw movement since we last sent an update to the server. If this exceeds mThresholdDegreesOfYawForAvatarRotation we need to send an update to the server.
           */
           float mAccumulatedHorizontalRotation;
          
           /**
           * Attempts to move the avatar in a certain direction
           * Note that depending on what the rules allows (  i.e. collision detection,  
           * character rules etc. ) the outcome of the attempt is uncertain.
           *
           * The parameter timeSlice denotes the slice of time under which the movement
           * shall take place.
           */
     195   void attemptMove(  AvatarControllerMovement& movement );
          
           /**
           * Attempts to rotate the avatar to a certain direction
           * Note that depending on what the rules allows (  i.e. collision detection,  
           * character rules etc. ) the outcome of the attempt is uncertain.
           *
           * When standing still one can rotate how much one want.
           * But when moving,   rotation happens in interval
           *
           */
     206   void attemptRotate(  AvatarControllerMovement& movement );
          
          
           /**
           * Attempts to stop the avatar.
           * This should work in most cases.
           *
           */
     214   void attemptStop(   );
          
           /**
           * Attempt to jump.
           */
     219   void attemptJump(   );
          
          
           /**
           * Creates the avatar. We'll have to extend this functionality later on to
           * allow for different avatars.
           */
     226   void createAvatar(   );
          
          
           /**
           * Creates and sets up the different cameras.
           */
     232   void createAvatarCameras(  Ogre::SceneNode* avatarSceneNode );
          
           /**
           * How many meters per second the avatar can walk.
           * This should be set through some kind of rule checking with the server
           * depending on the character. To be done later.
           */
           float mWalkSpeed;
          
           /**
           * How many meters per second the avatar can run.
           * This should be set through some kind of rule checking with the server
           * depending on the character. To be done later.
           */
           float mRunSpeed;
          
           /**
           * The main avatar model
           */
     251   Model::Model* mAvatarModel;
          
           /**
           * The main avatar scenenode
           */
     256   Ogre::SceneNode* mAvatarNode;
          
          
          
           /** node for rotating the model for the entity
           * if it's not looking in the -Z direction (  default )
           * To be removed once we've standarized on models
           */
     264   Ogre::SceneNode* mAvatarModelNode;
          
           /**
           The Eris::Entity which represents the Avatar.
           */
     269   AvatarEmberEntity* mErisAvatarEntity;
          
           /**
           * this is used to make sure starts and stops of movement is only sent to the server once
           */
           AvatarMovementState mCurrentMovementState;
           AvatarMovementState mMovementStateAtBeginningOfMovement; //this is perhaps not needed
           AvatarMovementState mMovementStateAtLastServerMessage;
          
           /**
           The instance responsible for listening for movement updates and sending those to the server.
           */
     281   AvatarController* mAvatarController;
          
           /**
           Keep a temporary list of entities that needs to be added to the inventory.
           */
     286   std::set<Eris::Entity*> mEntitiesToBeAddedToInventory;
          
           /**
           Keep a temporary list of entities that needs to be removed from the inventory.
           */
     291   std::set<Eris::Entity*> mEntitiesToBeRemovedFromInventory;
          
          
           /**
           * catch changes to the configuration
           * @param section
           * @param key
           */
     299   void ConfigService_EventChangedConfigItem(  const std::string& section,   const std::string& key );
          
           /**
           * Listen for location changes,   since after a location change we need to honour the onMoved updates even if we're in movement mode.
           * @param entity
           */
     305   void avatar_LocationChanged(  Eris::Entity* entity );
          
           /**
           * updates values from the configuration
           */
     310   void updateFromConfig(   );
          
           /**
           True if the current user have admin rights,   i.e. is a "creator".
           */
     315   bool mIsAdmin;
          
           /**
           If set to true,   the avatar has just changed location,   so the next onMoved operation will contain the new orientation and position information for the new location.
           */
     320   bool mHasChangedLocation;
          
          
          }; //End of class declaration
          
     325  bool Avatar::isAdmin(   ) const
          {
           return mIsAdmin;
          }
     329  Ogre::SceneNode* Avatar::getAvatarSceneNode(   ) const
          {
           return mAvatarNode;
          }
          
          }
          
          #endif // ENTITY_LISTENER_H

./components/ogre/AvatarCamera.cpp

          /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #include "AvatarCamera.h"
          #include "Avatar.h"
          #include "GUIManager.h"
          #include "EmberOgre.h"
          #include "EmberEntity.h"
          // #include "WorldEmberEntity.h"
          #include "MathConverter.h"
          
          
          #include "services/EmberServices.h"
          #include "services/config/ConfigService.h"
          #ifndef WIN32
          #include "services/sound/SoundService.h"
          #endif
          
          #include "MousePicker.h"
          // #include "jesus/JesusPickerObject.h"
          
          #include "SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeRaySceneQuery.h"
          #include "framework/Tokeniser.h"
          #include "framework/ConsoleBackend.h"
          
          #include "GUIManager.h"
          #include "input/Input.h"
          
          #include "IWorldPickListener.h"
          
          #include "framework/osdir.h"
          
          #ifdef __WIN32__
          #include <windows.h>
          #include <direct.h>
          #endif
          
          
          namespace EmberOgre {
          
      56  Recorder::Recorder(   ): mSequence(  0 ),   mAccruedTime(  0.0f ),   mFramesPerSecond(  20.0f )
          {
          }
          
      60  void Recorder::startRecording(   )
          {
           Ogre::Root::getSingleton(   ).addFrameListener(  this );
          }
      64  void Recorder::stopRecording(   )
          {
           Ogre::Root::getSingleton(   ).removeFrameListener(  this );
          }
          
      69  bool Recorder::frameStarted(  const Ogre::FrameEvent& event )
          {
           mAccruedTime += event.timeSinceLastFrame;
           if (  mAccruedTime >= (  1.0f / mFramesPerSecond ) ) {
           mAccruedTime = 0.0f;
           std::stringstream filename;
           filename << "screenshot_" << mSequence++ << ".tga";
           const std::string dir = Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getHomeDirectory(   ) + "/recordings/";
           try {
           //make sure the directory exists
          
           struct stat tagStat;
           int ret;
           ret = stat(   dir.c_str(   ),   &tagStat  );
           if (  ret == -1 ) {
           #ifdef __WIN32__
           mkdir(  dir.c_str(   ) );
           #else
           mkdir(  dir.c_str(   ),   S_IRWXU );
           #endif
           }
           } catch (  const std::exception& ex ) {
           S_LOG_FAILURE(  "Error when creating directory for screenshots. Message: " << std::string(  ex.what(   ) ) );
           stopRecording(   );
           return true;
           }
           try {
           // take screenshot
           EmberOgre::getSingleton(   ).getRenderWindow(   )->writeContentsToFile(  dir + filename.str(   ) );
           } catch (  const Ogre::Exception& ex ) {
           S_LOG_FAILURE(  "Could not write screenshot to disc. Message: "<< ex.getFullDescription(   ) );
           stopRecording(   );
           return true;
           }
           }
           return true;
          }
          
          
          
     109  AvatarCamera::AvatarCamera(  Ogre::SceneNode* avatarNode,   Ogre::SceneManager* sceneManager,   Ogre::RenderWindow* window,   GUIManager* guiManager,   Ogre::Camera* camera ) :
           SetCameraDistance(  "setcameradistance",   this,   "Set the distance of the camera." ),  
           ToggleRendermode(  "toggle_rendermode",   this,   "Toggle between wireframe and solid render modes." ),  
           ToggleFullscreen(  "toggle_fullscreen",   this,   "Switch between windowed and full screen mode." ),  
           Screenshot(  "screenshot",   this,   "Take a screenshot and write to disk." ),  
           Record(  "+record",   this,   "Record to disk." ),  
           mInvertCamera(  false ),  
           mGUIManager(  guiManager ),  
           mCamera(  camera ),  
           mAvatarNode(  0 ),  
           mSceneManager(  sceneManager ),  
           mDegreeOfPitchPerSecond(  50 ),  
           mDegreeOfYawPerSecond(  50 ),  
           degreePitch(  0 ),  
           degreeYaw(  0 ),  
           mWindow(  window ),  
           mViewPort(  0 ),  
           mClosestPickingDistance(  10000 ),  
           mLastPosition(  Ogre::Vector3::ZERO ),  
           mAdjustTerrainRaySceneQuery(  0 ),  
           mCameraRaySceneQuery(  0 ),  
           mIsAdjustedToTerrain(  true )
          // mLastOrientationOfTheCamera(  avatar->getOrientation(   ) )
          {
           createNodesForCamera(   );
           createViewPort(   );
           setAvatarNode(  avatarNode );
          
           /// Register this as a frame listener
           Ogre::Root::getSingleton(   ).addFrameListener(  this );
          
          
           if (  mGUIManager ) {
           mGUIManager->getInput(   ).EventMouseMoved.connect(  sigc::mem_fun(  *this,   &AvatarCamera::Input_MouseMoved ) );
           }
          
           Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->EventChangedConfigItem.connect(  sigc::mem_fun(  *this,   &AvatarCamera::ConfigService_EventChangedConfigItem ) );
          
           updateValuesFromConfig(   );
           createRayQueries(   );
          }
          
          AvatarCamera::~AvatarCamera(   )
          {
           Ogre::Root::getSingleton(   ).removeFrameListener(  this );
           EmberOgre::getSingleton(   ).getSceneManager(   )->destroyQuery(  mAdjustTerrainRaySceneQuery );
           EmberOgre::getSingleton(   ).getSceneManager(   )->destroyQuery(  mCameraRaySceneQuery );
          }
          
          void AvatarCamera::createRayQueries(   )
          {
           mAdjustTerrainRaySceneQuery = EmberOgre::getSingletonPtr(   )->getSceneManager(   )->createRayQuery(  mAdjustTerrainRay,   Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK );
           ///only test for terrain
           mAdjustTerrainRaySceneQuery->setWorldFragmentType(  Ogre::SceneQuery::WFT_SINGLE_INTERSECTION );
           mAdjustTerrainRaySceneQuery->setSortByDistance(  true );
           mAdjustTerrainRaySceneQuery->setQueryTypeMask(  Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK );
          
          
           unsigned long queryMask = Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK;
           queryMask |= MousePicker::CM_AVATAR;
           queryMask |= MousePicker::CM_ENTITY;
           queryMask |= MousePicker::CM_NATURE;
           queryMask |= MousePicker::CM_UNDEFINED;
          // queryMask |= Ogre::RSQ_FirstTerrain;
          
           mCameraRaySceneQuery = mSceneManager->createRayQuery(   Ogre::Ray(   ),   queryMask );
           mCameraRaySceneQuery->setWorldFragmentType(  Ogre::SceneQuery::WFT_SINGLE_INTERSECTION );
           mCameraRaySceneQuery->setSortByDistance(  true );
          
          }
          
          
          void AvatarCamera::createNodesForCamera(   )
          {
           mAvatarCameraRootNode = mSceneManager->createSceneNode(  "AvatarCameraRootNode" );
           //we need to adjust for the height of the avatar mesh
           mAvatarCameraRootNode->setPosition(  Ogre::Vector3(  0,  2,  0 ) );
           //rotate to sync with WF world
           mAvatarCameraRootNode->rotate(  Ogre::Vector3::UNIT_Y,  (  Ogre::Degree )-90 );
          
           mAvatarCameraPitchNode = mAvatarCameraRootNode->createChildSceneNode(  "AvatarCameraPitchNode" );
           mAvatarCameraPitchNode->setPosition(  Ogre::Vector3(  0,  0,  0 ) );
           mAvatarCameraNode = mAvatarCameraPitchNode->createChildSceneNode(  "AvatarCameraNode" );
           setCameraDistance(  10 );
          
          // mCamera = mSceneManager->createCamera(  "AvatarCamera" );
           mAvatarCameraNode->attachObject(  mCamera );
           // Look to the Avatar's head
           //mAvatar3pCamera->setAutoTracking(  true,   mAvatar1pCameraNode );
           mCamera->setNearClipDistance(  0.5 );
          
           ///set the far clip distance high to make sure that the sky is completely shown
           if (  Ogre::Root::getSingleton(   ).getRenderSystem(   )->getCapabilities(   )->hasCapability(  Ogre::RSC_INFINITE_FAR_PLANE ) )
           {
          /* //NOTE: this won't currently work with the sky
           mCamera->setFarClipDistance(  0 );*/
          
           mCamera->setFarClipDistance(  10000 );
           } else {
           mCamera->setFarClipDistance(  10000 );
           }
          
           //create the nodes for the camera
           setMode(  MODE_THIRD_PERSON );
          // createViewPort(   );
          }
          
          void AvatarCamera::setMode(  Mode mode )
          {
           mMode = mode;
          /* if (  mMode == MODE_THIRD_PERSON ) {
           mCamera->setAutoTracking(  true,   mAvatarCameraRootNode );
           } else {
           mCamera->setAutoTracking(  false );
           }*/
          
          
          }
          
          const Ogre::Quaternion& AvatarCamera::getOrientation(  bool onlyHorizontal ) const {
           if (  !onlyHorizontal ) {
           return getCamera(   )->getDerivedOrientation(   );
           } else {
           static Ogre::Quaternion quat;
           quat = getCamera(   )->getDerivedOrientation(   );
           quat.x = 0;
           quat.z = 0;
           return quat;
           }
          }
          
          const Ogre::Vector3& AvatarCamera::getPosition(   ) const
          {
           return mCamera->getDerivedPosition(   );
          }
          
          void AvatarCamera::attach(  Ogre::SceneNode* toNode ) {
           mIsAttached = true;
           assert(  mAvatarCameraRootNode );
           if (  mAvatarCameraRootNode->getParent(   ) ) {
           mAvatarCameraRootNode->getParent(   )->removeChild(  mAvatarCameraRootNode->getName(   ) );
           }
           toNode->addChild(  mAvatarCameraRootNode );
          
           setCameraDistance(  10 );
           mAvatarCameraNode->setOrientation(  Ogre::Quaternion::IDENTITY );
           mAvatarCameraNode->_update(  true,   true );
           std::stringstream ss;
           ss << "Attached camera to node: " << toNode->getName(   ) <<". New position: " << mCamera->getWorldPosition(   ) << " New orientation: " << mCamera->getWorldOrientation(   );
           S_LOG_VERBOSE(  ss.str(   ) );
          }
          
          
          void AvatarCamera::enableCompositor(  const std::string& compositorName,   bool enable )
          {
           if (  std::find(  mLoadedCompositors.begin(   ),   mLoadedCompositors.end(   ),   compositorName ) == mLoadedCompositors.end(   ) ) {
           Ogre::CompositorManager::getSingleton(   ).addCompositor(  mWindow->getViewport(  0 ),   compositorName );
           }
           Ogre::CompositorManager::getSingleton(   ).setCompositorEnabled(  mWindow->getViewport(  0 ),   compositorName,   enable );
          }
          
          void AvatarCamera::createViewPort(   )
          {
          
          // Ogre::CompositorManager::getSingleton(   ).addCompositor(  mWindow->getViewport(  0 ),   "Bloom" );
          // Ogre::CompositorManager::getSingleton(   ).setCompositorEnabled(  mWindow->getViewport(  0 ),   "Bloom",   true );
          
          // assert(  mCamera );
          // assert(  !mViewPort );
          // // Create 1st person viewport,   entire window
          // mViewPort = mWindow->addViewport(  mCamera );
          // mViewPort->setBackgroundColour(  Ogre::ColourValue(  0,  0,  0 ) );
          // mCamera->setAspectRatio(  
          // Ogre::Real(  mViewPort->getActualWidth(   ) ) / Ogre::Real(  mViewPort->getActualHeight(   ) ) );
          
          
          }
          
          
          void AvatarCamera::toggleRenderMode(   )
          {
           S_LOG_INFO(  "Switching render mode." );
           if (  mCamera->getPolygonMode(   ) == Ogre::PM_SOLID ) {
           mCamera->setPolygonMode(  Ogre::PM_WIREFRAME );
           } else {
           mCamera->setPolygonMode(  Ogre::PM_SOLID );
           }
          }
          
          void AvatarCamera::setAvatarNode(  Ogre::SceneNode* sceneNode )
          {
           mAvatarNode = sceneNode;
           attach(  mAvatarNode );
          }
          
          void AvatarCamera::setCameraDistance(  Ogre::Real distance )
          {
           mWantedCameraDistance = distance;
           _setCameraDistance(  distance );
          }
          
          void AvatarCamera::_setCameraDistance(  Ogre::Real distance )
          {
           mCurrentCameraDistance = distance;
           Ogre::Vector3 pos(  0,  0,  distance );
           mAvatarCameraNode->setPosition(  pos );
           EventChangedCameraDistance.emit(  distance );
          }
          
          void AvatarCamera::pitch(  Ogre::Degree degrees )
          {
           if (  mInvertCamera ) {
           degrees -= degrees * 2;
           }
           if (  mMode == MODE_THIRD_PERSON ) {
           degreePitch += degrees;
           mAvatarCameraPitchNode->pitch(  degrees );
           } else {
           mAvatarCameraNode->pitch(  degrees );
           }
          }
          void AvatarCamera::yaw(  Ogre::Degree degrees )
          {
           if (  mMode == MODE_THIRD_PERSON ) {
           degreeYaw += degrees;
           mAvatarCameraRootNode->yaw(  degrees );
          
           mAvatarCameraRootNode->needUpdate(   );
          // Ogre::Quaternion q = mAvatarCameraRootNode->_getDerivedOrientation(   );
           } else {
           mAvatarCameraNode->yaw(  degrees );
           }
          
          }
          
          void AvatarCamera::Input_MouseMoved(  const MouseMotion& motion,   Input::InputMode mode )
          /*(  int xPosition,   int yPosition,   Ogre::Real xRelativeMovement,   Ogre::Real yRelativeMovement,   Ogre::Real timeSinceLastMovement )*/
          {
           if (  mode == Input::IM_MOVEMENT ) {
           Ogre::Degree diffX(  mDegreeOfYawPerSecond * motion.xRelativeMovement );
           Ogre::Degree diffY(  mDegreeOfPitchPerSecond * motion.yRelativeMovement );
          
           if (  diffX.valueDegrees(   ) ) {
           this->yaw(  diffX );
           // this->yaw(  diffX * e->timeSinceLastFrame );
           }
           if (  diffY.valueDegrees(   ) ) {
           this->pitch(  diffY );
           // this->pitch(  diffY * e->timeSinceLastFrame );
           }
          
           if (  diffY.valueDegrees(   ) || diffX.valueDegrees(   ) ) {
           MovedCamera.emit(  mCamera );
           }
           }
          }
          
          
          
          
          void AvatarCamera::pickInWorld(  Ogre::Real mouseX,   Ogre::Real mouseY,   const MousePickerArgs& mousePickerArgs )
          {
           S_LOG_INFO(  "Trying to pick an entity at mouse coords: " << Ogre::StringConverter::toString(  mouseX ) << ":" << Ogre::StringConverter::toString(  mouseY ) << "." );
          
           /// Start a new ray query
           Ogre::Ray cameraRay = getCamera(   )->getCameraToViewportRay(   mouseX,   mouseY  );
          
           mCameraRaySceneQuery->setRay(  cameraRay );
           mCameraRaySceneQuery->execute(   );
          
          
           ///now check the entity picking
           Ogre::RaySceneQueryResult& queryResult = mCameraRaySceneQuery->getLastResults(   );
           bool continuePicking = true;
          
           for (  WorldPickListenersStore::iterator I = mPickListeners.begin(   ); I != mPickListeners.end(   ); ++I ) {
           (  *I )->initializePickingContext(   );
           }
          
          
           Ogre::RaySceneQueryResult::iterator rayIterator = queryResult.begin(    );
           Ogre::RaySceneQueryResult::iterator rayIterator_end = queryResult.end(    );
           if (  rayIterator != rayIterator_end ) {
           for (   ; rayIterator != rayIterator_end && continuePicking; rayIterator++  ) {
           for (  WorldPickListenersStore::iterator I = mPickListeners.begin(   ); I != mPickListeners.end(   ); ++I ) {
           (  *I )->processPickResult(  continuePicking,   *rayIterator,   cameraRay,   mousePickerArgs );
           if (  !continuePicking ) {
           break;
           }
           }
           }
           }
          
           for (  WorldPickListenersStore::iterator I = mPickListeners.begin(   ); I != mPickListeners.end(   ); ++I ) {
           (  *I )->endPickingContext(  mousePickerArgs );
           }
          }
          
           bool AvatarCamera::worldToScreen(  const Ogre::Vector3& worldPos,   Ogre::Vector3& screenPos )
           {
          
           Ogre::Vector3 hcsPosition = mCamera->getProjectionMatrix(   ) * (  mCamera->getViewMatrix(   ) * worldPos );
          
           if (  (  hcsPosition.x < -1.0f ) ||
           (  hcsPosition.x > 1.0f ) ||
           (  hcsPosition.y < -1.0f ) ||
           (  hcsPosition.y > 1.0f ) )
           return false;
          
          
           screenPos.x = (  hcsPosition.x + 1 ) * 0.5;
           screenPos.y = (  -hcsPosition.y + 1 ) * 0.5;
          
           return true;
           }
          
           void AvatarCamera::setClosestPickingDistance(  Ogre::Real distance )
           {
           mClosestPickingDistance = distance;
           }
          
           Ogre::Real AvatarCamera::getClosestPickingDistance(   )
           {
           return mClosestPickingDistance;
           }
          
           bool AvatarCamera::adjustForTerrain(   )
           {
           /// We will shoot a ray from the camera base node to the camera. If it hits anything on the way we know that there's something between the camera and the avatar and we'll position the camera closer to the avatar. Thus we'll avoid having the camera dip below the terrain
           ///For now we'll only check against the terrain
           const Ogre::Vector3 direction(  -mCamera->getDerivedDirection(   ) );
           ///If the direction if pointing straight upwards we'll end up in an infinite loop in the ray query
           if (  direction.z != 0 ) {
          
           mAdjustTerrainRay.setDirection(  direction );
           mAdjustTerrainRay.setOrigin(  mAvatarCameraRootNode->getWorldPosition(   ) );
          
           mAdjustTerrainRaySceneQuery->setRay(  mAdjustTerrainRay );
          
           mAdjustTerrainRaySceneQuery->execute(   );
          
           Ogre::RaySceneQueryResult queryResult = mAdjustTerrainRaySceneQuery->getLastResults(   );
           Ogre::RaySceneQueryResult::iterator rayIterator = queryResult.begin(    );
           for (   ; rayIterator != queryResult.end(   ); ++rayIterator  ) {
           Ogre::RaySceneQueryResultEntry& entry = *rayIterator;
          
           if (  entry.worldFragment ) {
           Ogre::Vector3 position = entry.worldFragment->singleIntersection;
           Ogre::Real distance = mAvatarCameraRootNode->getWorldPosition(   ).distance(  position );
           if (  distance < mWantedCameraDistance ) {
           _setCameraDistance(  distance - 0.1 );
           } else {
           if (  mWantedCameraDistance != mCurrentCameraDistance ) {
           _setCameraDistance(  mWantedCameraDistance );
           }
           }
           break;
           }
           }
           }
          
          /* Ogre::RaySceneQuery *raySceneQueryHeight = EmberOgre::getSingletonPtr(   )->getSceneManager(   )->createRayQuery(   Ogre::Ray(  mCamera->getDerivedPosition(   ),   Ogre::Vector3::NEGATIVE_UNIT_Y ),   Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK );
          
          
           raySceneQueryHeight->execute(   );
          
           //first check the terrain picking
           Ogre::RaySceneQueryResult queryResult = raySceneQueryHeight->getLastResults(   );
          
           if (  queryResult.begin(    ) != queryResult.end(   ) ) {
           Ogre::Vector3 position = queryResult.begin(   )->worldFragment->singleIntersection;
           Ogre::Real terrainHeight = position.y;
           //pad it a little
           //terrainHeight += 0.4;
           Ogre::Real cameraHeight = mCamera->getDerivedPosition(   ).y;
           Ogre::Real cameraNodeHeight = mAvatarCameraNode->getWorldPosition(   ).y;
           if (  terrainHeight > cameraHeight ) {
           mCamera->move(  mCamera->getDerivedOrientation(   ).Inverse(   ) * Ogre::Vector3(  0,  terrainHeight - cameraHeight,  0 ) );
          // mCamera->lookAt(  mAvatarCameraRootNode->getPosition(   ) );
          
           } else if (  cameraHeight != cameraNodeHeight ) {
           Ogre::Real newHeight = std::max<Ogre::Real>(  terrainHeight,   cameraNodeHeight );
           mCamera->move(  Ogre::Vector3(  0,  newHeight - cameraHeight,  0 ) );
           mCamera->lookAt(  mAvatarCameraRootNode->getWorldPosition(   ) );
          
           }
          
           }*/
          
           return true;
           }
          
          void AvatarCamera::runCommand(  const std::string &command,   const std::string &args )
          {
           if(  Screenshot == command ) {
           //just take a screen shot
           takeScreenshot(   );
           } else if(  SetCameraDistance == command )
           {
           Ember::Tokeniser tokeniser;
           tokeniser.initTokens(  args );
           std::string distance = tokeniser.nextToken(   );
           if (  distance != "" ) {
           float fDistance = Ogre::StringConverter::parseReal(  distance );
           setCameraDistance(  fDistance );
           }
           } else if (  ToggleFullscreen == command ){
           SDL_WM_ToggleFullScreen(  SDL_GetVideoSurface(   ) );
          
           } else if (  ToggleRendermode == command ) {
           toggleRenderMode(   );
           } else if (  Record == command ) {
           mRecorder.startRecording(   );
           } else if (  Record.getInverseCommand(   ) == command ) {
           mRecorder.stopRecording(   );
           }
          }
          
          void AvatarCamera::updateValuesFromConfig(   )
          {
           if (  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->itemExists(  "input",   "invertcamera" ) ) {
           mInvertCamera = static_cast<bool>(  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getValue(  "input",   "invertcamera" ) );
           }
           if (  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->itemExists(  "input",   "cameradegreespersecond" ) ) {
           mDegreeOfPitchPerSecond = mDegreeOfYawPerSecond = (  double )Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getValue(  "input",   "cameradegreespersecond" );
           }
           if (  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->itemExists(  "input",   "adjusttoterrain" ) ) {
           mIsAdjustedToTerrain = static_cast<bool>(  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getValue(  "input",   "adjusttoterrain" ) );
           }
          }
          
          void AvatarCamera::ConfigService_EventChangedConfigItem(  const std::string& section,   const std::string& key )
          {
           if (  section == "input" ) {
           if (  key == "invertcamera" || key == "cameradegreespersecond" || key == "adjusttoterrain" ) {
           updateValuesFromConfig(   );
           }
           }
          }
          
          bool AvatarCamera::frameStarted(  const Ogre::FrameEvent& event )
          {
           if (  mIsAdjustedToTerrain ) {
           if (  mCamera->getDerivedPosition(   ) != mLastPosition ) {
           adjustForTerrain(   );
           }
           }
           mLastPosition = mCamera->getDerivedPosition(   );
          // #ifndef WIN32
          // Ember::SoundService* mySoundService = Ember::EmberServices::getSingleton(   ).getSoundService(   );
          // {
          // mySoundService->updateListenerPosition(  
          // Ogre2Atlas(  mCamera->getPosition(   ) ),  
          // Ogre2Atlas(  mCamera->getOrientation(   ) ) );
          // }
          // #endif
           return true;
          }
          
          void AvatarCamera::pushWorldPickListener(  IWorldPickListener* worldPickListener )
          {
           mPickListeners.push_front(  worldPickListener );
          }
          
          const std::string AvatarCamera::_takeScreenshot(   )
          {
           // retrieve current time
           time_t rawtime;
           struct tm* timeinfo;
           time(  &rawtime );
           timeinfo = localtime(  &rawtime );
          
           // construct filename string
           // padding with 0 for single-digit values
           std::stringstream filename;
           filename << "screenshot_" << (  (  *timeinfo ).tm_year + 1900 ); // 1900 is year "0"
           int month = (  (  *timeinfo ).tm_mon + 1 ); // January is month "0"
           if(  month <= 9 )
           {
           filename << "0";
           }
           filename << month;
           int day = (  *timeinfo ).tm_mday;
           if(  day <= 9 )
           {
           filename << "0";
           }
           filename << day << "_";
           int hour = (  *timeinfo ).tm_hour;
           if(  hour <= 9 )
           {
           filename << "0";
           }
           filename << hour;
           int min = (  *timeinfo ).tm_min;
           if(  min <= 9 )
           {
           filename << "0";
           }
           filename << min;
           int sec = (  *timeinfo ).tm_sec;
           if(  sec <= 9 )
           {
           filename << "0";
           }
           filename << sec << ".jpg";
          
           const std::string dir = Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getHomeDirectory(   ) + "/screenshots/";
           try {
           //make sure the directory exists
          
           oslink::directory osdir(  dir );
          
           if (  !osdir.isExisting(   ) ) {
          #ifdef __WIN32__
           mkdir(  dir.c_str(   ) );
          #else
           mkdir(  dir.c_str(   ),   S_IRWXU );
          #endif
           }
           } catch (  const std::exception& ex ) {
           S_LOG_FAILURE(  "Error when creating directory for screenshots. Message: " << std::string(  ex.what(   ) ) );
           throw Ember::Exception(  "Error when saving screenshot. Message: " + std::string(  ex.what(   ) ) );
           }
          
           try {
           // take screenshot
           mWindow->writeContentsToFile(  dir + filename.str(   ) );
           } catch (  const Ogre::Exception& ex ) {
           S_LOG_FAILURE(  "Could not write screenshot to disc. Message: "<< ex.getFullDescription(   ) );
           throw Ember::Exception(  "Error when saving screenshot. Message: " + ex.getDescription(   ) );
           }
           return dir + filename.str(   );
          }
          
          void AvatarCamera::takeScreenshot(   )
          {
           try {
           const std::string& result = _takeScreenshot(   );
           S_LOG_INFO(  result );
           Ember::ConsoleBackend::getMainConsole(   )->pushMessage(  "Wrote image: " + result );
           } catch (  const Ember::Exception& ex ) {
           Ember::ConsoleBackend::getMainConsole(   )->pushMessage(  "Error when saving screenshot: " + ex.getError(   ) );
           }
          }
          
          }
          
          
          
          
          

./components/ogre/AvatarCamera.h

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          
          /*
           * An instance of this is a player controlled camera fastened to the Avatar.
           * It should be possible to subclass this in order to provide different behaviour
           */
          
          
          #ifndef AVATARCAMERA_H
          #define AVATARCAMERA_H
          
          #include "EmberOgrePrerequisites.h"
          
          #include <sigc++/trackable.h>
          
          
          #include "framework/ConsoleObject.h"
          
          #include "input/Input.h"
          #include <stack>
          
          namespace EmberOgre {
          
      41  class Avatar;
      42  class InputManager;
      43  class GUIManager;
      44  class EmberEntity;
          struct MouseMotion;
          struct EntityPickResult;
      47  class IWorldPickListener;
          struct MousePickerArgs;
          
      50  class Recorder :public Ogre::FrameListener
          {
          public:
      53   Recorder(   );
      54   void startRecording(   );
      55   void stopRecording(   );
           /**
           * Methods from Ogre::FrameListener
           */
      59   bool frameStarted(  const Ogre::FrameEvent& event );
          private:
           int mSequence;
           float mAccruedTime;
           float mFramesPerSecond;
          };
          
          
      67  class AvatarCamera
          :
      69  public sigc::trackable,  
      70  public Ember::ConsoleObject,  
      71  public Ogre::FrameListener
          {
          public:
          
           enum Mode {
           MODE_THIRD_PERSON = 1,  
           MODE_FIRST_PERSON = 2
           };
          
      80   AvatarCamera(  Ogre::SceneNode* avatarNode,   Ogre::SceneManager* sceneManager,   Ogre::RenderWindow* window,   GUIManager* guiManager,   Ogre::Camera* camera );
      81   virtual ~AvatarCamera(   );
          
           /**
           * Pitches the camera the supplied degrees
           */
      86   virtual void pitch(  Ogre::Degree degrees );
          
           /**
           * Yaws the camera the supplied degrees
           */
      91   virtual void yaw(  Ogre::Degree degrees );
          
           /**
           * returns the current degrees of pitch from the cameras initial position
           */
      96   inline const Ogre::Degree& getPitch(   ) const;
          
           /**
           * returns the current degrees of yaw from the cameras initial position
           */
     101   inline const Ogre::Degree& getYaw(   ) const;
          
           /**
           * returns a pointer to the Ogre::Camera instance
           */
     106   inline Ogre::Camera* getCamera(   );
     107   inline Ogre::Camera* getCamera(   ) const;
          
           /**
           * Returns the current camera orientation in the world
           */
     112   virtual const Ogre::Quaternion& getOrientation(  bool onlyHorizontal = true ) const;
          
          
           /**
           * Returns the position of the camera in the world.
           * @return
           */
     119   const Ogre::Vector3& getPosition(   ) const;
          
          
     122   void setMode(  Mode mode );
          
           /**
           * sets the node to which the camera is attached
           */
     127   virtual void setAvatarNode(  Ogre::SceneNode* sceneNode );
          
           /**
           * emitted when the camra moves
           */
     132   sigc::signal<void,   Ogre::Camera*> MovedCamera;
          
           /**
           * emitted when the distance between the camera and the avatar has changed
           * @param Ogre::Real the new distance
           */
     138   sigc::signal<void,   Ogre::Real> EventChangedCameraDistance;
          
          // int xPosition,   int yPosition,   Ogre::Real xRelativeMovement,   Ogre::Real yRelativeMovement,   Ogre::Real timeSinceLastMovement );
          
          // void mouseMoved (  Ogre::MouseEvent *e );
          // void mouseDragged (  Ogre::MouseEvent *e ) {};
          
     145   void pickInWorld(  Ogre::Real mouseX,   Ogre::Real mouseY,   const MousePickerArgs& args );
          
          // EntityPickResult pickAnEntity(  Ogre::Real mouseX,   Ogre::Real mouseY );
          // std::vector<Ogre::RaySceneQueryResultEntry> AvatarCamera::pickObject(  Ogre::Real mouseX,   Ogre::Real mouseY,   std::vector<Ogre::UserDefinedObject*> exclude,   unsigned long querymask  );
          
     150   void setClosestPickingDistance(  Ogre::Real distance );
     151   Ogre::Real getClosestPickingDistance(   );
          
           /**
           * returns true if the worldPos is on screen,   putting the screen pos into the x & y of the second Vector3
           * returns false if the worldPos is off screen
           * @param worldPos
           * @param screenPos
           * @return
           */
     160   bool worldToScreen(  const Ogre::Vector3& worldPos,   Ogre::Vector3& screenPos );
          
           /**
           * Attaches the camera to the specified scene node.
           * @param toNode
           */
     166   void attach(  Ogre::SceneNode* toNode );
          
           /**
           * Adjusts the camera for the terrain,   so it doesn't dip below it.
           * @return
           */
     172   bool adjustForTerrain(   );
          
          
           /**
           * Reimplements the ConsoleObject::runCommand method
           * @param command
           * @param args
           */
     180   virtual void runCommand(  const std::string &command,   const std::string &args );
          
          
           /**
           * Sets the distance from the camera to the avatar.
           * @param distance the new distance
           */
     187   void setCameraDistance(  Ogre::Real distance );
          
           /**
           * Methods from Ogre::FrameListener
           */
     192   bool frameStarted(  const Ogre::FrameEvent& event );
           //bool frameEnded(  const Ogre::FrameEvent& event );
          
           /**
           * Enables and disables a compositor by name.
           * @param compositorName
           * @param enable
           */
     200   void enableCompositor(  const std::string& compositorName,   bool enable );
          
          
           /**
           * Adds a new world pick listener to the queue of listeners.
           * @param worldPickListener
           */
     207   void pushWorldPickListener(  IWorldPickListener* worldPickListener );
          
     209   const Ember::ConsoleCommandWrapper SetCameraDistance;
     210   const Ember::ConsoleCommandWrapper ToggleRendermode;
     211   const Ember::ConsoleCommandWrapper ToggleFullscreen;
     212   const Ember::ConsoleCommandWrapper Screenshot;
     213   const Ember::ConsoleCommandWrapper Record;
          
           /**
           Toggles between wireframe and solid render mode.
           */
     218   void toggleRenderMode(   );
          
           /**
           * takes a screen shot and writes it to disk
           */
     223   void takeScreenshot(   );
          
          protected:
          
           typedef std::deque<IWorldPickListener*> WorldPickListenersStore;
     228   WorldPickListenersStore mPickListeners;
          
           typedef std::vector<std::string> CompositorNameStore;
          
     232   Recorder mRecorder;
          
     234   CompositorNameStore mLoadedCompositors;
          
           Mode mMode;
          
     238   bool mIsAttached;
          
           /**
           If true,   the camera is inverted in the y axis.
           */
     243   bool mInvertCamera;
          
           /**
           Creates the rays needed for mouse picking and camera adjustment.
           */
     248   void createRayQueries(   );
          
          
           /**
           * creates all nodes needed for the camera
           */
     254   void createNodesForCamera(   );
          
     256   const std::string _takeScreenshot(   );
          
     258   void createViewPort(   );
     259   GUIManager* mGUIManager;
          
          
     262   Ogre::Camera* mCamera;
     263   Ogre::SceneNode* mAvatarNode;
     264   Ogre::SceneManager* mSceneManager;
           //Ogre::Quaternion mLastOrientationOfTheCamera;
          
     267   Ogre::SceneNode* mAvatarCameraRootNode;
     268   Ogre::SceneNode* mAvatarCameraPitchNode;
     269   Ogre::SceneNode* mAvatarCameraNode;
          
     271   Ogre::Degree mDegreeOfPitchPerSecond;
     272   Ogre::Degree mDegreeOfYawPerSecond;
          
     274   Ogre::Degree degreePitch;
     275   Ogre::Degree degreeYaw;
     276   Ogre::RenderWindow* mWindow;
     277   Ogre::Viewport* mViewPort;
          
           //in meters how far we can pick objects
     280   Ogre::Real mClosestPickingDistance;
          
     282   Ogre::Vector3 mLastPosition;
     283   Ogre::Real mWantedCameraDistance,   mCurrentCameraDistance;
          
     285   Ogre::RaySceneQuery *mAdjustTerrainRaySceneQuery,   *mCameraRaySceneQuery;
     286   Ogre::Ray mAdjustTerrainRay;
          
     288   bool mIsAdjustedToTerrain;
          
     290   void Input_MouseMoved(  const MouseMotion& motion,   Input::InputMode mode );
          
     292   void ConfigService_EventChangedConfigItem(  const std::string& section,   const std::string& key );
          
     294   void updateValuesFromConfig(   );
          
           /**
           * Internal method for setting the camera distance.
           * @param distance the new distance
           */
     300   void _setCameraDistance(  Ogre::Real distance );
          
          };
          
          
          ///inline implementations
          
     307   const Ogre::Degree& AvatarCamera::getPitch(   ) const
           {
           return degreePitch;
           }
          
     312   const Ogre::Degree& AvatarCamera::getYaw(   ) const
           {
           return degreeYaw;
           }
          
     317   Ogre::Camera* AvatarCamera::getCamera(   ) {
           return mCamera;
           }
     320   Ogre::Camera* AvatarCamera::getCamera(   ) const {
           return mCamera;
           }
          
          
          
     326  class ICameraMount
          {
     328   virtual ~ICameraMount(   ) {};
          
           /**
           * Pitches the camera the supplied degrees
           */
     333   virtual void pitch(  Ogre::Degree degrees ) = 0;
          
           /**
           * Yaws the camera the supplied degrees
           */
     338   virtual void yaw(  Ogre::Degree degrees ) = 0;
          
           /**
           * returns the current degrees of pitch from the cameras initial position
           */
     343   virtual const Ogre::Degree& getPitch(   ) const = 0;
          
           /**
           * returns the current degrees of yaw from the cameras initial position
           */
     348   virtual const Ogre::Degree& getYaw(   ) const = 0;
          
           /**
           * Returns the current camera orientation in the world
           */
     353   virtual const Ogre::Quaternion& getOrientation(  bool onlyHorizontal = true ) const = 0;
          
           /**
           * Returns the position of the camera in the world.
           * @return
           */
     359   virtual const Ogre::Vector3& getPosition(   ) const = 0;
          
     361   void setMode(  AvatarCamera::Mode mode );
          
           /**
           * sets the node to which the camera is attached
           */
     366   virtual void setAvatarNode(  Ogre::SceneNode* sceneNode );
          
          };
          
     370  class MainCamera
          {
     372   virtual ~MainCamera(   ) {}
          
           /**
           * returns a pointer to the Ogre::Camera instance
           */
     377   inline Ogre::Camera* getCamera(   );
     378   inline Ogre::Camera* getCamera(   ) const;
          
           /**
           * emitted when the camra moves
           */
     383   sigc::signal<void,   Ogre::Camera*> MovedCamera;
          
          
     386   void pickInWorld(  Ogre::Real mouseX,   Ogre::Real mouseY,   const MousePickerArgs& args );
          
     388   void setClosestPickingDistance(  Ogre::Real distance );
     389   Ogre::Real getClosestPickingDistance(   );
          
           /**
           * returns true if the worldPos is on screen,   putting the screen pos into the x & y of the second Vector3
           * returns false if the worldPos is off screen
           * @param worldPos
           * @param screenPos
           * @return
           */
     398   bool worldToScreen(  const Ogre::Vector3& worldPos,   Ogre::Vector3& screenPos );
          
           /**
           * Reimplements the ConsoleObject::runCommand method
           * @param command
           * @param args
           */
     405   virtual void runCommand(  const std::string &command,   const std::string &args );
          
           /**
           * Methods from Ogre::FrameListener
           */
     410   bool frameStarted(  const Ogre::FrameEvent& event );
          
           /**
           * Enables and disables a compositor by name.
           * @param compositorName
           * @param enable
           */
     417   void enableCompositor(  const std::string& compositorName,   bool enable );
          
          
           /**
           * Adds a new world pick listener to the queue of listeners.
           * @param worldPickListener
           */
     424   void pushWorldPickListener(  IWorldPickListener* worldPickListener );
          
     426   const Ember::ConsoleCommandWrapper ToggleRendermode;
     427   const Ember::ConsoleCommandWrapper ToggleFullscreen;
     428   const Ember::ConsoleCommandWrapper Screenshot;
     429   const Ember::ConsoleCommandWrapper Record;
          
           /**
           Toggles between wireframe and solid render mode.
           */
     434   void toggleRenderMode(   );
          
           /**
           * takes a screen shot and writes it to disk
           */
     439   void takeScreenshot(   );
          
          };
          
     443  class AvatarCameraMount : ICameraMount
          {
           /**
           * emitted when the distance between the camera and the avatar has changed
           * @param Ogre::Real the new distance
           */
     449   sigc::signal<void,   Ogre::Real> EventChangedCameraDistance;
          
           /**
           * Sets the distance from the camera to the avatar.
           * @param distance the new distance
           */
     455   void setCameraDistance(  Ogre::Real distance );
          
     457   const Ember::ConsoleCommandWrapper SetCameraDistance;
          
          };
          
     461  class FreeFlyingMount : ICameraMount
          {
          };
          
          
          
          }
          
          #endif // AVATARCAMERA_H

./components/ogre/AvatarController.cpp

          /*
           Copyright (  C ) 2004 Erik Hjortsberg
           some parts Copyright (  C ) 2004 bad_camel at Ogre3d forums
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          
          
          #include "AvatarController.h"
          
          
          #include "EmberEntity.h"
          #include "EmberPhysicalEntity.h"
          #include "AvatarEmberEntity.h"
          #include "AvatarCamera.h"
          #include "GUIManager.h"
          #include "Avatar.h"
          #include "EmberOgre.h"
          // #include "SceneManagers/EmberPagingSceneManager/include/EmberPagingSceneManager.h"
          #include "terrain/TerrainGenerator.h"
          #include "terrain/ISceneManagerAdapter.h"
          
          
          #include "input/Input.h"
          
          #include "framework/Tokeniser.h"
          #include "MathConverter.h"
          #include "services/EmberServices.h"
          #include "services/server/ServerService.h"
          
          
          using namespace Ogre;
          namespace EmberOgre {
          
          
          AvatarControllerMovement::AvatarControllerMovement(   ) :
           rotationDegHoriz(  0 ),  
           rotationDegVert(  0 ),  
           timeSlice(  0 ),  
           movementDirection(  Ogre::Vector3::ZERO ),  
           mode(  AvatarMovementMode::MM_WALK ),  
           isMoving(  false )
          {
          }
          
          
          
      61  AvatarControllerInputListener::AvatarControllerInputListener(  AvatarController& controller )
          : mController(  controller )
          {
           Input::getSingleton(   ).EventMouseButtonPressed.connect(  sigc::mem_fun(  *this,   &AvatarControllerInputListener::input_MouseButtonPressed ) );
           Input::getSingleton(   ).EventMouseButtonReleased.connect(  sigc::mem_fun(  *this,   &AvatarControllerInputListener::input_MouseButtonReleased ) );
          
          }
          
      69  void AvatarControllerInputListener::input_MouseButtonPressed(  Input::MouseButton button,   Input::InputMode mode )
          {
           if (  mode == Input::IM_MOVEMENT && button == Input::MouseButtonLeft ) {
           mController.mMovementDirection.x = 1;
           }
          }
          
      76  void AvatarControllerInputListener::input_MouseButtonReleased(  Input::MouseButton button,   Input::InputMode mode )
          {
           if (  mode == Input::IM_MOVEMENT && button == Input::MouseButtonLeft ) {
           mController.mMovementDirection.x = 0;
           }
          }
          
      83  AvatarController::AvatarController(  Avatar* avatar,   Ogre::RenderWindow* window,   GUIManager* guiManager,   Ogre::Camera* camera )
          : RunToggle(  "+run",   this,   "Toggle running mode." )
      85  ,   ToggleCameraAttached(  "toggle_cameraattached",   this,   "Toggle between the camera being attached to the avatar and free flying." )
          ,   CharacterMoveForward(  "+character_move_forward",   this,   "Move the avatar forward." )
          ,   CharacterMoveBackward(  "+character_move_backward",   this,   "Move the avatar backward." )
          ,   CharacterMoveDownwards(  "+character_move_downwards",   this,   "Move the avatar downwards." )
          ,   CharacterMoveUpwards(  "+character_move_upwards",   this,   "Move the avatar upwards." )
          ,   CharacterStrafeLeft(  "+character_strafe_left",   this,   "Strafe left." )
          ,   CharacterStrafeRight(  "+character_strafe_right",   this,   "Strafe right." )
          /*,   CharacterRotateLeft(  "+character_rotate_left",   this,   "Rotate left." )
          ,   CharacterRotateRight(  "+character_rotate_right",   this,   "Rotate right." )*/
          ,   MoveCameraTo(  "movecamerato",   this,   "Moves the camera to a point." )
          ,   mMovementCommandMapper(  "movement",   "key_bindings_movement" )
          ,   mWindow(  window )
          ,   mGUIManager(  guiManager )
          ,   mAvatarCamera(  0 )
          ,   mCamera(  camera )
          ,   mEntityUnderCursor(  0 )
          ,   mSelectedEntity(  0 )
          ,   mFreeFlyingCameraNode(  0 )
          ,   mIsRunning(  false )
          ,   mMovementDirection(  Ogre::Vector3::ZERO )
          ,   mDecalObject(  0 )
          ,   mDecalNode(  0 )
          ,   mControllerInputListener(  *this )
          {
          
           mMovementCommandMapper.restrictToInputMode(  Input::IM_MOVEMENT  );
          
           setAvatar(  avatar );
          
          
           mAvatar->setAvatarController(  this );
          
           Ogre::Root::getSingleton(   ).addFrameListener(  this );
          
          
           mFreeFlyingCameraNode = EmberOgre::getSingleton(   ).getSceneManager(   )->getRootSceneNode(   )->createChildSceneNode(   );
           mFreeFlyingCameraNode->setPosition(  0,  30,  0 );
           detachCamera(   );
          
          
           mMovementCommandMapper.bindToInput(  Input::getSingleton(   ) );
          
           GUIManager::getSingleton(   ).getEntityPickListener(   )->EventPickedEntity.connect(  sigc::mem_fun(  *this,   &AvatarController::entityPicker_PickedEntity ) );
          
          }
     130  AvatarController::~AvatarController(   )
          {
           Ogre::Root::getSingleton(   ).removeFrameListener(  this );
           delete mAvatarCamera;
          }
          
     136  void AvatarController::createAvatarCameras(  Ogre::SceneNode* avatarSceneNode )
          {
           if (  mAvatarCamera == 0 ) {
           mAvatarCamera = new AvatarCamera(  avatarSceneNode,   EmberOgre::getSingletonPtr(   )->getSceneManager(   ),   mWindow,   mGUIManager,   mCamera );
           } else {
           attachCamera(   );
           }
          }
          
     145  void AvatarController::setAvatar(  Avatar* avatar )
          {
           mAvatar = avatar;
           createAvatarCameras(  avatar->getAvatarSceneNode(   ) );
           attachCamera(   );
          }
          
          
          
     154  void AvatarController::runCommand(  const std::string &command,   const std::string &args )
          {
           if (  RunToggle == command ) {
           mIsRunning = true;
           } else if (  RunToggle.getInverseCommand(   ) == command ) {
           mIsRunning = false;
           } else if (  ToggleCameraAttached == command )
           {
           if (  mIsAttached ) {
           detachCamera(   );
           } else {
           attachCamera(   );
           }
           } else if (  CharacterMoveForward == command ) {
           mMovementDirection.x = 1;
           } else if (  CharacterMoveForward.getInverseCommand(   ) == command ) {
           mMovementDirection.x = 0;
           } else if (  CharacterMoveBackward == command ) {
           mMovementDirection.x = -1;
           } else if (  CharacterMoveBackward.getInverseCommand(   ) == command ) {
           mMovementDirection.x = 0;
           } else if (  CharacterStrafeLeft == command ) {
           mMovementDirection.z = -1;
           } else if (  CharacterStrafeLeft.getInverseCommand(   ) == command ) {
           mMovementDirection.z = 0;
           } else if (  CharacterStrafeRight == command ) {
           mMovementDirection.z = 1;
           } else if (  CharacterStrafeRight.getInverseCommand(   ) == command ) {
           mMovementDirection.z = 0;
           } else if (  CharacterMoveUpwards == command ) {
           mMovementDirection.y = 1;
           } else if (  CharacterMoveUpwards.getInverseCommand(   ) == command ) {
           mMovementDirection.y = 0;
           } else if (  CharacterMoveDownwards == command ) {
           mMovementDirection.y = -1;
           } else if (  CharacterMoveDownwards.getInverseCommand(   ) == command ) {
           mMovementDirection.y = 0;
          /* } else if (  CharacterRotateLeft == command ) {
           mAvatarCamera->yaw(  Ogre::Degree(  -15 ) );
           } else if (  CharacterRotateRight == command ) {
           mAvatarCamera->yaw(  Ogre::Degree(  15 ) );*/
           } else if (  MoveCameraTo == command ) {
           if (  !mIsAttached ) {
           Ember::Tokeniser tokeniser;
           tokeniser.initTokens(  args );
           std::string x = tokeniser.nextToken(   );
           std::string y = tokeniser.nextToken(   );
           std::string z = tokeniser.nextToken(   );
          
           if (  x == "" || y == "" || z == "" ) {
           return;
           } else {
           Ogre::Vector3 position(  Ogre::StringConverter::parseReal(  x ),  Ogre::StringConverter::parseReal(  y ),  Ogre::StringConverter::parseReal(  z ) );
           mFreeFlyingCameraNode->setPosition(  position );
           }
           }
           }
          }
          
          
     214  void AvatarController::detachCamera(   )
          {
           mIsAttached = false;
           mAvatarCamera->attach(  mFreeFlyingCameraNode );
           //mAvatarCamera->setMode(  AvatarCamera::MODE_FIRST_PERSON );
          }
          
          
     222  void AvatarController::attachCamera(   )
          {
           mIsAttached = true;
           mAvatarCamera->attach(  mAvatar->getAvatarSceneNode(   ) );
           //mAvatarCamera->setMode(  AvatarCamera::MODE_FIRST_PERSON );
          }
          
          
     230  bool AvatarController::frameStarted(  const Ogre::FrameEvent& event )
          {
          
           if (  mDecalObject )
           {
           ///hide the decal when we're close to it
           if (  mDecalNode->getWorldPosition(   ).distance(  mAvatar->getAvatarSceneNode(   )->getWorldPosition(   ) ) < 1 ) {
           mDecalNode->setVisible(  false );
           }
           }
          
          // if (  mDecalObject ) {
          // Ogre::Real newSize = mPulsatingController->calculate(  event.timeSinceLastFrame );
          // //mDecalNode->setScale(  Ogre::Vector3(  newSize,   1.0f,   newSize ) );
          // // mDecalNode->yaw(  Ogre::Radian(  0.1f ) );
          // }
          
          // EmberPagingSceneManager* mScnMgr = static_cast<EmberPagingSceneManager*>(  EmberOgre::getSingleton(   ).getSceneManager(   ) );
          // if (  mGUIManager->getInput(   )->isKeyDown(  SDLK_F4 ) ) {
          // /* Real change;
          // mScnMgr->getOption(   "MaxPixelError",   &change  );
          // change -= 0.5f;
          // mScnMgr->setOption(   "MaxPixelError",   &change  ); */
          // --Ogre::PagingLandScapeOptions::getSingleton(   ).maxPixelError;
          // Ogre::PagingLandScapeOptions::getSingleton(   ).calculateCFactor(   );
          // mScnMgr->WorldDimensionChange(   );
          // }
          // if (  mGUIManager->getInput(   )->isKeyDown(  SDLK_F5 ) ) {
          // /* Real change;
          // mScnMgr->getOption(   "MaxPixelError",   &change  );
          // change += 0.5f;
          // mScnMgr->setOption(   "MaxPixelError",   &change  ); */
          // ++Ogre::PagingLandScapeOptions::getSingleton(   ).maxPixelError;
          // Ogre::PagingLandScapeOptions::getSingleton(   ).calculateCFactor(   );
          // mScnMgr->WorldDimensionChange(   );
          // }
          //
          
           movementForFrame = AvatarControllerMovement(   );
          
          /* if (  mMovementDirection != Ogre::Vector3::ZERO ) {*/
           movementForFrame.mode = mIsRunning ? AvatarMovementMode::MM_RUN : AvatarMovementMode::MM_WALK;
           movementForFrame.isMoving = true;
           movementForFrame.movementDirection = mMovementDirection;
           movementForFrame.timeSlice = event.timeSinceLastFrame;
           if (  movementForFrame.mode != mPreviousMovementForFrame.mode ) {
           EventMovementModeChanged.emit(  movementForFrame.mode );
           }
          // } else {
          // }
          
          // if (  mGUIManager->isInMovementKeysMode(   ) ) {
          // movementForFrame.movementDirection = Ogre::Vector3::ZERO;
          // movementForFrame.mIsRunning = false;
          // movementForFrame.isMoving = false;
          
          /* checkMovementKeys(  event,   EmberOgre::getSingleton(   ).getInput(   ) );
          
          
           movementForFrame.timeSlice = event.timeSinceLastFrame;
           } */
          
           if (  mIsAttached ) {
          // mAvatarCamera->adjustForTerrain(   );
           mAvatar->updateFrame(  movementForFrame );
           } else {
           Ogre::Real scaler = 50;
           //make this inverse,   so that when the run key is pressed,   the free flying camera goes slower
           //this is since we assume that one wants to go fast when in free flying mode
           if (  movementForFrame.mode == AvatarMovementMode::MM_RUN ) {
           scaler = 10;
           }
           Ogre::Vector3 correctDirection(  movementForFrame.movementDirection.z,   movementForFrame.movementDirection.y,   -movementForFrame.movementDirection.x );
           mFreeFlyingCameraNode->translate(  mAvatarCamera->getOrientation(  false ) * (  correctDirection * movementForFrame.timeSlice * scaler ) );
          
           }
           mPreviousMovementForFrame = movementForFrame;
          
          
          
           return true;
          }
          
          
     314  const AvatarControllerMovement & AvatarController::getCurrentMovement(   ) const
          {
           return movementForFrame;
          }
          
          
     320  AvatarCamera* AvatarController::getAvatarCamera(   ) const
          {
           return mAvatarCamera;
          }
          
     325  void AvatarController::entityPicker_PickedEntity(  const EntityPickResult& result,   const MousePickerArgs& args )
          {
          ///don't do this now that we have a "move to" option in the menu,   since it will confuse the users
          /* if (  args.pickType == MPT_DOUBLECLICK ) {
           moveToPoint(  result.position );
           }*/
          }
          
     333  void AvatarController::moveToPoint(  const Ogre::Vector3& point )
          {
           if (  !mDecalNode ) {
           createDecal(  point );
           }
          
           if (  mDecalNode ) {
           ///make sure it's at the correct height,   since the visibility of it is determined by the bounding box
           Ogre::Real height = EmberOgre::getSingleton(   ).getTerrainGenerator(   )->getAdapter(   )->getHeightAt(  point.x,   point.z );
           mDecalNode->setPosition(  Ogre::Vector3(  point.x,   height,   point.z ) );
           mDecalNode->setVisible(  true );
           }
          
           WFMath::Vector<3> atlasVector = Ogre2Atlas_Vector3(  point );
           WFMath::Point<3> atlasPos(  atlasVector.x(   ),   atlasVector.y(   ),   atlasVector.z(   ) );
          /* WFMath::Point<3> atlas2dPos(  atlasVector.x(   ),   atlasVector.y(   ),   0 );
           WFMath::Point<3> avatar2dPos(  mAvatar->getAvatarEmberEntity(   )->getPosition(   ).x(   ),   mAvatar->getAvatarEmberEntity(   )->getPosition(   ).y(   ),   0 );
           WFMath::Vector<3> direction(  1,   0,   0 );
           direction = direction.rotate(  mAvatar->getAvatarEmberEntity(   )->getOrientation(   ) );
           WFMath::Vector<3> directionToPoint = atlas2dPos - avatar2dPos;
           WFMath::Quaternion rotation;
           rotation = rotation.rotation(  directionToPoint,   direction );*/
           //Ember::EmberServices::getSingletonPtr(   )->getServerService(   )->moveInDirection(  WFMath::Vector<3>(  0,  0,  0 ),   rotation );
          
          
           Ember::EmberServices::getSingletonPtr(   )->getServerService(   )->moveToPoint(  atlasPos );
          }
          
          
     362  void AvatarController::teleportTo(  const Ogre::Vector3& point,   EmberEntity* locationEntity )
          {
           WFMath::Vector<3> atlasVector = Ogre2Atlas_Vector3(  point );
           WFMath::Point<3> atlasPos(  atlasVector.x(   ),   atlasVector.y(   ),   atlasVector.z(   ) );
          
          
           Ember::EmberServices::getSingletonPtr(   )->getServerService(   )->place(  mAvatar->getAvatarEmberEntity(   ),   locationEntity,   atlasPos );
          }
          
          
     372  void AvatarController::createDecal(  Ogre::Vector3 position )
          {
           try {
           // Create object MeshDecal
           Ogre::SceneManager* sceneManager = EmberOgre::getSingleton(   ).getSceneManager(   );
           Ogre::NameValuePairList params;
           params["materialName"] = "/global/ember/terraindecal";
           params["width"] = StringConverter::toString(   2  );
           params["height"] = StringConverter::toString(   2  );
           params["sceneMgrInstance"] = sceneManager->getName(   );
          
           mDecalObject = sceneManager->createMovableObject(  
           "AvatarControllerMoveToDecal",  
           "PagingLandScapeMeshDecal",  
           &params  );
          
           // Add MeshDecal to Scene
           mDecalNode = sceneManager->createSceneNode(  "AvatarControllerMoveToDecalNode" );
           ///the decal code is a little shaky and relies on us setting the position of the node before we add the moveable object
           EmberOgre::getSingleton(   ).getWorldSceneNode(   )->addChild(  mDecalNode );
           mDecalNode->setPosition(  position );
           mDecalNode->attachObject(  mDecalObject );
           // mDecalNode->showBoundingBox(  true );
          
          
           mPulsatingController = new Ogre::WaveformControllerFunction(  Ogre::WFT_SINE,   1,   0.33,   0.25 );
           } catch (  const Ogre::Exception& ex )
           {
           S_LOG_WARNING(  "Error when creating terrain decal: " << ex.what(   ) );
           }
          }
          
          
          }
          

./components/ogre/AvatarController.h

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef AVATARCONTROLLER_H
          #define AVATARCONTROLLER_H
          
          #include "EmberOgrePrerequisites.h"
          
          
          // #include <SDL.h>
          #include <sigc++/trackable.h>
          
          #include "input/Input.h"
          #include "input/InputCommandMapper.h"
          #include "framework/ConsoleObject.h"
          #include "EntityWorldPickListener.h"
          
          
          
          namespace EmberOgre {
      36  class Avatar;
      37  class EmberEntity;
      38  class AvatarCamera;
          
      40  class GUIManager;
          
      42  class InputManager;
      43  class Input;
      44  class AvatarController;
          
          /**
          The movement mode of the avatar,   run or walk.
          */
      49  class AvatarMovementMode {
          public:
           enum Mode
           {
           MM_WALK = 0,  
           MM_RUN = 1
           };
          };
          
          
          /**
          Used for sending the current desired movement to the actual avatar.
          */
          struct AvatarControllerMovement
          {
           AvatarControllerMovement(   );
          
           float rotationDegHoriz;
           float rotationDegVert;
           Ogre::Real timeSlice;
           Ogre::Vector3 movementDirection;
           AvatarMovementMode::Mode mode;
           bool isMoving;
           Ogre::Quaternion cameraOrientation;
          };
          
          /**
          Listens for left mouse button pressed in movement mode and moves the character forward.
          */
      78  class AvatarControllerInputListener
          {
          public:
      81   AvatarControllerInputListener(  AvatarController& controller );
          
          protected:
          
      85   void input_MouseButtonPressed(  Input::MouseButton button,   Input::InputMode mode );
      86   void input_MouseButtonReleased(  Input::MouseButton button,   Input::InputMode mode );
      87   AvatarController& mController;
          };
          
          /**
          Controls the avatar. All avatar movement is handled by an instance of this class.
          */
      93  class AvatarController
      94  : public Ogre::FrameListener,  
      95  public sigc::trackable,  
      96  public Ember::ConsoleObject
          {
          public:
      99   friend class AvatarControllerInputListener;
          
     101   AvatarController(  Avatar* avatar,   Ogre::RenderWindow* window,   GUIManager* guiManager,   Ogre::Camera* camera );
          
     103   virtual ~AvatarController(   );
          
           /**
           Each frame we check if we should update the avatar.
           */
     108   virtual bool frameStarted(  const Ogre::FrameEvent & event );
          
          
           /**
           Emitted when the movement mode changes between run and walk.
           */
     114   sigc::signal<void,   AvatarMovementMode::Mode> EventMovementModeChanged;
          
          
          
     118   void createAvatarCameras(  Ogre::SceneNode* avatarSceneNode );
          
           /**
           * Gets the AvatarCamera.
           * @return
           */
     124   AvatarCamera* getAvatarCamera(   ) const;
          
           /**
           * Detaches the camera from the avatar and attaches it to the free flying node.
           */
     129   void detachCamera(   );
          
           /**
           * Attaches the camera to the avatar.
           */
     134   void attachCamera(   );
          
           /**
           * Gets the current movement for this frame.
           * @return
           */
     140   const AvatarControllerMovement& getCurrentMovement(   ) const;
          
     142   const Ember::ConsoleCommandWrapper RunToggle;
     143   const Ember::ConsoleCommandWrapper ToggleCameraAttached;
          
     145   const Ember::ConsoleCommandWrapper CharacterMoveForward;
     146   const Ember::ConsoleCommandWrapper CharacterMoveBackward;
     147   const Ember::ConsoleCommandWrapper CharacterMoveDownwards;
     148   const Ember::ConsoleCommandWrapper CharacterMoveUpwards;
     149   const Ember::ConsoleCommandWrapper CharacterStrafeLeft;
     150   const Ember::ConsoleCommandWrapper CharacterStrafeRight;
          /* const Ember::ConsoleCommandWrapper CharacterRotateLeft;
           const Ember::ConsoleCommandWrapper CharacterRotateRight;*/
          
     154   const Ember::ConsoleCommandWrapper MoveCameraTo;
          
          
           /**
           * Reimplements the ConsoleObject::runCommand method
           * @param command
           * @param args
           */
     162   virtual void runCommand(  const std::string &command,   const std::string &args );
          
           /**
           Moves the avatar to the specified point.
           A terrain decal will be shown.
           */
     168   void moveToPoint(  const Ogre::Vector3& point );
          
           /**
           * Teleports the avatar to the specified point.
           * @param point
           * @param locationEntity
           */
     175   void teleportTo(  const Ogre::Vector3& point,   EmberEntity* locationEntity );
          
          protected:
          
     179   InputCommandMapper mMovementCommandMapper;
          
     181   Ogre::RenderWindow* mWindow;
          
     183   GUIManager* mGUIManager;
          
          
          // void checkMovementKeys(  const Ogre::FrameEvent & event,   const Input& input );
          
          
     189   AvatarCamera* mAvatarCamera;
     190   void setAvatar(  Avatar* avatar );
     191   Ogre::Camera* mCamera;
          
          
           /**
           * Avatar
           */
     197   Avatar* mAvatar;
          
     199   EmberEntity* mEntityUnderCursor;
     200   EmberEntity* mSelectedEntity;
          
           AvatarControllerMovement movementForFrame,   mPreviousMovementForFrame;
          
     204   Ogre::SceneNode* mFreeFlyingCameraNode;
     205   bool mIsAttached;
           /**
           True if we're in running mode.
           */
     209   bool mIsRunning;
          
     211   Ogre::Vector3 mMovementDirection;
          
           /**
           Listen for double clicks and send the avatar to the double clicked position.
           */
     216   void entityPicker_PickedEntity(  const EntityPickResult& result,   const MousePickerArgs& args );
          
           /**
           Creates the terrain decal needed for displaying where the avatar is heading.
           */
     221   void createDecal(  Ogre::Vector3 position );
          
     223   Ogre::MovableObject* mDecalObject;
     224   Ogre::SceneNode* mDecalNode;
     225   Ogre::WaveformControllerFunction* mPulsatingController;
          
     227   AvatarControllerInputListener mControllerInputListener;
          };
          
          
          
          }
          
          #endif // AvatarController_H

./components/ogre/AvatarEmberEntity.cpp

          /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          
          #include "EmberEntity.h"
          #include "EmberPhysicalEntity.h"
          // #include "PersonEmberEntity.h"
          #include "framework/ConsoleBackend.h"
          #include "Avatar.h"
          #include "GUIManager.h"
          #include "model/Model.h"
          #include "AvatarEmberEntity.h"
          #include "EmberOgre.h"
          #include "MousePicker.h"
          
          #include <Eris/Entity.h>
          #include <Eris/Avatar.h>
          #include <OgreTagPoint.h>
          
          namespace EmberOgre {
          
          
      38  AvatarEmberEntity::AvatarEmberEntity(  const std::string& id,   Eris::TypeInfo* type,   Eris::View* vw,   Ogre::SceneManager* sceneManager,   Eris::Avatar* erisAvatar ) : EmberPhysicalEntity(  id,   type,   vw,   sceneManager ),   SetAttachedOrientation(  "setattachedorientation",   this,   "Sets the orienation of an item attached to the avatar: <attachpointname> <x> <y> <z> <degrees>" ),  
      39  mAvatar(  0 ),   mErisAvatar(  erisAvatar )
          {
          }
          
      43  AvatarEmberEntity::~AvatarEmberEntity(   )
          {}
          
          
      47  void AvatarEmberEntity::runCommand(  const std::string &command,   const std::string &args )
          {
           if(  SetAttachedOrientation == command ) {
           Ember::Tokeniser tokeniser;
           tokeniser.initTokens(  args );
           std::string attachPointName = tokeniser.nextToken(   );
           if (  attachPointName != "" ) {
           std::string x = tokeniser.nextToken(   );
           std::string y = tokeniser.nextToken(   );
           std::string z = tokeniser.nextToken(   );
           std::string degrees = tokeniser.nextToken(   );
           if (  x != "" && y != "" && z != "" && degrees != "" ) {
           Ogre::Degree ogreDegrees(  Ogre::StringConverter::parseReal(  degrees ) );
           Ogre::Quaternion rotation(  ogreDegrees,   Ogre::Vector3(  Ogre::StringConverter::parseReal(  x ),   Ogre::StringConverter::parseReal(  y ),   Ogre::StringConverter::parseReal(  z ) ) );
           if (  getModel(   ) ) {
           const Model::Model::AttachPointWrapperStore* attachPoints = getModel(   )->getAttachedPoints(   );
           if (  attachPoints ) {
           for (  Model::Model::AttachPointWrapperStore::const_iterator I = attachPoints->begin(   ); I != attachPoints->end(   ); ++I ) {
           if (  I->AttachPointName == attachPointName ) {
           I->TagPoint->setOrientation(  rotation );
           }
           }
           }
           }
           }
           }
           }
          }
          
      76  void AvatarEmberEntity::init(  const Atlas::Objects::Entity::RootEntity &ge,   bool fromCreateOp )
          {
           EmberPhysicalEntity::init(  ge,   fromCreateOp );
           mModel->setQueryFlags(  MousePicker::CM_AVATAR );
          
          
          }
          
      84  void AvatarEmberEntity::onMoved(   )
          {
           //EmberPhysicalEntity::onMoved(   );
          
           if (  getAvatar(   ) ) {
           getAvatar(   )->movedInWorld(   );
           }
           Eris::Entity::onMoved(   );
          }
          
      94  void AvatarEmberEntity::onImaginary(  const Atlas::Objects::Root& act )
          {
           Atlas::Message::Element attr;
           if (  act->copyAttr(  "description",   attr ) != 0 || !attr.isString(   ) ) {
           return;
           }
          
           /// Make the message appear in the chat box
           GUIManager::getSingleton(   ).AppendAvatarImaginary.emit(  getName(   ) + " " + attr.String(   ) );
          }
          
          /*
          void AvatarEmberEntity::handleTalk(  const std::string &msg )
          {
           std::string message = "<";
           message.append(  getName(   ) );
           message.append(  "> " );
           message.append(  msg );
           GUIManager::getSingleton(   ).AppendIGChatLine.emit(  message );
           std::cout << "TRACE - AVATAR SAYS: [" << message << "]\n" << std::endl;
           Ember::ConsoleBackend::getMainConsole(   )->pushMessage(  message );
          }
          */
          /*
          void AvatarEmberEntity::setVisible(  bool vis )
          {
           //TODO
           //mOgreEntity->setVisible(  true );
          }
          */
          
          //void AvatarEmberEntity::addMember(  Entity *e )
     126  void AvatarEmberEntity::onChildAdded(  Entity *e )
          {
           //mAvatar->EventAddedEntityToInventory.emit(  static_cast<EmberEntity*>(  e ) );
           EmberOgre::getSingleton(   ).getAvatar(   )->mEntitiesToBeAddedToInventory.insert(  e );
           //PersonEmberEntity::addMember(  e );
           EmberPhysicalEntity::onChildAdded(  e );
          
          }
          
          
          /*void AvatarEmberEntity::rmvMember(  Entity *e )*/
     137  void AvatarEmberEntity::onChildRemoved(  Entity *e )
          {
           EmberOgre::getSingleton(   ).getAvatar(   )->EventRemovedEntityFromInventory.emit(  static_cast<EmberEntity*>(  e ) );
           EmberPhysicalEntity::onChildRemoved(  e );
          // mAvatar->mEntitiesToBeRemovedFromInventory.insert(  e );
          // PersonEmberEntity::rmvMember(  e );
          }
          
          
          
          // void AvatarEmberEntity::onLocationChanged(  Eris::Entity *oldLocation,   Eris::Entity *newLocation )
          // {
          // return EmberEntity::onLocationChanged(  oldLocation,   newLocation );
          //
          //
          //
          // Ogre::Vector3 oldWorldPosition = getSceneNode(   )->getWorldPosition(   );
          // EmberEntity* EmberEntity = dynamic_cast<EmberEntity*>(  newLocation );
          // Ogre::SceneNode* newOgreParentNode = EmberEntity->getSceneNode(   );
          //
          // /* if (  EmberEntity )
          // {
          // newOgreParentNode = EmberEntity->getSceneNode(   );
          // } else {
          // newOgreParentNode = EmberOgre::getSingleton(   ).getSceneManager(   )->getSceneNode(  newLocation->getId(   ) );
          // }*/
          //
          // if (  getSceneNode(   )->getParent(   ) ) {
          // //detach from our current object and add to the new entity
          // getSceneNode(   )->getParent(   )->removeChild(  getSceneNode(   )->getName(   ) );
          // }
          // newOgreParentNode->addChild(  getSceneNode(   ) );
          //
          //
          // // Entity::setContainer(  pr );
          // Eris::Entity::onLocationChanged(  oldLocation,   newLocation );
          //
          // //we adjust the entity so it retains it's former position in the world
          // Ogre::Vector3 newWorldPosition = getSceneNode(   )->getWorldPosition(   );
          // getSceneNode(   )->translate(  oldWorldPosition - newWorldPosition );
          // }
          
     179  Ogre::SceneNode* AvatarEmberEntity::getAvatarSceneNode(   )
          {
           return getScaleNode(   );
          }
          
          
          
          
          }
          

./components/ogre/AvatarEmberEntity.h

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          
          #ifndef AVATARDIMEENTITY_H
          #define AVATARDIMEENTITY_H
          
          namespace Eris
          {
      25   class Entity;
      26   class Avatar;
          }
          
          namespace EmberOgre {
          
          namespace Model {
      32   class Model;
          }
          
          class EmberPhysicalEntity;
      36  class EmberEntity;
      37  class Avatar;
          
          /**
           * This is the main player avatar. We want this one to behave a little different
           * than the other game entities,   thus it has it's own subclass.
           *
           */
      44  class AvatarEmberEntity
      45  : public EmberPhysicalEntity,  
      46  public Ember::ConsoleObject
          {
          public:
          
      50   AvatarEmberEntity(  const std::string& id,   Eris::TypeInfo* type,   Eris::View* vw,   Ogre::SceneManager* sceneManager,   Eris::Avatar* erisAvatar );
      51   virtual ~AvatarEmberEntity(   );
          
           /**
           * used by the main application to set the EmberOgre::Avatar connected to this instance
           */
      56   inline void setAvatar(  Avatar* avatar );
      57   inline Avatar* getAvatar(   );
          
           /**
           * returns the Ogre::SceneNode which represents the avatar
           */
      62   Ogre::SceneNode* getAvatarSceneNode(   );
          
           /**
           * Returns the Eris Avatar instance.
           * @return
           */
      68   inline Eris::Avatar* getErisAvatar(   );
          
           /**
           * Reimplements the ConsoleObject::runCommand method
           * @param command
           * @param args
           */
      75   virtual void runCommand(  const std::string &command,   const std::string &args );
          
      77   const Ember::ConsoleCommandWrapper SetAttachedOrientation;
          
          protected:
          
      81   virtual void onChildAdded(  Entity *e );
      82   virtual void onChildRemoved(  Entity *e );
          
           /**Eris methods,   see Eris::Entity.h for documentation */
          // virtual void handleTalk(  const std::string &msg );
      86   virtual void onMoved(   );
      87   virtual void onImaginary(  const Atlas::Objects::Root& act );
          /* virtual void addMember(  Entity *e );
           virtual void rmvMember(  Entity *e );*/
           //virtual void setVisible(  bool vis );
           //virtual void setContainer(  Eris::Entity *pr );
           //virtual void onLocationChanged(  Eris::Entity *oldLocation,   Eris::Entity *newLocation );
      93   virtual void init(  const Atlas::Objects::Entity::RootEntity &ge,   bool fromCreateOp );
          
          
      96   Avatar* mAvatar;
      97   Eris::Avatar* mErisAvatar;
          };
          
          ///inline implementations
     101  void AvatarEmberEntity::setAvatar(  Avatar* avatar )
          {
           mAvatar = avatar;
          }
     105  Avatar* AvatarEmberEntity::getAvatar(   )
          {
           return mAvatar;
          }
     109  Eris::Avatar* AvatarEmberEntity::getErisAvatar(   )
          {
           return mErisAvatar;
          }
          
          }
          
          #endif // AVATARDIMEENTITY_H

./components/ogre/CameraMount.cpp

       1  //
          // C++ Implementation: CameraMount
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "CameraMount.h"
          
          namespace EmberOgre {
          
      27  CameraMount::CameraMount(   )
          {
          }
          
          
      32  CameraMount::~CameraMount(   )
          {
          }
          
          
          }

./components/ogre/CameraMount.h

       1  //
          // C++ Interface: CameraMount
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGRECAMERAMOUNT_H
          #define EMBEROGRECAMERAMOUNT_H
          
          namespace EmberOgre {
          
          /**
          @author Erik Hjortsberg
          */
      31  class CameraMount{
          public:
      33   CameraMount(   );
          
      35   ~CameraMount(   );
          
          };
          
          }
          
          #endif

./components/ogre/ConsoleObjectImpl.cpp

          /*
           ConsoleObjectImpl.cpp by Miguel Guzman (  Aglanor )
           Copyright (  C ) 2002 Miguel Guzman & The Worldforge Project
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          // config headers
          #ifdef HAVE_CONFIG_H
          #include "config.h"
          #endif
          
          // system headers
          
          // library headers
          #include "EmberOgrePrerequisites.h"
          
          // local headers
          #include "ConsoleObjectImpl.h"
          #include "framework/ConsoleBackend.h"
          #include "framework/Tokeniser.h"
          
          #include "main/Application.h"
          // #include <SDL.h>
          
          template<> EmberOgre::ConsoleObjectImpl* Ember::Singleton<EmberOgre::ConsoleObjectImpl>::ms_Singleton = 0;
          
          namespace EmberOgre {
          
          
      43  ConsoleObjectImpl::ConsoleObjectImpl(  void ) :
          Quit(  "quit",   this,   "Quit Ember." ),  
      45  ToggleErisPolling(  "toggle_erispolling",   this,   "Switch server polling on and off." )
          {
          }
      48  ConsoleObjectImpl::~ConsoleObjectImpl(   )
          {
          
          }
          
          
      54  void ConsoleObjectImpl::runCommand(  const std::string &command,   const std::string &args )
          {
           if(  command == Quit.getCommand(   ) ) {
           Ember::ConsoleBackend::getMainConsole(   )->pushMessage(  "Bye" );
           quit(   );
           } else if (  ToggleErisPolling == command ){
           Ember::Application::getSingleton(   ).setErisPolling(  !Ember::Application::getSingleton(   ).getErisPolling(   ) );
           }
          }
          
      64  void ConsoleObjectImpl::quit(   )
          {
           Ember::Application::getSingleton(   ).quit(   );
          }
          
          }
          

./components/ogre/ConsoleObjectImpl.h

       1  /*
           ConsoleObjectImpl.h by Miguel Guzman (  Aglanor )
           Copyright (  C ) 2002 Miguel Guzman & The Worldforge Project
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef __EmberOgre_ConsoleObjectImpl_H__
          #define __EmberOgre_ConsoleObjectImpl_H__
          
          #include "framework/ConsoleObject.h"
          #include "framework/Singleton.h"
          
          namespace EmberOgre {
      27  class ConsoleObjectImpl: public Ember::ConsoleObject,   public Ember::Singleton<ConsoleObjectImpl>
          {
           public:
          
      31   ConsoleObjectImpl(  void );
      32   ~ConsoleObjectImpl(   );
          
           /**
           * Receive commands from console
           */
      37   void runCommand(  const std::string &command,   const std::string &args );
          
           private:
          
          
          
      43   void quit(   );
          
           /// List of Ogre's console commands
      46   const Ember::ConsoleCommandWrapper Quit;
      47   const Ember::ConsoleCommandWrapper ToggleErisPolling;
          
          
          }; // End of class declaration
          
          }
          
          #endif

./components/ogre/EmberEntity.cpp

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #include "EmberEntity.h"
          
          #include "framework/Service.h"
          #include "framework/ConsoleBackend.h"
          #include "services/EmberServices.h"
          #include "services/sound/SoundService.h"
          #include "EmberEntityFactory.h"
          #include "MotionManager.h"
          #include "GUIManager.h"
          #include "terrain/TerrainArea.h"
          #include "MathConverter.h"
          
          #include "EmberOgre.h"
          #include <OgreWireBoundingBox.h>
          #include <OgreException.h>
          
          #include <Mercator/Area.h>
          //#include <Atlas/Objects/ObjectsFwd.h>
          #include <Eris/TypeInfo.h>
          #include <Eris/View.h>
          #include <Atlas/Formatter.h>
          #include <Atlas/Objects/Decoder.h>
          #include <Atlas/Codecs/XML.h>
          #include <Atlas/Message/MEncoder.h>
          #include <Atlas/Message/QueuedDecoder.h>
          
          
          #include "model/Model.h"
          
          using namespace Ogre;
          
          
          namespace Ogre {
          
           /**
           This is just like a WireBoundBox but not aligned to the axes,   hence it will correctly line up according to it's orientation.
           */
      56   class OOBBWireBoundingBox : public WireBoundingBox
           {
           public:
          
      60   void getWorldTransforms(   Matrix4* xform  ) const
           {
           SimpleRenderable::getWorldTransforms(  xform );
           }
           //-----------------------------------------------------------------------
      65   const Quaternion& getWorldOrientation(  void ) const
           {
           return SimpleRenderable::getWorldOrientation(   );
           }
           //-----------------------------------------------------------------------
      70   const Vector3& getWorldPosition(  void ) const
           {
           return SimpleRenderable::getWorldPosition(   );
           }
          
           };
          
          };
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          namespace EmberOgre {
          
          
      95  const std::string EmberEntity::MODE_STANDING(  "standing" );
      96  const std::string EmberEntity::MODE_RUNNING(  "running" );
      97  const std::string EmberEntity::MODE_WALKING(  "walking" );
      98  const std::string EmberEntity::MODE_SWIMMING(  "swimming" );
      99  const std::string EmberEntity::MODE_FLOATING(  "floating" );
     100  const std::string EmberEntity::MODE_FIXED(  "fixed" );
          
     102  const std::string EmberEntity::BboxMaterialName(  "BaseYellowNoLightning" );
          
          
     105  EmberEntity::EmberEntity(  const std::string& id,   Eris::TypeInfo* ty,   Eris::View* vw,  Ogre::SceneManager* sceneManager )
          :
          Eris::Entity(  id,   ty,   vw )
          ,   mIsInitialized(  false )
          ,   mIsInMotionManager(  false )
          ,   mErisEntityBoundingBox(  0 )
          ,   mOgreNode(  0 )
          ,   mTerrainArea(  0 )
          {
           createSceneNode(  sceneManager );
          }
          
     117  EmberEntity::~EmberEntity(   )
          {
           //detach all children so we don't destroy them
           while (  getSceneNode(   )->numChildren(   ) ) {
           getSceneNode(   )->removeChild(  (  short unsigned int )0 );
           }
           Ogre::SceneNode* parent = static_cast<Ogre::SceneNode*>(  getSceneNode(   )->getParent(   ) );
           if (  parent ) {
           parent->removeAndDestroyChild(  getSceneNode(   )->getName(   ) );
           } else {
           getSceneNode(   )->getCreator(   )->destroySceneNode(  getSceneNode(   )->getName(   ) );
           }
           ///make sure it's not in the MotionManager
           ///TODO: keep a marker in the entity so we don't need to call this for all entities
           MotionManager::getSingleton(   ).removeEntity(  this );
          
           if (  mErisEntityBoundingBox ) {
           mErisEntityBoundingBox->getParentSceneNode(   )->getCreator(   )->destroySceneNode(  mErisEntityBoundingBox->getParentSceneNode(   )->getName(   ) );
           }
           delete mErisEntityBoundingBox;
          
           //mSceneManager->destroySceneNode(  getSceneNode(   )->getName(   ) );
          }
          
     141  void EmberEntity::init(  const Atlas::Objects::Entity::RootEntity &ge,   bool fromCreateOp )
          {
           Eris::Entity::init(  ge,   fromCreateOp );
          
           synchronizeWithServer(   );
          
           // set the Ogre node position and orientation based on Atlas data
           std::stringstream ss;
           ss << "Entity " << getId(   ) << "(  " << getName(   ) << " ) placed at (  " << getPredictedPos(   ).x(   ) << ",  " << getPredictedPos(   ).y(   ) << ",  " << getPredictedPos(   ).x(   ) << " )";
           S_LOG_VERBOSE(   ss.str(   ) );
          
           if (  hasAttr(  "area" ) ) {
           mTerrainArea = std::auto_ptr<Terrain::TerrainArea>(  new Terrain::TerrainArea(  this ) );
           if (  mTerrainArea->init(   ) ) {
           addArea(  mTerrainArea.get(   ) );
           }
           }
          
           mIsInitialized = true;
          
          }
          
     163  void EmberEntity::synchronizeWithServer(   )
          {
           if (  getPosition(   ).isValid(   ) ) {
           getSceneNode(   )->setPosition(  Atlas2Ogre(  getPredictedPos(   ) ) );
           adjustPosition(   );
           }
           if (  getOrientation(   ).isValid(   ) ) {
           getSceneNode(   )->setOrientation(  Atlas2Ogre(  getOrientation(   ) ) );
           }
          
          }
          
          
     176  void EmberEntity::createSceneNode(  Ogre::SceneManager* sceneManager )
          {
           EmberEntity* container = getEmberLocation(   );
           if (  container == 0 ) {
           //S_LOG_VERBOSE(   "Entity created in limbo: "<< this->getId(   ) << " (  " << this->getName(   ) << " )"  )
          
           mOgreNode = sceneManager->createSceneNode(  getId(   ) );
          
           } else {
           Ogre::SceneNode * node = container->getSceneNode(   );
           mOgreNode = node->createChildSceneNode(  getId(   ) );
           }
          }
          
     190  void EmberEntity::updateMotion(  Ogre::Real timeSlice )
          {
           getSceneNode(   )->setPosition(  Atlas2Ogre(  getPredictedPos(   ) ) );
           adjustPosition(   );
          
           //if there's a debug bounding box for the eris entity,   update it's position
           if (  mErisEntityBoundingBox ) {
           mErisEntityBoundingBox->getParentSceneNode(   )->setPosition(  getSceneNode(   )->getPosition(   ) );
           mErisEntityBoundingBox->getParentSceneNode(   )->setOrientation(  getSceneNode(   )->getOrientation(   ) );
           }
          
          }
          
          
          
          
     206  void EmberEntity::onMoved(   )
          {
           Eris::Entity::onMoved(   );
           const WFMath::Quaternion& orient = getOrientation(   );
           getSceneNode(   )->setOrientation(  Atlas2Ogre(  orient ) );
           updateMotion(  0 );
          }
          
     214  void EmberEntity::setMoving(  bool moving )
          {
           // Call the overridden method
           Eris::Entity::setMoving(  moving );
          
           MotionManager* motionManager = &MotionManager::getSingleton(   );
           if (  moving ) {
           //the entity is moving
           if (  !mIsInMotionManager ) {
           motionManager->addEntity(  this );
           mIsInMotionManager = true;
           }
           } else {
           //the entity has stopped moving
           if (  mIsInMotionManager ) {
           motionManager->removeEntity(  this );
           mIsInMotionManager = false;
           }
           }
          
          
          
          }
          
     238  void EmberEntity::onTalk(  const Atlas::Objects::Operation::RootOperation& talkArgs )
          {
           const std::vector<Atlas::Objects::Root>& args = talkArgs->getArgs(   );
           if (  args.empty(   ) ) {
           Eris::Entity::onTalk(  talkArgs );
           return;
           }
          
           const Atlas::Objects::Root& talk = args.front(   );
          
          
           if (  !talk->hasAttr(  "say" ) ) {
           Eris::Entity::onTalk(  talkArgs );
           return;
           }
          
          
           ///some talk operations come with a predefined set of suitable responses,   so we'll store those so that they can later on be queried by the GUI for example
           mSuggestedResponses.clear(   );
           if (  talk->hasAttr(  "responses" ) ) {
           if (  talk->getAttr(  "responses" ).isList(   ) ) {
           const Atlas::Message::ListType & responseList = talk->getAttr(  "responses" ).asList(   );
           Atlas::Message::ListType::const_iterator I = responseList.begin(   );
           for(  ; I != responseList.end(   ); ++I ) {
           mSuggestedResponses.push_back(  I->asString(   ) );
           }
          
           }
           }
          
           const std::string& msg = talk->getAttr(  "say" ).asString(   );
          
          
          
          
           std::string message = "<";
           message.append(  getName(   ) );
           message.append(  ",  " );
           const std::string& type = getType(   )->getName(   ); // Eris type as a string
           message.append(  type );
           message.append(  "> " );
           message.append(  msg );
           S_LOG_VERBOSE(   "Entity says: [" << message << "]\n"  )
          
           /// Make the message appear in the chat box
           GUIManager::getSingleton(   ).AppendIGChatLine.emit(  msg,   this );
          
           /// Make a sound in OpenAL
          // Ember::EmberServices::getSingleton(   ).getSoundService(   )->playTalk(  msg,  
          // getPosition(   ),  getOrientation(   ) );
          
           /// Call the method of the base class (  since we've overloaded it )
           Eris::Entity::onTalk(  talkArgs );
          }
          
          
     294  void EmberEntity::onSoundAction(   const Atlas::Objects::Operation::RootOperation & op  )
          {
           Eris::Entity::onSoundAction(  op );
          }
          
          
     300  void EmberEntity::onVisibilityChanged(  bool vis )
          {
           checkVisibility(  vis );
           Eris::Entity::onVisibilityChanged(  vis );
          }
          
     306  void EmberEntity::checkVisibility(  bool vis )
          {
           ///since we don't want to show all entities solely by their server flags (  for example,   an inventory item belonging to a character might not be shown even though the server thinks it's visible ) we have to some more checks before we decide whether to show this or not
           EmberEntity* container = static_cast<EmberEntity*>(  getLocation(   ) );
           if (  container ) {
           ///check with the parent first if we should show ourselves
           if (  vis && container->allowVisibilityOfMember(  this ) ) {
           ///don't cascade,   only change the top node
           setVisible(  true );
           } else {
           setVisible(  false );
           }
          
           } else {
           setVisible(  vis );
           }
          }
          
          
     325  void EmberEntity::setVisible(  bool visible )
          {
           ///when entities are hidden,   we detach them from the rendering scene graph altogether. this speeds up Ogre since it doesn't have to calculate visibility for nodes that are hidden anyway
           if (  !visible ) {
           if (  getSceneNode(   )->getParent(   ) ) {
           getSceneNode(   )->getParent(   )->removeChild(  getSceneNode(   ) );
           }
           } else {
           if (  getLocation(   ) ) {
           if (  !getSceneNode(   )->getParent(   ) ) {
           getEmberLocation(   )->getSceneNode(   )->addChild(  getSceneNode(   ) );
           }
           }
           }
          
           getSceneNode(   )->setVisible(  visible && getLocation(   ),   false );
          }
          
          
     344  void EmberEntity::adjustPosition(   )
          {
           if (  getPredictedPos(   ).isValid(   ) ) {
           adjustPosition(  Atlas2Ogre(   getPredictedPos(   )  ) );
           }
          }
          
     351  void EmberEntity::adjustPosition(  const Ogre::Vector3& position )
          {
           if (  mMovementMode == MM_FIXED ) {
          
           } else {
           EmberEntity* container = getEmberLocation(   );
           if (  container ) {
           container->adjustPositionForContainedNode(  this,   position );
           }
           }
          }
          
     363  const Ogre::Vector3& EmberEntity::getOffsetForContainedNode(  const Ogre::Vector3& localPosition,   EmberEntity* const entity )
          {
           ///send it upwards until we get a an entity which knows how to set the position (  we'll in most cases end up in the world which will adjust the height a bit )
           EmberEntity* container = getEmberLocation(   );
           if (  container ) {
           //TerrainPosition derivedPosition(  getPredictedPos(   ).x(   ) + position.x(   ),   getPredictedPos(   ).y(   ) + position.y(   ) );
           return container->getOffsetForContainedNode(  localPosition + getSceneNode(   )->getPosition(   ),   entity );
           } else {
           return Ogre::Vector3::ZERO;
           }
          
          
          }
          
          
          
     379  void EmberEntity::adjustPositionForContainedNode(  EmberEntity* const entity,   const Ogre::Vector3& position )
          {
          
           Ogre::SceneNode* sceneNode = entity->getSceneNode(   );
           //Ogre::Vector3 position = sceneNode->getPosition(   );
           const Ogre::Vector3& offset = getOffsetForContainedNode(  position,   entity );
           if (  offset != Ogre::Vector3::ZERO ) {
           sceneNode->setPosition(  position + offset );
           }
          
          }
          
     391  void EmberEntity::onLocationChanged(  Eris::Entity *oldLocation )
          {
          
           if (  getLocation(   ) == oldLocation )
           {
           S_LOG_WARNING(   "Same new location as old for entity: " << this->getId(   ) << " (  " << this->getName(   ) << " )"  );
           return Eris::Entity::onLocationChanged(  oldLocation );
          
           }
           Eris::Entity::onLocationChanged(  oldLocation );
          
           ///if we're attached to something,   detach from it
           detachFromModel(   );
          
           if (  !getLocation(   ) ) {
           return;
           } else {
           EmberEntity* newLocationEntity = getEmberLocation(   );
          
           const Ogre::Vector3 oldWorldPosition = getSceneNode(   )->getWorldPosition(   );
          // const Ogre::Quaternion oldWorldOrientation = getSceneNode(   )->getWorldOrientation(   );
          
           if (  getSceneNode(   )->getParentSceneNode(   ) ) {
           ///detach from our current object
           getSceneNode(   )->getParentSceneNode(   )->removeChild(  getSceneNode(   )->getName(   ) );
           }
           if (  newLocationEntity ) {
           // add to the new entity
           newLocationEntity->getSceneNode(   )->addChild(  getSceneNode(   ) );
           S_LOG_VERBOSE(   "Entity: " << this->getId(   ) << " (  " << this->getName(   ) << " ) relocated to: "<< newLocationEntity->getId(   ) << " (  " << newLocationEntity->getName(   ) << " )"  );
           if (  getPosition(   ).isValid(   ) ) {
           ///note that in some instances,   for instance when the avatar enters the sty,   the position isn't updated yet,   which will make the avatar "snap" to an incorrect position (  since the parent node has changed ) until next frame,   when the position should have been updated
           getSceneNode(   )->setPosition(  Atlas2Ogre(  getPredictedPos(   ) ) );
           adjustPosition(   );
           std::stringstream ss;
           ss << getPredictedPos(   );
           S_LOG_VERBOSE(  "New position for entity: " << this->getId(   ) << " (  " << this->getName(   ) << "  ) :" << ss.str(   ) );
           }
           if (  getOrientation(   ).isValid(   ) ) {
           getSceneNode(   )->setOrientation(  Atlas2Ogre(  getOrientation(   ) ) );
           std::stringstream ss;
           ss << getOrientation(   );
           S_LOG_VERBOSE(  "New orientation for entity: " << this->getId(   ) << " (  " << this->getName(   ) << "  ) :" << ss.str(   ) );
           }
          // getSceneNode(   )->rotate(  newLocationEntity->getSceneNode(   )->getWorldOrientation(   ) - oldWorldOrientation );
          
           } else {
           ///the entity has no current parent,   and should be placed in limbo (  hopefully a more correct parent will be submitted in a future LocationChanged event
           S_LOG_VERBOSE(   "Entity relocated to limbo: "<< this->getId(   ) << " (  " << this->getName(   ) << " )"  );
           // mSceneManager->getRootSceneNode(   )->addChild(  getSceneNode(   ) );
           }
          
           checkVisibility(  isVisible(   ) );
          
           ///we'll adjust the entity so it retains it's former position in the world,   but only for moving entities
           ///since else we'll get a "gap" when we're waiting on updated positions from the server
           ///this isn't optimal
           if (  isMoving(   ) ) {
           const Ogre::Vector3& newWorldPosition = getSceneNode(   )->getWorldPosition(   );
           getSceneNode(   )->translate(  oldWorldPosition - newWorldPosition );
           }
           }
          
          }
          
     456  void EmberEntity::onAction(  const Atlas::Objects::Operation::RootOperation& act )
          {
           const std::list<std::string> &p = act->getParents(   );
           std::list<std::string>::const_iterator I = p.begin(   );
          
           if (  I == p.end(   ) ) return;
          
           const std::string& name = *I;
           std::string message = getName(   ) + " performs a " + name + ".";
          
           Ember::ConsoleBackend::getMainConsole(   )->pushMessage(  message );
          
           S_LOG_VERBOSE(   "Entity: " << this->getId(   ) << " (  " << this->getName(   ) << " ) action: " << name );
           Entity::onAction(  act );
          }
          
     472  void EmberEntity::onImaginary(  const Atlas::Objects::Root& act )
          {
           Atlas::Message::Element attr;
           if (  act->copyAttr(  "description",   attr ) && attr.isString(   ) ) {
           std::string message = getName(   ) + " " + attr.asString(   ) + ".";
          
           Ember::ConsoleBackend::getMainConsole(   )->pushMessage(  message );
          
           S_LOG_VERBOSE(  "Entity: " << this->getId(   ) << " (  " << this->getName(   ) << " ) imaginary: " << attr.String(   ) );
           }
          
           Entity::onImaginary(  act );
          
          }
          
          
     488  bool EmberEntity::allowVisibilityOfMember(  EmberEntity* entity ) {
           return true;
          }
          
     492  const std::vector< std::string >& EmberEntity::getSuggestedResponses(    ) const
          {
           return mSuggestedResponses;
          }
          
     497  bool EmberEntity::hasSuggestedResponses(    ) const
          {
           return mSuggestedResponses.size(   ) > 0;
          }
          
          
     503  void EmberEntity::addArea(  Terrain::TerrainArea* area )
          {
          ///just pass it on to the parent until we get to someone who knows how to handle this (  preferrably the terrain )
           if (  getEmberLocation(   ) ) {
           getEmberLocation(   )->addArea(  area );
           }
          }
          
     511  void EmberEntity::onAttrChanged(  const std::string& str,   const Atlas::Message::Element& v )
          {
           if (  str == "mode" ) {
           parseModeChange(  v );
           } else if (  str == "bbox" ) {
           Entity::onAttrChanged(  str,   v );
           onBboxChanged(   );
           return;
           }
           Entity::onAttrChanged(  str,   v );
          }
          
     523  void EmberEntity::parseModeChange(  const Atlas::Message::Element& v )
          {
           const std::string& mode = v.asString(   );
           MovementMode newMode;
           if (  mode.empty(   ) ) {
           newMode = MM_DEFAULT;
           } else if (  mode == MODE_STANDING ) {
           newMode = MM_STANDING;
           } else if (  mode == MODE_RUNNING ) {
           newMode = MM_RUNNING;
           } else if (  mode == MODE_WALKING ) {
           newMode = MM_WALKING;
           } else if (  mode == MODE_SWIMMING ) {
           newMode = MM_SWIMMING;
           } else if (  mode == MODE_FLOATING ) {
           newMode = MM_FLOATING;
           } else if (  mode == MODE_FIXED ) {
           newMode = MM_FIXED;
           } else {
           newMode = MM_DEFAULT;
           }
          
           onModeChanged(  newMode );
          }
          
     548  void EmberEntity::onModeChanged(  MovementMode newMode )
          {
           if (  newMode == MM_FIXED ) {
           adjustPosition(   );
           }
           mMovementMode = newMode;
          }
          
     556  void EmberEntity::setVisualize(  const std::string& visualization,   bool visualize )
          {
           if (  visualization == "OgreBBox" ) {
           showOgreBoundingBox(  visualize );
           } else if (  visualization == "ErisBBox" ) {
           showErisBoundingBox(  visualize );
           }
          }
          
     565  bool EmberEntity::getVisualize(  const std::string& visualization ) const
          {
           if (  visualization == "OgreBBox" ) {
           return getShowOgreBoundingBox(   );
           } else if (  visualization == "ErisBBox" ) {
           return getShowErisBoundingBox(   );
           }
           return false;
          }
          
          
     576  void EmberEntity::showOgreBoundingBox(  bool show )
          {
           getSceneNode(   )->showBoundingBox(  show );
          }
          
     581  void EmberEntity::showErisBoundingBox(  bool show )
          {
          
           createErisBboxMaterial(   );
          
           ///if there's no bounding box,   create one now
           ///allowing for some lazy loading
           if (  !mErisEntityBoundingBox ) {
           mErisEntityBoundingBox = new Ogre::OOBBWireBoundingBox(   );
           mErisEntityBoundingBox->setMaterial(  BboxMaterialName );
           Ogre::SceneNode* boundingBoxNode = EmberOgre::getSingleton(   ).getWorldSceneNode(   )->createChildSceneNode(   );
           boundingBoxNode->attachObject(  mErisEntityBoundingBox );
          
           Ogre::AxisAlignedBox aabb(  Atlas2Ogre(  getBBox(   ) ) );
          
           mErisEntityBoundingBox->setupBoundingBox(  aabb );
          
           boundingBoxNode->setPosition(  Atlas2Ogre(  getPredictedPos(   ) ) );
           boundingBoxNode->setOrientation(  Atlas2Ogre(  getOrientation(   ) ) );
           }
           mErisEntityBoundingBox->setVisible(  show );
          
          }
          
     605  void EmberEntity::createErisBboxMaterial(   )
          {
           if (  !Ogre::MaterialManager::getSingleton(   ).resourceExists(  BboxMaterialName ) ) {
           Ogre::MaterialPtr baseYellowNoLighting = Ogre::MaterialManager::getSingleton(   ).create(  BboxMaterialName,  
           Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME );
           baseYellowNoLighting->setLightingEnabled(  false );
           baseYellowNoLighting->setAmbient(  Ogre::ColourValue(  1,   1,   0.7 ) );
           baseYellowNoLighting->setDiffuse(  Ogre::ColourValue(  1,   1,   0.7 ) );
           }
          }
          
     616  void EmberEntity::onBboxChanged(   )
          {
           if (  mErisEntityBoundingBox ) {
           mErisEntityBoundingBox->setupBoundingBox(  Atlas2Ogre(  getBBox(   ) ) );
           }
          }
          
          
     624  bool EmberEntity::getShowOgreBoundingBox(   ) const
          {
           return getSceneNode(   )->getShowBoundingBox(   );
          }
     628  bool EmberEntity::getShowErisBoundingBox(   ) const
          {
           return (  mErisEntityBoundingBox && mErisEntityBoundingBox->isVisible(   ) );
          
          }
          
          //inline
     635  Ogre::SceneNode* EmberEntity::getSceneNode(   ) const
          {
           return mOgreNode;
          }
          
     640  EmberEntity* EmberEntity::getEmberLocation(   ) const
          {
           return static_cast<EmberEntity*>(  getLocation(   ) );
          }
          
          
     646  const Ogre::AxisAlignedBox& EmberEntity::getWorldBoundingBox(  bool derive ) const
          {
           static Ogre::AxisAlignedBox boundingBox(  0,  0,  0,  0,  0,  0 );
           return boundingBox;
          }
          
     652  const Ogre::Sphere & EmberEntity::getWorldBoundingSphere (  bool derive ) const
          {
           static Ogre::Sphere sphere;
           return sphere;
          }
          
     658  std::vector<std::string> EmberEntity::getDefaultUseOperators(   )
          {
           ///get the use operations from Eris and return them a simple vector of strings
           std::vector<std::string> operators;
          
           Eris::TypeInfoArray types = getUseOperations(   );
          
           for (  Eris::TypeInfoArray::iterator I = types.begin(   ); I != types.end(   ); ++I ) {
           operators.push_back(  (  *I )->getName(   ) );
           }
          
           return operators;
          }
          
     672  Ogre::SceneManager* EmberEntity::getSceneManager(   )
          {
           assert(  mOgreNode );
           return mOgreNode->getCreator(   );
          }
          
     678  static void dumpElement(  const std::string &prefix,   const std::string &name,   const Atlas::Message::Element &e,   std::ostream& outstream,   std::ostream& logOutstream )
          {
          
           if (  e.isMap(   ) ) {
           logOutstream << prefix << name << ": Dumping Map" << std::endl;
           Atlas::Message::MapType::const_iterator itr = e.asMap(   ).begin(   );
           Atlas::Message::MapType::const_iterator end = e.asMap(   ).end(   );
           outstream << prefix << name << ":" << std::endl;
           for (  ; itr != end; ++itr ) {
           dumpElement(  prefix + " ",   itr->first,   itr->second,   outstream,   logOutstream );
           }
           logOutstream << prefix << "Finished Dumping Map" << std::endl;
           } else if (  e.isList(   ) ) {
           logOutstream << prefix << name << ": Dumping List" << std::endl;
           Atlas::Message::ListType::const_iterator itr = e.asList(   ).begin(   );
           Atlas::Message::ListType::const_iterator end = e.asList(   ).end(   );
           outstream << prefix << name << ":" << std::endl;
           for (  ; itr != end; ++itr ) {
           dumpElement(  prefix + " ",   "",   *itr,   outstream,   logOutstream );
           }
           logOutstream << prefix << "Finished Dumping List" << std::endl;
           } else {
           if (  e.isString(   ) ) outstream << prefix << name << ": " << e.asString(   ) << std::endl;
           if (  e.isNum(   ) ) outstream << prefix << name << ": " << e.asNum(   ) << std::endl;
           }
          }
          
     705  void EmberEntity::dumpAttributes(  std::iostream& outstream,   std::ostream& logOutstream ) const
          {
           logOutstream << "Dumping attributes for entity " << getId(   ) << "(  " << getName(   ) << " )" << std::endl;
          
           Atlas::Message::QueuedDecoder decoder;
           //std::fstream file;
          
           Atlas::Codecs::XML codec(  outstream,   decoder );
           Atlas::Formatter formatter(  outstream,   codec );
           Atlas::Message::Encoder encoder(  formatter );
           formatter.streamBegin(   );
           encoder.streamMessageElement(  getAttributes(   ) );
          
           formatter.streamEnd(   );
          
          
          // const Eris::Entity::AttrMap &attribs = getAttributes(   );
          
          // Eris::Entity::AttrMap::const_iterator itr = attribs.begin(   );
          // Eris::Entity::AttrMap::const_iterator end = attribs.end(   );
          // for (  ; itr != end; ++itr ) {
          // dumpElement(  "",  itr->first,   itr->second,   outstream,   logOutstream );
          // }
          }
          
          }
          
          
          
          
          

./components/ogre/EmberEntity.h

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef DIMEENTITY_H
          #define DIMEENTITY_H
          
          #include "EmberOgrePrerequisites.h"
          
          
          #include <Atlas/Objects/Entity.h>
          #include <Atlas/Objects/Operation.h>
          
          #include <Eris/Entity.h>
          
          namespace Ogre
          {
      32   class OOBBWireBoundingBox;
          }
          
          namespace Mercator
          {
      37   class Area;
          }
          
      40  namespace Eris
          {
           class View;
          }
          
          namespace EmberOgre {
          
          namespace Model {
      48   class Model;
          }
          
      51  namespace Terrain
          {
           class TerrainArea;
          }
          
      56  class EmberEntityFactory;
          /**
           * A representation of an Eris::Entity,   ie. a world entity.
           * Note that most entities in the game world will be of type EmberPhysicalEntity
           * as they will have some sort of physical representation.
           * For things such as boundaries and weather,   this is a nice class.
           */
      63  class EmberEntity : public Eris::Entity {
      64   friend class EmberEntityFactory;
          public:
          
          
           enum MovementMode
           {
           MM_DEFAULT = 0,  
           MM_STANDING = 1,  
           MM_FLOATING = 2,  
           MM_PROJECTILE = 3,  
           MM_SWIMMING = 4,  
           MM_WALKING = 5,  
           MM_RUNNING = 6,  
           MM_FIXED = 7
           };
          
      80   static const std::string MODE_STANDING;
      81   static const std::string MODE_RUNNING;
      82   static const std::string MODE_WALKING;
      83   static const std::string MODE_SWIMMING;
      84   static const std::string MODE_FLOATING;
      85   static const std::string MODE_FIXED;
          
           /**
           The material used for showing the eris bbox.
           */
      90   static const std::string BboxMaterialName;
          
          
          
      94   EmberEntity(  const std::string& id,   Eris::TypeInfo* ty,   Eris::View* vw,  Ogre::SceneManager* sceneManager );
      95   virtual ~EmberEntity(   );
          
          
           /**
           * Called by contained entites to determine how they should be adjusted,   for example snap to the ground.
           * For instance a house entitiy containing a player entity.
           * This should of course be extended to a more dynamic physics simulation
           * in the future
           */
     104   virtual void adjustPositionForContainedNode(  EmberEntity* const entity,   const Ogre::Vector3& position );
          
          
           /**
           * Adjust the height of the entity so that it "snaps" to the ground.
           * This is most often done by making a call to the containing node's
           * adjustPositionForContainedNode method.
           */
     112   virtual void adjustPosition(   );
     113   virtual void adjustPosition(  const Ogre::Vector3& position );
          
           /**
           * return the scenenode to which this entity belongs
           */
     118   Ogre::SceneNode* getSceneNode(   ) const;
          
           /**
           * Called by a contained member to see if the member is allowed to be shown.
           * This can be reimplemented in a subclass such as AvatarEmberEntity to
           * disallow things that belongs to a characters inventory to be shown.
           */
     125   virtual bool allowVisibilityOfMember(  EmberEntity* entity );
          
          
           /**
           *return true if the entity has a list of suggested responses
           */
     131   bool hasSuggestedResponses(   ) const;
          
           /**
           * returns a list of all suggested responses
           */
     136   const std::vector< std::string >& getSuggestedResponses(   ) const;
          
          
           /**
           * Sets the visibity of the Entity
           * @param visible
           */
     143   virtual void setVisible(  bool visible );
          
          
           /**
           * gets the location as cast to an EmberEntity
           * @return
           */
     150   EmberEntity* getEmberLocation(   ) const;
          
           /**
           attaches the entity to another entity (  or in reality another Model )
           */
     155   virtual void attachToPointOnModel(  const std::string& point,   Model::Model* model ) {};
          
           /**
           detaches the entity from another entity (  or in reality another Model )
           */
     160   virtual void detachFromModel(   ) {};
          
           /**
           if this is true,   init(  ... ) has been called and the entity been set up
           */
     165   inline bool isInitialized(   ) const;
          
           /**
           the mode the entity is in,   like walking,   running,   swimming etc.
           */
     170   inline MovementMode getMovementMode(   ) const;
          
           /**
           Call this method once per frame to update the motion of the entity
           */
     175   virtual void updateMotion(  Ogre::Real timeSlice );
          
           /**
           For debugging.
           Shows the Ogre bounding box.
           */
     181   virtual void showOgreBoundingBox(  bool show );
          
          
           /**
           For debugging.
           Shows the eris/atlas bounding box.
           @see mErisEntityBoundingBox
           */
     189   virtual void showErisBoundingBox(  bool show );
          
           /**
           returns whether the ogre bounding box is shown
           */
     194   virtual bool getShowOgreBoundingBox(   ) const;
          
           /**
           returns whether the eris/atlas bounding box is shown
           @see mErisEntityBoundingBox
           */
     200   virtual bool getShowErisBoundingBox(   ) const;
          
           /**
           * returns the world bounding box of the entity
           * @param derive whether to derive from attached objects too
           * @return
           */
     207   virtual const Ogre::AxisAlignedBox& getWorldBoundingBox(  bool derive = true ) const;
          
          
     210   virtual const Ogre::Sphere & getWorldBoundingSphere (  bool derive=true ) const;
          
           /**
           * Returns a list of the default use operators that can be used with this entity.
           For example,   an axe would have a list of operators such as "chop" and "sharpen".
           * @return
           */
     217   std::vector<std::string> getDefaultUseOperators(   );
          
          
           /**
           * Synchronizes the position and orientation of the entity with the server.
           */
     223   void synchronizeWithServer(   );
          
          
           /**
           Dumps all of this entity's attributes to the supplied outstream.
           */
     229   void dumpAttributes(  std::iostream& outstream,   std::ostream& logOutstream ) const;
          
           /**
           * General method for turning on and off debug visualizations. Subclasses might support more types of visualizations than the ones defined here.
           * @param visualization The type of visualization. Currently supports "OgreBBox" and "ErisBBox".
           * @param visualize Whether to visualize or not.
           */
     236   virtual void setVisualize(  const std::string& visualization,   bool visualize );
          
          
           /**
           * Gets whether a certain visualization is turned on or off.
           * @param visualization The type of visualization. Currently supports "OgreBBox" and "ErisBBox".
           * @return true if visualization is turned on,   else false
           */
     244   virtual bool getVisualize(  const std::string& visualization ) const;
          
          protected:
          
          
           /**
           * Gets the position of a contained node.
           * @param position
           * @param entity
           * @return
           */
     255   virtual const Ogre::Vector3& getOffsetForContainedNode(  const Ogre::Vector3& position,   EmberEntity* const entity );
          
          
           /**
           if this is true,   init(  ... ) has been called and the entity been set up
           */
     261   bool mIsInitialized;
          
           /**
           if true,   the entity is already registered with the motion manager,   so we don't need to add it again (  which can be expensive since
           the motionmanager holds all entities needing updated motions in a std::set )
           */
     267   bool mIsInMotionManager;
          
           /**
           * Overridden from Eris::Entity
           * @see Eris::Entity
           */
     273   virtual void onMoved(   );
     274   virtual void setMoving(  bool moving );
     275   virtual void onTalk(  const Atlas::Objects::Operation::RootOperation& talk );
          // virtual void setContainer(  Entity *pr );
     277   virtual void onVisibilityChanged(  bool vis );
     278   virtual void onLocationChanged(  Eris::Entity *oldLocation );
     279   virtual void onAction(  const Atlas::Objects::Operation::RootOperation& act );
     280   virtual void onImaginary(  const Atlas::Objects::Root& act );
     281   virtual void onSoundAction(  const Atlas::Objects::Operation::RootOperation& op );
          
     283   virtual void addArea(  Terrain::TerrainArea* area );
     284   virtual void onAttrChanged(  const std::string& str,   const Atlas::Message::Element& v );
          
          
     287   virtual void onModeChanged(  MovementMode newMode );
          
           /**
           * Called when the bounding box has changed.
           */
     292   virtual void onBboxChanged(   );
          
           /**
          
           For debugging purposes. This holds a bounding box of how the entity appears in the eris/atlas world.
           This is often different from the Ogre bounding box.
           */
     299   Ogre::OOBBWireBoundingBox* mErisEntityBoundingBox;
          
           /**
           * Creates the material used for the eris bboxes,   if not already created.
           */
     304   void createErisBboxMaterial(   );
          
          
          
           /**
           * Creates the main scene node which holds the entity.
           */
     311   void createSceneNode(  Ogre::SceneManager* sceneManager );
          
           /**
           override from eris
           this is called by eris just after the entity has been put into the world
           */
     317   virtual void init(  const Atlas::Objects::Entity::RootEntity &ge,   bool fromCreateOp );
          
     319   virtual void checkVisibility(  bool vis );
          
           /**
           Sometimes when talking to an entity,   the server will provide suggested responses. These are stored here.
           */
     324   std::vector<std::string> mSuggestedResponses;
          
           /**
           * The main SceneNode which holds the entity in the ogre world space.
           */
     329   Ogre::SceneNode* mOgreNode;
          
           /**
           Gets the scene manager that manages the Ogre scene node held by this.
           */
     334   Ogre::SceneManager* getSceneManager(   );
          
           /**
           If there's a terrainarea belonging to this entity,   that's stored here.
           */
     339   std::auto_ptr<Terrain::TerrainArea> mTerrainArea;
          
          
           /**
           the mode the entity is in,   like walking,   running,   swimming etc.
           */
           MovementMode mMovementMode;
          
          
           /**
           * parses the current mode from the submitted element,   which should be taken from the "mode" attribute
           * this method will in turn call onModeChanged if the mode is changed
           * @param v
           */
     353   void parseModeChange(  const Atlas::Message::Element& v );
          
          };
          
          
          ///inline implementations
     359   bool EmberEntity::isInitialized(   ) const
           {
           return mIsInitialized;
           }
          
     364   EmberEntity::MovementMode EmberEntity::getMovementMode(   ) const
           {
           return mMovementMode;
           }
          
          
          }
          
          #endif // DIMEENTITY_H

./components/ogre/EmberEntityActionCreator.cpp

       1  //
          // C++ Implementation: EmberEntityActionCreator
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "EmberEntityActionCreator.h"
          #include "EmberEntityModelAction.h"
          #include "EmberEntityPartAction.h"
          #include "model/mapping/Cases/CaseBase.h"
          
          using namespace EmberOgre::Model::Mapping;
          
          namespace EmberOgre {
          
      32  EmberEntityActionCreator::EmberEntityActionCreator(  EmberPhysicalEntity& entity )
          : mEntity(  entity )
          {
          }
          
          
      38  EmberEntityActionCreator::~EmberEntityActionCreator(   )
          {
          }
          
      42  void EmberEntityActionCreator::createActions(  ModelMapping& modelMapping,   Cases::CaseBase* aCase,   Definitions::CaseDefinition& caseDefinition )
          {
           Definitions::CaseDefinition::ActionStore::iterator endJ = caseDefinition.getActions(   ).end(   );
           for (  Definitions::CaseDefinition::ActionStore::iterator J = caseDefinition.getActions(   ).begin(   ); J != endJ; ++J ) {
           if (  J->getType(   ) == "display-part" ) {
           EmberEntityPartAction* action = new EmberEntityPartAction(  mEntity,   J->getValue(   ) );
           aCase->addAction(  action );
           } else if (  J->getType(   ) == "display-model" ) {
           EmberEntityModelAction* action = new EmberEntityModelAction(  mEntity,   J->getValue(   ) );
           aCase->addAction(  action );
           }
           }
          
          }
          
          }

./components/ogre/EmberEntityActionCreator.h

       1  //
          // C++ Interface: EmberEntityActionCreator
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREEMBERENTITYACTIONCREATOR_H
          #define EMBEROGREEMBERENTITYACTIONCREATOR_H
          #include "EmberOgrePrerequisites.h"
          #include "EmberPhysicalEntity.h"
          
          #include "model/mapping/ModelMapping.h"
          #include "model/mapping/Definitions/ModelMappingDefinition.h"
          #include "model/mapping/ModelMappingManager.h"
          #include "model/mapping/IActionCreator.h"
          
          namespace EmberOgre {
          
          /**
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
      38  class EmberEntityActionCreator : public Model::Mapping::IActionCreator
          {
          public:
      41   EmberEntityActionCreator(  EmberPhysicalEntity& entity );
          
      43   ~EmberEntityActionCreator(   );
      44   virtual void createActions(  Model::Mapping::ModelMapping& modelMapping,   Model::Mapping::Cases::CaseBase* aCase,   Model::Mapping::Definitions::CaseDefinition& caseDefinition );
          protected:
      46   EmberPhysicalEntity& mEntity;
          
          
          };
          
          }
          
          #endif

./components/ogre/EmberEntityFactory.cpp

          /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifdef HAVE_CONFIG_H
          #include "config.h"
          #endif
          
          #include "EmberEntityFactory.h"
          
          #include <Eris/Entity.h>
          #include <Eris/View.h>
          #include <Eris/TypeInfo.h>
          #include <Eris/Avatar.h>
          
          #include "services/server/ServerService.h"
          #include "services/EmberServices.h"
          
          
          #include "EmberEntity.h"
          #include "WorldEmberEntity.h"
          #include "EmberPhysicalEntity.h"
          #include "AvatarEmberEntity.h"
          #include "EmberOgre.h"
          
          
          #include "model/Model.h"
          #include "model/ModelDefinition.h"
          #include "model/ModelDefinitionManager.h"
          #include "model/mapping/EmberModelMappingManager.h"
          
          
          
          #include "framework/ConsoleBackend.h"
          #include "terrain/TerrainGenerator.h"
          
          #include "Avatar.h"
          
          #include "services/EmberServices.h"
          #include "services/config/ConfigService.h"
          #include "framework/osdir.h"
          
          #ifdef WIN32
           #include <tchar.h>
           #define snprintf _snprintf
           #include <io.h> // for _access,   Win32 version of stat(   )
           #include <direct.h> // for _mkdir
          // #include <sys/stat.h>
          
           #include <iostream>
           #include <fstream>
           #include <ostream>
          #else
           #include <dirent.h>
          #endif
          
          namespace EmberOgre {
          
          
      74  EmberEntityFactory::EmberEntityFactory(  Eris::View* view,   Terrain::TerrainGenerator* terrainGenerator,   Eris::TypeService* typeService )
          : ShowModels(  "showmodels",   this,   "Show or hide models." )
      76  ,   DumpAttributes(  "dump_attributes",   this,   "Dumps the attributes of a supplied entity to a file. If no entity id is supplied the current avatar will be used." )
          ,   mTerrainGenerator(  terrainGenerator )
          ,   mTypeService(  typeService )
          ,   mTerrainType(  0 )
          ,   mWorldEntity(  0 )
          ,   mView(  view )
          {
           mView->registerFactory(  this );
          
           mTerrainType = mTypeService->getTypeByName(  "world" );
          
           getErisAvatar(   )->GotCharacterEntity.connect(  sigc::mem_fun(  *this,   &EmberEntityFactory::gotAvatarCharacter ) );
          
          }
          
          
          
      93  EmberEntityFactory::~EmberEntityFactory(   )
          {
          /// there is no way to deregister the factory from the View,   instead the View will delete the factory when deleted
          // mView->deregisterFactory(  this );
          }
          
          /// create whatever entity the client desires
     100  Eris::Entity* EmberEntityFactory::instantiate(  const Atlas::Objects::Entity::RootEntity &ge,   Eris::TypeInfo* type,   Eris::View* w )
          {
          
           Eris::Entity* emberEntity(  0 );
          
           bool isPhysical = Model::Mapping::EmberModelMappingManager::getSingleton(   ).getManager(   ).getDefinitionForType(  type ) != 0;
          
           if (  ge->getId(   ) == getErisAvatar(   )->getId(   ) ) {
          
           AvatarEmberEntity* avatarEntity = createAvatarEntity(  ge,   type,   w );
           emberEntity = avatarEntity;
          
           } else if (  type->isA(  mTerrainType ) ) {
          
           emberEntity = createWorld(  ge,   type,   w );
          
           } else if (  !isPhysical ) {
           S_LOG_VERBOSE(  "Creating immaterial entity." );
          
           ///we don't want this to have any Ogre::Entity
           emberEntity = new EmberEntity(  ge->getId(   ),   type,   w,   EmberOgre::getSingleton(   ).getSceneManager(   ) );
          
           } else {
          
           emberEntity = createPhysicalEntity(  ge,   type,   w );
          
           }
          
           S_LOG_VERBOSE(  "Entity added to game view." );
           return emberEntity;
          }
          
     132  bool EmberEntityFactory::accept(  const Atlas::Objects::Entity::RootEntity &ge,   Eris::TypeInfo* type )
          {
           return true;
          }
          
          
     138  Eris::Entity* EmberEntityFactory::createWorld(  const Atlas::Objects::Entity::RootEntity & ge,   Eris::TypeInfo* type,   Eris::View *world ) {
           assert(  !mWorldEntity );
           mWorldEntity = new WorldEmberEntity(  ge->getId(   ),   type,   world,   EmberOgre::getSingleton(   ).getSceneManager(   ),   mTerrainGenerator );
           return mWorldEntity;
          }
          
     144  WorldEmberEntity* EmberEntityFactory::getWorld(   ) const
          {
           return mWorldEntity;
          }
          
     149  void EmberEntityFactory::gotAvatarCharacter(  Eris::Entity* entity )
          {
           AvatarEmberEntity* avatarEntity = static_cast<AvatarEmberEntity*>(  entity );
           EmberOgre::getSingleton(   ).getAvatar(   )->createdAvatarEmberEntity(  avatarEntity );
           EmberOgre::getSingleton(   ).EventCreatedAvatarEntity.emit(  avatarEntity );
          }
          
          
          
          
          
          
     161  EmberPhysicalEntity* EmberEntityFactory::createPhysicalEntity(  const Atlas::Objects::Entity::RootEntity &ge,  Eris::TypeInfo* type,   Eris::View *world ) {
          
           EmberPhysicalEntity* entity = new EmberPhysicalEntity(  ge->getId(   ),   type,   world,   EmberOgre::getSingleton(   ).getSceneManager(   ) );
          
           return entity;
          
          }
          
     169  AvatarEmberEntity* EmberEntityFactory::createAvatarEntity(  const Atlas::Objects::Entity::RootEntity &ge,   Eris::TypeInfo* type,   Eris::View *world )
          {
           return new AvatarEmberEntity(  ge->getId(   ),   type,   world,  EmberOgre::getSingleton(   ).getSceneManager(   ),   getErisAvatar(   ) );
          }
          
     174  int EmberEntityFactory::priority(   ) {
           return 10;
          }
          
     178  Eris::Avatar* EmberEntityFactory::getErisAvatar(   )
          {
           return mView->getAvatar(   );
          }
          
     183  void EmberEntityFactory::dumpAttributesOfEntity(  const std::string& entityId ) const
          {
           EmberEntity* entity = EmberOgre::getSingleton(   ).getEmberEntity(  entityId );
           if (  entity ) {
           ///make sure the directory exists
           std::string dir(  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getHomeDirectory(   ) + "/entityexport/" );
          
           if (  !oslink::directory(  dir ).isExisting(   ) ) {
           S_LOG_INFO(  "Creating directory " << dir );
          #ifdef __WIN32__
           mkdir(  dir.c_str(   ) );
          #else
           mkdir(  dir.c_str(   ),   S_IRWXU );
          #endif
           }
          
           const std::string fileName(  dir + entityId + ".atlas" );
           std::fstream exportFile(  fileName.c_str(   ),   std::fstream::out );
          
           S_LOG_INFO(  "Dumping attributes to " << fileName );
           entity->dumpAttributes(  exportFile,   std::cout );
           Ember::ConsoleBackend::getMainConsole(   )->pushMessage(  std::string(  "Dumped attributes to " ) + fileName );
           }
          }
          
          
     209  void EmberEntityFactory::runCommand(  const std::string &command,   const std::string &args )
          {
           if(  command == ShowModels.getCommand(   ) )
           {
           Ember::Tokeniser tokeniser;
           tokeniser.initTokens(  args );
           std::string value = tokeniser.nextToken(   );
           if (  value == "true" ) {
           S_LOG_INFO(  "Showing models." );
           Model::ModelDefinitionManager::getSingleton(   ).setShowModels(  true );
           } else if (  value == "false" ) {
           S_LOG_INFO(  "Hiding models." );
           Model::ModelDefinitionManager::getSingleton(   ).setShowModels(  false );
           }
           } else if (  DumpAttributes == command ) {
           Ember::Tokeniser tokeniser;
           tokeniser.initTokens(  args );
           std::string value = tokeniser.nextToken(   );
           if (  value == "" ) {
           if (  getErisAvatar(   ) ) {
           dumpAttributesOfEntity(  getErisAvatar(   )->getEntity(   )->getId(   ) );
           }
           } else {
           dumpAttributesOfEntity(  value );
           }
           }
          }
          
          
          
          
          }
          

./components/ogre/EmberEntityFactory.h

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef DIMEENTITYFACTORY_H
          #define DIMEENTITYFACTORY_H
          #include "EmberOgrePrerequisites.h"
          
          #include <Eris/Factory.h>
          
          #include <Atlas/Objects/Entity.h>
          
          #include <sigc++/trackable.h>
          
          #include "framework/ConsoleObject.h"
          namespace Eris
          {
      32   class Entity;
      33   class View;
      34   class TypeService;
      35   class TypeInfo;
      36   class Avatar;
          }
          
          namespace EmberOgre {
          
          namespace Terrain
          {
      43  class TerrainGenerator;
          }
          
          class AvatarEmberEntity;
      47  class EmberTerrainPageSource;
      48  class EmberPhysicalEntity;
      49  class EmberEntity;
      50  class ViewEmberEntity;
      51  class WorldEmberEntity;
          
          /**
           * Creates the EmberEntities required.
           * Basically this attaches to Eris and creates Entites on demand.
           * @see Eris::Factory
           *
           */
      59  class EmberEntityFactory :
      60  public Eris::Factory,  
      61  public sigc::trackable,  
      62  public Ember::ConsoleObject
          {
          public:
          
           typedef std::set<Ogre::String> StringSet;
          
          
           /**
           Default constructor. This should be instantiated by EmberOgre or similiar high level object. Note that Eris upon shutdown will delete all registered factories,   so don't delete an instance of this yourself.
           */
      72   EmberEntityFactory(  Eris::View* view,   Terrain::TerrainGenerator* terrainGenerator,   Eris::TypeService* typeService );
      73   virtual ~EmberEntityFactory(   );
          
           /**
           Will always return true.
           */
      78   virtual bool accept(  const Atlas::Objects::Entity::RootEntity &ge,   Eris::TypeInfo* type );
          
           /**
           Creates instances of EmberEntity and its subclasses.
           */
      83   virtual Eris::Entity* instantiate(  const Atlas::Objects::Entity::RootEntity &ge,   Eris::TypeInfo* type,   Eris::View* w );
          
           /** retrieve this factory's priority level; higher priority factories
           get first chance to process a recieved Atlas entity. The default implementation
           returns one. */
      88   virtual int priority(   );
          
           /**
           Returns the main world entity.
           */
      93   WorldEmberEntity* getWorld(   ) const;
          
           /**
           * Reimplements the ConsoleObject::runCommand method
           * @param command
           * @param args
           */
     100   virtual void runCommand(  const std::string &command,   const std::string &args );
          
          
           /**
           Command for setting whether models should be shown or not.
           */
     106   const Ember::ConsoleCommandWrapper ShowModels;
          
           /**
           Dumps the attributes of a supplied entity to the std::out.
           */
     111   const Ember::ConsoleCommandWrapper DumpAttributes;
          
          
           /**
           * Dumps the attributes of the entity with the supplied id to the std::out.
           * @param entityId
           * @return
           */
     119   void dumpAttributesOfEntity(  const std::string& entityId ) const;
          
          protected:
          
          
           /**
           Creates a WorldEmberEntity instance.
           */
     127   Eris::Entity* createWorld(  const Atlas::Objects::Entity::RootEntity & ge,  Eris::TypeInfo* type,   Eris::View *world );
           /**
           Creates a EmberPhysicalEntity instance.
           */
     131   EmberPhysicalEntity* createPhysicalEntity(  const Atlas::Objects::Entity::RootEntity &ge,   Eris::TypeInfo* type,   Eris::View *world );
           /**
           Creates a AvatarEmberEntity instance.
           */
     135   AvatarEmberEntity* createAvatarEntity(  const Atlas::Objects::Entity::RootEntity &ge,   Eris::TypeInfo* type,   Eris::View *world );
          
     137   void gotAvatarCharacter(  Eris::Entity* entity );
          
          
          
     141   Terrain::TerrainGenerator* mTerrainGenerator;
     142   Eris::TypeService* mTypeService;
     143   Eris::TypeInfo* mTerrainType;
          
     145   Eris::Avatar* getErisAvatar(   );
          
     147   WorldEmberEntity *mWorldEntity;
          
     149   Eris::View* mView;
          
          
          };
          
          }
          
          #endif // DIMEENTITYFACTORY_H

./components/ogre/EmberEntityModelAction.cpp

       1  //
          // C++ Implementation: EmberEntityModelAction
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "EmberEntityModelAction.h"
          
          namespace EmberOgre {
          
      27  EmberEntityModelAction::EmberEntityModelAction(  EmberPhysicalEntity& entity,   std::string modelName )
          : mEntity(  entity ),   mModelName(  modelName )
          {
          }
          
          
      33  EmberEntityModelAction::~EmberEntityModelAction(   )
          {
          }
          
      37  void EmberEntityModelAction::activate(   )
          {
           mEntity.setModel(  mModelName );
           S_LOG_VERBOSE(  "Showing model " << mModelName );
          }
          
      43  void EmberEntityModelAction::deactivate(   )
          {
           mEntity.setModel(  "" );
           S_LOG_VERBOSE(  "Hiding model " << mModelName );
          }
          
          
          }

./components/ogre/EmberEntityModelAction.h

       1  //
          // C++ Interface: EmberEntityModelAction
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREEMBERENTITYMODELACTION_H
          #define EMBEROGREEMBERENTITYMODELACTION_H
          
          #include "EmberOgrePrerequisites.h"
          #include "EmberPhysicalEntity.h"
          
          // #include "model/mapping/ModelMapping.h"
          #include "model/mapping/Actions/Action.h"
          
          namespace EmberOgre {
          
          /**
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
      37  class EmberEntityModelAction : public Model::Mapping::Actions::Action
          {
          public:
      40   EmberEntityModelAction(  EmberPhysicalEntity& entity,   std::string modelName );
      41   ~EmberEntityModelAction(   );
          
      43   virtual void activate(   );
      44   virtual void deactivate(   );
          
          protected:
      47   EmberPhysicalEntity& mEntity;
          
      49   std::string mModelName;
          };
          
          }
          
          #endif

./components/ogre/EmberEntityPartAction.cpp

       1  //
          // C++ Implementation: EmberEntityPartAction
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #include "EmberEntityPartAction.h"
          
          #include "model/Model.h"
          
          
          namespace EmberOgre {
          
          
      32  EmberEntityPartAction::EmberEntityPartAction(  EmberPhysicalEntity& entity,   std::string partName )
          : mEntity(  entity ),   mPartName(  partName )
          {
          }
          
          
      38  EmberEntityPartAction::~EmberEntityPartAction(   )
          {
          }
          
      42  void EmberEntityPartAction::activate(   )
          {
           S_LOG_VERBOSE(  "Showing part " << mPartName );
           mEntity.showModelPart(  mPartName );
          // Model::Model* model = mEntity.getModel(   );
          // if (  model ) {
          // model->showPart(  mPartName );
          //
          // }
          }
          
      53  void EmberEntityPartAction::deactivate(   )
          {
           S_LOG_VERBOSE(  "Hiding part " << mPartName );
           mEntity.hideModelPart(  mPartName );
          // Model::Model* model = mEntity.getModel(   );
          // if (  model ) {
          // model->hidePart(  mPartName,   false );
          // }
          }
          
          }

./components/ogre/EmberEntityPartAction.h

       1  //
          // C++ Interface: EmberEntityPartAction
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREEMBERENTITYPARTACTION_H
          #define EMBEROGREEMBERENTITYPARTACTION_H
          #include "EmberOgrePrerequisites.h"
          #include "EmberPhysicalEntity.h"
          
          #include "model/mapping/ModelMapping.h"
          #include "model/mapping/Actions/Action.h"
          
          namespace EmberOgre {
          
          /**
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
      36  class EmberEntityPartAction : public Model::Mapping::Actions::Action
          {
          public:
      39   EmberEntityPartAction(  EmberPhysicalEntity& entity,   std::string partName );
      40   ~EmberEntityPartAction(   );
          
      42   virtual void activate(   );
      43   virtual void deactivate(   );
          
          protected:
      46   EmberPhysicalEntity& mEntity;
          
      48   std::string mPartName;
          };
          
          }
          
          #endif

./components/ogre/EmberEntityUserObject.cpp

       1  //
          // C++ Implementation: EmberEntityUserObject
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "EmberEntityUserObject.h"
          #include "ogreopcode/include/OgreCollisionObject.h"
          #include "EmberEntity.h"
          #include "model/Model.h"
          
          
          namespace EmberOgre {
          
          const Ogre::String EmberEntityUserObject::s_TypeName = "EmberEntityPickerObject";
          
          
      34  EmberEntityUserObject::EmberEntityUserObject(  EmberEntity* emberEntity,   Model::Model* model,   ICollisionDetector* collisionDetector )
          : mEmberEntity(  emberEntity ),  
          mModel(  model ),  
          mCollisionDetector(  collisionDetector )
          // mCollisionObjects(  collisionObjects ),  
          {
          }
          
          // CollisionObjectStore EmberEntityUserObject::getCollisionObjects(   ) const
          // {
          // return mCollisionObjects;
          // }
          
      47  EmberEntityUserObject::~EmberEntityUserObject(   )
          {
           delete mCollisionDetector;
          /* OgreOpcode::CollisionContext* collideContext = OgreOpcode::CollisionManager::getSingletonPtr(   )->getDefaultContext(   );
           for (  EmberEntityUserObject::CollisionObjectStore::iterator I = mCollisionObjects.begin(   ); I != mCollisionObjects.end(   ); ++I )
           {
           collideContext->removeObject(  *I );
           OgreOpcode::CollisionManager::getSingleton(   ).destroyShape(  (  *I )->getShape(   ) );
           delete *I;
           }*/
          }
          
      59  void EmberEntityUserObject::refit(   )
          {
           if (  mCollisionDetector ) {
           mCollisionDetector->refit(   );
           }
          /* for (  EmberEntityUserObject::CollisionObjectStore::iterator I = mCollisionObjects.begin(   ); I != mCollisionObjects.end(   ); ++I )
           {
           (  *I )->refit(   );;
           }*/
          }
          
      70  EmberEntity* EmberEntityUserObject::getEmberEntity(   ) const
          {
           return mEmberEntity;
          }
          
      75  Model::Model* EmberEntityUserObject::getModel(   ) const
          {
           return mModel;
          }
          
      80  const Ogre::String & EmberEntityUserObject::getTypeName (  void ) const
          {
           return s_TypeName;
          }
          
          
          
          };

./components/ogre/EmberEntityUserObject.h

       1  //
          // C++ Interface: EmberEntityUserObject
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREEMBERENTITYUSEROBJECT_H
          #define EMBEROGREEMBERENTITYUSEROBJECT_H
          
          #include "EmberOgrePrerequisites.h"
          
          
          
          namespace Ogre
          {
      32   class Entity;
          };
          
          namespace EmberOgre {
          
          namespace Model {
      38   class Model;
          }
      40  class EmberEntity;
          
          
          struct CollisionResult
          {
           bool collided;
           Ogre::Vector3 position;
           Ogre::Real distance;
          };
          
          /**
          @author Erik Hjortsberg
          
          * Interface for collision detectors,   responsible for determining collision information for the entity that they are attached to.
          */
      55  class ICollisionDetector
          {
          public:
      58   virtual ~ICollisionDetector(   ) {};
          
           /**
           * Testa whether the provided ray hits the entity.
           * @param ray The ray to test.
           * @param result The result of the collision. If the ray hits,   the collision detector must update this object.
           */
      65   virtual void testCollision(  Ogre::Ray& ray,   CollisionResult& result ) = 0;
           /**
           * Refits the collision mesh against the entity. This is called to ensure that the collision mesh fits animated entities.
           */
      69   virtual void refit(   ) = 0;
          
          
           /**
           * Called when the entity changes,   such as a subentity being hidden or shown. Implementations must reload the collision data.
           */
      75   virtual void reload(   ) = 0;
          
           /**
           * Sets whether the collision data should be visualized for debugging purposes.
           * @param visualize
           */
      81   virtual void setVisualize(  bool visualize ) = 0;
           /**
           * Gets whether the collision data should be visualized for debugging purposes.
           * @return
           */
      86   virtual bool getVisualize(   ) const = 0;
          
          };
          
          
          /**
          @author Erik Hjortsberg
          
          Instances of this class can be attached to scene nodes in the ogre system. They will allow for the Ember system to be accessed directly from Ogre,   without having to do lookups.
          This is generally mostly used for mouse picking and collision handling.
          
          */
      98  class EmberEntityUserObject : public Ogre::UserDefinedObject
          {
          public:
          
           /**
           The type of UserDefinedObject
           */
     105   static const std::string s_TypeName;
          // typedef std::vector<OgreOpcode::CollisionObject*> CollisionObjectStore;
          
           /**
           * Constructor.
           * @param emberEntity A valid EmberEntity instance.
           * @param model A valid Model instance.
           * @param collisionObject A valid vector of collision objects.
           * @return
           */
     115   EmberEntityUserObject(  EmberEntity* emberEntity,   Model::Model* model,   ICollisionDetector* collisionDetector );
          
     117   virtual ~EmberEntityUserObject(   );
          
           /**
           * Gets the EmberEntity contained.
           * @return
           */
     123   EmberEntity* getEmberEntity(   ) const;
          
           /**
           * Gets the Model instance.
           * @return
           */
     129   Model::Model* getModel(   ) const ;
          
           /**
           * Gets a pointer to a vector of CollisionObjects. This can be used for checking collisions.
           * @return
           */
          // CollisionObjectStore* getCollisionObjects(   ) { return &mCollisionObjects; }
          
           /**
           * Overloaded method for getting the type name of this instance.
           * @param
           * @return
           */
     142   virtual const Ogre::String & getTypeName (  void ) const;
          
     144   void refit(   );
          
     146   inline ICollisionDetector* getCollisionDetector(   ) const;
          
          private:
     149   EmberEntity* mEmberEntity;
     150   Model::Model* mModel;
           //CollisionObjectStore mCollisionObjects;
     152   ICollisionDetector* mCollisionDetector;
          
          };
          
     156  ICollisionDetector* EmberEntityUserObject::getCollisionDetector(   ) const
          {
           return mCollisionDetector;
          }
          
          };
          
          #endif

./components/ogre/EmberOgre.cpp

       1  /*
          -----------------------------------------------------------------------------
          OgreApp.cpp by Miguel Guzman Miranda (  Aglanor )
          Based on OGRE sample applications:
           OGRE (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://ogre.sourceforge.net
          Based on the Ember main application by the Ember team
          
          This program is free software; you can redistribute it and/or modify it under
          the terms of the GNU 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          
          
          -----------------------------------------------------------------------------
          */
          
          
          #ifdef HAVE_CONFIG_H
          #include "config.h"
          #endif
          
          #include "EmberOgre.h"
          
          // Headers to stop compile problems from headers
          #include <stdlib.h>
          #include <stddef.h>
          #include <stdio.h>
          #include <sys/types.h>
          
          #ifdef WIN32
           #include <tchar.h>
           #define snprintf _snprintf
           #include <io.h> // for _access,   Win32 version of stat(   )
           #include <direct.h> // for _mkdir
          // #include <sys/stat.h>
          
           #include <iostream>
           #include <fstream>
           #include <ostream>
          #else
           #include <dirent.h>
          #endif
          
          #include "EmberOgrePrerequisites.h"
          
          // ------------------------------
          // Include Eris header files
          // ------------------------------
          /*#include <Eris/PollDefault.h>*/
          #include <Eris/Connection.h>
          #include <Eris/View.h>
          
          
          
          //Ember headers
          #include "services/EmberServices.h"
          #include "services/logging/LoggingService.h"
          #include "services/server/ServerService.h"
          #include "services/config/ConfigService.h"
          #include "services/metaserver/MetaserverService.h"
          #include "services/sound/SoundService.h"
          #include "services/scripting/ScriptingService.h"
          #include "services/wfut/WfutService.h"
          #include "framework/ConsoleBackend.h"
          #include "framework/ConsoleObject.h" //TODO: this will be included in a different class
          #include "framework/binreloc.h" //this is needed for binreloc functionality
          
          
          // ------------------------------
          // Include OGRE Ember client files
          // ------------------------------
          #include "terrain/TerrainGenerator.h"
          #include "terrain/TerrainLayerDefinitionManager.h"
          
          
          #include "ConsoleObjectImpl.h"
          #include "Avatar.h"
          #include "AvatarController.h"
          #include "EmberEntityFactory.h"
          #include "MotionManager.h"
          #include "AvatarCamera.h"
          #include "GUIManager.h"
          #include "manipulation/EntityMoveManager.h"
          
          
          #include "EmberEntity.h"
          #include "WorldEmberEntity.h"
          
          #include "environment/meshtree/TParameters.h"
          #include "environment/Tree.h"
          
          #include "carpenter/Carpenter.h"
          #include "carpenter/BluePrint.h"
          
          #include <OgreSceneManager.h>
          #include "SceneManagers/EmberPagingSceneManager/include/EmberPagingSceneManager.h"
          #include "SceneManagers/EmberPagingSceneManager/include/EmberPagingSceneManagerAdapter.h"
          #include "model/ModelDefinitionManager.h"
          #include "model/ModelDefinition.h"
          #include "model/mapping/EmberModelMappingManager.h"
          
          #include "ogreopcode/include/OgreCollisionManager.h"
          #include "OpcodeCollisionDetectorVisualizer.h"
          
          // ------------------------------
          // Include Ember header files
          // ------------------------------
          
          #include "framework/ConsoleBackend.h"
          
          
          
          #include "jesus/Jesus.h"
          #include "jesus/XMLJesusSerializer.h"
          
          #include "framework/osdir.h"
          
          #include "framework/Exception.h"
          #include "OgreLogObserver.h"
          #include "OgreResourceLoader.h"
          
          #include "widgets/LoadingBar.h"
          
          #include "sound/OgreSoundProvider.h"
          
          #include "OgreSetup.h"
          
          #include "manipulation/MaterialEditor.h"
          #include "MediaUpdater.h"
          
          #include "main/Application.h"
          #include "input/InputCommandMapper.h"
          #include "input/Input.h"
          
          #include "OgreResourceProvider.h"
          #include "scripting/LuaScriptingProvider.h"
          
          template<> EmberOgre::EmberOgre* Ember::Singleton<EmberOgre::EmberOgre>::ms_Singleton = 0;
          
          namespace EmberOgre {
          
     152   void assureConfigFile(  const std::string& filename,   const std::string& originalConfigFileDir )
           {
           struct stat tagStat;
           int ret = stat(   filename.c_str(   ),   &tagStat  );
           if (  ret == -1 ) {
           ret = stat(   (  originalConfigFileDir +filename ).c_str(   ),   &tagStat  );
           if (  ret == 0 ) {
           ///copy conf file from shared
           std::ifstream instream (  (  originalConfigFileDir + filename ).c_str(   ) );
           std::ofstream outstream (  filename.c_str(   ) );
           outstream << instream.rdbuf(   );
           }
           }
           }
          
          
          
     169  EmberOgre::EmberOgre(   ) :
          mAvatar(  0 ),  
          mAvatarController(  0 ),  
          mRoot(  0 ),  
          mSceneMgr(  0 ),  
          mWindow(  0 ),  
          mInput(  std::auto_ptr<Input>(  new Input ) ),  
          mGeneralCommandMapper(  std::auto_ptr<InputCommandMapper>(  new InputCommandMapper(  "general" ) ) ),  
          mEmberEntityFactory(  0 ),  
          mTerrainGenerator(  0 ),  
          mMotionManager(  0 ),  
          mGUIManager(  0 ),  
          mModelDefinitionManager(  0 ),  
          mModelMappingManager(  0 ),  
          mTerrainLayerManager(  0 ),  
          mMoveManager(  0 ),  
          mKeepOnRunning(  true ),  
          mJesus(  0 ),  
          mLogObserver(  0 ),  
          mMaterialEditor(  0 ),  
          mCollisionManager(  0 ),  
          mCollisionDetectorVisualizer(  0 )
          {
           Ember::Application::getSingleton(   ).EventServicesInitialized.connect(  sigc::mem_fun(  *this,   &EmberOgre::Application_ServicesInitialized ) );
          }
          
     195  EmberOgre::~EmberOgre(   )
          {
           delete mCollisionDetectorVisualizer;
           delete mCollisionManager;
           delete mMaterialEditor;
           delete mJesus;
           delete mMoveManager;
          
           ///The factory will be deleted by the mWorldView when that is deleted later on,   so we shall not delete it here
          // delete mEmberEntityFactory;
           delete mAvatarController;
           delete mAvatar;
          
           ///start with deleting the eris world,   then shut down ogre
          // delete mWorldView;
          
           delete mMotionManager;
           delete mTerrainGenerator;
          
           delete mGUIManager;
          
           delete mTerrainLayerManager;
           delete mModelMappingManager;
          
           ///we need to make sure that all Models are destroyed before Ogre begins destroying other movable objects (  such as Entities )
           ///this is because Model internally uses Entities,   so if those Entities are destroyed by Ogre before the Models are destroyed,   the Models will try to delete them again,   causing segfaults and other wickedness
           ///by deleting the model manager we'll assure that
           delete mModelDefinitionManager;
          
           if (  mWindow ) {
           mRoot->detachRenderTarget(  mWindow );
           }
          
           Ogre::LogManager::getSingleton(   ).getDefaultLog(   )->removeListener(  mLogObserver );
           delete mLogObserver;
          
           if (  mOgreSetup.get(   ) ) {
           mOgreSetup->shutdown(   );
           mOgreSetup.release(   );
           }
          
          
          /* delete mOgreResourceLoader;
          // mSceneMgr->shutdown(   );
          // delete mWorldView;
           //mSceneMgr->removeAllCameras(   );
          // mSceneMgr->clearScene(   );
           delete mGUIManager;
           delete mTerrainGenerator;
           delete mMotionManager;
          // if (  mAvatar )
          // delete mAvatar;
           delete mAvatarController;*/
          // delete mModelDefinitionManager;
          /* if (  mEmberEntityFactory )
           delete mEmberEntityFactory;*/
          // delete mRoot;
          
          
          
          
          
          }
          
     259  bool EmberOgre::frameEnded(  const Ogre::FrameEvent & evt )
          {
           return true;
          }
          
     264  bool EmberOgre::frameStarted(  const Ogre::FrameEvent & evt )
          {
           //OgreOpcode::CollisionManager::getSingletonPtr(   )->getDefaultContext(   )->visualize(  true,   false,   false,   false,   true,   true );
          // if (  !mKeepOnRunning )
          // S_LOG_INFO(   "Shutting down Ember." );
          // return mKeepOnRunning;
           return true;
          }
          
     273  bool EmberOgre::renderOneFrame(   )
          {
           mInput->processInput(   );
           if (  mInput->isApplicationVisible(   ) ) {
           return mRoot->renderOneFrame(   );
           }
           return true;
          }
          
     282  void EmberOgre::shutdownGui(   )
          {
           delete mGUIManager;
           mGUIManager = 0;
          }
          
     288  void EmberOgre::go(   )
          {
           if (  !setup(   ) )
           return;
          }
          
          
          
          // These internal methods package up the stages in the startup process
          /** Sets up the application - returns false if the user chooses to abandon configuration. */
     298  bool EmberOgre::setup(   )
          {
           S_LOG_INFO(  "Compiled against ogre version " << OGRE_VERSION );
          
           Ember::ConfigService* configSrv = Ember::EmberServices::getSingleton(   ).getConfigService(   );
          
           checkForConfigFiles(   );
          
           ///Create a setup object through which we will start up Ogre.
           mOgreSetup = std::auto_ptr<OgreSetup>(  new OgreSetup );
          
           mLogObserver = new OgreLogObserver(   );
          
           ///if we do this we will override the automatic creation of a LogManager and can thus route all logging from ogre to the ember log
           new Ogre::LogManager(   );
           Ogre::LogManager::getSingleton(   ).createLog(  "Ogre",   true,   false,   true );
           Ogre::LogManager::getSingleton(   ).getDefaultLog(   )->addListener(  mLogObserver );
          
           ///We need a root object.
           mRoot = mOgreSetup->createOgreSystem(   );
          
           if (  !mRoot ) {
           throw Ember::Exception(  "There was a problem setting up the Ogre environment,   aborting." );
           }
          
           ///Create the model definition manager
           mModelDefinitionManager = new Model::ModelDefinitionManager(   );
          
           mModelMappingManager = new Model::Mapping::EmberModelMappingManager(   );
          
           mTerrainLayerManager = new Terrain::TerrainLayerDefinitionManager(   );
          
           ///Create a resource loader which loads all the resources we need.
           OgreResourceLoader ogreResourceLoader;
           ogreResourceLoader.initialize(   );
          
           ///check if we should preload the media
           bool preloadMedia = configSrv->itemExists(  "media",   "preloadmedia" ) && (  bool )configSrv->getValue(  "media",   "preloadmedia" );
           bool useWfut = configSrv->itemExists(  "wfut",   "enabled" ) && (  bool )configSrv->getValue(  "wfut",   "enabled" );
          
          
           bool carryOn = mOgreSetup->configure(   );
           if (  !carryOn ) return false;
           mWindow = mOgreSetup->getRenderWindow(   );
          
          
           ///start with the bootstrap resources,   after those are loaded we can show the LoadingBar
           ogreResourceLoader.loadBootstrap(   );
          
          
           mSceneMgr = mOgreSetup->chooseSceneManager(   );
          
           ///create the main camera,   we will of course have a couple of different cameras,   but this will be the main one
           Ogre::Camera* camera = mSceneMgr->createCamera(  "MainCamera" );
           Ogre::Viewport* viewPort = mWindow->addViewport(  camera );
           ///set the background colour to black
           viewPort->setBackgroundColour(  Ogre::ColourValue(  0,  0,  0 ) );
           camera->setAspectRatio(  Ogre::Real(  viewPort->getActualWidth(   ) ) / Ogre::Real(  viewPort->getActualHeight(   ) ) );
          
           ///The input object must know the resoluton of the screen
           unsigned int height,   width,   depth;
           int top,   left;
           mWindow->getMetrics(  width,   height,   depth,   left,   top );
           mInput->initialize(  width,   height );
          
           ///bind general commands
           mGeneralCommandMapper->readFromConfigSection(  "key_bindings_general" );
           mGeneralCommandMapper->bindToInput(  *mInput );
          
           ///we need a nice loading bar to show the user how far the setup has progressed
           Gui::LoadingBar loadingBar;
          
           Gui::LoadingBarSection wfutSection(  loadingBar,   0.2,   "Media update" );
           loadingBar.addSection(  &wfutSection );
           Gui::WfutLoadingBarSection wfutLoadingBarSection(  wfutSection );
          
           Gui::LoadingBarSection resourceGroupSection(  loadingBar,   0.8,   "Resource loading" );
           loadingBar.addSection(  &resourceGroupSection );
           unsigned int numberOfSections = ogreResourceLoader.numberOfSections(   ) - 1; ///remove bootstrap since that's already loaded
           Gui::ResourceGroupLoadingBarSection resourceGroupSectionListener(  resourceGroupSection,   numberOfSections,   (  preloadMedia ? numberOfSections : 0  ),   0.7 );
          
           loadingBar.start(  mWindow );
           loadingBar.setVersionText(  std::string(  "Version " ) + VERSION  );
          
           /// Turn off rendering of everything except overlays
           mSceneMgr->clearSpecialCaseRenderQueues(   );
           mSceneMgr->addSpecialCaseRenderQueue(  Ogre::RENDER_QUEUE_OVERLAY );
           mSceneMgr->setSpecialCaseRenderQueueMode(  Ogre::SceneManager::SCRQM_INCLUDE );
          
           if (  useWfut ) {
           S_LOG_INFO(  "Updating media." );
           MediaUpdater updater;
           updater.performUpdate(   );
           }
          
           ///create the collision manager
           mCollisionManager = new OgreOpcode::CollisionManager(  mSceneMgr );
           mCollisionDetectorVisualizer = new OpcodeCollisionDetectorVisualizer(   );
          
           ogreResourceLoader.loadGui(   );
           ogreResourceLoader.loadGeneral(   );
          
           ///add ourself as a frame listener
           Ogre::Root::getSingleton(   ).addFrameListener(  this );
          
           ///should media be preloaded?
           if (  preloadMedia )
           {
           S_LOG_INFO(   "Begin preload." );
           ogreResourceLoader.preloadMedia(   );
           S_LOG_INFO(   "End preload." );
           }
           try {
           mGUIManager = new GUIManager(  mWindow,   mSceneMgr );
           EventGUIManagerCreated.emit(  *mGUIManager );
           } catch (  ... ) {
           ///we failed at creating a gui,   abort (  since the user could be running in full screen mode and could have some trouble shutting down )
           throw Ember::Exception(  "Could not load gui,   aborting. Make sure that all media got downloaded and installed correctly." );
           }
          
          
          
           if (  chdir(  configSrv->getHomeDirectory(   ).c_str(   ) ) ) {
           S_LOG_WARNING(  "Failed to change directory to '"<< configSrv->getHomeDirectory(   ) << "'" );
           }
          
           // Avatar
           mAvatar = new Avatar(   );
          
           mAvatarController = new AvatarController(  mAvatar,   mWindow,   mGUIManager,   camera );
           EventAvatarControllerCreated.emit(  *mAvatarController );
          
           mTerrainGenerator = new Terrain::TerrainGenerator(  new EmberPagingSceneManagerAdapter(  mSceneMgr ) );
           EventTerrainGeneratorCreated.emit(  *mTerrainGenerator );
           mMotionManager = new MotionManager(   );
          // mMotionManager->setTerrainGenerator(  mTerrainGenerator );
           EventMotionManagerCreated.emit(  *mMotionManager );
          
          // mSceneMgr->setPrimaryCamera(  mAvatar->getAvatarCamera(   )->getCamera(   ) );
          
           mMoveManager = new EntityMoveManager(   );
          
          
          
          
           mRoot->addFrameListener(  mMotionManager );
           new ConsoleObjectImpl(   );
          
          
           try {
           mGUIManager->initialize(   );
           EventGUIManagerInitialized.emit(  *mGUIManager );
           } catch (  ... ) {
           ///we failed at creating a gui,   abort (  since the user could be running in full screen mode and could have some trouble shutting down )
           throw Ember::Exception(  "Could not initialize gui,   aborting. Make sure that all media got downloaded and installed correctly." );
           }
          
           /// Create the scene
           createScene(   );
           EventSceneCreated.emit(   );
          
           ///this should be in a separate class,   a separate plugin even
           ///disable for now,   since it's not used
           //setupJesus(   );
          
           /// Back to full rendering
           mSceneMgr->clearSpecialCaseRenderQueues(   );
           mSceneMgr->setSpecialCaseRenderQueueMode(  Ogre::SceneManager::SCRQM_EXCLUDE );
          
           mMaterialEditor = new MaterialEditor(   );
          
           loadingBar.finish(   );
          
           return true;
          
          }
          
          
     476  EmberEntity* EmberOgre::getEmberEntity(  const std::string & eid )
          {
           assert(  getMainView(   ) );
           return static_cast<EmberEntity*>(  getMainView(   )->getEntity(  eid ) );
          }
          
          
     483  void EmberOgre::checkForConfigFiles(   )
          {
           if (  chdir(  Ember::EmberServices::getSingleton(   ).getConfigService(   )->getHomeDirectory(   ).c_str(   ) ) ) {
           S_LOG_WARNING(  "Failed to change directory to '"<< Ember::EmberServices::getSingleton(   ).getConfigService(   )->getHomeDirectory(   ) << "',   will not copy config files." );
           return;
           }
          
           const std::string& sharePath(  Ember::EmberServices::getSingleton(   ).getConfigService(   )->getSharedConfigDirectory(   ) );
          
           ///make sure that there are files
           assureConfigFile(  "ogre.cfg",   sharePath );
           //assureConfigFile(  "plugins.cfg",   sharePath );
          }
          
          
     498  void EmberOgre::preloadMedia(  void )
          {
           Ogre::ResourceGroupManager::getSingleton(   ).initialiseAllResourceGroups(   );
          
           Ember::ConfigService* configSrv = Ember::EmberServices::getSingleton(   ).getConfigService(   );
          
          
           std::vector<std::string> shaderTextures;
          
           shaderTextures.push_back(  std::string(  configSrv->getValue(  "shadertextures",   "rock" ) ) );
           shaderTextures.push_back(  std::string(  configSrv->getValue(  "shadertextures",   "sand" ) ) );
           shaderTextures.push_back(  std::string(  configSrv->getValue(  "shadertextures",   "grass" ) ) );
          
           for (  std::vector<std::string>::iterator I = shaderTextures.begin(   ); I != shaderTextures.end(   ); ++I ) {
           try {
           Ogre::TextureManager::getSingleton(   ).load(  *I,   "General" );
           } catch (  const Ogre::Exception& e ) {
           S_LOG_FAILURE(   "Error when loading texture " << *I << ".\n\rError message: " << e.getDescription(   ) );
           }
           }
          
           //only autogenerate trees if we're not using the pregenerated ones
           if (  configSrv->itemExists(  "tree",   "usedynamictrees" ) && (  (  bool )configSrv->getValue(  "tree",   "usedynamictrees" ) ) ) {
           Environment::Tree tree;
           tree.makeMesh(  "GeneratedTrees/European_Larch",   Ogre::TParameters::European_Larch );
           tree.makeMesh(  "GeneratedTrees/Fir",   Ogre::TParameters::Fir );
           }
          
          
          
          
          }
          
     531  void EmberOgre::setupJesus(   )
          {
           const std::string datadir = Ember::EmberServices::getSingleton(   ).getConfigService(   )->getSharedDataDirectory(   );
          
           Carpenter::Carpenter* carpenter = new Carpenter::Carpenter(   );
           mJesus = new Jesus(  carpenter );
           XMLJesusSerializer serializer(  mJesus );
          
           std::string dir(  Ember::EmberServices::getSingleton(   ).getConfigService(   )->getSharedDataDirectory(   ) + "carpenter/blockspec" );
          
           std::string filename;
          
           //oslink::directory needs to be destroyed before a new one can be used,   regular copy constructor doesn't seem to work
           //we could also use new/delete,   but scopes works as well
           {
           oslink::directory osdir(  dir );
           while (  osdir ) {
           filename = osdir.next(   );
           S_LOG_VERBOSE(   "Loading blockspec: " << filename  );
           serializer.loadBlockSpec(  dir + "/" + filename );
           }
           }
           //load all buildingblockspecs
           dir = Ember::EmberServices::getSingleton(   ).getConfigService(   )->getSharedDataDirectory(   ) + "carpenter/modelblockspecs";
           {
           oslink::directory osdir(  dir );
           while (  osdir ) {
           filename = osdir.next(   );
           S_LOG_VERBOSE(   "Loading buildingblockspecC: " << filename );
           serializer.loadBuildingBlockSpecDefinition(  dir + "/" + filename );
           }
           }
           //load all modelmappings
           dir = Ember::EmberServices::getSingleton(   ).getConfigService(   )->getSharedDataDirectory(   ) + "jesus/modelmappings";
           {
           oslink::directory osdir(  dir );
           while (  osdir ) {
           filename = osdir.next(   );
           S_LOG_VERBOSE(   "Loading modelmapping: " << filename  );
           serializer.loadModelBlockMapping(  dir + "/" + filename );
           }
           }
          
           //load all global blueprints
           dir = Ember::EmberServices::getSingleton(   ).getConfigService(   )->getSharedDataDirectory(   ) + "carpenter/blueprints";
           {
           oslink::directory osdir(  dir );
           while (  osdir ) {
           filename = osdir.next(   );
           S_LOG_VERBOSE(   "Loading blueprint: " << filename  );
           Carpenter::BluePrint* blueprint = serializer.loadBlueprint(  dir + "/" + filename );
           if (  blueprint ) {
           blueprint->compile(   );
           bool result = mJesus->addBluePrint(  blueprint );
           if (  !result )
           {
           S_LOG_FAILURE(   "Could not add blueprint: " << filename );
           }
           }
           }
           }
           //load all local blueprints
           dir = Ember::EmberServices::getSingleton(   ).getConfigService(   )->getHomeDirectory(   ) + "carpenter/blueprints";
           {
           oslink::directory osdir(  dir );
           while (  osdir ) {
           filename = osdir.next(   );
           S_LOG_VERBOSE(   "Loading local blueprint: " << filename  );
           Carpenter::BluePrint* blueprint = serializer.loadBlueprint(  dir + "/" + filename );
           if (  blueprint ) {
           blueprint->compile(   );
           bool result = mJesus->addBluePrint(  blueprint );
           if (  !result )
           {
           S_LOG_FAILURE(   "Could not add blueprint: " << filename  );
           }
           }
           }
           }
          
          
           EventCreatedJesus.emit(  mJesus );
          }
          
     615  void EmberOgre::createScene(  void )
          {
          
           ///initially,   while in the "void",   we'll use a clear ambient light
           mSceneMgr->setAmbientLight(  Ogre::ColourValue(  1,   1,   1 ) );
          
          }
          
     623  void EmberOgre::Server_GotView(  Eris::View* view )
          {
          // mWorldView = view;
           mEmberEntityFactory = new EmberEntityFactory(  view,   mTerrainGenerator,   Ember::EmberServices::getSingleton(   ).getServerService(   )->getConnection(   )->getTypeService(   ) );
          }
          
     629  EmberEntity* EmberOgre::getEntity(  const std::string & id )
          {
           ///this of course relies upon all entities being created by our factory
           return static_cast<EmberEntity*>(  getMainView(   )->getEntity(  id ) );
          }
          
          
     636  void EmberOgre::connectedToServer(  Eris::Connection* connection )
          {
           //EventCreatedAvatarEntity.connect(  sigc::mem_fun(  *mAvatar,   &Avatar::createdAvatarEmberEntity ) );
           EventCreatedEmberEntityFactory.emit(  mEmberEntityFactory );
          }
          
          
          
     644  Avatar* EmberOgre::getAvatar(   ) const {
           return mAvatar;
          }
          
          
     649  Ogre::SceneManager* EmberOgre::getSceneManager(   ) const
          {
           return mSceneMgr;
          }
          
     654  Terrain::TerrainGenerator* EmberOgre::getTerrainGenerator(   ) const
          {
           return mTerrainGenerator;
          }
          
     659  MotionManager* EmberOgre::getMotionManager(   ) const
          {
           return mMotionManager;
          }
          
     664  Ogre::Root* EmberOgre::getOgreRoot(   ) const
          {
           assert(  mRoot );
           return mRoot;
          }
          
     670  Ogre::SceneNode * EmberOgre::getWorldSceneNode(    ) const
          {
           if (  mEmberEntityFactory && mEmberEntityFactory->getWorld(   ) ) {
           return mEmberEntityFactory->getWorld(   )->getSceneNode(   );
           } else {
           return mSceneMgr->getRootSceneNode(   );
           }
          /* Ogre::SceneNode* node = mSceneMgr->getSceneNode(  "0" );
           //TODO: implement better exception handling
           if (  node == 0 )
           throw Exception(   );
           return node;*/
          }
          
     684  Ogre::SceneNode* EmberOgre::getRootSceneNode(   ) const
          {
           return mSceneMgr->getRootSceneNode(   );
          }
          
          
     690  AvatarCamera* EmberOgre::getMainCamera(   ) const
          {
           return mAvatar->getAvatarCamera(   );
          }
          
     695  EmberEntityFactory* EmberOgre::getEntityFactory(   ) const
          {
           return mEmberEntityFactory;
          }
          
     700  AvatarController* EmberOgre::getAvatarController(   ) const
          {
           return mAvatarController;
          }
          
          // // void EmberOgre::setErisPolling(  bool doPoll )
          // // {
          // // mPollEris = doPoll;
          // // }
          // //
          // // bool EmberOgre::getErisPolling(   ) const
          // // {
          // // return mPollEris;
          // // }
          
          
     716  void EmberOgre::initializeEmberServices(  const std::string& prefix,   const std::string& homeDir )
          {
          
          }
          
     721  void EmberOgre::Application_ServicesInitialized(   )
          {
           Ember::EmberServices::getSingleton(   ).getServerService(   )->GotConnection.connect(  sigc::mem_fun(  *this,   &EmberOgre::connectedToServer ) );
           Ember::EmberServices::getSingleton(   ).getServerService(   )->GotView.connect(  sigc::mem_fun(  *this,   &EmberOgre::Server_GotView ) );
          
           mScriptingResourceProvider = std::auto_ptr<OgreResourceProvider>(  new OgreResourceProvider(  "Scripting" ) );
           Ember::EmberServices::getSingleton(   ).getScriptingService(   )->setResourceProvider(  mScriptingResourceProvider.get(   ) );
           ///register the lua scripting provider
           Ember::EmberServices::getSingleton(   ).getScriptingService(   )->registerScriptingProvider(  new LuaScriptingProvider(   ) );
          
          }
          
     733  Eris::View* EmberOgre::getMainView(   )
          {
           return Ember::Application::getSingleton(   ).getMainView(   );
          }
          
          
          }

./components/ogre/EmberOgre.h

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
           (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://ogre.sourceforge.net/
          
          Copyright � 2000-2002 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          */
          
          #ifndef __EmberOgre_H__
          #define __EmberOgre_H__
          
          #include "EmberOgrePrerequisites.h"
          
          // ------------------------------
          // Include sigc header files
          // ------------------------------
          #include <sigc++/trackable.h>
          #include <sigc++/signal.h>
          
          
          #include "framework/Singleton.h"
          
          
          
          namespace Eris {
      42  class View;
      43  class Connection;
          }
          
          namespace Carpenter
          {
      48  class Carpenter;
      49  class BluePrint;
          }
          
      52  namespace Ember
          {
          class StreamLogObserver;
          }
          
          namespace OgreOpcode {
      58  class CollisionManager;
          }
          
      61  namespace EmberOgre {
          
          namespace Terrain
          {
          class TerrainGenerator;
          class TerrainLayerDefinitionManager;
          }
          
          namespace Model {
           class ModelDefinitionManager;
           namespace Mapping {
           class EmberModelMappingManager;
           }
          }
          
          class CameraRotator;
          
          class CameraFrameListener;
          
          class Avatar;
          
          class AvatarCamera;
          
          class AvatarController;
          
          class AvatarEmberEntity;
          
          class EmberEntityFactory;
          
          class EmberPagingSceneManager;
          
          class MotionManager;
          
          class Input;
          
          class InputManager;
          
          class InputCommandMapper;
          
          class GUIManager;
          
          class Jesus;
          
          class EmberEntity;
          
          class OgreResourceLoader;
          
          class OgreLogObserver;
          
          class EntityMoveManager;
          
          class MaterialEditor;
          
          class OgreSetup;
          
          class OgreResourceProvider;
          class OpcodeCollisionDetectorVisualizer;
          
          /**
          
          The main class of ember. This functions as a hub for almost all subsystems. (  Perhaps this should be refactored? )
          
          */
          class EmberOgre : public Ember::Singleton<EmberOgre>,  
          public sigc::trackable,  
          public Ogre::FrameListener
          {
          public:
          
          
           /// Standard constructor
           EmberOgre(   );
          
           /// Standard destructor
           ~EmberOgre(   );
          
           virtual bool frameStarted(  const Ogre::FrameEvent & evt );
           virtual bool frameEnded(  const Ogre::FrameEvent & evt );
          
           /**
           * starts the main app
           */
           virtual void go(   );
          // void shutdown(   );
          
           /**
           * Initialize all Ember services needed for this application
           * @param the prefix for the application,   not appliable if running under win32
           * @param the an alternative home directory. If the default should be used,   send an empty string.
           */
           void initializeEmberServices(  const std::string& prefix,   const std::string& homeDir );
          
           void Server_GotView(  Eris::View* world );
           void connectedToServer(  Eris::Connection* connection );
          
          
           // TODO: possibly we'd like to do the following in a different way,  
           // perhaps refactoring stuff
           Avatar* getAvatar(   ) const;
           Ogre::SceneManager* getSceneManager(   ) const;
           Terrain::TerrainGenerator* getTerrainGenerator(   ) const;
           MotionManager* getMotionManager(   ) const;
           Ogre::Root* getOgreRoot(   ) const;
           EmberEntityFactory* getEntityFactory(   ) const;
           AvatarCamera* getMainCamera(   ) const;
           AvatarController* getAvatarController(   ) const;
           inline EntityMoveManager* getMoveManager(   ) const;
          // inline Input& getInput(   );
          
           /**
           * Gets the entity with the supplies id from the world.
           */
           EmberEntity* getEmberEntity(  const std::string & eid );
          
           inline Jesus* getJesus(   ) const;
          
           inline Ogre::RenderWindow* getRenderWindow(   ) const;
          
          
           sigc::signal<void,   EmberEntityFactory*> EventCreatedEmberEntityFactory;
           sigc::signal<void,   AvatarEmberEntity*> EventCreatedAvatarEntity;
           sigc::signal<void,   Jesus*> EventCreatedJesus;
          
           /**
           Emitted before the eris polling is started
           */
          // sigc::signal<void> EventStartErisPoll;
          
           /**
           Emitted after the eris polling has finished
           */
          // sigc::signal<void> EventEndErisPoll;
          
           /**
           * returns the scenenode of the world entity
           * throws en exception if no such node has been created
           * @return
           */
           Ogre::SceneNode* getWorldSceneNode(   ) const;
          
          
           /**
           * returns the root scene node
           * @return
           */
           Ogre::SceneNode* getRootSceneNode(   ) const;
          
          
           /**
           Emitted after the GUIManager has been created,   but not yet initialized
           */
           sigc::signal<void,   GUIManager&> EventGUIManagerCreated;
           /**
           Emitted after the GUIManager has been initilized
           */
           sigc::signal<void,   GUIManager&> EventGUIManagerInitialized;
          
           /**
           Emitted after the Motion has been created
           */
           sigc::signal<void,   MotionManager&> EventMotionManagerCreated;
          
          
           /**
           Emitted after the TerrainGenerator has been created
           */
           sigc::signal<void,   Terrain::TerrainGenerator&> EventTerrainGeneratorCreated;
          
           /**
           Emitted after the AvatarController has been created
           */
           sigc::signal<void,   AvatarController&> EventAvatarControllerCreated;
          
           /**
           Emitted after the base Ogre scene has been created
           */
           sigc::signal<void> EventSceneCreated;
          
           EmberEntity* getEntity(  const std::string & id );
          
           /**
           * Call this to "soft quit" the app. This means that an signal will be emitted,   which hopefully will be taken care of by some widget,   which will show a confirmation window,   asking the user if he/she wants to quit.
           However,   if there is no widget etc. handling the request,   the application will instantly quit.
           */
          // void requestQuit(   );
          
           /**
           * Sets whether eris should be polled each frame. Defaults to true.
           * @param doPoll
           */
          // void setErisPolling(  bool doPoll );
          
           /**
           * Gets whether eris should be polled each frame.
           * @return
           */
          // bool getErisPolling(   ) const;
          
           /**
           Renders one frame.
           */
           bool renderOneFrame(   );
          
           /**
           * Sets up the application - returns false if the user chooses to abandon configuration.
           * @return
           */
           bool setup(   );
          
           void shutdownGui(   );
          
          protected:
          
           /**
           utility object for setting up and tearing down ogre
           */
           std::auto_ptr<OgreSetup> mOgreSetup;
          
           Eris::View* getMainView(   );
          
           /**
           * The main user avatar
           */
           Avatar* mAvatar;
          
           /**
           When connected to a world,   handles the avatar and patches mouse and keyboard movement events on the avatar.
           */
           AvatarController* mAvatarController;
          
           /**
           The main Ogre root object. All of Ogre is accessed through this.
           */
           Ogre::Root *mRoot;
          
           /**
           The main scene manager of the world.
           */
           EmberPagingSceneManager* mSceneMgr;
          
           /**
           The main render window. There can be many more render targets in the system,   but they will all reside within this render window (  such as entity preview through CEGUI ).
           */
           Ogre::RenderWindow* mWindow;
          
           /**
           The main input object.
           */
           std::auto_ptr<Input> mInput;
          
           /**
           An InputCommandMapper that will handle all general input events.
           */
           std::auto_ptr<InputCommandMapper> mGeneralCommandMapper;
          
           /**
           Main factory for all entities created in the world.
           */
           EmberEntityFactory* mEmberEntityFactory;
          
           /**
           * Creates the basic scene with a single avatar,   just for testing purpose.
           * NOTE: remove this when going final
           * @param
           */
           void createScene(  void );
          
           /**
           * Sets up Jesus. This inialized the mJesus member and loads all building blocks,   blueprint and modelblocks etc.
           */
           void setupJesus(   );
          
           /**
           * Preloads the media,   thus avoiding frame rate drops ingame.
           * @param
           */
           void preloadMedia(  void );
          
           /**
          
           makes sure that there are files in ~/.ember
           */
           void checkForConfigFiles(   );
          
           /**
           Responsible for handling of terrain.
           */
           Terrain::TerrainGenerator* mTerrainGenerator;
          
           /**
           Responsible for updating motions and animations of entities.
           */
           MotionManager* mMotionManager;
          
           /**
           Responsible for the GUI.
           */
           GUIManager* mGUIManager;
          
           /**
           Resonsible for managing all Model definitions;
           */
           Model::ModelDefinitionManager* mModelDefinitionManager;
          
           /**
           Handles all model mappings.
           */
           Model::Mapping::EmberModelMappingManager* mModelMappingManager;
          
           Terrain::TerrainLayerDefinitionManager* mTerrainLayerManager;
          
           /**
           Responsible for allowing movement of entities in the world by the user.
           */
           EntityMoveManager* mMoveManager;
          
           /**
           when this is false the app will exit
           */
           bool mKeepOnRunning;
          
           /**
           main entry point for the Jesus system (  which is an Ember wrapper for the Carpenter lib )
           */
           Jesus* mJesus;
          
           /**
           Once connected to a world,   this will hold the main world view.
           */
          // Eris::View* mWorldView;
          
           /**
           Controls whether eris should be polled at each frame update.
           */
          // bool mPollEris;
          
           /**
           The main log observer used for all logging. This will send Ogre logging events on to the internal Ember logging framework.
           */
           OgreLogObserver* mLogObserver;
          
           /**
           Patches logging events from the Ember logging framework on to a file writer.
           */
          // Ember::StreamLogObserver* mStreamLogObserver;
          
           /**
           Helper object that allows for easy Ogre material editing.
           */
           MaterialEditor* mMaterialEditor;
          
           void Application_ServicesInitialized(   );
          
           std::auto_ptr<OgreResourceProvider> mScriptingResourceProvider;
          
           OgreOpcode::CollisionManager* mCollisionManager;
           OpcodeCollisionDetectorVisualizer* mCollisionDetectorVisualizer;
          
          };
          
          // Input& EmberOgre::getInput(   )
          // {
          // return mInput;
          // }
          EntityMoveManager* EmberOgre::getMoveManager(   ) const
          {
           return mMoveManager;
          }
          
          Jesus* EmberOgre::getJesus(   ) const
          {
           return mJesus;
          }
          Ogre::RenderWindow* EmberOgre::getRenderWindow(   ) const
          {
           return mWindow;
          }
          
          
          }
          
          
          #endif

./components/ogre/EmberOgrePrerequisites.h

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef __EmberPrerequisites_H__
          #define __EmberPrerequisites_H__
          
          
          #ifdef HAVE_CONFIG_H
          #include "config.h"
          #endif
          
          #include "OgreIncludes.h"
          
          // #include "MathConverter.h"
          
          ///include the Logging service,   since we want logging available from most classes
          ///in most cases,   use the S_LOG* defines
          ///such as:
          ///S_LOG_INFO(  "some info" )
          #include "services/logging/LoggingService.h"
          
          #include "framework/Exception.h"
          
          
          
          
          ///utility defines for stl containers
          ///for example:
          ///TYPEDEF_STL_VECTOR(  std::string,   StringVector )
          ///defines a new type called StringVector
          ///you can then use StringVector::iterator etc..
          
          #define TYPEDEF_STL_MKITERATORS(  name ) \
           typedef name::iterator name##Iter; \
           typedef name::const_iterator name##CIter; \
           typedef name::reverse_iterator name##RIter; \
           typedef name::const_reverse_iterator name##CRIter
          
          #define TYPEDEF_STL_CONTAINER1(  container,   tp,   name ) \
           typedef std::container<tp> name; \
           TYPEDEF_STL_MKITERATORS(  name )
          
          #define TYPEDEF_STL_CONTAINER2(  container,   tp1,   tp2,   name ) \
           typedef std::container<tp1,   tp2> name; \
           TYPEDEF_STL_MKITERATORS(  name )
          
          #define TYPEDEF_STL_VECTOR(  tp,   name ) TYPEDEF_STL_CONTAINER1(  vector,   tp,   name )
          #define TYPEDEF_STL_LIST(  tp,   name ) TYPEDEF_STL_CONTAINER1(  list,   tp,   name )
          #define TYPEDEF_STL_SET(  tp,   name ) TYPEDEF_STL_CONTAINER1(  set,   tp,   name )
          #define TYPEDEF_STL_MAP(  tpkey,   tpval,   name ) TYPEDEF_STL_CONTAINER2(  map,   tpkey,   tpval,   name )
          
          typedef unsigned int uint;
          
          #endif

./components/ogre/EmberPhysicalEntity.cpp

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #include "EmberPhysicalEntity.h"
          
          
          #include "framework/ConsoleBackend.h"
          #include "MotionManager.h"
          #include "model/Model.h"
          #include "model/ModelDefinition.h"
          #include "model/SubModel.h"
          #include "model/ParticleSystemBinding.h"
          #include "model/Action.h"
          
          #include "model/mapping/EmberModelMappingManager.h"
          #include "model/mapping/ModelMapping.h"
          #include "model/mapping/ModelMappingManager.h"
          
          #include "environment/Environment.h"
          #include "environment/Forest.h"
          #include "EmberEntityFactory.h"
          #include "WorldEmberEntity.h"
          
          
          #include "EmberEntityActionCreator.h"
          
          
          #include <OgreException.h>
          
          #include "EmberOgre.h"
          #include "MousePicker.h"
          
          #include "EmberEntityUserObject.h"
          #include "OpcodeCollisionDetector.h"
          #include "MeshCollisionDetector.h"
          
          
          #include <Eris/Entity.h>
          #include <Eris/View.h>
          #include <Eris/TypeInfo.h>
          
          
          namespace EmberOgre {
          
      60  const char * const EmberPhysicalEntity::ACTION_STAND = "__movement_idle";
      61  const char * const EmberPhysicalEntity::ACTION_RUN = "__movement_run";
      62  const char * const EmberPhysicalEntity::ACTION_WALK = "__movement_walk";
      63  const char * const EmberPhysicalEntity::ACTION_SWIM = "__movement_swim";
      64  const char * const EmberPhysicalEntity::ACTION_FLOAT = "__movement_float";
          
          
          
      68  EmberPhysicalEntity::EmberPhysicalEntity(  const std::string& id,   Eris::TypeInfo* ty,   Eris::View* vw,   Ogre::SceneManager* sceneManager ) :
          EmberEntity(  id,   ty,   vw,   sceneManager ),  
          mCurrentMovementAction(  0 ),  
          mActiveAction(  0 ),  
          mModelAttachedTo(  0 ),  
          mModelMarkedToAttachTo(  0 ),  
          mModel(  0 ),  
          mScaleNode(  0 ),  
          mModelMapping(  0 )
          {
          }
          
      80  EmberPhysicalEntity::~EmberPhysicalEntity(   )
          {
           delete mModelMapping;
          
           if (  mModel ) {
           delete mModel->getUserObject(   );
           getSceneManager(   )->destroyMovableObject(  mModel );
           }
           Ogre::SceneNode *parent = static_cast<Ogre::SceneNode*>(  getScaleNode(   )->getParent(   ) );
           if (  parent ) {
           parent->removeAndDestroyChild(  getScaleNode(   )->getName(   ) );
           }
          
           ///make sure it's not in the MotionManager
           ///TODO: keep a marker in the entity so we don't need to call this for all entities
           MotionManager::getSingleton(   ).removeAnimatedEntity(  this );
          
          /*
          
           mSceneManager->removeEntity(  mOgreEntity );
           mSceneManager->removeEntity(  mOgreEntity );
          
           delete mOgreEntity;
           delete mSceneNode;
           */
          }
          
     107  EmberEntity* EmberPhysicalEntity::getEntityAttachedToPoint(  const std::string& attachPoint )
          {
           ///first check with the attach points
           const std::string* entityId(  0 );
           for(  AttachedEntitiesStore::const_iterator I = mAttachedEntities.begin(   ); I != mAttachedEntities.end(   ); ++I ) {
           if (  I->second == attachPoint ) {
           entityId = &I->first;
           break;
           }
           }
          
           if (  entityId ) {
           ///then get the entity from the world
           EmberEntity* entity = EmberOgre::getSingleton(   ).getEmberEntity(  *entityId );
           return entity;
           }
           return 0;
          }
          
          
     127  void EmberPhysicalEntity::setVisible(  bool visible )
          {
           EmberEntity::setVisible(  visible );
          // if (  !visible ) {
          // if (  getScaleNode(   )->getParent(   ) ) {
          // mOgreNode->removeChild(  getScaleNode(   ) );
          // }
          // } else {
          // if (  !getScaleNode(   )->getParent(   ) ) {
          // mOgreNode->addChild(  getScaleNode(   ) );
          // }
          // }
           getScaleNode(   )->setVisible(  visible && getLocation(   ),   false );
           //getModel(   )->setVisible(  visible );
          }
          
     143  void EmberPhysicalEntity::createScaleNode(   )
          {
           mScaleNode = mOgreNode->createChildSceneNode(  getId(   ) + "_scaleNode" );
          }
          
     148  void EmberPhysicalEntity::setModel(  const std::string& modelName )
          {
           if (  mModel ) {
           if (  mModel->getDefinition(   )->getName(   ) == modelName ) {
           return;
           } else {
           getSceneManager(   )->destroyMovableObject(  mModel );
           }
           }
           mModel = Model::Model::createModel(  EmberOgre::getSingleton(   ).getSceneManager(   ),   modelName,   getId(   ) );
          
           ///if the model definition isn't valid,   use a placeholder
           if (  !mModel->getDefinition(   )->isValid(   ) ) {
           S_LOG_FAILURE(   "Could not find " << modelName << ",   using placeholder." );
           ///add a placeholder model
           Model::ModelDefnPtr modelDef = mModel->getDefinition(   );
           modelDef->createSubModelDefinition(  "placeholder.mesh" )->createPartDefinition(  "main" )->setShow(   true );
           modelDef->setValid(   true );
           modelDef->reloadAllInstances(   );
           }
           ///rotate node to fit with WF space
           ///perhaps this is something to put in the model spec instead?
          // scaleNode->rotate(  Ogre::Vector3::UNIT_Y,  (  Ogre::Degree )90 );
          
           mScaleNode->attachObject(  mModel );
          }
          
          
     176  void EmberPhysicalEntity::showModelPart(  const std::string& partName )
          {
           Model::Model* model = getModel(   );
           if (  model ) {
           model->showPart(  partName );
          
           ///if we already have set up a collision object we must reload it
           EmberEntityUserObject* userObject = static_cast<EmberEntityUserObject*>(  getModel(   )->getUserObject(   ) );
           if (  userObject && userObject->getCollisionDetector(   ) ) {
           userObject->getCollisionDetector(   )->reload(   );
           }
           }
          }
          
     190  void EmberPhysicalEntity::hideModelPart(  const std::string& partName )
          {
           Model::Model* model = getModel(   );
           if (  model ) {
           model->hidePart(  partName );
          
           ///if we already have set up a collision object we must reload it
           EmberEntityUserObject* userObject = static_cast<EmberEntityUserObject*>(  getModel(   )->getUserObject(   ) );
           if (  userObject && userObject->getCollisionDetector(   ) ) {
           userObject->getCollisionDetector(   )->reload(   );
           }
           }
          }
          
     204  void EmberPhysicalEntity::init(  const Atlas::Objects::Entity::RootEntity &ge,   bool fromCreateOp )
          {
           ///first we need to create the scale node
           createScaleNode(   );
          
           /// we need a model mapping
           createModelMapping(   );
          
           assert(  mModelMapping );
           mModelMapping->initialize(   );
           if (  !mModel ) {
           S_LOG_WARNING(  "Entity of type " << getType(   )->getName(   ) << " have no default model,   using placeholder." );
           setModel(  "placeholder" );
           }
          
           ///once we have that,   we need which model to use and can create the model
          // createModel(   );
          
           onModeChanged(  EmberEntity::MM_DEFAULT );
           EmberEntity::init(  ge,   fromCreateOp );
           getModel(   )->setQueryFlags(  MousePicker::CM_ENTITY );
          
          /* assert(  mOgreNode );
           assert(  mScaleNode );*/
          
           //if there is no bounding box,   scaleNode hasn't been called,   so do it here
          /* if (  !hasBBox(   ) ) {
           scaleNode(   );
           }*/
          
           //translate the scale node according to the translate defined in the model
          // getScaleNode(   )->translate(  getModel(   )->getDefinition(   )->getTranslate(   ) );
           initFromModel(   );
          
          /* EmberEntityUserObject* userObject = new EmberEntityUserObject(  this,   getModel(   ),   0,   0 );
           getModel(   )->setUserObject(  userObject );*/
          
           /** If there's an idle animation,   we'll randomize the entry value for that so we don't end up with too many similiar entities with synched animations (  such as when you enter the world at origo and have 20 settlers doing the exact same motions. */
           Model::Action* idleaction = mModel->getAction(  ACTION_STAND );
           if (  idleaction ) {
           idleaction->getAnimations(   ).addTime(  Ogre::Math::RangeRandom(  0,   15 ) );
           }
          
          
           //check if we should do delayed attachment
           if (  mModelMarkedToAttachTo ) {
           attachToPointOnModel(  mAttachPointMarkedToAttachTo,   mModelMarkedToAttachTo );
           mModelMarkedToAttachTo = 0;
           mAttachPointMarkedToAttachTo = "";
           }
          
           //NOTE: for now,   add all particle systems. we will want to add some visibility flag or something in the future
           for (  Model::ParticleSystemSet::iterator I = mModel->getParticleSystems(   ).begin(   ); I != mModel->getParticleSystems(   ).end(   ); ++I )
           {
           getScaleNode(   )->attachObject(  (  *I )->getOgreParticleSystem(   ) );
           }
          
           getModel(   )->Reloaded.connect(  sigc::mem_fun(  *this,   &EmberPhysicalEntity::Model_Reloaded ) );
           getModel(   )->Resetting.connect(  sigc::mem_fun(  *this,   &EmberPhysicalEntity::Model_Resetting ) );
          
          
          
          }
          
     268  void EmberPhysicalEntity::initFromModel(   )
          {
          
           ///make a copy of the original bbox
           mDefaultOgreBoundingBox = mModel->getBoundingBox(   );
          
           getScaleNode(   )->setOrientation(  Ogre::Quaternion::IDENTITY );
           ///rotate node to fit with WF space
           ///perhaps this is something to put in the model spec instead?
           getScaleNode(   )->rotate(  Ogre::Vector3::UNIT_Y,  (  Ogre::Degree )90 );
           getScaleNode(   )->rotate(  getModel(   )->getRotation(   ) );
          
           scaleNode(   );
          
           getScaleNode(   )->setPosition(  Ogre::Vector3::ZERO );
           ///translate the scale node according to the translate defined in the model
           getScaleNode(   )->translate(  getModel(   )->getDefinition(   )->getTranslate(   ) );
          
           connectEntities(   );
          
           const Model::RenderingDefinition* renderingDef = mModel->getDefinition(   )->getRenderingDefinition(   );
           if (  renderingDef && renderingDef->getScheme(   ) == "forest" ) {
           Environment::Forest* forest = EmberOgre::getSingleton(   ).getEntityFactory(   )->getWorld(   )->getEnvironment(   )->getForest(   );
           for (  Model::Model::SubModelSet::const_iterator I = mModel->getSubmodels(   ).begin(   ); I != mModel->getSubmodels(   ).end(   ); ++I ) {
          // if (  (  *I )->getEntity(   )->isVisible(   ) ) {
           (  *I )->getEntity(   )->setVisible(  true );
           forest->addTree(  (  *I )->getEntity(   ),   getScaleNode(   )->getWorldPosition(   ),   getScaleNode(   )->getWorldOrientation(   ).getYaw(   ),   getScaleNode(   )->getScale(   ).y );
          // }
           }
           mModel->setRenderingDistance(  100 );
          // getScaleNode(   )->detachObject(  mModel );
          // getSceneNode(   )->removeChild(  getScaleNode(   ) );
          // getScaleNode(   )->setVisible(  false );
           }
          
          }
          
     305  void EmberPhysicalEntity::createModelMapping(   )
          {
           delete mModelMapping;
           EmberEntityActionCreator creator(  *this );
           mModelMapping = ::EmberOgre::Model::Mapping::EmberModelMappingManager::getSingleton(   ).getManager(   ).createMapping(  this,   &creator );
          }
          
     312  void EmberPhysicalEntity::connectEntities(   )
          {
           if (  getModel(   ) ) {
           if (  getModel(   )->getUserObject(   ) ) {
           delete getModel(   )->getUserObject(   );
           }
          // ICollisionDetector* collisionDetector = new OpcodeCollisionDetector(  getModel(   ) );
           ICollisionDetector* collisionDetector = new MeshCollisionDetector(  getModel(   ) );
           EmberEntityUserObject* userObject = new EmberEntityUserObject(  this,   getModel(   ),   collisionDetector );
           getModel(   )->setUserObject(  userObject );
           }
          }
          
          
     326  void EmberPhysicalEntity::attachToPointOnModel(  const std::string& point,   Model::Model* model )
          {
           //if we're not initialized,   delay attachment until after init
           if (  !isInitialized(   ) ) {
           mModelMarkedToAttachTo = model;
           mAttachPointMarkedToAttachTo = point;
           } else {
           if (  model->hasAttachPoint(  point ) && model->getSkeleton(   ) ) {
           getScaleNode(   )->detachObject(  getModel(   ) );
           getModel(   )->setVisible(  true );
           model->attachObjectToAttachPoint(   point,   getModel(   ),   getScaleNode(   )->getScale(   ),   getModel(   )->getDefinition(   )->getRotation(   ) );
           mModelAttachedTo = model;
           }
           }
          }
          
     342  void EmberPhysicalEntity::detachFromModel(   )
          {
           if (  mModelAttachedTo ) {
           mModelAttachedTo->detachObjectFromBone(  getModel(   )->getName(   ) );
           getScaleNode(   )->attachObject(  getModel(   ) );
           checkVisibility(  isVisible(   ) );
           mModelAttachedTo = 0;
           }
          }
          
     352  void EmberPhysicalEntity::showOgreBoundingBox(  bool show )
          {
           getScaleNode(   )->showBoundingBox(  show );
          }
          
          
     358  bool EmberPhysicalEntity::getShowOgreBoundingBox(   ) const
          {
           return getScaleNode(   )->getShowBoundingBox(   );
          }
          
     363  Model::Model* EmberPhysicalEntity::getModel(   ) const
          {
           return mModel;
          }
          
     368  void EmberPhysicalEntity::Model_Reloaded(   )
          {
           initFromModel(   );
           attachAllEntities(   );
          }
          
     374  void EmberPhysicalEntity::Model_Resetting(   )
          {
           if (  getModel(   )->getUserObject(   ) ) {
           delete getModel(   )->getUserObject(   );
           }
           getModel(   )->setUserObject(  0 );
           detachAllEntities(   );
          }
          
     383  void EmberPhysicalEntity::processWield(  const std::string& wieldName,   const Atlas::Message::Element& idElement )
          {
           S_LOG_VERBOSE(  "Set " << wieldName << " to " << idElement.asString(   ) );
           const std::string& id = idElement.asString(   );
           if (  id.empty(   ) ) {
           detachEntity(  wieldName );
           } else {
           //detach first
           detachEntity(  wieldName );
           attachEntity(  wieldName,   id );
           }
          }
          
     396  void EmberPhysicalEntity::processOutfit(  const Atlas::Message::MapType & outfitMap )
          {
          }
          
          
     401  void EmberPhysicalEntity::onAttrChanged(  const std::string& str,   const Atlas::Message::Element& v ) {
           EmberEntity::onAttrChanged(  str,   v );
          
           ///this is kind of a hack,   but it allows characters to wield other entities in their hands
           if (  str == "right_hand_wield" || str == "left_hand_wield" ) {
           processWield(  str,   v );
           return;
           }
          // if (  str == "outfit" ) {
          // if (  v.isMap(   ) ) {
          // const Atlas::Message::MapType & outfitMap = v.asMap(   );
          // int i = 0;
          // }
          // }
          // if (  str == "bbox" ) {
          // scaleNode(   );
          // }
          
           //check if the changed attribute should affect any particle systems
           if (  mModel->hasParticles(   ) ) {
           const Model::ParticleSystemBindingsPtrSet& bindings = mModel->getAllParticleSystemBindings(   );
           for (  Model::ParticleSystemBindingsPtrSet::const_iterator I = bindings.begin(   ); I != bindings.end(   ); ++I ) {
           if (  (  *I )->getVariableName(   ) == str && v.isNum(   ) ) {
           (  *I )->scaleValue(  v.asNum(   ) );
           }
           }
           }
          
          
          }
          
     432  void EmberPhysicalEntity::onModeChanged(  MovementMode newMode )
          {
          /* if (  newMode != mMovementMode )
           {*/
           const char * actionName;
           if (  newMode == EmberEntity::MM_WALKING ) {
           actionName = ACTION_WALK;
           } else if (  newMode == EmberEntity::MM_RUNNING ) {
           actionName = ACTION_RUN;
           } else if (  newMode == EmberEntity::MM_SWIMMING ) {
           actionName = ACTION_SWIM;
           } else {
           actionName = ACTION_STAND;
           }
           if (  !mCurrentMovementAction || mCurrentMovementAction->getName(   ) != actionName ) {
           ///first disable the current action
           if (  mCurrentMovementAction ) {
           mCurrentMovementAction->getAnimations(   ).reset(   );
           }
          
           Model::Action* newAction = mModel->getAction(  actionName );
           mCurrentMovementAction = newAction;
           if (  newAction ) {
           MotionManager::getSingleton(   ).addAnimatedEntity(  this );
          // mCurrentMovementAction->getAnimations(   )->setEnabled(  true );
          
           } else {
           MotionManager::getSingleton(   ).removeAnimatedEntity(  this );
           }
           }
           //might set mCurrentMovementAction to 0
          // }
          
           EmberEntity::onModeChanged(  newMode );
          }
          
          
     469  void EmberPhysicalEntity::onChildAdded(  Entity *e )
          {
           Eris::Entity::onChildAdded(  e );
           //see if it's in our attach map
           if (  mAttachedEntities.find(  e->getId(   ) ) != mAttachedEntities.end(   ) ) {
           EmberEntity* emberEntity = static_cast<EmberEntity*>(  e );
           emberEntity->attachToPointOnModel(  mAttachedEntities[e->getId(   )],   getModel(   ) );
           }
          
          /* if (  hasChild(  entityId ) ) {
           }*/
          
          
          }
          
          
          
     486  void EmberPhysicalEntity::onChildRemoved(  Entity *e )
          {
           //NOTE: we don't have to do detachment here,   like we do attachment in onChildAdded,   since that is done by the EmberEntity::onLocationChanged(  ... ) method
           Eris::Entity::onChildRemoved(  e );
          }
          
          
     493  void EmberPhysicalEntity::scaleNode(   ) {
          
           getScaleNode(   )->setScale(  1,   1,   1 );
          
           const Ogre::Vector3& ogreMax = mDefaultOgreBoundingBox.getMaximum(   );
           const Ogre::Vector3& ogreMin = mDefaultOgreBoundingBox.getMinimum(   );
          
           if (  hasBBox(   ) ) {
          
           const WFMath::AxisBox<3>& wfBoundingBox = getBBox(   );
           const WFMath::Point<3>& wfMax = wfBoundingBox.highCorner(   );
           const WFMath::Point<3>& wfMin = wfBoundingBox.lowCorner(   );
          
           Ogre::Real scaleX;
           Ogre::Real scaleY;
           Ogre::Real scaleZ;
          
          
          
           switch (  getModel(   )->getUseScaleOf(   ) ) {
           case Model::ModelDefinition::MODEL_HEIGHT:
           scaleX = scaleY = scaleZ = fabs(  (  wfMax.z(   ) - wfMin.z(   ) ) / (  ogreMax.y - ogreMin.y ) );
           break;
           case Model::ModelDefinition::MODEL_WIDTH:
           scaleX = scaleY = scaleZ = fabs(  (  wfMax.x(   ) - wfMin.x(   ) ) / (  ogreMax.x - ogreMin.x ) );
           break;
           case Model::ModelDefinition::MODEL_DEPTH:
           scaleX = scaleY = scaleZ = fabs(  (  wfMax.y(   ) - wfMin.y(   ) ) / (  ogreMax.z - ogreMin.z ) );
           break;
           case Model::ModelDefinition::MODEL_NONE:
           scaleX = scaleY = scaleZ = 1;
           break;
          
           case Model::ModelDefinition::MODEL_ALL:
           default:
           scaleX = fabs(  (  wfMax.x(   ) - wfMin.x(   ) ) / (  ogreMax.x - ogreMin.x ) );
           scaleY = fabs(  (  wfMax.z(   ) - wfMin.z(   ) ) / (  ogreMax.y - ogreMin.y ) );
           scaleZ = fabs(  (  wfMax.y(   ) - wfMin.y(   ) ) / (  ogreMax.z - ogreMin.z ) );
           }
          
          
           //Ogre::Real finalScale = std::max(  scaleX,   scaleY );
           //finalScale = std::max(  finalScale,   scaleZ );
           getScaleNode(   )->setScale(  scaleX,   scaleY,   scaleZ );
          
           } else if (  !getModel(   )->getScale(   ) ) {
           //set to small size
          
           Ogre::Real scaleX = (  0.25 / (  ogreMax.x - ogreMin.x ) );
           Ogre::Real scaleY = (  0.25 / (  ogreMax.y - ogreMin.y ) );
           Ogre::Real scaleZ = (  0.25 / (  ogreMax.z - ogreMin.z ) );
           getScaleNode(   )->setScale(  scaleX,   scaleY,   scaleZ );
           }
          
           if (  getModel(   )->getScale(   ) ) {
           if (  getModel(   )->getScale(   ) != 1 ) {
           //only scale if it's not 1
           getScaleNode(   )->scale(  getModel(   )->getScale(   ),   getModel(   )->getScale(   ),   getModel(   )->getScale(   ) );
           }
           }
          
          
          }
          
     557  const Ogre::Vector3& EmberPhysicalEntity::getOffsetForContainedNode(  const Ogre::Vector3& position,   EmberEntity* const entity )
          {
           ///if the model has an offset specified,   use that,   else just send to the base class
           const Ogre::Vector3& offset = getModel(   )->getDefinition(   )->getContentOffset(   );
           if (  offset != Ogre::Vector3::ZERO ) {
           return offset;
           } else {
           return EmberEntity::getOffsetForContainedNode(  position,   entity );
           }
          
          }
          
          
     570  void EmberPhysicalEntity::updateMotion(  Ogre::Real timeSlice )
          {
           EmberEntity::updateMotion(  timeSlice );
          }
          
          
     576  void EmberPhysicalEntity::updateAnimation(  Ogre::Real timeSlice )
          {
           if (  mActiveAction ) {
           bool continuePlay = false;
           mActiveAction->getAnimations(   ).addTime(  timeSlice,   continuePlay );
           if (  !continuePlay ) {
           mActiveAction->getAnimations(   ).reset(   );
           mActiveAction = 0;
           }
           } else {
           if (  mCurrentMovementAction ) {
           bool continuePlay = false;
           //check if we're walking backward
           if (  static_cast<int>(  (  WFMath::Vector<3>(  getVelocity(   ) ).rotate(  (  getOrientation(   ).inverse(   ) ) ) ).x(   ) ) < 0 ) {
           mCurrentMovementAction->getAnimations(   ).addTime(  -timeSlice,   continuePlay );
           } else {
           mCurrentMovementAction->getAnimations(   ).addTime(  timeSlice,   continuePlay );
           }
           }
           }
          }
          
     598  void EmberPhysicalEntity::setMoving(  bool moving )
          {
          // MotionManager* motionManager = &MotionManager::getSingleton(   );
          // if (  moving ) {
          // if (  getModel(   )->isAnimated(   ) ) {
          // getModel(   )->stopAnimation(  "idle" );
          // getModel(   )->startAnimation(  "walk" );
          // }
          // } else {
          // if (  getModel(   )->isAnimated(   ) ) {
          // getModel(   )->stopAnimation(  "walk" );
          // getModel(   )->startAnimation(  "idle" );
          // }
          // }
           EmberEntity::setMoving(  moving );
          }
          
     615  void EmberPhysicalEntity::detachEntity(  const std::string & attachPoint )
          {
           const std::string* entityId(  0 );
           for(  AttachedEntitiesStore::const_iterator I = mAttachedEntities.begin(   ); I != mAttachedEntities.end(   ); ++I ) {
           if (  I->second == attachPoint ) {
           entityId = &I->first;
           break;
           }
           }
          
           if (  entityId ) {
           if (  hasChild(  *entityId ) ) {
           //we already have the entity,   do the detachment
           EmberEntity* entity = EmberOgre::getSingleton(   ).getEntity(  *entityId );
           if (  entity ) {
           entity->detachFromModel(   );
           }
           }
           mAttachedEntities.erase(  *entityId );
           }
          }
          
     637  void EmberPhysicalEntity::attachEntity(  const std::string & attachPoint,   const std::string & entityId )
          {
           mAttachedEntities[entityId] = attachPoint;
           if (  hasChild(  entityId ) ) {
           //we already have the entity,   do the attachment now,   else we will just wait for the onChildAdded event
           EmberEntity* entity = EmberOgre::getSingleton(   ).getEntity(  entityId );
           if (  entity ) {
           entity->attachToPointOnModel(  attachPoint,   getModel(   ) );
           }
           }
          }
          
     649  void EmberPhysicalEntity::detachAllEntities(   )
          {
           for(  AttachedEntitiesStore::const_iterator I = mAttachedEntities.begin(   ); I != mAttachedEntities.end(   ); ++I ) {
           detachEntity(  I->first );
           }
          }
          
     656  void EmberPhysicalEntity::attachAllEntities(   )
          {
          //HACK: this should be data driven
           if (  hasAttr(  "right_hand_wield" ) ) {
           const Atlas::Message::Element& idElement = valueOfAttr(  "right_hand_wield" );
           attachEntity(  "right_hand_wield",   idElement.asString(   ) );
           } else if (  hasAttr(  "left_hand_wield" ) ) {
           const Atlas::Message::Element& idElement = valueOfAttr(  "left_hand_wield" );
           attachEntity(  "left_hand_wield",   idElement.asString(   ) );
           }
          }
          
          
     669  void EmberPhysicalEntity::onBboxChanged(   )
          {
           EmberEntity::onBboxChanged(   );
           scaleNode(   );
          }
          
     675  const Ogre::AxisAlignedBox& EmberPhysicalEntity::getWorldBoundingBox(  bool derive ) const
          {
           return getModel(   )->getWorldBoundingBox(  derive );
          }
          
     680  const Ogre::Sphere & EmberPhysicalEntity::getWorldBoundingSphere (  bool derive ) const
          {
           return getModel(   )->getWorldBoundingSphere(  derive );
          }
          
     685  void EmberPhysicalEntity::onAction(  const Atlas::Objects::Operation::RootOperation& act )
          {
          
          /* std::string allattribs;
          
           //Atlas::Objects::BaseObjectData::const_iterator I = act->begin(   );
           std::list< std::string >::const_iterator I = act->getParents(   ).begin(   );
          
           for (  ; I != act->getParents(   ).end(   ); ++I )
           {
           //const Atlas::Message::Element e = (  const Atlas::Message::Element )(  *I ).second;
           allattribs.append(  (  *I ) + " : " );
          
           }*/
          
           const std::list<std::string> &p = act->getParents(   );
           std::list<std::string>::const_iterator I = p.begin(   );
          
           if (  I != p.end(   ) ) {
           const std::string& name = *I;
          
           Model::Action* newAction = mModel->getAction(  name );
          
           ///If there's no action found,   try to see if we have a "default action" defined to play instead.
           if (  !newAction ) {
           newAction = mModel->getAction(  "default_action" );
           }
          
           if (  newAction ) {
           MotionManager::getSingleton(   ).addAnimatedEntity(  this );
           mActiveAction = newAction;
           newAction->getAnimations(   ).reset(   );
           mCurrentMovementAction->getAnimations(   ).reset(   );
           }
           }
           EmberEntity::onAction(  act );
          }
          
     723  bool EmberPhysicalEntity::allowVisibilityOfMember(  EmberEntity* entity ) {
           return mModel->getDefinition(   )->getShowContained(   );
          }
          
     727  void EmberPhysicalEntity::setVisualize(  const std::string& visualization,   bool visualize )
          {
           if (  visualization == "CollisionObject" ) {
           if (  getModel(   ) ) {
           EmberEntityUserObject* userObject = static_cast<EmberEntityUserObject*>(  getModel(   )->getUserObject(   ) );
           if (  userObject && userObject->getCollisionDetector(   ) ) {
           userObject->getCollisionDetector(   )->setVisualize(  visualize );
           }
           }
           } else {
           EmberEntity::setVisualize(  visualization,   visualize );
           }
          }
          
     741  bool EmberPhysicalEntity::getVisualize(  const std::string& visualization ) const
          {
           if (  visualization == "CollisionObject" ) {
           if (  getModel(   ) ) {
           EmberEntityUserObject* userObject = static_cast<EmberEntityUserObject*>(  getModel(   )->getUserObject(   ) );
           if (  userObject && userObject->getCollisionDetector(   ) ) {
           return userObject->getCollisionDetector(   )->getVisualize(   );
           }
           }
           return false;
           } else {
           return EmberEntity::getVisualize(  visualization );
           }
          }
          
          /*
          void EmberPhysicalEntity::handleTalk(  const std::string &msg )
          {
          
           std::string message = "<";
           message.append(  getName(   ) );
           message.append(  "> " );
           message.append(  msg );
           std::cout << "TRACE - ENTITY SAYS: [" << message << "]\n" << std::endl;
           Ember::ConsoleBackend::getMainConsole(   )->pushMessage(  message );
          }
          */
          
          
          
          /*
          void EmberPhysicalEntity::setContainer(  Entity *pr )
          {
          
           EmberEntity* EmberEntity = dynamic_cast<EmberEntity*>(  pr );
           if (  EmberEntity ) {
           //detach from our current object and add to the new entity
           getSceneNode(   )->getParent(   )->removeChild(  getSceneNode(   )->getName(   ) );
           EmberEntity->getSceneNode(   )->addChild(  getSceneNode(   ) );
          
           } else {
           //detach from our current object and add to the world
           getSceneNode(   )->getParent(   )->removeChild(  getSceneNode(   )->getName(   ) );
           getSceneNode(   )->getCreator(   )->getRootSceneNode(   )->addChild(  getSceneNode(   ) );
           }
          
          }
          */
          
          
          
          
          
          
          }

./components/ogre/EmberPhysicalEntity.h

          /*
           Copyright (  C ) 2004 Erik Hjortsberg
           some parts Copyright (  C ) 2004 bad_camel at Ogre3d forums
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef DIMEPHYSICALENTITY_H
          #define DIMEPHYSICALENTITY_H
          
          #include "EmberOgrePrerequisites.h"
          
          #include "EmberEntity.h"
          
          
          namespace EmberOgre {
          
          namespace Model {
      31   class Model;
      32   class Action;
           namespace Mapping {
      34   class ModelMapping;
           }
          };
          
          
          
      40  class EmberEntity;
          
          typedef std::list<Model::Action*> ActionStore;
          
          /**
           * Represents a Ember entity with a physical representation in the world.
           * This is represented by a an Ogre::Entity.
           */
      48  class EmberPhysicalEntity : public EmberEntity
          {
      50  friend class EmberEntityModelAction;
      51  friend class EmberEntityPartAction;
          public:
          
           static const char * const ACTION_STAND;
      55   static const char * const ACTION_RUN;
      56   static const char * const ACTION_WALK;
      57   static const char * const ACTION_SWIM;
      58   static const char * const ACTION_FLOAT;
          
          
          
          
           EmberPhysicalEntity(  const std::string& id,   Eris::TypeInfo* ty,   Eris::View* vw,   Ogre::SceneManager* sceneManager );
           virtual ~EmberPhysicalEntity(   );
          
          
          
           /**
           * return the Model of this object
           */
           Model::Model* getModel(   ) const;
          
           inline Ogre::SceneNode* getScaleNode(   ) const;
          
          
          
          
          
           virtual void setVisible(  bool visible );
          
           virtual void attachToPointOnModel(  const std::string& point,   Model::Model* model );
           virtual void detachFromModel(   );
          
           virtual void updateMotion(  Ogre::Real timeSlice );
          
           void updateAnimation(  Ogre::Real timeSlice );
          
           virtual void showOgreBoundingBox(  bool show );
          // virtual void showErisBoundingBox(  bool show );
          
           virtual bool getShowOgreBoundingBox(   ) const;
          // virtual bool getShowErisBoundingBox(   );
          
          
           /**
           * Returns the entity that's attched to the specified point,   if there is such
           * @param attachPoint
           * @return a pointer to the EmberEntity,   or 0 if none found
           */
           EmberEntity* getEntityAttachedToPoint(  const std::string& attachPoint );
          
           virtual const Ogre::AxisAlignedBox& getWorldBoundingBox(  bool derive = true ) const;
           virtual const Ogre::Sphere & getWorldBoundingSphere (  bool derive=true ) const;
          
          
           /**
           * Called by a contained member to see if the member is allowed to be shown.
           * This can be reimplemented in a subclass such as AvatarEmberEntity to
           * disallow things that belongs to a characters inventory to be shown.
           */
           virtual bool allowVisibilityOfMember(  EmberEntity* entity );
          
          
           /**
           * General method for turning on and off debug visualizations. Subclasses might support more types of visualizations than the ones defined here.
           * @param visualization The type of visualization. Currently supports "OgreBBox" and "ErisBBox".
           * @param visualize Whether to visualize or not.
           */
           virtual void setVisualize(  const std::string& visualization,   bool visualize );
          
          
           /**
           * Gets whether a certain visualization is turned on or off.
           * @param visualization The type of visualization. Currently supports "OgreBBox" and "ErisBBox".
           * @return true if visualization is turned on,   else false
           */
           virtual bool getVisualize(  const std::string& visualization ) const;
          
          protected:
          
           void setModel(  const std::string& modelName );
          
           void showModelPart(  const std::string& partName );
           void hideModelPart(  const std::string& partName );
          
           virtual const Ogre::Vector3& getOffsetForContainedNode(  const Ogre::Vector3& position,   EmberEntity* const entity );
          
           /**
           * creates EmberEntityUserObjects,   connects them and sets up the collision detection system
           * @return
           */
           void connectEntities(   );
          
           void createModelMapping(   );
           void createScaleNode(   );
          
          
           /**
           * Called when the bounding box has changed.
           */
           virtual void onBboxChanged(   );
          
           /**
           * Called when the movement mode has changed. We might want to update the animation of the entity,   for example if it's a human.
           * @param newMode
           */
           virtual void onModeChanged(  MovementMode newMode );
          
           /**
           The current movement action of the entity,   for example a walk action or a run action.
           */
           Model::Action* mCurrentMovementAction;
          
           /**
           All the active actions,   except the movement action (  since it's stored in mCurrentMovementAction ).
           These actions will be updated each frame.
           NOTE: we currently don't allow for multiple actions playing at the same time
           */
           //ActionStore mActiveActions;
           Model::Action* mActiveAction;
          
           /**
           If the entity is attached to another entity,   this is the model to which it is attached to.
           This will be 0 if the entity isn't attached.
           */
           Model::Model* mModelAttachedTo;
          
           Model::Model* mModelMarkedToAttachTo;
           std::string mAttachPointMarkedToAttachTo;
          
           virtual void onChildAdded(  Entity *e );
           virtual void onChildRemoved(  Entity *e );
          
          
          
           /**
           * Detaches an entity which is already wielded.
           * @param entityId
           */
           void detachEntity(  const std::string & entityId );
          
           /**
           * Attaches an entity to a certain attach point
           * @param attachPoint the name of the attachpoint to attach to
           * @param entityId the id of the entity to attach to
           */
           void attachEntity(  const std::string & attachPoint,   const std::string & entityId );
          
           /**
           Detaches all currently attached entities. Call this before the Model is resetted.
           */
           void detachAllEntities(   );
          
           /**
           Attaches all entities that aren't currently attached.
           */
           void attachAllEntities(   );
          
          
           /**
           * Process wield ops,   which means wielding and unwielding entities. This methos will in turn call the appropriate attachEntity and detachEntity methods.
           * @param wieldName the attachpoint to update
           * @param idElement the id of the entity to wield
           */
           void processWield(  const std::string& wieldName,   const Atlas::Message::Element& idElement );
          
          
           /**
           * Processes the outfit map and updates the appearance.
           * @param outfitMap
           */
           void processOutfit(  const Atlas::Message::MapType & outfitMap );
          
           /**
           * Overridden from Eris::Entity
           * @param str
           * @param v
           */
           virtual void onAttrChanged(  const std::string& str,   const Atlas::Message::Element& v );
           /**
           * Overridden from Eris::Entity
           * @param act
           */
           virtual void onAction(  const Atlas::Objects::Operation::RootOperation& act );
          
           typedef std::map<std::string,   std::string> AttachedEntitiesStore;
           /**
           A store of all attached entities,   indexed by their id.
           */
           AttachedEntitiesStore mAttachedEntities;
          
          // virtual void onMoved(   );
           /**
           * Overridden from Eris::Entity
           * @param moving
           */
           virtual void setMoving(  bool moving );
          
           /**
           * Overridden from Eris::Entity
           * @param ge
           */
           virtual void init(  const Atlas::Objects::Entity::RootEntity &ge,   bool fromCreateOp );
          
          
           /**
           The default size of the ogre bounding box,   before any scaling is done.
           */
           Ogre::AxisAlignedBox mDefaultOgreBoundingBox;
          
          
           /**
           * Scales the Ogre::SceneNode to the size of the AxisBox defined by Eris::Entity
           */
           virtual void scaleNode(   );
          
           //void setNodes(   );
          
          
           /**
           * The model of the entity
           */
           Model::Model* mModel;
          
           /**
           * We need to scale the Ogre::Entity,   because the underlying media is not
           * always correctly scaled.
           * But since each Eris::Entity can contain child entites,   we'll get problems
           * with scaling if we attach the children to a scaled node.
           * Thus we use a separate,   scaled node.
           */
           Ogre::SceneNode* mScaleNode;
          
           void Model_Reloaded(   );
          
           void Model_Resetting(   );
          
           void initFromModel(   );
          
           Model::Mapping::ModelMapping* mModelMapping;
          
          
          };
          
          Ogre::SceneNode* EmberPhysicalEntity::getScaleNode(   ) const
          {
           return mScaleNode;
          }
          
          
          }
          #endif // DIMEPHYSICALENTITY_H

./components/ogre/EntityWorldPickListener.cpp

          //
          // C++ Implementation: EntityWorldPickListener
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "EntityWorldPickListener.h"
          #include "EmberOgre.h"
          #include "EmberEntityUserObject.h"
          
          #include "model/Model.h"
          #include "EmberEntityFactory.h"
          
          #include "EmberEntity.h"
          #include "WorldEmberEntity.h"
          
          #include "MousePicker.h"
          
          namespace EmberOgre {
          
      37  EntityWorldPickListenerVisualizer::EntityWorldPickListenerVisualizer(  EntityWorldPickListener& pickListener )
          : mEntity(  0 ),   mDebugNode(  0 )
          {
           mDebugNode = EmberOgre::getSingleton(   ).getSceneManager(   )->getRootSceneNode(   )->createChildSceneNode(   );
           Ogre::Entity* mEntity = EmberOgre::getSingleton(   ).getSceneManager(   )->createEntity(  "pickerDebugObject",   "fireball.mesh" );
           ///start out with a normal material
           mEntity->setMaterialName(  "BasePointMarkerMaterial" );
           mEntity->setRenderingDistance(  300 );
           mEntity->setQueryFlags(  MousePicker::CM_NONPICKABLE );
           mDebugNode->attachObject(  mEntity );
          
           pickListener.EventPickedEntity.connect(  sigc::mem_fun(  *this,   &EntityWorldPickListenerVisualizer::picker_EventPickedEntity ) );
          }
          
      51  EntityWorldPickListenerVisualizer::~EntityWorldPickListenerVisualizer(   )
          {
           EmberOgre::getSingleton(   ).getSceneManager(   )->destroyEntity(  mEntity );
           EmberOgre::getSingleton(   ).getSceneManager(   )->destroySceneNode(  mDebugNode->getName(   ) );
          }
          
      57  void EntityWorldPickListenerVisualizer::picker_EventPickedEntity(  const EntityPickResult& result,   const MousePickerArgs& mouseArgs )
          {
           mDebugNode->setPosition(  result.position );
          }
          
          
          
      64  EntityWorldPickListener::EntityWorldPickListener(   )
          : VisualizePicking(  "visualize_picking",   this,   "Visualize mouse pickings." )
      66  ,   mClosestPickingDistance(  0 )
          ,   mFurthestPickingDistance(  0 )
          ,   mVisualizer(  0 )
          {
          }
          
          
      73  EntityWorldPickListener::~EntityWorldPickListener(   )
          {
          }
          
      77  void EntityWorldPickListener::initializePickingContext(   )
          {
           mClosestPickingDistance = 0;
           mFurthestPickingDistance = 0;
           mResult = EntityPickResult(   );
           mResult.entity = 0;
           mResult.position = Ogre::Vector3::ZERO;
           mResult.distance = 0;
          }
          
      87  void EntityWorldPickListener::endPickingContext(  const MousePickerArgs& mousePickerArgs )
          {
           if (  mResult.entity ) {
           std::stringstream ss;
           ss << mResult.position;
           S_LOG_VERBOSE(  "Picked entity: " << ss.str(   ) << " distance: " << mResult.distance );
           EventPickedEntity(  mResult,   mousePickerArgs );
           }
          }
          
          
          
          
     100  void EntityWorldPickListener::processPickResult(  bool& continuePicking,   Ogre::RaySceneQueryResultEntry& entry,   Ogre::Ray& cameraRay,   const MousePickerArgs& mousePickerArgs )
          {
          
           if (  entry.worldFragment ) {
           ///this is terrain
           ///a position of -1,   -1,   -1 is not valid terrain
           Ogre::SceneQuery::WorldFragment* wf = entry.worldFragment;
           static Ogre::Vector3 invalidPos(  -1,   -1,   -1 );
           if (  wf->singleIntersection != invalidPos ) {
           if (  mFurthestPickingDistance == 0 ) {
           mResult.entity = EmberOgre::getSingleton(   ).getEntityFactory(   )->getWorld(   );
           mResult.position = wf->singleIntersection;
           mResult.distance = entry.distance;
           continuePicking = false;
           } else {
           if (  entry.distance < mResult.distance ) {
           mResult.entity = EmberOgre::getSingleton(   ).getEntityFactory(   )->getWorld(   );
           mResult.position = wf->singleIntersection;
           mResult.distance = entry.distance;
           continuePicking = false;
           }
           }
           }
          /* std::stringstream ss;
           ss << wf->singleIntersection;
           S_LOG_VERBOSE(  "Picked in terrain: " << ss.str(   ) << " distance: " << mResult.distance );*/
          
           } else if (  entry.movable ) {
           Ogre::MovableObject* pickedMovable = entry.movable;
           if (  pickedMovable->isVisible(   ) && pickedMovable->getUserObject(   ) != 0 && pickedMovable->getUserObject(   )->getTypeName(   ) == "EmberEntityPickerObject" ) {
           EmberEntityUserObject* anUserObject = static_cast<EmberEntityUserObject*>(  pickedMovable->getUserObject(   ) );
           ///refit the opcode mesh to adjust for changes in the mesh (  for example animations )
           anUserObject->refit(   );
          
           ICollisionDetector* collisionDetector = anUserObject->getCollisionDetector(   );
           if (  collisionDetector ) {
           CollisionResult collisionResult;
           collisionResult.collided = false;
           collisionDetector->testCollision(  cameraRay,   collisionResult );
           if (  collisionResult.collided ) {
           EntityPickResult result;
           result.entity = anUserObject->getEmberEntity(   );
           result.position = collisionResult.position;
           result.distance = collisionResult.distance;
           if (  mFurthestPickingDistance == 0 ) {
           ///test all objects that fall into this distance
           mFurthestPickingDistance = (  pickedMovable->getParentSceneNode(   )->getWorldPosition(   ) - cameraRay.getOrigin(   ) ).length(   ) + pickedMovable->getBoundingRadius(   );
           mResult = result;
           } else {
           if (  (  pickedMovable->getParentSceneNode(   )->getWorldPosition(   ) - cameraRay.getOrigin(   ) ).length(   ) - pickedMovable->getBoundingRadius(   ) > mFurthestPickingDistance ) {
           continuePicking = false;
           } else {
           if (  result.distance < mResult.distance ) {
           mResult = result;
           }
           }
           }
          
           }
           }
          
          
          
          
           ///only do opcode detection if there's a CollisionObject
          // for (  EmberEntityUserObject::CollisionObjectStore::iterator I = collisionObjects->begin(   ); I != collisionObjects->end(   ); ++I ) {
          // OgreOpcode::ICollisionShape* collisionShape = (  *I )->getShape(   );
          // OgreOpcode::CollisionPair pick_result;
          //
          // if (  collisionShape->rayCheck(  OgreOpcode::COLLTYPE_QUICK,  anUserObject->getModel(   )->_getParentNodeFullTransform(   ),  cameraRay,   1000,   pick_result ) ) {
          // EntityPickResult result;
          // result.entity = anUserObject->getEmberEntity(   );
          // result.position = pick_result.contact;
          // result.distance = pick_result.distance;
          //
          // std::stringstream ss;
          // ss << result.position;
          // S_LOG_VERBOSE(  "Picked entity: " << ss.str(   ) << " distance: " << result.distance );
          // EventPickedEntity(  result,   mousePickerArgs );
          // continuePicking = false;
          //
          // }
          // }
           }
           }
          
          }
          
     188  void EntityWorldPickListener::runCommand(  const std::string &command,   const std::string &args )
          {
           if(  VisualizePicking == command ) {
           if (  mVisualizer.get(   ) ) {
           mVisualizer.reset(   );
           } else {
           mVisualizer = std::auto_ptr<EntityWorldPickListenerVisualizer>(  new EntityWorldPickListenerVisualizer(  *this ) );
           }
           }
          }
          
          }

./components/ogre/EntityWorldPickListener.h

       1  //
          // C++ Interface: EntityWorldPickListener
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREENTITYWORLDPICKLISTENER_H
          #define EMBEROGREENTITYWORLDPICKLISTENER_H
          
          #include "EmberOgrePrerequisites.h"
          #include "IWorldPickListener.h"
          #include <sigc++/signal.h>
          #include "framework/ConsoleObject.h"
          
          
          namespace EmberOgre {
          
          
      35  class EmberEntity;
      36  class EntityWorldPickListener;
          /**
           * Struct used for returning the result of a mouse pick.
           */
          struct EntityPickResult
          {
           EmberEntity* entity;
           Ogre::Vector3 position;
           Ogre::Real distance;
          };
          
          /**
          Visualizes the picking operation by placing a large ball at the picked position.
          */
      50  class EntityWorldPickListenerVisualizer : public virtual sigc::trackable
          {
          public:
      53   EntityWorldPickListenerVisualizer(  EntityWorldPickListener& pickListener );
      54   virtual ~EntityWorldPickListenerVisualizer(   );
          
          private:
      57   Ogre::Entity* mEntity;
      58   Ogre::SceneNode* mDebugNode;
      59   void picker_EventPickedEntity(  const EntityPickResult& result,   const MousePickerArgs& mouseArgs );
          };
          
          /**
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
      65  class EntityWorldPickListener : public IWorldPickListener,   public Ember::ConsoleObject
          {
          public:
      68   EntityWorldPickListener(   );
          
      70   ~EntityWorldPickListener(   );
          
      72   virtual void initializePickingContext(   );
          
      74   virtual void endPickingContext(  const MousePickerArgs& mousePickerArgs );
          
          
      77   virtual void processPickResult(  bool& continuePicking,   Ogre::RaySceneQueryResultEntry& entry,   Ogre::Ray& cameraRay,   const MousePickerArgs& mousePickerArgs );
          
      79   sigc::signal<void,   const EntityPickResult&,   const MousePickerArgs&> EventPickedEntity;
          
      81   const Ember::ConsoleCommandWrapper VisualizePicking;
          
           /**
           * Reimplements the ConsoleObject::runCommand method
           * @param command
           * @param args
           */
      88   virtual void runCommand(  const std::string &command,   const std::string &args );
          
          protected:
           float mClosestPickingDistance,   mFurthestPickingDistance;
           EntityPickResult mResult;
          
      94   std::auto_ptr<EntityWorldPickListenerVisualizer> mVisualizer;
          
          };
          
          }
          
          #endif

./components/ogre/FreeCameraController.cpp

       1  //
          // C++ Implementation: FreeCameraController
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "FreeCameraController.h"
          
          namespace EmberOgre {
          
      27  FreeCameraController::FreeCameraController(   )
          {
          }
          
          
      32  FreeCameraController::~FreeCameraController(   )
          {
          }
          
          
          };

./components/ogre/FreeCameraController.h

       1  //
          // C++ Interface: FreeCameraController
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREFREECAMERACONTROLLER_H
          #define EMBEROGREFREECAMERACONTROLLER_H
          
          namespace EmberOgre {
          
          /**
          @author Erik Hjortsberg
          
          This is a controller wchich allows for free flight.
          */
      33  class FreeCameraController{
          public:
      35   FreeCameraController(   );
          
      37   ~FreeCameraController(   );
          
          };
          
          };
          
          #endif

./components/ogre/GUICEGUIAdapter.cpp

       1  //
          // C++ Implementation: GUICEGUIAdapter
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "GUICEGUIAdapter.h"
          
          #include <CEGUIExceptions.h>
          #include <CEGUIGlobalEventSet.h>
          #include <elements/CEGUIEditbox.h>
          #include <elements/CEGUIMultiLineEditbox.h>
          
          namespace EmberOgre {
          
      32  GUICEGUIAdapter::GUICEGUIAdapter(  CEGUI::System *system,   CEGUI::OgreCEGUIRenderer *renderer ):
          mGuiSystem(  system )
          ,   mGuiRenderer(  renderer )
          ,   mSelectedText(  0 )
          {
          
           //lookup table for sdl scancodes and CEGUI keys
           mKeyMap[SDLK_BACKSPACE] = CEGUI::Key::Backspace;
           mKeyMap[SDLK_TAB] = CEGUI::Key::Tab;
          /* mKeyMap[SDLK_CLEAR] = CEGUI::Key::Clear;*/
           mKeyMap[SDLK_RETURN] = CEGUI::Key::Return;
           mKeyMap[SDLK_PAUSE] = CEGUI::Key::Pause;
           mKeyMap[SDLK_ESCAPE] = CEGUI::Key::Escape;
           mKeyMap[SDLK_SPACE] = CEGUI::Key::Space;
          /* mKeyMap[SDLK_EXCLAIM] = CEGUI::Key::Exclaim;*/
          /* mKeyMap[SDLK_QUOTEDBL] = CEGUI::Key::;
           mKeyMap[SDLK_HASH] = CEGUI::Key::;
           mKeyMap[SDLK_DOLLAR] = CEGUI::Key::;
           mKeyMap[SDLK_AMPERSAND] = CEGUI::Key::;
           mKeyMap[SDLK_QUOTE] = CEGUI::Key::;
           mKeyMap[SDLK_LEFTPAREN] = CEGUI::Key::;
           mKeyMap[SDLK_RIGHTPAREN] = CEGUI::Key::;
           mKeyMap[SDLK_ASTERISK] = CEGUI::Key::;*/
           mKeyMap[SDLK_PLUS] = CEGUI::Key::Add;
          /* mKeyMap[SDLK_COMMA] = CEGUI::Key::;*/
           mKeyMap[SDLK_MINUS] = CEGUI::Key::Minus;
           mKeyMap[SDLK_PERIOD] = CEGUI::Key::Period;
          /* mKeyMap[SDLK_SLASH] = CEGUI::Key::;*/
           mKeyMap[SDLK_0] = CEGUI::Key::One;
           mKeyMap[SDLK_1] = CEGUI::Key::Two;
           mKeyMap[SDLK_2] = CEGUI::Key::Two;
           mKeyMap[SDLK_3] = CEGUI::Key::Three;
           mKeyMap[SDLK_4] = CEGUI::Key::Four;
           mKeyMap[SDLK_5] = CEGUI::Key::Five;
           mKeyMap[SDLK_6] = CEGUI::Key::Six;
           mKeyMap[SDLK_7] = CEGUI::Key::Seven;
           mKeyMap[SDLK_8] = CEGUI::Key::Eight;
           mKeyMap[SDLK_9] = CEGUI::Key::Nine;
           mKeyMap[SDLK_COLON] = CEGUI::Key::Colon;
           mKeyMap[SDLK_SEMICOLON] = CEGUI::Key::Semicolon;
          /* mKeyMap[SDLK_LESS] = CEGUI::Key::;*/
          /* mKeyMap[SDLK_EQUALS] = CEGUI::Key::;
           mKeyMap[SDLK_GREATER] = CEGUI::Key::;
           mKeyMap[SDLK_QUESTION] = CEGUI::Key::;*/
          /* mKeyMap[SDLK_AT] = CEGUI::Key::;*/
          /* mKeyMap[SDLK_LEFTBRACKET] = CEGUI::Key::;*/
           mKeyMap[SDLK_BACKSLASH] = CEGUI::Key::Backslash;
          /* mKeyMap[SDLK_RIGHTBRACKET] = CEGUI::Key::;*/
          /* mKeyMap[SDLK_CARET] = CEGUI::Key::;
           mKeyMap[SDLK_UNDERSCORE] = CEGUI::Key::;
           mKeyMap[SDLK_BACKQUOTE] = CEGUI::Key::;*/
           mKeyMap[SDLK_a] = CEGUI::Key::A;
           mKeyMap[SDLK_b] = CEGUI::Key::B;
           mKeyMap[SDLK_c] = CEGUI::Key::C;
           mKeyMap[SDLK_d] = CEGUI::Key::D;
           mKeyMap[SDLK_e] = CEGUI::Key::E;
           mKeyMap[SDLK_f] = CEGUI::Key::F;
           mKeyMap[SDLK_g] = CEGUI::Key::G;
           mKeyMap[SDLK_h] = CEGUI::Key::H;
           mKeyMap[SDLK_i] = CEGUI::Key::I;
           mKeyMap[SDLK_j] = CEGUI::Key::J;
           mKeyMap[SDLK_k] = CEGUI::Key::K;
           mKeyMap[SDLK_l] = CEGUI::Key::L;
           mKeyMap[SDLK_m] = CEGUI::Key::M;
           mKeyMap[SDLK_n] = CEGUI::Key::N;
           mKeyMap[SDLK_o] = CEGUI::Key::O;
           mKeyMap[SDLK_p] = CEGUI::Key::P;
           mKeyMap[SDLK_q] = CEGUI::Key::Q;
           mKeyMap[SDLK_r] = CEGUI::Key::R;
           mKeyMap[SDLK_s] = CEGUI::Key::S;
           mKeyMap[SDLK_t] = CEGUI::Key::T;
           mKeyMap[SDLK_u] = CEGUI::Key::U;
           mKeyMap[SDLK_v] = CEGUI::Key::V;
           mKeyMap[SDLK_w] = CEGUI::Key::W;
           mKeyMap[SDLK_x] = CEGUI::Key::X;
           mKeyMap[SDLK_y] = CEGUI::Key::Y;
           mKeyMap[SDLK_z] = CEGUI::Key::Z;
           mKeyMap[SDLK_DELETE] = CEGUI::Key::Delete;
           mKeyMap[SDLK_UP] = CEGUI::Key::ArrowUp;
           mKeyMap[SDLK_DOWN] = CEGUI::Key::ArrowDown;
           mKeyMap[SDLK_RIGHT] = CEGUI::Key::ArrowRight;
           mKeyMap[SDLK_LEFT] = CEGUI::Key::ArrowLeft;
           mKeyMap[SDLK_INSERT] = CEGUI::Key::Insert;
           mKeyMap[SDLK_HOME] = CEGUI::Key::Home;
           mKeyMap[SDLK_END] = CEGUI::Key::End;
           mKeyMap[SDLK_PAGEUP] = CEGUI::Key::PageUp;
           mKeyMap[SDLK_PAGEDOWN] = CEGUI::Key::PageDown;
           mKeyMap[SDLK_F1] = CEGUI::Key::F1;
           mKeyMap[SDLK_F2] = CEGUI::Key::F2;
           mKeyMap[SDLK_F3] = CEGUI::Key::F3;
           mKeyMap[SDLK_F4] = CEGUI::Key::F4;
           mKeyMap[SDLK_F5] = CEGUI::Key::F5;
           mKeyMap[SDLK_F6] = CEGUI::Key::F6;
           mKeyMap[SDLK_F7] = CEGUI::Key::F7;
           mKeyMap[SDLK_F8] = CEGUI::Key::F8;
           mKeyMap[SDLK_F9] = CEGUI::Key::F9;
           mKeyMap[SDLK_F10] = CEGUI::Key::F10;
           mKeyMap[SDLK_F11] = CEGUI::Key::F11;
           mKeyMap[SDLK_F12] = CEGUI::Key::F12;
           mKeyMap[SDLK_F13] = CEGUI::Key::F13;
           mKeyMap[SDLK_F14] = CEGUI::Key::F14;
           mKeyMap[SDLK_F15] = CEGUI::Key::F15;
           mKeyMap[SDLK_NUMLOCK] = CEGUI::Key::NumLock;
           mKeyMap[SDLK_SCROLLOCK] = CEGUI::Key::ScrollLock;
           mKeyMap[SDLK_RSHIFT] = CEGUI::Key::RightShift;
           mKeyMap[SDLK_LSHIFT] = CEGUI::Key::LeftShift;
           mKeyMap[SDLK_RCTRL] = CEGUI::Key::RightControl;
           mKeyMap[SDLK_LCTRL] = CEGUI::Key::LeftControl;
           mKeyMap[SDLK_RALT] = CEGUI::Key::RightAlt;
           mKeyMap[SDLK_LALT] = CEGUI::Key::LeftAlt;
          
          
           ///set up the capturing of text selected event for the copy-and-paste functionality
          
          //window->subscribeEvent(  event,   CEGUI::Event::Subscriber(  &method,   this ) );
          
           CEGUI::GlobalEventSet::getSingleton(   ).subscribeEvent(  "MultiLineEditbox/TextSelectionChanged",   CEGUI::Event::Subscriber(  &GUICEGUIAdapter::MultiLineEditbox_selectionChangedHandler,   this ) );
           CEGUI::GlobalEventSet::getSingleton(   ).subscribeEvent(  "Editbox/TextSelectionChanged",   CEGUI::Event::Subscriber(  &GUICEGUIAdapter::Editbox_selectionChangedHandler,   this ) );
           //CEGUI::GlobalEventSet::getSingleton(   ).subscribeEvent(  "Editbox/TextSelectionChanged",   &GUICEGUIAdapter::selectionChangedHandler );
          
          
          
          }
          
          
     157  GUICEGUIAdapter::~GUICEGUIAdapter(   )
          {
          }
          
     161  bool GUICEGUIAdapter::MultiLineEditbox_selectionChangedHandler(  const CEGUI::EventArgs& args )
          {
           CEGUI::MultiLineEditbox* editbox = static_cast<CEGUI::MultiLineEditbox*>(  mGuiSystem->getGUISheet(   )->getActiveChild(   ) );
           mSelectedText = &editbox->getText(   );
           mSelectionStart = editbox->getSelectionStartIndex(   );
           mSelectionEnd = editbox->getSelectionEndIndex(   );
          /* const CEGUI::String& text = editbox->getText(   );
           if (  editbox->getSelectionLength(   ) > 0 ) {
           std::string selection = text.substr(  editbox->getSelectionStartIndex(   ),   editbox->getSelectionEndIndex(   ) ).c_str(   );
           S_LOG_VERBOSE(  "Selected text: " << selection );
           }*/
          // S_LOG_VERBOSE(  "Selected text." );
          
           return true;
          }
          
     177  bool GUICEGUIAdapter::Editbox_selectionChangedHandler(  const CEGUI::EventArgs& args )
          {
           CEGUI::Editbox* editbox = static_cast<CEGUI::Editbox*>(  mGuiSystem->getGUISheet(   )->getActiveChild(   ) );
           mSelectedText = &editbox->getText(   );
           mSelectionStart = editbox->getSelectionStartIndex(   );
           mSelectionEnd = editbox->getSelectionEndIndex(   );
           S_LOG_VERBOSE(  "Selected text." );
           return true;
          }
          
          // bool GUICEGUIAdapter::selectionChangedHandler(  const CEGUI::EventArgs& args )
          // {
          // S_LOG_VERBOSE(  "" );
          // }
          
     192  bool GUICEGUIAdapter::injectMouseMove(  const MouseMotion& motion,   bool& freezeMouse )
          {
           try {
           CEGUI::MouseCursor::getSingleton(   ).setPosition(  CEGUI::Point(  (  motion.xPosition ),   (  motion.yPosition ) ) );
           mGuiSystem->injectMouseMove(  0.0f,   0.0f );
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           }
           return true;
          }
          
     203  bool GUICEGUIAdapter::injectMouseButtonUp(  const Input::MouseButton& button )
          {
           CEGUI::MouseButton ceguiButton;
           if (  button == Input::MouseButtonLeft ) {
           ceguiButton = CEGUI::LeftButton;
           } else if(  button == Input::MouseButtonRight ) {
           ceguiButton = CEGUI::RightButton;
           } else if(  button == Input::MouseButtonMiddle ) {
           ceguiButton = CEGUI::MiddleButton;
           } else {
           return true;
           }
          
           try {
           mGuiSystem->injectMouseButtonUp(  ceguiButton );
           return false;
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           } catch (  ... ) {
           S_LOG_WARNING(  "Unknown error in CEGUI." );
           }
           return true;
          }
          
     227  bool GUICEGUIAdapter::injectMouseButtonDown(  const Input::MouseButton& button )
          {
           CEGUI::MouseButton ceguiButton;
           if (  button == Input::MouseButtonLeft ) {
           ceguiButton = CEGUI::LeftButton;
           } else if(  button == Input::MouseButtonRight ) {
           ceguiButton = CEGUI::RightButton;
           } else if(  button == Input::MouseButtonMiddle ) {
           ceguiButton = CEGUI::MiddleButton;
           } else if(  button == Input::MouseWheelDown ) {
           try {
           mGuiSystem->injectMouseWheelChange(  -1.0 );
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           }
           return false;
           } else if(  button == Input::MouseWheelUp ) {
           try {
           mGuiSystem->injectMouseWheelChange(  1.0 );
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           }
           return false;
           } else {
           return true;
           }
          
           try {
           mGuiSystem->injectMouseButtonDown(  ceguiButton );
           return false;
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           }
           return true;
          }
          
     263  bool GUICEGUIAdapter::injectChar(  char character )
          {
           try {
           //cegui can't handle tabs,   so we have to convert it to a couple of spaces
           if (  character == '\t' ) {
           mGuiSystem->injectChar(  ' ' );
           mGuiSystem->injectChar(  ' ' );
           mGuiSystem->injectChar(  ' ' );
           mGuiSystem->injectChar(  ' ' );
           //can't handle CR either really,   insert a line break (  0x0a ) instead
           } else if (  character == '\r' ) {
           //mGuiSystem->injectChar(  0x0a );
           mGuiSystem->injectKeyDown(  CEGUI::Key::Return );
           mGuiSystem->injectKeyUp(  CEGUI::Key::Return );
           } else {
           mGuiSystem->injectChar(  character );
           }
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           }
           return true;
          
          }
          
     287  bool GUICEGUIAdapter::injectKeyDown(  const SDLKey& key )
          {
           try {
           mGuiSystem->injectKeyDown(  mKeyMap[key] );
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           }
           return true;
          
          }
          
     298  bool GUICEGUIAdapter::injectKeyUp(  const SDLKey& key )
          {
           try {
           mGuiSystem->injectKeyUp(  mKeyMap[key] );
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           }
           return true;
          
          }
          
          
          
          }

./components/ogre/GUICEGUIAdapter.h

       1  //
          // C++ Interface: GUICEGUIAdapter
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREGUICEGUIADAPTER_H
          #define EMBEROGREGUICEGUIADAPTER_H
          
          #include "EmberOgrePrerequisites.h"
          #include <CEGUISystem.h>
          #include <CEGUIEventArgs.h>
          #include <CEGUIInputEvent.h>
          
          #include "input/IInputAdapter.h"
          #include "input/Input.h"
          
          
          namespace CEGUI {
      36  class System;
      37  class OgreCEGUIRenderer;
          
          }
          
          namespace EmberOgre {
          
      43  TYPEDEF_STL_MAP(  SDLKey,   CEGUI::Key::Scan,   SDLKeyMap );
          
          /**
          @author Erik Hjortsberg
          
          Provides an adapter between the input system and CEGUI.
          */
      50  class GUICEGUIAdapter : public IInputAdapter {
          public:
          
           /**
           * Creates a new instance.
           * @param system A valid CEGUI::System
           * @param renderer A valid CEGUI::OgreCEGUIRenderer
           * @return
           */
      59   GUICEGUIAdapter(  CEGUI::System *system,   CEGUI::OgreCEGUIRenderer *renderer );
          
      61   ~GUICEGUIAdapter(   );
          
      63   virtual bool injectMouseMove(  const MouseMotion& motion,   bool& freezeMouse );
      64   virtual bool injectMouseButtonUp(  const Input::MouseButton& button );
      65   virtual bool injectMouseButtonDown(  const Input::MouseButton& button );
      66   virtual bool injectChar(  char character );
      67   virtual bool injectKeyDown(  const SDLKey& key );
      68   virtual bool injectKeyUp(  const SDLKey& key );
          
          private:
      71   CEGUI::System *mGuiSystem;
      72   CEGUI::OgreCEGUIRenderer *mGuiRenderer;
          
           /**
           mapping of SDL-keys to CEGUI keys
           */
      77   SDLKeyMap mKeyMap;
          
      79   bool MultiLineEditbox_selectionChangedHandler(  const CEGUI::EventArgs& args );
      80   bool Editbox_selectionChangedHandler(  const CEGUI::EventArgs& args );
          
      82   const CEGUI::String* mSelectedText;
      83   size_t mSelectionStart,   mSelectionEnd;
          };
          
          }
          
          #endif

./components/ogre/GUIManager.cpp

          /*
           Copyright (  C ) 2004 Miguel Guzman (  Aganor )
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #include "GUIManager.h"
          #include "services/EmberServices.h"
          #include "services/config/ConfigService.h"
          #include "services/scripting/ScriptingService.h"
          
          #include <CEGUIWindowManager.h>
          #include <CEGUISchemeManager.h>
          #include <CEGUIExceptions.h>
          #include <CEGUIFactoryModule.h>
          #include <elements/CEGUIPushButton.h>
          #include <elements/CEGUIGUISheet.h>
          #include <elements/CEGUIMultiLineEditbox.h>
          #include <elements/CEGUIEditbox.h>
          
          
          #include "widgets/Widget.h"
          #include "MousePicker.h"
          
          #include "AvatarCamera.h"
          #include "EmberOgre.h"
          #include "input/Input.h"
          #include "gui/ActiveWidgetHandler.h"
          
          #include "widgets/WidgetDefinitions.h"
          
          #include "EmberEntity.h"
          #include "EmberPhysicalEntity.h"
          #include "AvatarEmberEntity.h"
          
          #include "framework/IScriptingProvider.h"
          
          #include "components/ogre/scripting/LuaScriptingProvider.h"
          
          #include "GUICEGUIAdapter.h"
          
          #include "widgets/icons/IconManager.h"
          #include "widgets/EntityIconManager.h"
          
          
          #ifdef __WIN32__
          #include <windows.h>
          #include <direct.h>
          #endif
          
          #include "EntityWorldPickListener.h"
          
          template<> EmberOgre::GUIManager* Ember::Singleton<EmberOgre::GUIManager>::ms_Singleton = 0;
          
          using namespace CEGUI;
          using namespace EmberOgre::Gui;
          
          namespace EmberOgre {
          
      72  unsigned long GUIManager::msAutoGenId(  0 );
          
          
      75  GUIManager::GUIManager(  Ogre::RenderWindow* window,   Ogre::SceneManager* sceneMgr )
          : ToggleInputMode(  "toggle_inputmode",   this,   "Toggle the input mode." )
      77  ,   ReloadGui(  "reloadgui",   this,   "Reloads the gui." )
          ,   mGuiCommandMapper(  "gui",   "key_bindings_gui" )
          ,   mPicker(  0 )
          ,   mEntityWorldPickListener(  0 )
          ,   mSheet(  0 )
          ,   mWindowManager(  0 )
          ,   mDebugText(  0 )
          ,   mWindow(  window )
          ,   mGuiSystem(  0 )
          ,   mGuiRenderer(  0 )
          ,   mLuaScriptModule(  0 )
          ,   mIconManager(  0 )
          ,   mActiveWidgetHandler(  0 )
          {
           mGuiCommandMapper.restrictToInputMode(  Input::IM_GUI  );
          
           ///we need this here just to force the linker to also link in the WidgetDefinitions
           WidgetDefinitions w;
          
           try {
          
           S_LOG_INFO(  "Starting CEGUI" );
           mDefaultScheme = "EmberLook";
           S_LOG_VERBOSE(  "Setting default scheme to "<< mDefaultScheme );
          
           Ember::ConfigService* configSrv = Ember::EmberServices::getSingletonPtr(   )->getConfigService(   );
           if (  chdir(  configSrv->getEmberDataDirectory(   ).c_str(   ) ) ) {
           S_LOG_WARNING(  "Failed to change to the data directory. Gui loading might fail." );
           }
          
           //use a macro from CEGUIFactoryModule
           //DYNLIB_LOAD(   "libCEGUIFalagardBase.so" );
          
          
          
           mGuiRenderer = new CEGUI::OgreCEGUIRenderer(  window,   Ogre::RENDER_QUEUE_OVERLAY,   false,   0,   sceneMgr );
          // mScriptManager = new GUIScriptManager(   );
           CEGUI::ResourceProvider* resourceProvider = mGuiRenderer->createResourceProvider(   );
           resourceProvider->setDefaultResourceGroup(  "Gui" );
          
           Ember::IScriptingProvider* provider;
           provider = Ember::EmberServices::getSingleton(   ).getScriptingService(   )->getProviderFor(  "LuaScriptingProvider" );
           if (  provider != 0 ) {
           LuaScriptingProvider* luaScriptProvider = static_cast<LuaScriptingProvider*>(  provider );
           mLuaScriptModule = new LuaScriptModule(  luaScriptProvider->getLuaState(   ) );
           mGuiSystem = new CEGUI::System(  mGuiRenderer,   resourceProvider,   0,   mLuaScriptModule,   "cegui/datafiles/configs/cegui.config" );
          
           Ember::EmberServices::getSingleton(   ).getScriptingService(   )->EventStopping.connect(  sigc::mem_fun(  *this,   &GUIManager::scriptingServiceStopping ) );
           } else {
           mGuiSystem = new CEGUI::System(  mGuiRenderer,   resourceProvider,   0,   0,   "cegui/datafiles/configs/cegui.config" );
           }
          
           mWindowManager = &CEGUI::WindowManager::getSingleton(   );
          
          
          
           try {
           mGuiSystem->setDefaultMouseCursor(  getDefaultScheme(   ),   "MouseArrow" );
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_FAILURE(  "CEGUI - could not set mouse pointer. Make sure that the correct scheme " << getDefaultScheme(   ) << " is available. Message: " << ex.getMessage(   ).c_str(   ) );
           throw Ember::Exception(  ex.getMessage(   ).c_str(   ) );
           }
          
          
           mSheet = mWindowManager->createWindow(  (  CEGUI::utf8* )"DefaultGUISheet",   (  CEGUI::utf8* )"root_wnd" );
           mGuiSystem->setGUISheet(  mSheet );
           mSheet->activate(   );
           mSheet->moveToBack(   );
           mSheet->setDistributesCapturedInputs(  false );
          
           BIND_CEGUI_EVENT(  mSheet,   CEGUI::ButtonBase::EventMouseButtonDown,   GUIManager::mSheet_MouseButtonDown );
           BIND_CEGUI_EVENT(  mSheet,   CEGUI::Window::EventInputCaptureLost,   GUIManager::mSheet_CaptureLost );
           BIND_CEGUI_EVENT(  mSheet,   CEGUI::ButtonBase::EventMouseDoubleClick,   GUIManager::mSheet_MouseDoubleClick );
          
           //set a default tool tip
           CEGUI::System::getSingleton(   ).setDefaultTooltip(  getDefaultScheme(   ) + "/Tooltip" );
          
           S_LOG_INFO(  "CEGUI system set up" );
          
           mPicker = new MousePicker(   );
          
           ///create a new entity world pick listener which listens for event
           ///TODO: should this really be here?
           mEntityWorldPickListener = new EntityWorldPickListener(   );
          
           ///don't connect it yet since there's no AvatarCamera yet,   wait until that's created
           EmberOgre::getSingleton(   ).EventAvatarControllerCreated.connect(  sigc::mem_fun(  *this,   &GUIManager::EmberOgre_AvatarControllerCreated ) );
          
           getInput(   ).EventKeyPressed.connect(  sigc::mem_fun(  *this,   &GUIManager::pressedKey ) );
           getInput(   ).setInputMode(  Input::IM_GUI );
          
           ///add adapter for CEGUI
           mCEGUIAdapter = new GUICEGUIAdapter(  mGuiSystem,   mGuiRenderer );
           getInput(   ).addAdapter(  mCEGUIAdapter );
          
           mGuiCommandMapper.bindToInput(  getInput(   ) );
          
           ///connect to the creation of the avatar,   since we want to switch to movement mode when that happens
           EmberOgre::getSingleton(   ).EventCreatedAvatarEntity.connect(  sigc::mem_fun(  *this,   &GUIManager::EmberOgre_CreatedAvatarEntity ) );
          
           mActiveWidgetHandler = new Gui::ActiveWidgetHandler(  *this );
          
           Ogre::Root::getSingleton(   ).addFrameListener(  this );
          
          
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_FAILURE(  "GUIManager - error when creating gui. Message: " << ex.getMessage(   ).c_str(   ) );
           throw Ember::Exception(  ex.getMessage(   ).c_str(   ) );
          
           }
          
          }
          
          
     191  GUIManager::~GUIManager(   )
          {
           S_LOG_INFO(  "Shutting down GUI manager." );
          
           WidgetStore widgetStoreCopy(  mWidgets );
           for (  WidgetStore::iterator I = widgetStoreCopy.begin(   ); I != widgetStoreCopy.end(   ); ++I ) {
           S_LOG_INFO(  "Deleting widget " << (  *I )->getPrefix(   ) << "." );
           delete *I;
           }
          
           delete mActiveWidgetHandler;
           delete mEntityIconManager;
           delete mIconManager;
          
           delete mGuiSystem;
           Ogre::Root::getSingleton(   ).removeFrameListener(  this );
           delete mCEGUIAdapter;
          
           delete mEntityWorldPickListener;
           delete mPicker;
           delete mGuiRenderer;
           delete mLuaScriptModule;
           //delete mMousePicker;
           //mMousePicker = 0;
          
          }
          
     218  void GUIManager::initialize(   )
          {
           Ember::ConfigService* configSrv = Ember::EmberServices::getSingletonPtr(   )->getConfigService(   );
           chdir(  configSrv->getEmberDataDirectory(   ).c_str(   ) );
           try {
           mDebugText = (  CEGUI::GUISheet* )mWindowManager->createWindow(  "DefaultGUISheet",   (  CEGUI::utf8* )"DebugText" );
           mSheet->addChildWindow(  mDebugText );
           mDebugText->setMaxSize(  CEGUI::UVector2(  UDim(  1.0f,   0 ),   UDim(  0,   25 ) ) );
           mDebugText->setPosition(  CEGUI::UVector2(  UDim(  0.0f,   0 ),   UDim(  1.0f,   -25 ) ) );
           mDebugText->setSize(  CEGUI::UVector2(  UDim(  1.0f,   0 ),   UDim(  0,   25 ) ) );
          
          /* mDebugText->setFrameEnabled(  false );
           mDebugText->setBackgroundEnabled(  false );*/
           //stxt->setHorizontalFormatting(  StaticText::WordWrapCentred );
          
          
           //the console and quit widgets are not lua scripts,   and should be loaded explicit
          // mConsoleWidget = static_cast<ConsoleWidget*>(  createWidget(  "ConsoleWidget" ) );
          // if (  !mConsoleWidget ) {
          // throw Ember::Exception(  "Could not create console widget." );
          // }
           createWidget(  "Quit" );
           } catch (  const std::exception& e ) {
           S_LOG_FAILURE(  "GUIManager - error when initializing widgets: " << e.what(   ) );
           throw e;
           } catch (  const CEGUI::Exception& e ) {
           S_LOG_FAILURE(  "GUIManager - error when initializing widgets: " << e.getMessage(   ).c_str(   ) );
           throw e;
           }
           try {
           mIconManager = new Gui::Icons::IconManager(   );
           } catch (  const std::exception& e ) {
           S_LOG_FAILURE(  "GUIManager - error when creating icon manager: " << e.what(   ) );
           } catch (  const CEGUI::Exception& e ) {
           S_LOG_FAILURE(  "GUIManager - error when creating icon manager: " << e.getMessage(   ).c_str(   ) );
           }
          
           try {
           mEntityIconManager = new Gui::EntityIconManager(  *this );
           } catch (  const std::exception& e ) {
           S_LOG_FAILURE(  "GUIManager - error when creating entity icon manager: " << e.what(   ) );
           } catch (  const CEGUI::Exception& e ) {
           S_LOG_FAILURE(  "GUIManager - error when creating entity icon manager: " << e.getMessage(   ).c_str(   ) );
           }
          
          
           std::vector<std::string> widgetsToLoad;
           widgetsToLoad.push_back(  "StatusIconBar" );
           widgetsToLoad.push_back(  "IngameChatWidget" );
          // widgetsToLoad.push_back(  "InventoryWidget" );
           widgetsToLoad.push_back(  "InspectWidget" );
           widgetsToLoad.push_back(  "MakeEntityWidget" );
           widgetsToLoad.push_back(  "JesusEdit" );
           widgetsToLoad.push_back(  "ServerWidget" );
           widgetsToLoad.push_back(  "Help" );
           widgetsToLoad.push_back(  "MeshPreview" );
          
           ///this should be defined in some kind of text file,   which should be different depending on what game you're playing (  like mason )
           try {
           ///load the bootstrap script which will load all other scripts
           Ember::EmberServices::getSingleton(   ).getScriptingService(   )->loadScript(  "lua/Bootstrap.lua" );
           } catch (  const std::exception& e ) {
           S_LOG_FAILURE(  "Error when loading bootstrap script. Error message: " << e.what(   ) );
           } catch (  const CEGUI::Exception& e ) {
           S_LOG_FAILURE(  "Error when loading bootstrap script. Error message: " << e.getMessage(   ).c_str(   ) );
           }
          
           for (  std::vector<std::string>::iterator I = widgetsToLoad.begin(   ); I != widgetsToLoad.end(   ); ++I ) {
           try {
           S_LOG_VERBOSE(  "Loading widget " << *I );
           createWidget(  *I );
           } catch (  const std::exception& e ) {
           S_LOG_FAILURE(  "Error when initializing widget " << *I << " : " << e.what(   ) );
           } catch (  const CEGUI::Exception& e ) {
           S_LOG_FAILURE(  "Error when initializing widget " << *I << " : " << e.getMessage(   ).c_str(   ) );
           }
           }
          
          }
          
     298  void GUIManager::scriptingServiceStopping(   )
          {
           mGuiSystem->setScriptingModule(  0 );
           delete mLuaScriptModule;
           mLuaScriptModule = 0;
          }
          
     305  void GUIManager::EmitEntityAction(  const std::string& action,   EmberEntity* entity )
          {
           EventEntityAction.emit(  action,   entity );
          }
          
          
     311  CEGUI::Window* GUIManager::createWindow(  const std::string& windowType )
          {
           std::stringstream ss;
           ss << "_autoWindow_" << (  msAutoGenId++ );
           return createWindow(  windowType,   ss.str(   ) );
          }
          
     318  CEGUI::Window* GUIManager::createWindow(  const std::string& windowType,   const std::string& windowName )
          {
           try {
           CEGUI::Window* window = mWindowManager->createWindow(  windowType,   windowName );
           return window;
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_FAILURE(  "Error when creating new window of type " << windowType << " with name " << windowName << ".\n" << ex.getMessage(   ).c_str(   ) );
           return 0;
           } catch (  const std::exception& ex ) {
           S_LOG_FAILURE(  "Error when creating new window of type " << windowType << " with name " << windowName << ".\n" << ex.what(   ) );
           return 0;
           }
          }
          
     332  Widget* GUIManager::createWidget(   )
          {
           return createWidget(  "Widget" );
          }
          
     337  Widget* GUIManager::createWidget(  const std::string& name )
          {
           Widget* widget(  0 );
           try {
          
           widget = WidgetLoader::createWidget(  name );
           if (  widget == 0 ) {
           S_LOG_FAILURE(   "Could not find widget with name " << name  );
           return 0;
           }
           widget->init(  this );
           widget->buildWidget(   );
           addWidget(  widget );
           S_LOG_INFO(   "Successfully loaded widget " << name  );
           } catch (  const std::exception& e ) {
           S_LOG_FAILURE(   "Error when loading widget " << name << ": " << e.what(   ) );
           return 0;
           } catch (  const CEGUI::Exception& e ) {
           S_LOG_FAILURE(   "Error when loading widget " << name << ": " << e.getMessage(   ).c_str(   ) );
           return 0;
           }
           return widget;
          }
          
     361  void GUIManager::destroyWidget(  Widget* widget )
          {
           if (  !widget )
           {
           S_LOG_WARNING(  "Trying to destroy null widget." );
           return;
           }
           removeWidget(  widget );
           delete widget;
          }
          
          
     373  void GUIManager::setDebugText(  const std::string& text )
          {
           if (  mDebugText )
           {
           mDebugText->setText(  text );
           }
          }
          
     381  Input& GUIManager::getInput(   ) const
          {
           return Input::getSingleton(   );
          }
          
          
     387  CEGUI::Window* GUIManager::getMainSheet(   ) const
          {
           return mSheet;
          }
          
     392  void GUIManager::removeWidget(  Widget* widget )
          {
           WidgetStore::iterator I = std::find(  mWidgets.begin(   ),   mWidgets.end(   ),   widget );
           if (  I != mWidgets.end(   ) ) {
           mWidgets.erase(  I );
           }
          }
          
     400  void GUIManager::addWidget(  Widget* widget )
          {
           mWidgets.push_back(  widget );
          }
          
          
          
          
          
          
     410  bool GUIManager::frameStarted(  const Ogre::FrameEvent& evt )
          {
           try {
           CEGUI::System::getSingleton(   ).injectTimePulse(  evt.timeSinceLastFrame );
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           }
          // if (  mPreviousInputMode == IM_GUI ) {
          // if (  !mInput->getInputMode(   ) ) {
          // EventInputModeChanged.emit(  IM_MOVEMENT );
          // mPreviousInputMode = IM_MOVEMENT;
          // }
          // } else {
          // if (  mInput->isInGUIMode(   ) ) {
          // EventInputModeChanged.emit(  IM_GUI );
          // mPreviousInputMode = IM_GUI;
          // }
          // }
          
          
          
           //iterate over all widgets and send them a frameStarted event
           WidgetStore::iterator I = mWidgets.begin(   );
           WidgetStore::iterator I_end = mWidgets.end(   );
          
           for (  ; I != I_end; ++I ) {
           Widget* aWidget = *I;
           try {
           aWidget->frameStarted(  evt );
           } catch (  const CEGUI::Exception& ex ) {
           S_LOG_WARNING(  "Error in CEGUI: " << ex.getMessage(   ).c_str(   ) );
           }
           }
          
           EventFrameStarted.emit(  evt.timeSinceLastFrame );
          
           return true;
          
          
          }
          
     451  bool GUIManager::mSheet_MouseButtonDown(  const CEGUI::EventArgs& args )
          {
           if (  isInGUIMode(   ) ) {
           const CEGUI::MouseEventArgs& mouseArgs = static_cast<const CEGUI::MouseEventArgs&>(  args );
           S_LOG_VERBOSE(  "Main sheet is capturing input" );
           CEGUI::Window* aWindow = CEGUI::Window::getCaptureWindow(   );
           if (  aWindow ) {
           aWindow->releaseInput(   );
           aWindow->deactivate(   );
           }
           //mSheet->activate(   );
           //mSheet->captureInput(   );
          
           if (  mPicker ) {
           const CEGUI::Point& position = CEGUI::MouseCursor::getSingleton(   ).getDisplayIndependantPosition(   );
           MousePickerArgs pickerArgs;
           pickerArgs.windowX = mouseArgs.position.d_x;
           pickerArgs.windowY = mouseArgs.position.d_y;
           pickerArgs.pickType = MPT_CLICK;
           mPicker->doMousePicking(  position.d_x,   position.d_y,   pickerArgs );
           }
           }
          
          
           return true;
          }
          
     478  bool GUIManager::mSheet_MouseDoubleClick(  const CEGUI::EventArgs& args )
          {
          
           const CEGUI::MouseEventArgs& mouseArgs = static_cast<const CEGUI::MouseEventArgs&>(  args );
           S_LOG_VERBOSE(  "Main sheet double click." );
           CEGUI::Window* aWindow = CEGUI::Window::getCaptureWindow(   );
           if (  aWindow ) {
           aWindow->releaseInput(   );
           aWindow->deactivate(   );
           }
           //mSheet->activate(   );
           //mSheet->captureInput(   );
          
           if (  mPicker ) {
           const CEGUI::Point& position = CEGUI::MouseCursor::getSingleton(   ).getDisplayIndependantPosition(   );
           MousePickerArgs pickerArgs;
           pickerArgs.windowX = mouseArgs.position.d_x;
           pickerArgs.windowY = mouseArgs.position.d_y;
           pickerArgs.pickType = MPT_DOUBLECLICK;
           mPicker->doMousePicking(  position.d_x,   position.d_y,   pickerArgs );
           }
          
          
           return true;
          }
          
     504  bool GUIManager::mSheet_CaptureLost(  const CEGUI::EventArgs& args )
          {
           S_LOG_VERBOSE(  "Main sheet lost input" );
           return true;
          }
          
     510  const bool GUIManager::isInMovementKeysMode(   ) const {
           return mSheet->isCapturedByThis(   ) || !isInGUIMode(   );
          }
          
     514  const bool GUIManager::isInGUIMode(   ) const {
           return getInput(   ).getInputMode(   ) == Input::IM_GUI;
          }
          
     518  void GUIManager::pressedKey(  const SDL_keysym& key,   Input::InputMode inputMode )
          {
           if (  (  key.mod & KMOD_CTRL || key.mod & KMOD_LCTRL || key.mod & KMOD_RCTRL ) && (  key.sym == SDLK_c || key.sym == SDLK_x ) ) {
          
           bool cut = (  key.sym == SDLK_x );
           CEGUI::Window* active = mSheet->getActiveChild(   );
           if (  !active ) return;
          
           CEGUI::String seltext;
           const CEGUI::String& type = active->getType(   );
          
           if (  type.find(  "/MultiLineEditbox" ) != CEGUI::String::npos ) {
           CEGUI::MultiLineEditbox* edit = static_cast<CEGUI::MultiLineEditbox*>(  active );
           CEGUI::String::size_type beg = edit->getSelectionStartIndex(   );
           CEGUI::String::size_type len = edit->getSelectionLength(   );
           seltext = edit->getText(   ).substr(   beg,   len  ).c_str(   );
          
           // are we cutting or just copying?
           if (  cut ) {
           if (  edit->isReadOnly(   ) ) return;
           CEGUI::String newtext = edit->getText(   );
           edit->setText(   newtext.erase(   beg,   len  )  );
           }
          
           } else if (  type.find(  "/Editbox" ) != CEGUI::String::npos ) {
           CEGUI::Editbox* edit = static_cast<CEGUI::Editbox*>(  active );
           CEGUI::String::size_type beg = edit->getSelectionStartIndex(   );
           CEGUI::String::size_type len = edit->getSelectionLength(   );
           seltext = edit->getText(   ).substr(   beg,   len  ).c_str(   );
          
           // are we cutting or just copying?
           if (  cut ) {
           if (  edit->isReadOnly(   ) ) return;
           CEGUI::String newtext = edit->getText(   );
           edit->setText(   newtext.erase(   beg,   len  )  );
           }
           }
           getInput(   ).writeToClipboard(   seltext.c_str(   )  );
           }
          }
          
          
          
     561  void GUIManager::runCommand(  const std::string &command,   const std::string &args )
          {
           if (  command == ToggleInputMode.getCommand(   ) ) {
           getInput(   ).toggleInputMode(   );
           } else if (  command == ReloadGui.getCommand(   ) ) {
           Ogre::TextureManager* texMgr = Ogre::TextureManager::getSingletonPtr(   );
           Ogre::ResourcePtr resource = texMgr->getByName(  "cegui/" + getDefaultScheme(   ) + ".png" );
           if (  !resource.isNull(   ) ) {
           resource->reload(   );
           }
           }
          }
          
          // void GUIManager::pushMousePicker(   MousePicker * mousePicker  )
          // {
          // mMousePickers.push(  mousePicker );
          // }
          
          // MousePicker * GUIManager::popMousePicker(   )
          // {
          // ///only pop if there's more than one registered picker
          // if (  mMousePickers.size(   ) > 1 )
          // mMousePickers.pop(   );
          // return mMousePickers.top(   );
          // }
          
     587  void GUIManager::EmberOgre_CreatedAvatarEntity(  AvatarEmberEntity* entity )
          {
           ///switch to movement mode,   since it appears most people don't know how to change from gui mode
           getInput(   ).setInputMode(  Input::IM_MOVEMENT );
          }
          
     593  void GUIManager::EmberOgre_AvatarControllerCreated(  AvatarController& controller )
          {
           EmberOgre::getSingleton(   ).getMainCamera(   )->pushWorldPickListener(  mEntityWorldPickListener );
          }
          
     598  const std::string& GUIManager::getLayoutDir(   ) const
          {
           static std::string dir(  "cegui/datafiles/layouts/" );
           return dir;
          }
          
     604  const std::string& GUIManager::getDefaultScheme(   ) const
          {
           return mDefaultScheme;
          }
          
     609  EntityWorldPickListener* GUIManager::getEntityPickListener(   ) const
          {
           return mEntityWorldPickListener;
          }
          
     614  Gui::Icons::IconManager* GUIManager::getIconManager(   )
          {
           return mIconManager;
          }
          
     619  Gui::EntityIconManager* GUIManager::getEntityIconManager(   )
          {
           return mEntityIconManager;
          }
          
          
          }
          
          

./components/ogre/GUIManager.h

       1  /*
           Copyright (  C ) 2004 Miguel Guzman (  Aglanor )
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef GUIMANAGER_H
          #define GUIMANAGER_H
          
          
          #include "EmberOgrePrerequisites.h"
          
          #include <CEGUIBase.h>
          #include <OgreCEGUIRenderer.h>
          
          #include <sigc++/trackable.h>
          
          #include "framework/Singleton.h"
          
          #include <SDL.h>
          #include <stack>
          
          #include "framework/ConsoleObject.h"
          
          #include "input/Input.h"
          #include "input/InputCommandMapper.h"
          
          namespace CEGUI
          {
      42  class GUISheet;
      43  class LuaScriptModule;
          }
          
          namespace Ember {
      47  class IScriptingProvider;
          }
          
      50  namespace EmberOgre {
          
          class EmberEntity;
          class TerrainGenerator;
          class CEGUI::Window;
          class MousePicker;
          class Input;
          class AvatarEmberEntity;
          class GUICEGUIAdapter;
          class EntityWorldPickListener;
          class AvatarController;
          
          namespace Gui {
          class Widget;
          class EntityIconManager;
          class ActiveWidgetHandler;
          namespace Icons {
          class IconManager;
          }
          }
          
          /**
           * This class will be responsible for all the GUI related things
           */
          class GUIManager :
          public Ember::Singleton<GUIManager>,  
          Ogre::FrameListener,  
          public sigc::trackable,  
          public Ember::ConsoleObject
          {
          public:
          
           typedef std::vector<Gui::Widget*> WidgetStore;
          
           static const std::string SCREENSHOT;
           static const std::string TOGGLEINPUTMODE;
          
          
           GUIManager(  Ogre::RenderWindow* window,   Ogre::SceneManager* sceneMgr );
           virtual ~GUIManager(   );
          
           sigc::signal<void,   const std::string&,   EmberEntity*> AppendIGChatLine;
           sigc::signal<void,   const std::string&,   EmberEntity*> AppendOOGChatLine;
           sigc::signal<void,   const std::string&> AppendAvatarImaginary;
          
           sigc::signal<void,   const std::string&,   EmberEntity*> EventEntityAction;
          
           /**
           Emitted every frame.
           */
           sigc::signal<void,   float> EventFrameStarted;
          
           /**
           * Emits an action for a certain entity.
           * An action could be something like "touch" or "inspect".
           * @param action
           */
           void EmitEntityAction(  const std::string& action,   EmberEntity* entity );
          
           /**
           * Removed a widget from the system.
           * @param widget
           */
           void removeWidget(  Gui::Widget* widget );
          
           /**
           * Adds a new widget to the system. This means it will recieve FrameStarted events.
           * @param widget
           */
           void addWidget(  Gui::Widget* widget );
          
           /**
           * Called by Ogre each frame.
           * @param evt
           * @return
           */
           bool frameStarted(  const Ogre::FrameEvent& evt );
          
           /**
           * Gets the root sheet of the CEGUI windowing system.
           * @return
           */
           CEGUI::Window* getMainSheet(   ) const;
          
          
           /**
           * Called by EmberOgre at initialization.
           */
           void initialize(   );
          
          
           /**
           * sets a text to be shown somewhere on the screen,   used for debugging purposes
           * @param text
           */
           void setDebugText(  const std::string& text );
          
           /**
           * true if we're in GUI mode,   which means that input events will be sent to the CEGUI system instead of the "world"
           * @return
           */
           const bool isInGUIMode(   ) const;
          
          
           /**
           * true if keyboard input should make the avatar move
           * this happens when wither 1 ) we're not in gui mode 2 ) the background sheet has the input control (  thus,   when something else,   like an edit box has input control,   that edit box will recieve key strokes
           * @return
           */
           const bool isInMovementKeysMode(   ) const;
          
           /**
           * Gets the currently active MousePicker instance.
           * @return
           */
           inline MousePicker* getMousePicker(   ) { return mMousePickers.top(   ); }
          
          
           /**
           * accessor for the Input instance object
           * @return
           */
           Input& getInput(   ) const;
          
           /**
           * Pushes a new mouse picker onto the stack,   "pushing down" the current mouse picker.
           * @param mousePicker
           */
          // void pushMousePicker(  MousePicker* mousePicker );
          
           /**
           * Pops the current mouse picker from the stack and returns the next in line.
           * It's not possible to empty the stack. If there's only one picker left,   no popping will be done,   and the last picker will be returned.
           * @return
           */
          // MousePicker* popMousePicker(   );
          
           inline CEGUI::OgreCEGUIRenderer* getGuiRenderer(   ) const {return mGuiRenderer;}
          
           /**
           * Reimplements the ConsoleObject::runCommand method
           * @param command
           * @param args
           */
           virtual void runCommand(  const std::string &command,   const std::string &args );
          
          
           /**
           * returns the path to the directory where all layouts are stored
           * @return
           */
           const std::string& getLayoutDir(   ) const;
          
           /**
           Creates a new window of the supplied type,   giving it an autogenerated,   unique name.
           */
           CEGUI::Window* createWindow(  const std::string& windowType );
          
           /**
           Creates a new window of the supplied type with the supplied name.
           */
           CEGUI::Window* createWindow(  const std::string& windowType,   const std::string& windowName );
          
           /**
           * Creates a new Widget
           * @return
           */
           Gui::Widget* createWidget(   );
          
           /**
           * creates a widget
           * @see WidgetLoader
           * @param name the type of widget to create
           * @return
           */
           Gui::Widget* createWidget(  const std::string& name );
          
           /**
           * Destroys a widget previously created by createWidget
           * @param widget The widget to destroy.
           */
           void destroyWidget(  Gui::Widget* widget );
          
           /**
           * Gets the name of the default scheme used (  such as "EmberLook" or "WindowsLook" )
           * @return
           */
           const std::string& getDefaultScheme(   ) const;
          
           EntityWorldPickListener* getEntityPickListener(   ) const;
          
           /**
           Command for toggling between the input modes.
           */
           const Ember::ConsoleCommandWrapper ToggleInputMode;
          
           /**
           Command for reloading the gui.
           */
           const Ember::ConsoleCommandWrapper ReloadGui;
          
          
           /**
           * Accessor for the IconManager which handles low level icons.
           * @return The main IconManager
           */
           Gui::Icons::IconManager* getIconManager(   );
          
           /**
           * Accessor for the EntityIconManager,   which handles entity icons and slots.
           * @return The main EntityIconManager
           */
           Gui::EntityIconManager* getEntityIconManager(   );
          
          protected:
          
           /**
           Counter for autonaming of windows.
           */
           static unsigned long msAutoGenId;
          
           InputCommandMapper mGuiCommandMapper;
          
           MousePicker* mPicker;
          
           EntityWorldPickListener* mEntityWorldPickListener;
          
           CEGUI::Window* mSheet;
           CEGUI::WindowManager* mWindowManager;
           CEGUI::GUISheet* mDebugText;
          
           Ogre::RenderWindow* mWindow;
           CEGUI::System* mGuiSystem;
           CEGUI::OgreCEGUIRenderer* mGuiRenderer;
          
           std::string mDefaultScheme;
          
           /**
           all loaded widgets are stored here
           */
           WidgetStore mWidgets;
          
           /**
           A stack of the mouse pickers used. This allows for a component to "push down" the current mouse picker in favor of its own
           */
           std::stack<MousePicker*> mMousePickers;
          
           //events
           bool mSheet_MouseButtonDown(  const CEGUI::EventArgs& args );
           bool mSheet_MouseDoubleClick(  const CEGUI::EventArgs& args );
           bool mSheet_CaptureLost(  const CEGUI::EventArgs& args );
          
           /**
           * hooked to EmberOgre::EventCreatedAvatarEntity,   switches the input mode to movement mode
           * @param entity
           */
           void EmberOgre_CreatedAvatarEntity(  AvatarEmberEntity* entity );
          
           /**
           * hooked to EmberOgre::EventAvatarControllerCreated,   connects the mEntityWorldPickListener to the main AvatarCamera
           * @param controller
           */
           void EmberOgre_AvatarControllerCreated(  AvatarController& controller );
          
          // InputMode mPreviousInputMode;
           void pressedKey(  const SDL_keysym& key,   Input::InputMode inputMode );
          
           /**
           Adapter for CEGUI which will send input events to CEGUI
           */
           GUICEGUIAdapter* mCEGUIAdapter;
          
           CEGUI::LuaScriptModule* mLuaScriptModule;
          
           void scriptingServiceStopping(   );
          
           Gui::Icons::IconManager* mIconManager;
           Gui::EntityIconManager* mEntityIconManager;
           Gui::ActiveWidgetHandler* mActiveWidgetHandler;
          };
          }
          
          
          #endif

./components/ogre/IWorldPickListener.h

       1  //
          // C++ Interface: IWorldPickListener
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREIWORLDPICKLISTENER_H
          #define EMBEROGREIWORLDPICKLISTENER_H
          
          #include "EmberOgrePrerequisites.h"
          
          namespace EmberOgre {
          
          /**
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
          
          /**
          The kind of mouse click operation.
          */
          enum MousePickType
          {
           ///Simple click
           MPT_CLICK = 1,  
           ///Double click
           MPT_DOUBLECLICK = 2
          
          };
          
          /**
          Mouse picking info from the windowing system.
          */
          struct MousePickerArgs
          {
           /**
           The x and y coords in local window space.
           */
           float windowX,   windowY;
          
           MousePickType pickType;
          };
          
          
      60  class IWorldPickListener
          {
          public:
          
      64  virtual ~IWorldPickListener(   ) {}
          
          /**
          Called at the start of a picking context. This allows the pickers to be reset and to keep state for each picking.
          */
      69  virtual void initializePickingContext(   ) {}
          
          /**
          Called when the picking is over,   either because one of the processPickResult calls set continuePicking to false,   or because there are no more objects to pick.
          */
      74  virtual void endPickingContext(  const MousePickerArgs& mousePickerArgs ) {}
          
          /**
           * Processes the pick result.
           * This will be called for each picked object.
           * @param continuePicking set this to false if you don't want to process any more pick results,   or don't want any other IWorldPickListener to process the pick any more
           * @param entry The actual pick entry.
           * @param cameraRay The ray which resulted in the pick.
           * @param mousePickerArgs The original mouse picker arguments.
           */
      84  virtual void processPickResult(  bool& continuePicking,   Ogre::RaySceneQueryResultEntry& entry,   Ogre::Ray& cameraRay,   const MousePickerArgs& mousePickerArgs ) = 0;
          
          
          };
          
          }
          
          #endif

./components/ogre/MathConverter.h

       1  /*
          -----------------------------------------------------------------------------
          MathConverter.h by Miguel Guzman Miranda (  Aglanor )
          Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          
          Copyright © 2003 The Worldforge Project (  http://www.worldforge.org )
          This file is part of Ember client (  http://www.worldforge.org/dev/eng/clients/Ember )
          
          This code is distributed under the GNU GPL (  General Public License ).
          See file COPYING for details.
          
          -----------------------------------------------------------------------------
          
          -----------------------------------------------------------------------------
          Filename: MathConverter.h
          Description: Point,   Vector and Quaternion converter
           for world-centric coordinates (  Atlas-wfmath like )
           to/from screen-centric coordinates (  Ogre like ).
          
           Atlas is World-centric (  picture a map ):
           x is east
           y is north
           z is up
          
           Ogre is screen-centric (  picture your monitor screen ):
           x is right
           y is up
           z is depth (  negative towards the screen,  
           positive is towards you,  
           so the coord system is also dextrogyrous )
          
           --------------------------------------------------------
           Example of Atlas --> Ogre conversion
          
           Picture this is the world map,   in both cases:
           ^ North
           |
           | East
           (  Up )--->
          
          
           Atlas Ogre
          
           ^ a.y ^ -o.z
           | |
           | a.x | o.x
           (  a.z )---> (  o.y )--->
          
           --------------------------------------------------------
           Example of Ogre --> Atlas conversion
          
           Picture this is your computer screen,   in both cases:
           ^ Up
           |
           | Left
           (  You )--->
          
           Ogre Atlas
          
           ^ o.y ^ a.z
           | |
           | o.x | a.x
           (  o.z )---> (  -a.y )--->
          
           The math is:
          
           Atlas.x = Ogre.x
           Atlas.y = -Ogre.z
           Atlas.z = Ogre.y
          
           Ogre.x = Atlas.x
           Ogre.y = Atlas.z
           Ogre.z = -Atlas.y
          
          -----------------------------------------------------------------------------
          */
          
          #ifndef __MATH_CONVERTER_H__
          #define __MATH_CONVERTER_H__
          
          // ------------------------------
          // Include WFmath header files
          // ------------------------------
          #include <wfmath/point.h>
          #include <wfmath/vector.h>
          #include <wfmath/axisbox.h>
          #include <wfmath/quaternion.h>
          #include <wfmath/const.h>
          
          #include <math.h>
          
          namespace EmberOgre {
          
          typedef WFMath::Point<2> TerrainPosition;
          
          // //note that this will ignore the y value of the supplied ogre vector
          // inline TerrainPosition Ogre2Atlas(  Ogre::Vector3& p ) {
          // return WFMath::Point<2>(  p.x,  -p.z );
          // }
          
          /*inline Ogre::Vector3 Atlas2Ogre(  TerrainPosition& p ) {
           return Ogre::Vector3(  p.x(   ),  0,  -p.y(   ) );
          }*/
     104  inline Ogre::Vector3 Atlas2Ogre(  const TerrainPosition& p ) {
           return Ogre::Vector3(  p.x(   ),  0,  -p.y(   ) );
          }
          
     108  inline Ogre::Vector2 Atlas2Ogre_Vector2(  const TerrainPosition& p ) {
           return Ogre::Vector2(  p.x(   ),  -p.y(   ) );
          }
          
          // inline WFMath::Point<3> Ogre2Atlas(  Ogre::Vector3& p ) {
          // return WFMath::Point<3>(  p.x,  -p.z,  p.y );
          // }
          
          /*inline WFMath::Vector<3> Ogre2Atlas_Vector3(  Ogre::Vector3& p ) {
           return WFMath::Vector<3>(  p.x,  -p.z,  p.y );
          }*/
     119  inline WFMath::Point<3> Ogre2Atlas(  const Ogre::Vector3& p ) {
           return WFMath::Point<3>(  p.x,  -p.z,  p.y );
          }
          
     123  inline TerrainPosition Ogre2Atlas(  const Ogre::Vector2& p ) {
           return TerrainPosition(  p.x,  -p.y );
          }
          
     127  inline TerrainPosition Ogre2Atlas_TerrainPosition(  const Ogre::Vector3& p ) {
           return TerrainPosition(  p.x,  -p.z );
          }
          
     131  inline WFMath::Vector<3> Ogre2Atlas_Vector3(  const Ogre::Vector3& p ) {
           return WFMath::Vector<3>(  p.x,  -p.z,  p.y );
          }
          
          // inline Ogre::Vector3 Atlas2Ogre(  WFMath::Point<3>& p ){
          // return Ogre::Vector3(  p.x(   ),  p.z(   ),  -p.y(   ) );
          // }
          
     139  inline Ogre::Vector3 Atlas2Ogre(  const WFMath::Point<3>& p ){
           return Ogre::Vector3(  p.x(   ),  p.z(   ),  -p.y(   ) );
          }
          
          // inline Ogre::Vector3 Atlas2Ogre(  WFMath::Vector<3>& v ){
          // return Ogre::Vector3(  v.x(   ),  v.z(   ),  -v.y(   ) );
          // }
          
     147  inline Ogre::Vector3 Atlas2Ogre(  const WFMath::Vector<3>& v ){
           return Ogre::Vector3(  v.x(   ),  v.z(   ),  -v.y(   ) );
          }
          
          // inline Ogre::Quaternion Atlas2Ogre(  WFMath::Quaternion& aq ){
          // if (  !aq.isValid(   ) ) {
          // return Ogre::Quaternion::IDENTITY;
          // }
          // return Ogre::Quaternion(  aq.scalar(   ),  aq.vector(   ).x(   ),  aq.vector(   ).z(   ),  -aq.vector(   ).y(   ) );
          // }
          
     158  inline Ogre::Quaternion Atlas2Ogre(  const WFMath::Quaternion& aq ){
           if (  !aq.isValid(   ) ) {
           return Ogre::Quaternion::IDENTITY;
           }
           return Ogre::Quaternion(  aq.scalar(   ),  aq.vector(   ).x(   ),  aq.vector(   ).z(   ),  -aq.vector(   ).y(   ) );
          }
          
          //is this correct?
          // inline WFMath::Quaternion Ogre2Atlas(  Ogre::Quaternion& aq ){
          // return WFMath::Quaternion(  aq.w,  aq.x,  -aq.z,  aq.y );
          // }
     169  inline WFMath::Quaternion Ogre2Atlas(  const Ogre::Quaternion& aq ){
           return WFMath::Quaternion(  aq.w,  aq.x,  -aq.z,  aq.y );
          }
          
     173  inline Ogre::AxisAlignedBox Atlas2Ogre(  const WFMath::AxisBox<3>& axisBox ){
           if (  !axisBox.isValid(   ) ) {
           return Ogre::AxisAlignedBox(   );
           }
           return Ogre::AxisAlignedBox(  axisBox.lowCorner(   ).x(   ),   axisBox.lowCorner(   ).z(   ),   -axisBox.highCorner(   ).y(   ),   axisBox.highCorner(   ).x(   ),   axisBox.highCorner(   ).z(   ),   -axisBox.lowCorner(   ).y(   ) );
          }
          
     180  inline Ogre::TRect<Ogre::Real> Atlas2Ogre(  const WFMath::AxisBox<2>& atlasBox ) {
           if (  !atlasBox.isValid(   ) ) {
           return Ogre::TRect<Ogre::Real>(   );
           }
           return Ogre::TRect<Ogre::Real>(  atlasBox.lowCorner(   ).x(   ),   -atlasBox.highCorner(   ).y(   ),   atlasBox.highCorner(   ).x(   ),   -atlasBox.lowCorner(   ).y(   ) );
          }
          
          
     188  inline WFMath::AxisBox<3> Ogre2Atlas(  const Ogre::AxisAlignedBox& axisBox ){
           if (  axisBox.isNull(   ) || axisBox.isInfinite(   ) ) {
           return WFMath::AxisBox<3>(   );
           }
           return WFMath::AxisBox<3>(  WFMath::Point<3>(  axisBox.getMinimum(   ).x,   axisBox.getMinimum(   ).z,   -axisBox.getMaximum(   ).y ),   WFMath::Point<3>(  axisBox.getMaximum(   ).x,   axisBox.getMaximum(   ).z,   -axisBox.getMinimum(   ).y ) );
          }
          
          
          }
          
          
          
          /*
          Ogre::Vector3 Ogre::Vector3(  WFMath::Vector<3> v ) {
           return Ogre::Vector3(  v.x(   ),  v.z(   ),  -v.y(   ) );
          }
          
          
          WFMath::Point<3>::operator Ogre::Vector3(   ) const{
           return Ogre::Vector3(  this.x(   ),  this.z(   ),  -this.y(   ) );
          }
          */
          
          #endif

./components/ogre/MediaDeployer.cpp

       1  /*
           ConsoleObjectImpl.cpp by Miguel Guzman (  Aglanor )
           Copyright (  C ) 2002 Miguel Guzman & The Worldforge Project
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          // config headers
          #ifdef HAVE_CONFIG_H
          #include "config.h"
          #endif
          
          // system headers
          
          // library headers
          #include "EmberOgrePrerequisites.h"
          
          // local headers
          #include "MediaDeployer.h"
          
          namespace EmberOgre {
          
          //TODO: add a sequence for mediadeployer ids
          //TODO: add several methods for adding media with different params
          
          MediaDeployer* MediaDeployer::_mediaDeployerInstance = 0;
          
      40  MediaDeployer & MediaDeployer::getSingleton(  void )
          {
           if(  _mediaDeployerInstance == 0 )
           _mediaDeployerInstance = new MediaDeployer;
           return *_mediaDeployerInstance;
          }
          
      47  MediaDeployer::MediaDeployer(  void )
          {
           mSceneMgr = Ogre::Root::getSingleton(   ).getSceneManager(  Ogre::ST_EXTERIOR_CLOSE );
          }
          
      52  MediaDeployer::~MediaDeployer(   )
          {
          
          }
          
      57  bool MediaDeployer::addMedia(  std::string modelName )
          {
           return true;
          }
          
      62  bool MediaDeployer::addMedia(  std::string modelName,   std::string id,   Ogre::Vector3 position )
          {
          
           // create the ogre node and entity
           Ogre::SceneNode* ogreNode = static_cast<Ogre::SceneNode*>(  mSceneMgr->getRootSceneNode(   )->createChild(   ) );
           Ogre::Entity* ogreEntity;
           ogreEntity = mSceneMgr->createEntity(  id,  modelName );
           ogreNode->setPosition(  position );
           ogreNode->attachObject(  ogreEntity );
          
           return true;
          }
          
          }
          

./components/ogre/MediaDeployer.h

       1  /*
           ConsoleObjectImpl.h by Miguel Guzman (  Aglanor )
           Copyright (  C ) 2002 Miguel Guzman & The Worldforge Project
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef __EmberOgre_MediaDeployer_H__
          #define __EmberOgre_MediaDeployer_H__
          
          namespace EmberOgre {
          
      25  class MediaDeployer
          {
          
           public:
          
      30   ~MediaDeployer(   );
          
      32   static MediaDeployer & getSingleton(  void );
          
      34   bool addMedia(  std::string );
      35   bool addMedia(  std::string,   std::string,   Ogre::Vector3 );
          
           private:
          
           /**
           * Private constructor (  for singleton )
           */
      42   MediaDeployer(  void );
          
           /**
           * Instance variable for singleton console object implementation.
           */
           static MediaDeployer* _mediaDeployerInstance;
          
           /**
           * Scene manager to which deploy the media
           */
      52   Ogre::SceneManager* mSceneMgr;
          
          }; // End of class declaration
          }
          
          
          #endif

./components/ogre/MediaUpdater.cpp

       1  //
          // C++ Implementation: MediaUpdater
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "MediaUpdater.h"
          
          #include "services/EmberServices.h"
          #include "services/config/ConfigService.h"
          #include "services/wfut/WfutService.h"
          
          namespace EmberOgre {
          
      31  MediaUpdater::MediaUpdater(   )
          {
          }
          
          
      36  MediaUpdater::~MediaUpdater(   )
          {
          }
          
      40  void MediaUpdater::performUpdate(   )
          {
           Ember::ConfigService* configSrv = Ember::EmberServices::getSingleton(   ).getConfigService(   );
           Ember::WfutService* wfutSrv= Ember::EmberServices::getSingleton(   ).getWfutService(   );
          
           if (  configSrv->itemExists(  "wfut",   "server" ) ) {
           std::string server(  configSrv->getValue(  "wfut",   "server" ) );
           if (  configSrv->itemExists(  "wfut",   "channel" ) ) {
           std::string channel(  configSrv->getValue(  "wfut",   "channel" ) );
          
           wfutSrv->startUpdate(  server,   channel,   configSrv->getHomeDirectory(   ) ,   "" );
           while (  wfutSrv->poll(   ) ) {
           }
          
           }
           }
          
          }
          
          
          }

./components/ogre/MediaUpdater.h

       1  //
          // C++ Interface: MediaUpdater
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREMEDIAUPDATER_H
          #define EMBEROGREMEDIAUPDATER_H
          
          namespace EmberOgre {
          
          /**
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
      31  class MediaUpdater{
          public:
      33   MediaUpdater(   );
          
      35   ~MediaUpdater(   );
          
      37   void performUpdate(   );
          
          
          
          };
          
          }
          
          #endif

./components/ogre/MeshCollisionDetector.cpp

       1  //
          // C++ Implementation: MeshCollisionDetector
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik.hjortsberg@iteam.se>,   (  C ) 2008
          // This code is taked from http://www.ogre3d.org/wiki/index.php/Raycasting_to_the_polygon_level (  2008-01-13 ),   where it's released as Public Domain,   and now relicensed to GPL. Author is unknown.
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifdef HAVE_CONFIG_H
          #include "config.h"
          #endif
          
          #include "MeshCollisionDetector.h"
          
          #include "EmberOgrePrerequisites.h"
          
          #include "model/Model.h"
          #include "model/SubModel.h"
          
          namespace EmberOgre {
          
      37  MeshCollisionDetector::MeshCollisionDetector(  Model::Model* model )
          :mModel(  model )
          {
          }
          
          
      43  MeshCollisionDetector::~MeshCollisionDetector(   )
          {
          }
          
      47  void MeshCollisionDetector::reload(   )
          {
          }
          
      51  void MeshCollisionDetector::refit(   )
          {
          }
          
      55  void MeshCollisionDetector::setVisualize(  bool visualize )
          {
          }
      58  bool MeshCollisionDetector::getVisualize(   ) const
          {
           return false;
          }
          
      63  void MeshCollisionDetector::testCollision(  Ogre::Ray& ray,   CollisionResult& result )
          {
          
           // at this point we have raycast to a series of different objects bounding boxes.
           // we need to test these different objects to see which is the first polygon hit.
           // there are some minor optimizations (  distance based ) that mean we wont have to
           // check all of the objects most of the time,   but the worst case scenario is that
           // we need to test every triangle of every object.
           Ogre::Real closest_distance = -1.0f;
           Ogre::Vector3 closest_result;
           const Model::Model::SubModelSet& submodels = mModel->getSubmodels(   );
           for (  Model::Model::SubModelSet::const_iterator I = submodels.begin(   ); I != submodels.end(   ); ++I )
           {
           Ogre::Entity* pentity = (  *I )->getEntity(   );
           if (  pentity->isVisible(   ) ) {
           // mesh data to retrieve
           size_t vertex_count;
           size_t index_count;
           Ogre::Vector3 *vertices;
           unsigned long *indices;
          
           // get the mesh information
           getMeshInformation(  pentity->getMesh(   ),   vertex_count,   vertices,   index_count,   indices,  
           pentity->getParentNode(   )->getWorldPosition(   ),  
           pentity->getParentNode(   )->getWorldOrientation(   ),  
           pentity->getParentNode(   )->getScale(   ) );
          
           // test for hitting individual triangles on the mesh
           bool new_closest_found = false;
           for (  int i = 0; i < static_cast<int>(  index_count ); i += 3 )
           {
           // check for a hit against this triangle
           std::pair<bool,   Ogre::Real> hit = Ogre::Math::intersects(  ray,   vertices[indices[i]],  
           vertices[indices[i+1]],   vertices[indices[i+2]],   true,   false );
          
           // if it was a hit check if its the closest
           if (  hit.first )
           {
           if (  (  closest_distance < 0.0f ) ||
           (  hit.second < closest_distance ) )
           {
           // this is the closest so far,   save it off
           closest_distance = hit.second;
           new_closest_found = true;
           }
           }
           }
          
           // free the verticies and indicies memory
           delete[] vertices;
           delete[] indices;
          
           // if we found a new closest raycast for this object,   update the
           // closest_result before moving on to the next object.
           if (  new_closest_found )
           {
           closest_result = ray.getPoint(  closest_distance );
           }
           }
           }
          
          
           // return the result
           if (  closest_distance >= 0.0f )
           {
           // raycast success
           result.collided = true;
           result.position = closest_result;
           result.distance = closest_distance;
           }
           else
           {
           // raycast failed
           result.collided = false;
           }
          }
          
          
          // Get the mesh information for the given mesh.
          // Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData
     143  void MeshCollisionDetector::getMeshInformation(  const Ogre::MeshPtr mesh,  
     144   size_t &vertex_count,  
     145   Ogre::Vector3* &vertices,  
     146   size_t &index_count,  
           unsigned long* &indices,  
     148   const Ogre::Vector3 &position,  
     149   const Ogre::Quaternion &orient,  
     150   const Ogre::Vector3 &scale )
          {
           bool added_shared = false;
           size_t current_offset = 0;
           size_t shared_offset = 0;
           size_t next_offset = 0;
           size_t index_offset = 0;
          
           vertex_count = index_count = 0;
          
           // Calculate how many vertices and indices we're going to need
           for (  unsigned short i = 0; i < mesh->getNumSubMeshes(   ); ++i )
           {
           Ogre::SubMesh* submesh = mesh->getSubMesh(   i  );
          
           // We only need to add the shared vertices once
           if(  submesh->useSharedVertices )
           {
           if(   !added_shared  )
           {
           vertex_count += mesh->sharedVertexData->vertexCount;
           added_shared = true;
           }
           }
           else
           {
           vertex_count += submesh->vertexData->vertexCount;
           }
          
           // Add the indices
           index_count += submesh->indexData->indexCount;
           }
          
          
           // Allocate space for the vertices and indices
           vertices = new Ogre::Vector3[vertex_count];
           indices = new unsigned long[index_count];
          
           added_shared = false;
          
           // Run through the submeshes again,   adding the data into the arrays
           for (   unsigned short i = 0; i < mesh->getNumSubMeshes(   ); ++i )
           {
           Ogre::SubMesh* submesh = mesh->getSubMesh(  i );
          
           Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
          
           if(  (  !submesh->useSharedVertices )||(  submesh->useSharedVertices && !added_shared ) )
           {
           if(  submesh->useSharedVertices )
           {
           added_shared = true;
           shared_offset = current_offset;
           }
          
           const Ogre::VertexElement* posElem =
           vertex_data->vertexDeclaration->findElementBySemantic(  Ogre::VES_POSITION );
          
           Ogre::HardwareVertexBufferSharedPtr vbuf =
           vertex_data->vertexBufferBinding->getBuffer(  posElem->getSource(   ) );
          
           unsigned char* vertex =
           static_cast<unsigned char*>(  vbuf->lock(  Ogre::HardwareBuffer::HBL_READ_ONLY ) );
          
           // There is _no_ baseVertexPointerToElement(   ) which takes an Ogre::Real or a double
           // as second argument. So make it float,   to avoid trouble when Ogre::Real will
           // be comiled/typedefed as double:
           // Ogre::Real* pReal;
           float* pReal;
          
           for(   size_t j = 0; j < vertex_data->vertexCount; ++j,   vertex += vbuf->getVertexSize(   ) )
           {
           posElem->baseVertexPointerToElement(  vertex,   &pReal );
          
           Ogre::Vector3 pt(  pReal[0],   pReal[1],   pReal[2] );
          
           vertices[current_offset + j] = (  orient * (  pt * scale ) ) + position;
           }
          
           vbuf->unlock(   );
           next_offset += vertex_data->vertexCount;
           }
          
          
           Ogre::IndexData* index_data = submesh->indexData;
           size_t numTris = index_data->indexCount / 3;
           Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
          
           bool use32bitindexes = (  ibuf->getType(   ) == Ogre::HardwareIndexBuffer::IT_32BIT );
          
           unsigned long* pLong = static_cast<unsigned long*>(  ibuf->lock(  Ogre::HardwareBuffer::HBL_READ_ONLY ) );
           unsigned short* pShort = reinterpret_cast<unsigned short*>(  pLong );
          
          
           size_t offset = (  submesh->useSharedVertices )? shared_offset : current_offset;
          
           if (   use32bitindexes  )
           {
           for (   size_t k = 0; k < numTris*3; ++k )
           {
           indices[index_offset++] = pLong[k] + static_cast<unsigned long>(  offset );
           }
           }
           else
           {
           for (   size_t k = 0; k < numTris*3; ++k )
           {
           indices[index_offset++] = static_cast<unsigned long>(  pShort[k] ) +
           static_cast<unsigned long>(  offset );
           }
           }
          
           ibuf->unlock(   );
           current_offset = next_offset;
           }
          }
          
          }

./components/ogre/MeshCollisionDetector.h

       1  //
          // C++ Interface: MeshCollisionDetector
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik.hjortsberg@iteam.se>,   (  C ) 2008
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREMESHCOLLISIONDETECTOR_H
          #define EMBEROGREMESHCOLLISIONDETECTOR_H
          
          #include "EmberEntityUserObject.h"
          
          namespace EmberOgre {
          
          /**
           Uses a brute force approach to checking for intersection by iterating through all vertices to see which intersects the ray.
           @author Erik Hjortsberg <erik.hjortsberg@iteam.se>
          */
      34  class MeshCollisionDetector : public ICollisionDetector
          {
          public:
      37   MeshCollisionDetector(  Model::Model* model );
          
      39   virtual ~MeshCollisionDetector(   );
          
      41   virtual void testCollision(  Ogre::Ray& ray,   CollisionResult& result );
      42   virtual void refit(   );
           /**
           * Called when the entity changes,   such as a subentity being hidden or shown. Implementations must reload the collision data.
           */
      46   virtual void reload(   );
          
      48   virtual void setVisualize(  bool visualize );
      49   virtual bool getVisualize(   ) const;
          
          protected:
      52   Model::Model* mModel;
      53   void getMeshInformation(  const Ogre::MeshPtr mesh,  
      54   size_t &vertex_count,  
      55   Ogre::Vector3* &vertices,  
      56   size_t &index_count,  
           unsigned long* &indices,  
      58   const Ogre::Vector3 &position,  
      59   const Ogre::Quaternion &orient,  
      60   const Ogre::Vector3 &scale );
          };
          
          }
          
          #endif

./components/ogre/MotionManager.cpp

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #include "EmberEntity.h"
          #include "EmberPhysicalEntity.h"
          
          #include "EmberOgre.h"
          #include "MathConverter.h"
          #include "MotionManager.h"
          // #include "terrain/TerrainGenerator.h"
          
          template<> EmberOgre::MotionManager* Ember::Singleton<EmberOgre::MotionManager>::ms_Singleton = 0;
          namespace EmberOgre {
          
          
      31  MotionManager::MotionManager(   )
          : mControllerManager(  &Ogre::ControllerManager::getSingleton(   ) )
          {
           mInfo.MovingEntities = mMotionSet.size(   );
           mInfo.AnimatedEntities = mAnimatedEntities.size(   );
           mInfo.Animations = mAnimations.size(   );
          }
          
          
      40  MotionManager::~MotionManager(   )
          {}
          
          
      44  void MotionManager::doMotionUpdate(  Ogre::Real timeSlice )
          {
           std::set<EmberEntity*>::iterator I;
           for (  I = mMotionSet.begin(   ); I != mMotionSet.end(   ); ++I ) {
           updateMotionForEntity(  *I,   timeSlice );
           }
          }
          
      52  void MotionManager::doAnimationUpdate(  Ogre::Real timeSlice )
          {
          
           EntityStore::iterator I = mAnimatedEntities.begin(   );
           for (  ;I != mAnimatedEntities.end(   ); ++I ) {
           I->second->updateAnimation(  timeSlice );
           }
          /* AnimationStateSet::iterator I = mAnimations.begin(   );
           AnimationStateSet::iterator I_end = mAnimations.end(   );
           for (  ;I != I_end; ++I ) {
           if (  (  *I )->getEnabled(   ) ) {
           (  *I )->addTime(  timeSlice );
           }
           }*/
          }
          
          
          
      70  void MotionManager::updateMotionForEntity(  EmberEntity* entity,   Ogre::Real timeSlice )
          {
           entity->updateMotion(  timeSlice );
          }
          
          // void MotionManager::adjustHeightPositionForNode(  Ogre::SceneNode* sceneNode ) {
          // Ogre::Vector3 position = sceneNode->getPosition(   );
          // //get the height from Mercator through the TerrainGenerator
          // assert(  mTerrainGenerator );
          // TerrainPosition pos = Ogre2Atlas_TerrainPosition(  position );
          // float height = mTerrainGenerator->getHeight(  pos );
          // sceneNode->setPosition(  position.x,   height,  position.z );
          //
          // }
          
      85  bool MotionManager::frameStarted(  const Ogre::FrameEvent& event )
          {
           doMotionUpdate(  event.timeSinceLastFrame );
           doAnimationUpdate(  event.timeSinceLastFrame );
           return true;
          }
          
      92  bool MotionManager::frameEnded(  const Ogre::FrameEvent& event )
          {
           return true;
          }
          
      97  void MotionManager::addEntity(  EmberEntity* entity )
          {
           mMotionSet.insert(  entity );
           mInfo.MovingEntities = mMotionSet.size(   );
           entity->updateMotion(  0 );
          }
          
     104  void MotionManager::removeEntity(  EmberEntity* entity )
          {
           mMotionSet.erase(  entity );
           mInfo.MovingEntities = mMotionSet.size(   );
          // entity->updateMotion(  0 );
          }
          
          
          
     113  void MotionManager::addAnimatedEntity(  EmberPhysicalEntity* entity )
          {
           mAnimatedEntities[entity->getId(   )] = entity;
           mInfo.AnimatedEntities = mAnimatedEntities.size(   );
          }
          
     119  void MotionManager::removeAnimatedEntity(  EmberPhysicalEntity* entity )
          {
           mAnimatedEntities.erase(  entity->getId(   ) );
           mInfo.AnimatedEntities = mAnimatedEntities.size(   );
          }
          
          
     126  void MotionManager::addAnimation(  Ogre::AnimationState* animationState )
          {
          
           animationState->setEnabled(  true );
           mAnimations.insert(  animationState );
           mInfo.Animations = mAnimations.size(   );
          
          /*
           //check if it's not already added
           AnimationStateSet::const_iterator I = mAnimations.find(  animationState );
           if (  I == mAnimations.end(   ) ) {
           animationState->setEnabled(  true );
           mAnimations.insert(  animationState );
          
          
           //how is the overhead on creating a ControllerFunction for each single AnimationState?
           //perhaps we should keep ControllerFunction bound to Animation instead?
           Ogre::AnimationControllerFunction* controllerFunction = new Ogre::AnimationControllerFunction(  animationState->getLength(   ) );
           animationControllerType* animationController = Ogre::ControllerManager::getSingleton(   ).createController(  mControllerManager->getFrameTimeSource(   ),   animationState,   controllerFunction );
          
           animationState->setEnabled(  true );
          
           mAnimations.insert(  animationStateMap::value_type(  animationState,   animationController ) );
          
           }
           */
          
          }
          
     155  void MotionManager::removeAnimation(  Ogre::AnimationState* animationState )
          {
           AnimationStateSet::const_iterator I = mAnimations.find(  animationState );
           if (  I != mAnimations.end(   ) ) {
           mAnimations.erase(  *I );
           //animationControllerType* animationController = mAnimations[animationState];
           /* don't need to do this as SharePtr uses reference counting
           Ogre::SharedPtr< ControllerFunction<Ogre::Real> > controllerFunctionPtr = (  animationController->getFunction(   ) );
           delete *controllerFunctionPtr;
           */
          
          /* mAnimations.erase(  I->first );
          
           animationControllerType* controllerFunction = I->second;
           if (  controllerFunction )
           {
           }
           Ogre::ControllerManager::getSingleton(   ).destroyController(  controllerFunction );
           std::cout << "removed controller\n";
           */
          // Ogre::ControllerManager::getSingleton(   ).destroyController(  I->second );
          
           }
           mInfo.Animations = mAnimations.size(   );
          
          }
          
     182  void MotionManager::pauseAnimation(  Ogre::AnimationState* animationState )
          {
           animationState->setEnabled(  false );
          /*
           animationControllerType* animationController = mAnimations[animationState];
           animationController->setEnabled(  false );
           */
          }
          
     191  void MotionManager::unpauseAnimation(  Ogre::AnimationState* animationState )
          {
           animationState->setEnabled(  true );
          /*
           animationControllerType* animationController = mAnimations[animationState];
           animationController->setEnabled(  true );
           */
          }
          
          
          // void MotionManager::setTerrainGenerator(  TerrainGenerator* generator ) {
          // mTerrainGenerator = generator;
          // }
          
          
          }

./components/ogre/MotionManager.h

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef MOTIONMANAGER_H
          #define MOTIONMANAGER_H
          
          #include "EmberOgrePrerequisites.h"
          #include <OgrePredefinedControllers.h>
          #include "framework/Singleton.h"
          
          namespace EmberOgre {
          
      28  class EmberEntity;
      29  class EmberPhysicalEntity;
          // class TerrainGenerator;
          
          /**
           * This class will be responsible for making sure that entites moves
           * in a nice and fluid way. Eventually we'll also implement physics,   perhaps it
           * will go into here.
           * The manager also takes care of keeping tabs on all animations.
           */
      38  class MotionManager : public Ogre::FrameListener,   public Ember::Singleton<MotionManager> {
          public:
          
           /**
           A struct containing information about the MotionManager.
           */
           struct MotionManagerInfo
           {
           size_t AnimatedEntities;
           size_t MovingEntities;
           size_t Animations;
           };
          
      51   MotionManager(   );
      52   virtual ~MotionManager(   );
           //static MotionManager & getSingleton(  void );
          
           /**
           * Adds a EmberEntity to the movement list.
           * That means that until removeEntity is called for the specific entity
           * new positions for the entity will be calculated for each frame.
           */
      60   void addEntity(  EmberEntity* entity );
      61   void removeEntity(  EmberEntity* entity );
          
           /**
           * Registers an animationState. After registration it will be enough to use
           * AnimationState::enabled(  bool ) to toggle the animation on and off
           */
      67   void addAnimation(  Ogre::AnimationState* animationState );
           /**
           * Deregisters an animationState
           */
      71   void removeAnimation(  Ogre::AnimationState* animationState );
           /**
           * Pauses the supplies animationState
           */
      75   void pauseAnimation(  Ogre::AnimationState* animationState );
           /**
           * Unpauses (  starts ) an already paused animationState
           */
      79   void unpauseAnimation(  Ogre::AnimationState* animationState );
          
      81   void addAnimatedEntity(  EmberPhysicalEntity* entity );
      82   void removeAnimatedEntity(  EmberPhysicalEntity* entity );
          
          /* void addAction(  Action* action );
           void removeAction(  Action* action );*/
          
          
          
           /**
           * Methods from Ogre::FrameListener
           */
      92   bool frameStarted(  const Ogre::FrameEvent& event );
      93   bool frameEnded(  const Ogre::FrameEvent& event );
          
           /**
           * Adjusts the height of the supplied node
           */
           //void adjustHeightPositionForNode(  Ogre::SceneNode* sceneNode );
          
          // void setTerrainGenerator(  TerrainGenerator* generator );
          
           /**
           * Gets info about the MotionManager.
           * @return
           */
     106   inline const MotionManagerInfo& getInfo(   ) const;
          
          private:
          
           typedef std::map<std::string ,   EmberPhysicalEntity*> EntityStore;
     111   EntityStore mAnimatedEntities;
          
          
           MotionManagerInfo mInfo;
          // typedef std::set<Action*> ActionStore;
          // ActionStore mActions;
          
           /**
           * A pointer to the applications ControllerManager. This will take care of
           * keeping tabs on all controllers.
           */
     122   Ogre::ControllerManager* mControllerManager;
           typedef Ogre::Controller<Ogre::Real> animationControllerType;
           typedef std::map<Ogre::AnimationState*,   animationControllerType*> animationStateMap;
           typedef std::set<Ogre::AnimationState*> AnimationStateSet;
           /**
           * A map of AnimationState's and their corresponding Controllers
           */
     129   AnimationStateSet mAnimations;
          
          
           //static MotionManager* _instance;
          
           /** This method will iterate over all registered moving entities and update
           * their positions.
           */
     137   void doMotionUpdate(  Ogre::Real timeSlice );
          
           /** This method will iterate over all registered animationStates and update
           * those that are enabled
           */
     142   void doAnimationUpdate(  Ogre::Real timeSlice );
          
          
           /**
           * Update the motion for a single EmberEntity
           */
     148   void updateMotionForEntity(  EmberEntity* entity,   Ogre::Real timeSlice );
          
           /**
           * This contains all of the entities that will be moved each frame
           */
     153   std::set<EmberEntity*> mMotionSet;
          
          // TerrainGenerator* mTerrainGenerator;
          
          };
          
     159  const MotionManager::MotionManagerInfo& MotionManager::getInfo(   ) const
          {
           return mInfo;
          }
          
          
          }
          
          
          #endif // MOTIONMANAGER_H

./components/ogre/MousePicker.cpp

       1  //
          // C++ Implementation: MousePicker
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2004
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #include "EmberEntity.h"
          #include "EmberOgre.h"
          //#include "EmberPhysicalEntity.h"
          //#include "PersonEmberEntity.h"
          //#include "AvatarEmberEntity.h"
          #include "AvatarCamera.h"
          #include "GUIManager.h"
          //#include "AvatarController.h"
          
          #include "MousePicker.h"
          
          namespace EmberOgre {
          
      37  MousePicker::MousePicker(   )
          {
          }
          
          
      42  MousePicker::~MousePicker(   )
          {
          }
          
      46  void MousePicker::doMousePicking(  const Ogre::Real x,   const Ogre::Real y,  const MousePickerArgs& args )
          {
           AvatarCamera* camera = EmberOgre::getSingleton(   ).getMainCamera(   );
          
          
           camera->pickInWorld(  x,   y,   args );
          /* if (  result.entity ) {
           mLastPickedEntityResult = result;
           onEventPickedEntity(  mLastPickedEntityResult,   args );
           } else {
           onEventPickedNothing(  args );
           }*/
          
          }
          
          
          
          // void MousePicker::onEventPickedEntity(  const EntityPickResult & result,   const MousePickerArgs& args )
          // {
          // EventPickedEntity.emit(  result,   args );
          // }
          //
          // void MousePicker::onEventPickedNothing(  const MousePickerArgs& args )
          // {
          // EventPickedNothing.emit(  args );
          // }
          
          
          
          };

./components/ogre/MousePicker.h

       1  //
          // C++ Interface: MousePicker
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2004
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef DIMEOGREMOUSEPICKER_H
          #define DIMEOGREMOUSEPICKER_H
          
          #include <sigc++/signal.h>
          
          
          #include "IWorldPickListener.h"
          #include "EmberOgrePrerequisites.h"
          
          namespace EmberOgre {
          
          
          /**
          Class used for picking stuff in the world.
          Since we sometimes want different picking behaviour (  sometimes we want to pick building blocks,   sometimes we want to pick entities ) it's possible to create derived classes and register them with the GUIManager.
          
          @author Erik Hjortsberg
          */
      41  class MousePicker
          {
          public:
           enum ClickMasks
           {
           CM_AVATAR = 1<<9,  
           CM_ENTITY = 1<<10,  
           CM_NATURE = 1<<11,  
           CM_UNDEFINED = 1<<12,  
           CM_NONPICKABLE = 1<<13
           };
          
      53   MousePicker(   );
          
      55   virtual ~MousePicker(   );
          
           /**
           * Try to pick something at the specified coordinates
           * @param x
           * @param y
           * @param args
           */
      63   virtual void doMousePicking(  const Ogre::Real x,   const Ogre::Real y,   const MousePickerArgs& args );
          
          
          
          // sigc::signal<void,   const MousePickerArgs&> EventPickedNothing;
          
          // inline EmberEntity* getLastPickedEntity(   ) { return mLastPickedEntityResult.entity; }
          
          
          protected:
          
          // virtual void onEventPickedEntity(  const EntityPickResult & result,   const MousePickerArgs& args );
          // virtual void onEventPickedNothing(  const MousePickerArgs& args );
          
          
          
          
           //the currently selected entity
          // EmberEntity* mEntityUnderCursor;
          
           //the last clicked entity
          // EntityPickResult mLastPickedEntityResult;
          };
          
          }
          
          #endif

./components/ogre/OgreIncludes.h

       1  //
          // C++ Interface: OgreIncludes
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          //base include files needed for Ogre
          
          
          //we don't want to use the ogre memory manager,   since it messes with Atlas in debug mode,   so we'll simply define __MemoryManager_H__ here so that the OgreMemoryMacros.h never will be parsed
          
          //however,   we'll put this in config.h for now instead
          
          // #ifndef __MemoryManager_H__
          // #define __MemoryManager_H__
          // #endif
          
          // #define OGRE_MEMORY_MACROS
          // #include <OgreMemoryMacros.h>
          // #include <OgreNoMemoryMacros.h>
          //#include <OgreNoMemoryMacros.h>
          #include <Ogre.h>

./components/ogre/OgreInfo.cpp

       1  //
          // C++ Implementation: OgreInfo
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "OgreInfo.h"
          
          #ifdef WIN32
          #else
           #include <GL/gl.h>
          #endif
          
          
          namespace EmberOgre {
          
      33  OgreInfo::OgreInfo(   )
          {
          }
          
          
      38  OgreInfo::~OgreInfo(   )
          {
          }
          
          
      43  bool OgreInfo::isIndirect(   ) const
          {
          #ifdef WIN32
           ///TODO: add checks for win32 too
           return false;
          #else
           const GLubyte* pcRenderer = glGetString(  GL_RENDERER );
           const std::string renderer(  (  const char* )pcRenderer );
          
           return renderer.find(  "Indirect" ) != std::string::npos;
          #endif
          
          }
          
          
          }

./components/ogre/OgreInfo.h

       1  //
          // C++ Interface: OgreInfo
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREOGREINFO_H
          #define EMBEROGREOGREINFO_H
          
          #include "EmberOgrePrerequisites.h"
          
          namespace EmberOgre {
          
          /**
          
           Provides methods for getting some basic information about the Ogre environment.
          
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
      36  class OgreInfo{
          public:
      38   OgreInfo(   );
          
      40   ~OgreInfo(   );
          
          
           /**
           * True if the rendering is indirect,   for example when using Mesa drivers on Linux. This will result in _very_ bad performance,   and is usually caused by the user not having vendor drivers installed.
           * @return
           */
      47   bool isIndirect(   ) const;
          
          };
          
          }
          
          #endif

./components/ogre/OgreLogObserver.cpp

       1  //
          // C++ Implementation: OgreLogObserver
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "OgreLogObserver.h"
          
          #include "services/EmberServices.h"
          #include "services/logging/LoggingService.h"
          
          
          using namespace Ogre;
          namespace EmberOgre {
          
          
          
      34  OgreLogObserver::OgreLogObserver(   )
          {
          }
          
      38  OgreLogObserver::~OgreLogObserver(   )
          {
          
          }
          
          
          
      45  void OgreLogObserver::messageLogged(   const String& message,   LogMessageLevel lml,   bool maskDebug,   const String &logName  )
          {
           static std::string ogre(  "(  Ogre ) " );
           switch (  lml ) {
           case Ogre::LML_TRIVIAL:
           Ember::EmberServices::getSingletonPtr(   )->getLoggingService(   )->log(  "Ogre",   Ember::LoggingService::VERBOSE,   (  ogre + message ).c_str(   ) );
           break;
           case Ogre::LML_NORMAL:
           Ember::EmberServices::getSingletonPtr(   )->getLoggingService(   )->log(  "Ogre",   Ember::LoggingService::INFO,   (  ogre + message ).c_str(   ) );
           break;
           case Ogre::LML_CRITICAL:
           Ember::EmberServices::getSingletonPtr(   )->getLoggingService(   )->log(  "Ogre",   Ember::LoggingService::FAILURE,   (  ogre + message ).c_str(   ) );
           break;
           }
          }
          
          
          
          
          }

./components/ogre/OgreLogObserver.h

       1  //
          // C++ Interface: OgreLogObserver
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREOGRELOGOBSERVER_H
          #define EMBEROGREOGRELOGOBSERVER_H
          
          #include "EmberOgrePrerequisites.h"
          #include "framework/StreamLogObserver.h"
          
          namespace EmberOgre {
          
          /**
          @author Erik Hjortsberg
          A log observer which writes to the Ogre log system.
          This is a combined Ogre::LogListener and a Ember::StreamLogObserver.
          The Ember::StreamLogObserver part does the main work,   while the Ogre::LogListener implementation allow us to recieve ogre log events.
          */
      37  class OgreLogObserver: public Ogre::LogListener
          {
           public:
           /**
           * Creates a new OgreLogObserver using default values.
           */
      43   OgreLogObserver(   );
      44   ~OgreLogObserver(   );
      45   virtual void messageLogged(   const Ogre::String& message,   Ogre::LogMessageLevel lml,   bool maskDebug,   const Ogre::String &logName  );
          
           protected:
          
          
          
          };
          
          }
          
          #endif

./components/ogre/OgreResourceLoader.cpp

       1  //
          // C++ Implementation: OgreResourceLoader
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "OgreResourceLoader.h"
          #include "services/EmberServices.h"
          #include "services/logging/LoggingService.h"
          #include "services/server/ServerService.h"
          #include "services/config/ConfigService.h"
          #include "model/ModelDefinitionManager.h"
          
          #include "framework/osdir.h"
          #include <fstream>
          
          namespace EmberOgre {
          
      35  OgreResourceLoader::OgreResourceLoader(   ) : mLoadRecursive(  false )
          {
          }
          
          
      40  OgreResourceLoader::~OgreResourceLoader(   )
          {
          }
          
      44  void OgreResourceLoader::initialize(   )
          {
           Ember::ConfigService* configSrv = Ember::EmberServices::getSingletonPtr(   )->getConfigService(   );
          
           ///check from the config if we should load media recursively
           ///this is needed for most authoring,   since it allows us to find all meshes before they are loaded
           if (  configSrv->itemExists(  "media",   "loadmediarecursive" ) ) {
           mLoadRecursive = (  bool )configSrv->getValue(  "media",   "loadmediarecursive" );
           }
          
          // chdir(  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getHomeDirectory(   ).c_str(   ) );
           ///load the resource file
           const std::string configPath(  Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getSharedConfigDirectory(   ) + "/resources.cfg" );
           S_LOG_VERBOSE(  "Loading resources definitions from " << configPath );
           mConfigFile.load(  configPath );
          
          }
          
      62  unsigned int OgreResourceLoader::numberOfSections(   )
          {
           unsigned int numberOfSections = 0;
           Ogre::ConfigFile::SectionIterator I = mConfigFile.getSectionIterator(   );
           while (  I.hasMoreElements(   ) ) {
           numberOfSections++;
           I.moveNext(   );
           }
           return numberOfSections - 1;
          }
          
          
      74  bool OgreResourceLoader::addSharedMedia(  const std::string& path,   const std::string& type,   const std::string& section,   bool recursive )
          {
           static const std::string& sharedMediaPath = Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getSharedMediaDirectory(   );
          
           bool foundDir = false;
          
           S_LOG_INFO(  "Looking for " << sharedMediaPath + path );
           if (  isExistingDir(  sharedMediaPath + path ) ) {
           S_LOG_INFO(  "Adding dir " << sharedMediaPath + path );
           try {
           Ogre::ResourceGroupManager::getSingleton(   ).addResourceLocation(  
           sharedMediaPath + path,   type,   section,   recursive );
           foundDir = true;
           } catch (  const Ogre::Exception& ex ) {
           const std::string& message = ex.getFullDescription(   );
           S_LOG_FAILURE(  "Couldn't load " + sharedMediaPath + path + ". Error: "<< message );
           }
           }
          
           return foundDir;
          }
          
      96  bool OgreResourceLoader::addUserMedia(  const std::string& path,   const std::string& type,   const std::string& section,   bool recursive )
          {
           static const std::string& userMediaPath = Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getUserMediaDirectory(   );
           static const std::string& emberMediaPath = Ember::EmberServices::getSingletonPtr(   )->getConfigService(   )->getEmberMediaDirectory(   );
          
           bool foundDir = false;
          
           S_LOG_VERBOSE(  "Looking for " << userMediaPath + path );
           if (  isExistingDir(  userMediaPath + path ) ) {
           S_LOG_VERBOSE(  "Adding dir " << userMediaPath + path );
           try {
           Ogre::ResourceGroupManager::getSingleton(   ).addResourceLocation(  
           userMediaPath + path,   type,   section,   recursive );
           foundDir = true;
           } catch (  const Ogre::Exception& ) {
           ///don't report anything
           }
           }
          
           ///try with ember-media
           S_LOG_VERBOSE(  "Looking for " << emberMediaPath + path );
           if (  isExistingDir(  emberMediaPath + path ) ) {
           S_LOG_VERBOSE(  "Adding dir " << emberMediaPath + path );
           try {
           Ogre::ResourceGroupManager::getSingleton(   ).addResourceLocation(  
           emberMediaPath + path,   type,   section,   recursive );
           foundDir = true;
           } catch (  const Ogre::Exception& ) {
           S_LOG_FAILURE(  "Couldn't load " + emberMediaPath + path + ". Continuing as if nothing happened." );
           }
           }
           return foundDir;
          }
          
          
     131  void OgreResourceLoader::loadBootstrap(   )
          {
           loadSection(  "Bootstrap" );
          }
          
     136  void OgreResourceLoader::loadGui(   )
          {
           loadSection(  "Gui" );
          }
          
     141  void OgreResourceLoader::loadGeneral(   )
          {
           loadSection(  "General" );
           loadSection(  "ModelDefinitions" );
          
          
           loadAllUnloadedSections(   );
          
           ///out of pure interest we'll print out how many modeldefinitions we've loaded
           Ogre::ResourceManager::ResourceMapIterator I = Model::ModelDefinitionManager::getSingleton(   ).getResourceIterator(   );
           int count = 0;
           while (  I.hasMoreElements(   ) ) {
           ++count;
           I.moveNext(   );
           }
          
           S_LOG_INFO(  "Finished loading " << count << " modeldefinitions." );
          }
          
     160  void OgreResourceLoader::preloadMedia(   )
          {
           try {
           Ogre::ResourceGroupManager::getSingleton(   ).loadResourceGroup(  "General" );
           } catch (  const Ogre::Exception& ex ) {
           S_LOG_FAILURE(  "An error occurred when preloading media. Message:\n\t"<< ex.getFullDescription(   ) );
           }
           try {
           Ogre::ResourceGroupManager::getSingleton(   ).loadResourceGroup(  "Gui" );
           } catch (  const Ogre::Exception& ex ) {
           S_LOG_FAILURE(  "An error occurred when preloading media. Message:\n\t"<< ex.getFullDescription(   ) );
           }
           try {
           Ogre::ResourceGroupManager::getSingleton(   ).loadResourceGroup(  "ModelDefinitions" );
           } catch (  const Ogre::Exception& ex ) {
           S_LOG_FAILURE(  "An error occurred when preloading media. Message:\n\t"<< ex.getFullDescription(   ) );
           }
          
          
          // Ember::ConfigService* configSrv = Ember::EmberServices::getSingletonPtr(   )->getConfigService(   );
          //
          //
          // std::vector<std::string> shaderTextures;
          //
          // shaderTextures.push_back(  std::string(  configSrv->getValue(  "shadertextures",   "rock" ) ) );
          // shaderTextures.push_back(  std::string(  configSrv->getValue(  "shadertextures",   "sand" ) ) );
          // shaderTextures.push_back(  std::string(  configSrv->getValue(  "shadertextures",   "grass" ) ) );
          //
          // for (  std::vector<std::string>::iterator I = shaderTextures.begin(   ); I != shaderTextures.end(   ); ++I ) {
          // try {
          // Ogre::TextureManager::getSingleton(   ).load(  *I,   "General" );
          // } catch (  const Ogre::Exception& e ) {
          // S_LOG_FAILURE(   "Error when loading texture " << *I  )
          // }
          // }
          }
          
     197  void OgreResourceLoader::loadSection(  const std::string& sectionName )
          {
           if (  sectionName != "" && std::find(  mLoadedSections.begin(   ),   mLoadedSections.end(   ),   sectionName ) == mLoadedSections.end(   ) )
           {
           bool mediaAdded = false;
          
           S_LOG_VERBOSE(  "Adding resource section " << sectionName );
           // Ogre::ResourceGroupManager::getSingleton(   ).createResourceGroup(  sectionName );
          
           Ogre::ConfigFile::SettingsIterator I = mConfigFile.getSettingsIterator(  sectionName );
           std::string finalTypename;
           while (  I.hasMoreElements(   ) ) {
           //Ogre::ConfigFile::SettingsMultiMap J = I.getNext(   );
           const std::string& typeName = I.peekNextKey(   );
           const std::string& archName = I.peekNextValue(   );
          
           finalTypename = typeName.substr(  0,   typeName.find(  "[" ) );
           if (  Ogre::StringUtil::endsWith(  typeName,   "[shared]" ) ) {
           mediaAdded |= addSharedMedia(  archName,   finalTypename,   sectionName,   mLoadRecursive );
           } else {
           mediaAdded |= addUserMedia(  archName,   finalTypename,   sectionName,   mLoadRecursive );
           }
           I.moveNext(   );
           }
           mLoadedSections.push_back(  sectionName );
          
           ///only initialize the resource group if it has media
           if (  mediaAdded ) {
           try {
           Ogre::ResourceGroupManager::getSingleton(   ).initialiseResourceGroup(  sectionName );
           } catch (  const Ogre::Exception& ex ) {
           S_LOG_FAILURE(  "An error occurred when loading media from section '" << sectionName << "'. Message:\n\t"<< ex.getFullDescription(   ) );
           } catch (  const std::exception& ex ) {
           S_LOG_FAILURE(  "An error occurred when loading media from section '" << sectionName << "'. Message:\n\t"<< ex.what(   ) );
           } catch (  ... ) {
           S_LOG_FAILURE(  "An unknown error occurred when loading media from section '" << sectionName << "'." );
           }
           }
           }
          }
          
     238  void OgreResourceLoader::loadAllUnloadedSections(   )
          {
           S_LOG_VERBOSE(  "Now loading all unloaded sections." );
           Ogre::ConfigFile::SectionIterator I = mConfigFile.getSectionIterator(   );
           while (  I.hasMoreElements(   ) ) {
           const std::string& sectionName = I.peekNextKey(   );
           loadSection(  sectionName );
           I.moveNext(   );
           }
          
          }
          
          
     251  bool OgreResourceLoader::isExistingDir(  const std::string& path ) const
          {
           bool exists = false;
           oslink::directory osdir(  path );
           exists = osdir.isExisting(   );
           if (  !exists ) {
           ///perhaps it's a file?
           std::ifstream fin(  path.c_str(   ) ,   std::ios::in  );
           exists = !fin.fail(   );
           }
           return exists;
          }
          
          
          }

./components/ogre/OgreResourceLoader.h

       1  //
          // C++ Interface: OgreResourceLoader
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREOGRERESOURCELOADER_H
          #define EMBEROGREOGRERESOURCELOADER_H
          
          #include "EmberOgrePrerequisites.h"
          
          namespace EmberOgre {
          
          /**
          @author Erik Hjortsberg
          */
      33  class OgreResourceLoader{
          public:
      35   OgreResourceLoader(   );
          
      37   ~OgreResourceLoader(   );
          
      39   void initialize(   );
          
      41   void loadBootstrap(   );
      42   void loadGui(   );
      43   void loadGeneral(   );
          
      45   void preloadMedia(   );
          
      47   unsigned int numberOfSections(   );
          
          protected:
      50   bool mLoadRecursive;
      51   Ogre::ConfigFile mConfigFile;
          
      53   void loadSection(  const std::string& sectionName );
          
      55   bool addUserMedia(  const std::string& path,   const std::string& type,   const std::string& section,   bool recursive );
      56   bool addSharedMedia(  const std::string& path,   const std::string& type,   const std::string& section,   bool recursive );
          
      58   bool isExistingDir(  const std::string& path ) const;
          
      60   void loadAllUnloadedSections(   );
          
      62   std::vector<std::string> mLoadedSections;
          };
          
          }
          
          #endif

./components/ogre/OgreResourceProvider.cpp

       1  //
          // C++ Implementation: OgreResourceProvider
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "OgreResourceProvider.h"
          #include "framework/Exception.h"
          
          namespace EmberOgre {
          
      28  OgreResourceWrapper::OgreResourceWrapper(  Ogre::DataStreamPtr dataStream )
          {
           mSize = dataStream->size(   );
           mBuffer = new char[mSize];
           dataStream->read(  mBuffer,   mSize );
          }
          
      35  OgreResourceWrapper::~OgreResourceWrapper(   )
          {
           delete[] mBuffer;
          }
          
      40  char* OgreResourceWrapper::getDataPtr(   )
          {
           return mBuffer;
          }
          
      45  bool OgreResourceWrapper::hasData(   )
          {
           return mSize != 0;
          }
          
      50  size_t OgreResourceWrapper::getSize(   )
          {
           return mSize;
          }
          
          
          
      57  OgreResourceProvider::OgreResourceProvider(  const std::string& groupName )
          : mGroupName(  groupName )
          {
          }
          
          
      63  OgreResourceProvider::~OgreResourceProvider(   )
          {
          }
          
      67  Ember::ResourceWrapper OgreResourceProvider::getResource(  const std::string& name )
          {
           Ogre::DataStreamPtr input =
           Ogre::ResourceGroupManager::getSingleton(   ).openResource(  name.c_str(   ),   mGroupName.c_str(   ) );
          
           if (  input.isNull(   ) )
           {
           throw Ember::Exception(  "Unable to open resource file '" + name + "' in resource group '" + name + "'." );
           }
           OgreResourceWrapper* wrapper = new OgreResourceWrapper(  input );
           input->close(   );
           return Ember::ResourceWrapper(  wrapper,   name );
          
          // Ogre::String buf = input->getAsString(   );
          // const size_t memBuffSize = buf.length(   );
          //
          // unsigned char* mem = new unsigned char[memBuffSize];
          // memcpy(  mem,   buf.c_str(   ),   memBuffSize );
          //
          // output.setData(  mem );
          // output.setSize(  memBuffSize );
          }
          
          
          
          
          }

./components/ogre/OgreResourceProvider.h

       1  //
          // C++ Interface: OgreResourceProvider
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREOGRERESOURCEPROVIDER_H
          #define EMBEROGREOGRERESOURCEPROVIDER_H
          
          #include "framework/IScriptingProvider.h"
          #include <Ogre.h>
          
          namespace EmberOgre {
          
          
      32  class OgreResourceWrapper : public Ember::IResourceWrapper
          {
          public:
      35   OgreResourceWrapper(  Ogre::DataStreamPtr dataStream );
      36   virtual ~OgreResourceWrapper(   );
          
      38   virtual char* getDataPtr(   );
      39   virtual bool hasData(   );
      40   virtual size_t getSize(   );
          private:
           char* mBuffer;
      43   size_t mSize;
          };
          
          
          /**
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
      50  class OgreResourceProvider : public Ember::IResourceProvider
          {
          public:
      53   OgreResourceProvider(  const std::string& groupName );
          
      55   virtual ~OgreResourceProvider(   );
          
      57   virtual Ember::ResourceWrapper getResource(  const std::string& name );
          private:
      59   std::string mGroupName;
          
          };
          
          }
          
          #endif

./components/ogre/OgreSetup.cpp

       1  //
          // C++ Implementation: OgreSetup
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          
          #ifdef HAVE_CONFIG_H
          #include "config.h"
          #endif
          
          #include "OgreSetup.h"
          
          #include "services/EmberServices.h"
          #include "services/config/ConfigService.h"
          
          #ifdef WIN32
           #include <SDL.h>
           #include <SDL_syswm.h>
          #else
           #include <SDL/SDL.h>
           #include <SDL/SDL_syswm.h>
           #include "framework/binreloc.h"
           #include <GL/glx.h>
          #endif
          #include "SceneManagers/EmberPagingSceneManager/include/EmberPagingSceneManager.h"
          // #include "image/OgreILCodecs.h"
          #include "framework/Tokeniser.h"
          
          extern "C" {
          #include <signal.h> /* signal name macros,   and the signal(   ) prototype */
          }
          
          namespace EmberOgre {
          
          
          
      55  OgreSetup::OgreSetup(   )
          {
          }
          
          
      60  OgreSetup::~OgreSetup(   )
          {
          }
          
      64  void OgreSetup::shutdown(   )
          {
          // Ogre::ILCodecs::deleteCodecs(   );
           delete mRoot;
           mRoot = 0;
           SDL_Quit(   );
          }
          
          
      73  Ogre::Root* OgreSetup::createOgreSystem(   )
          {
          
          // const std::string& sharePath(  Ember::EmberServices::getSingleton(   ).getConfigService(   )->getSharedConfigDirectory(   ) );
           std::string pluginExtension = ".so";
           mRoot = new Ogre::Root(  "",   "ogre.cfg",   "" );
          
           ///we will try to load the plugins from series of different location,   with the hope of getting at least one right
           std::vector<std::string> pluginLocations;
          
           Ember::ConfigService* configSrv = Ember::EmberServices::getSingleton(   ).getConfigService(   );
           if (  configSrv->itemExists(  "ogre",   "plugins" ) ) {
           std::string plugins(  configSrv->getValue(  "ogre",   "plugins" ) );
           ///if it's defined in the config,   use that location first
           if (  configSrv->itemExists(  "ogre",   "plugindir" ) ) {
           std::string pluginDir(  configSrv->getValue(  "ogre",   "plugindir" ) );
           pluginLocations.push_back(  pluginDir );
           }
           #ifdef __WIN32__
           pluginExtension = ".dll";
           #else
           pluginExtension = ".so";
          
           #ifdef ENABLE_BINRELOC
           ///binreloc might be used
           char* br_libdir = br_find_lib_dir(  br_strcat(  PREFIX,   "/lib" ) );
           std::string libDir(  br_libdir );
           free(  br_libdir );
           pluginLocations.push_back(  libDir + "/ember/OGRE" );
           #endif
           #ifdef OGRE_PLUGINDIR
           ///also try with the plugindir defined for Ogre
           pluginLocations.push_back(  OGRE_PLUGINDIR );
           #endif
           ///enter the usual locations if Ogre is installed system wide,   with local installations taking precedence
           pluginLocations.push_back(  "/usr/local/lib/OGRE" );
           pluginLocations.push_back(  "/usr/lib/OGRE" );
           #endif
           Ember::Tokeniser tokeniser(  plugins,   ",  " );
           std::string token = tokeniser.nextToken(   );
           while (  token != "" ) {
           for (  std::vector<std::string>::iterator I = pluginLocations.begin(   ); I != pluginLocations.end(   ); ++I ) {
           std::string pluginPath(  (  *I ) + "/" + token + pluginExtension );
           bool success = false;
           try {
           S_LOG_INFO(  "Trying to load the plugin " << pluginPath );
           mRoot->loadPlugin(  pluginPath );
           success = true;
           break;
           } catch (  ... ) {
           S_LOG_INFO(  "Error when loading plugin '" << token << "' with path '" << pluginPath << "'. This is not fatal,   we will continue trying with some other paths." );
           }
           if (  !success ) {
           S_LOG_WARNING(  "Error when loading plugin '" << token << "' after trying different parts. We'll continue,   but there might be problems later on." );
           }
           }
           token = tokeniser.nextToken(   );
           }
           }
          
          // std::vector<Ogre::String> tokens = Ogre::StringUtil::split(  dsp,   "." );
           Ember::Tokeniser tokeniser(   );
          
           // Register image codecs
          // Ogre::ILCodecs::registerCodecs(   );
          
           return mRoot;
          }
          
          /**
          Shut down SDL correctly,   else if run in full screen the display might be messed up.
          */
     145  extern "C" void shutdownHandler(  int signal )
          {
           std::cerr << "Crashed with signal " << signal << ",   will try to shut down SDL gracefully. Please report bugs at https://bugs.launchpad.net/ember" << std::endl;
           SDL_Quit(   );
           exit(  signal );
          }
          
          
          /** Configures the application - returns false if the user chooses to abandon configuration. */
     154  bool OgreSetup::configure(  void )
          {
           bool suppressConfig = false;
           bool success = false;
           if (  Ember::EmberServices::getSingleton(   ).getConfigService(   )->itemExists(  "ogre",   "suppressconfigdialog" ) ) {
           suppressConfig = static_cast<bool>(  Ember::EmberServices::getSingleton(   ).getConfigService(   )->getValue(  "ogre",   "suppressconfigdialog" ) );
           }
           if (  suppressConfig ) {
           success = mRoot->restoreConfig(   );
           } else {
           success = mRoot->showConfigDialog(   );
           }
          
           if(  success )
           {
          #if __WIN32__
           ///this will only apply on DirectX
           ///it will force DirectX _not_ to set the FPU to single precision mode (  since this will mess with mercator amongst others )
           try {
           mRoot->getRenderSystem(   )->setConfigOption(  "Floating-point mode",   "Consistent" );
          
           } catch (  const Ogre::Exception& )
           {
           ///we don't know what kind of render system is used,   so we'll just swallow the error since it doesn't affect anything else than DirectX
           }
          
          
           mRenderWindow = mRoot->initialise(  true,   "Ember" );
          
           ///do some FPU fiddling,   since we need the correct settings for stuff like mercator (  which uses fractals etc. ) to work
           _fpreset(   );
           _controlfp(  _PC_64,   _MCW_PC );
           _controlfp(  _RC_NEAR ,   _MCW_RC );
          
           // Allow SDL to use the window Ogre just created
          
           // Old method: do not use this,   because it only works
           // when there is 1 (  one ) window with this name!
           // HWND hWnd = FindWindow(  tmp,   0 );
          
           // New method: As proposed by Sinbad.
           // This method always works.
           HWND hWnd;
           mRenderWindow->getCustomAttribute(  "WINDOW",   &hWnd );
          
           char tmp[64];
           // Set the SDL_WINDOWID environment variable
           sprintf(  tmp,   "SDL_WINDOWID=%d",   hWnd );
           putenv(  tmp );
          
           if (  SDL_Init(  SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 )
           {
           S_LOG_FAILURE(  "Couldn't initialize SDL:\n\t\t" );
           S_LOG_FAILURE(  SDL_GetError(   ) );
           }
          
           // if width = 0 and height = 0,   the window is fullscreen
          
           // This is necessary to allow the window to move1
           // on WIN32 systems. Without this,   the window resets
           // to the smallest possible size after moving.
           SDL_SetVideoMode(  mRenderWindow->getWidth(   ),   mRenderWindow->getHeight(   ),   0,   0 ); // first 0: BitPerPixel,  
           // second 0: flags (  fullscreen/... )
           // neither are needed as Ogre sets these
          
           static SDL_SysWMinfo pInfo;
           SDL_VERSION(  &pInfo.version );
           SDL_GetWMInfo(  &pInfo );
          
           // Also,   SDL keeps an internal record of the window size
           // and position. Because SDL does not own the window,   it
           // missed the WM_POSCHANGED message and has no record of
           // either size or position. It defaults to {0,   0,   0,   0},  
           // which is then used to trap the mouse "inside the
           // window". We have to fake a window-move to allow SDL
           // to catch up,   after which we can safely grab input.
           RECT r;
           GetWindowRect(  pInfo.window,   &r );
           SetWindowPos(  pInfo.window,   0,   r.left,   r.top,   0,   0,   SWP_NOMOVE | SWP_NOSIZE );
          
           ///do some FPU fiddling,   since we need the correct settings for stuff like mercator (  which uses fractals etc. ) to work
           _fpreset(   );
           _controlfp(  _PC_64,   _MCW_PC );
           _controlfp(  _RC_NEAR ,   _MCW_RC );
          #else
          
           ///On *NIX,   Ogre can have either a SDL or an GLX backend (  or "platform",   it's selected at compile time by the --with-platform=[GLX|SDL] option ). Ogre 1.2+ uses GLX by default.
           ///However,   we use SDL for our input systems. If the SDL backend then is used,   everything is already set up for us.
           ///If on the other hand the GLX backend is used,   we need to do some fiddling to get SDL to play nice with the GLX render system.
          
           ///Check if SDL already has been initalized. If it has,   we know that Ogre uses the SDL backend (  the call to SDL_Init happens at mRoot->restoreConfig(   ) )
           if(  SDL_WasInit(  SDL_INIT_VIDEO )==0 ) {
           ///SDL hasn't been initilized,   we thus know that we're using the GLX platform,   and need to initialize SDL ourselves
          
           /// we start by trying to figure out what kind of resolution the user has selected,   and whether full screen should be used or not
           unsigned int height = 768,   width = 1024;
           bool fullscreen;
          
           parseWindowGeometry(  mRoot->getRenderSystem(   )->getConfigOptions(   ),   width,   height,   fullscreen );
          
           SDL_Init(  SDL_INIT_VIDEO );
          
          
          
           ///this is a failsafe which guarantees that SDL is correctly shut down (  returning the screen to correct resolution,   releasing mouse etc. ) if there's a crash.
           atexit(  SDL_Quit );
           signal(  SIGSEGV,   shutdownHandler );
           signal(  SIGABRT,   shutdownHandler );
           signal(  SIGBUS,   shutdownHandler );
           signal(  SIGILL,   shutdownHandler );
          
          
           ///set the window size
          // int flags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE | SDL_HWSURFACE;
           int flags = SDL_HWPALETTE | SDL_HWSURFACE;
          
          // SDL_GL_SetAttribute(   SDL_GL_DOUBLEBUFFER,   1  );
           // request good stencil size if 32-bit colour
          /* if (  colourDepth == 32 )
           {
           SDL_GL_SetAttribute(   SDL_GL_STENCIL_SIZE,   8 );
           }*/
          
           if (  fullscreen )
           flags |= SDL_FULLSCREEN;
          
           SDL_SetVideoMode(  width,   height,  0,   flags ); // create an SDL window
          
           SDL_WM_SetCaption(  "Ember",  "ember" );
          
           SDL_SysWMinfo info;
           SDL_VERSION(  &info.version );
          
           SDL_GetWMInfo(  &info );
          
           std::string dsp(  &(  DisplayString(  info.info.x11.display )[1] ) );
           std::vector<Ogre::String> tokens = Ogre::StringUtil::split(  dsp,   "." );
          
           Ogre::NameValuePairList misc;
           std::string s = Ogre::StringConverter::toString(  (  long )info.info.x11.display );
           s += ":" + tokens[1] +":";
           s += ":" + Ogre::StringConverter::toString(  (  long )info.info.x11.window );
           misc["parentWindowHandle"] = s;
          
           //misc["externalGLControl"] = "true";
          
          /* GLXContext glxContext(  glXGetCurrentContext(   ) );
           GLXDrawable glxDrawable(  glXGetCurrentDrawable(   ) );
           std::string glxContextString = Ogre::StringConverter::toString(  (  long )glxContext );
           glxContextString += ":" + Ogre::StringConverter::toString(  (  long )glxDrawable );
           misc["glxcontext"] = glxContextString;*/
          
           /// initialise root,   without creating a window
           mRoot->initialise(  false );
          
           mRenderWindow = mRoot->createRenderWindow(  "MainWindow",   width,   height,   true,   &misc );
          
           ///we need to set the window to be active by ourselves,   since GLX by default sets it to false,   but then activates it upon receiving some X event (  which it will never recieve since we'll use SDL ).
           ///see OgreGLXWindow.cpp
           mRenderWindow->setActive(  true );
           mRenderWindow->setAutoUpdated(  true );
          
           } else {
           mRenderWindow = mRoot->initialise(  true,   "Ember" );
           }
          
          
           ///set the icon of the window
           Uint32 rmask,   gmask,   bmask,   amask;
          
          #if SDL_BYTEORDER == SDL_BIG_ENDIAN
           rmask = 0xff000000;
           gmask = 0x00ff0000;
           bmask = 0x0000ff00;
           amask = 0x000000ff;
          #else
           rmask = 0x000000ff;
           gmask = 0x0000ff00;
           bmask = 0x00ff0000;
           amask = 0xff000000;
          #endif
          
          /**
          An bitmap of the ember icon,   to be used for setting the window icon for SDL.
          */
          static struct {
           unsigned int width;
           unsigned int height;
           unsigned int bytes_per_pixel; /* 3:RGB,   4:RGBA */
           unsigned char pixel_data[64 * 64 * 3 + 1];
          } emberIcon = {
           64,   64,   3,  
           "C+\37B )\36?&\31?'\32C+\36D-\40@(  \34='\33>(  \33C,  \40O8+YC7[F8U>1M6&F.\36E,  "
           "\35M3!R8&Q7&N3#J/\37F,  \35G*\34K.\40Q2$V7*\\<0^=2_>4_?5\\<1R2 )R2(  ]<5hIAjL"
           "BdHA_D;ZB8W@7V?7[F>bOFkYNsaUo^T`OFN>4I8.G5*?,  !7$\31:%\33D-$L2*M3*K1(  J.&N"
           "/(  U7/[<5Z<5R80N5+K1'E-\40B*\37C-\37B.\40@*\35? )\34B,  \37H1$N:-T?4M9+B,  \40"
           "<%\35>'\36C,  \37I2\"O5%R8(  S7(  R6'N3$N1#O3$S5'W8+X8.Y8.W6-T5*O/$B\"\31?\37\27"
           "F&\37Q4+S8/U;3X@7_E=aI@_I@^JB]KBaQHjZQn^UhYO_PFXI?PC8D7+:.!;-\40C2'H4*F1"
           "'A*!:#\32:#\33E,  $Q70X?7\\D<R:0U=3T<1bLCbMC_KBYE;UC8TC7SD9VE;[LCSC:I92E53"
           "G75K95L9/P;/YD9_J@^H=aI>bJ>bG<_D8aD9`C7aC8^@5Z:/Y8/Y:1_?6dF<gJ@dI@`G>^F>"
           "_G?_JAcMDdPGeTKhWNp_Wrd\\l`WeYQaWN]UJZRGZRFe]Qpf[vi`ug^jZQ\\IAP<4M:0J7.I"
           "4,  I4,  ZB7cMAzf[ye[wf\\wf[q`VhZQ[MESF=WI@VIAUHAPD;OA8SF=UG=VG<WH=ZH;fRFhRF"
           "rYLmTGfK>a@2`?0a=/f@1f<,  f=.c:,  ]3$c7+oOByXL{[NyZOwZOoRGt\\SnVL\\D:V@6R<1]"
           "I?saX\210xn\211|rwmaZSFSL@UPD_[Orm_|vi\177uj\202vk\201sj\201pg\200qfyi_h"
           "XNWG=P8-V?4r^UmZOveZxk_tg\\naXXLDI<5F:3J@9KA:MC;E:2L@9SG@PC9A1'Q<0Y?3fH;"
           "nOBrPBrOBnI8zVEuK7uH2wB+wB*u8!\243\32\24\240!\23\235\30\23r@-pI9g?1hB5lH"
           ";}_T\177cXeF:U8*K/#H.\"L5 )XB7`LBTH>D;2=7-<8.=9/EB6HB7KB8UJAbTLqd\\\177rh"
           "\203umzmdpcZF3 )@-$aQJUE=`QHl`Ti\\S_RIF:3;/(  LB;\\TMaZStngNG@D;4G<7>1,  7\"\32"
           "D*\36X:,  mOB{\\OsPArL;qJ7pD/o?'v@%u7\32u0\20\1772\22\262\17\4\260\30\3\200"
           "'\11z/\20s/\23m3\35d.\31d5\40mF4\177cSxYLiL@M0$C'\32;!\26@*!A,  \";*\":,  #<"
           "1(  3+\"/%\34:0&5+$,  $\37 )#\40'\36\32 )\35\25:.%I=6H<4MA8\36\21\15\27\14\12A"
           "857-%8.%K@8PC<:*&'\31\25\33\22\17\34\24\20""61*65-64.'$\37C<53&\40*\32\24"
           "= )\"F1'O5%X;*`?.iA.r@+|G.\205K1\217P2\226O/\226H\"\225?\21\232A\21\316\5"
           "\1\316\14\1\243C\26\240M\"\230B\30\220>\27\206>\34\202H+\204V;\204^G\177"
           "YHxSEkG:Y9+J,  \40P5*H.&@ )\";'!7%\35""4#\33,  \35\27#\27\22!\24\17\30\17\15\25"
           "\20\17\22\14\13\31\17\11+!\31;3+1 )\40*#\33\30\20\16\23\15\12<74+%\40\34\26"
           "\21\34\23\20(  \33\30""6%\".\36\33*\37\34""92,  _\\SLLBGF<DB63 )\37C3*ZB:sZR\220"
           "~uiJ:iC/nB-wE0\206Q:\233fL\243eF\242Q,  \250M\36\251C\17\261G\17\276=\21\351"
           "%\5\3475\10\301G$\260`9\255fC\237U3\220G&\206D&\210Q9\204S>\200UBvL;]3!X"
           "2#]=0eF:X:/U<3R;5S>7J73@/*T>9N:4<+#.\40\31!\31\23%\37\33(  $!-(  %\33\27\24\17"
           "\14\12\"\35\30\35\27\22C>972. )$\40,  %#4+(  5-+60-72/KFBRMH@93<5-:0'8'\34<'\35"
           "I1%I*\33T0\37U+\30i8!{F.\212V=\236iO\251lN\246Z4\245H\27\262O\31\276T\35"
           "\305R\31\3378\24\376O\0\376m\0\355=\"\332\205Y\323\203]\302lB\263_:\245X"
           "5\226N.\213L.\211ZB\204[FpI5c= )eA1`@0O1!G,  !J1 )='\40""0\37\31""6\"\34B+$D"
           ",  &;'!/\37\27,  #\36.'#1+(  /,  *\31\27\25\15\13\10\10\4\3\13\10\10""6/-6/,  FA<]"
           "WQ]VRQLIMKFIFBNGBJ?:?/ )A/(  I1(  M2%V</P6%cD/fA )l@%uC(  \212W9\222Y:\234Z7\240"
           "P'\245H\30\262M\27\277U\35\314b+\325g/\354?\37\376_\0\376\261\0\376\5\0\342"
           "s5\331n5\322p>\317\200Z\304zR\271rK\255kD\244kL\250\200j\240ze\205_G\204"
           "cNyXCkL7oTEs^PcPEWG<UD;L;0R@3O=1K;3XJA^QHvh`}tl^VN>7/2. )-*&D?<@:5TNIVOI0"
           "(  #'\40\32;/&WI=bN@P9+O6(  Q6&Q5'U?3fQC\\D4t[IoK4{O6\214_F\217Y=\244mO\244^"
           ";\256^7\270_4\306g8\323uD\334vC\346\200L\364=\40\376k\0\376\326\0\376D\0"
           "\364E\40\346s9\336uB\320f2\313sG\301qC\262c9\247a@\225R4\214P5\204Q6\200"
           "S:jA*^:#G*\30C.\37G8*H?5JF=<8-A=.C?/A;1LF=G?7WNFhaXQLBFA8841 )%!:53=74^XT"
           "mfaQIC<2+A4 )WF8U<*U: )W:*]>._@1cJ>ycWhQAfJ9nG3tB )\217[>\214K )\236X5\245Q )"
           "\264Z.\307nB\323wI\333q>\345r;\357s3\3720\22\376y\0\376\326\0\376\263\0\376"
           "\22\0\365o<\353{E\341zH\325qA\306b,  \277k=\261gB\252nP\225Y:\234lO\225jL\200"
           "U9mC+a<%cC0`E5WA3RA6YL>J?1RG7WK>RE9UIAZOG^TM>4-2+$\37\34\30\34\31\25=:65"
           "2/D?;UOIXQKXNFXNCVH;XE6R9,  S;/gK?^D7[C6aI:pVF\225\200p\207cN\217_F\217S3\232"
           "V3\253a=\270f=\301a2\321n?\332m7\344p8\360v:\365u7\3720\23\376z\0\376\326"
           "\0\376\326\0\376y\0\3726\32\365z=\356\203R\344\204W\326r=\310h5\267d:\254"
           "fC\225Q-\220X6\211V8\206X:yL0rJ7dA1X9+P7+S?6mYL_K=UC5M:1_MCTD;]PGcYQG<49"
           "/'\22\16\14\22\16\13=9640-1,  '60*80+7/ )1,  '80 )NA6N;2P=5ZE:^E:cH:iN@oO>wR=\177"
           "M4\211N0\234[;\264tU\271jE\276^0\316g6\332k7\347vA\363\203P\365~F\364w<\371"
           "@\36\376c\0\376\326\0\376\326\0\376\320\0\3767\0\370I!\365z?\355w@\341t="
           "\321g1\300^0\263\\4\240Q+\230R+\227\\;\226fF\213_AxR9{]IxdTeUHK;0]J<gUEe"
           "SFaPDZJ?RB:^QHl_XSF?F<4\24\21\16\11\7\6""421*'%\40\34\27#\36\31*$\36'\40"
           "\35!\33\27""4*$=0'L:/Q<0Y>.sSBqP>yUB\203YB\211Y>\226^?\242b?\257hB\271g;"
           "\311sF\325zJ\337yD\351v:\364\202G\365~C\364s5\364s4\366`-\376$\0\376\311"
           "\0\376\326\0\376\326\0\376\247\0\376\4\0\366e-\366\202J\357\205P\342|F\330"
           "|J\307l:\262X'\246U )\234X.\231c=\221b@\200S6\206bI\204eO\200eSiTFq_Sxg[f"
           "VIhXM]PFVJAdUNvh`cRKZMD\15\13\11\4\4\4-,  *%\"\40#\35\32""0 )$<50C<8:2,  @4,  K"
           "=4TB7[C5lN:tP9uL4{J/\200I*\216Q-\246f@\251]2\266`1\306k8\322o:\341}G\354"
           "\200E\366\210L\366\210L\367\212Q\366\212P\367\220X\367\221[\373-\32\376\215"
           "\0\376\326\0\376\326\0\376\326\0\376t\0\3736\36\365\200G\365|@\352m0\335"
           "k2\317f-\302e1\271i:\255i<\241g>\230eA\220aB\202U:yO7jG5fK;r\\Ls_QiWJbPD"
           "aOCM=3P@7[MEI8/I8/\6\5\5\1\1\1.++#\37\36\34\27\24\33\23\20$\33\31""1'$ )\""
           "\35*\36\26:&\32I1%Q5(  eB-\200V<\216aD\223aA\227[6\236Z2\257h>\277rF\305k7"
           "\323q;\337v<\353y;\365y<\365~B\365z9\365z6\365u.\365x6\365|=\371E\"\376^"
           "\0\376\326\0\376\326\0\376\326\0\376\326\0\376Q\0\371>\34\365u5\364p/\347"
           "g(  \332j0\307Z!\275a.\262f7\245c6\234c;\215V4\200L/tF,  oG-qQ<cG4L3\"\\F8XC"
           "5RA5K:2: )!C4-,  \32\22:(  \37\26\26\25\10\10\11""965,  '%\"\31\26\"\27\22(  \33\26"
           """6 )#4(  \40""8 )\37F0!X<(  aB.wP8\213_A\215X6\230^:\242`8\250\\/\267d3\307p="
           "\324u?\337t6\353t2\366p0\376\2\0\365v4\366\177=\365{7\365x3\366~<\365t1\370"
           "M\40\376G\0\376\326\0\376\326\0\376\326\0\376\326\0\376\272\0\376\17\0\366"
           "p4\365|<\364z6\347x;\327o7\306`+\272d4\260h;\235Y/\221T1\206O/\203T7yN5m"
           "I5oP=cF2W<*^F6cOAeRDcPDcSJVC9lYO\23\23\22\25\26\26PLLE?=0%!&\31\24 )\32\24"
           """4%\36""5'\35""5$\32F,  \33Z:%kG/\177S7\225bA\220R+\234X-\261l?\275qC\306"
           "o;\323t<\335q2\352u0\370d0\376\22\0\376\7\0\366x1\366}5\365p(  \364i\36\365"
           "y6\365|=\370U%\376=\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376"
           "?\0\370T&\365q,  \365x3\361s0\342o1\323k2\304g4\264b0\241T'\227U2\207H'y@\37"
           "r@\"qF+gA'bA+Y=-Z?.dK:r\\Lp\\P\\JA.\31\20""3\36\25\10\12\11\3\4\4?<=D>=9"
           "/.7-+>3/@3/D4-F0&R8 )W4!`4\34p9\36\212M-\231V1\242U,  \253S%\301i:\322{I\332"
           "o5\347s6\370d5\3762\0\376\36\0\366`\"\365p )\364o'\364l$\364l$\364j!\364l"
           "$\370H\32\376K\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376^\0"
           "\370=\25\364d\33\364l%\365v3\354e\40\332^\36\312`&\266S\37\237F\30\237X/"
           "\221R,  \200I'tD&c7\33`8\37U2\35V9'J/\40K3%fPC{f[\200meR;0:\"\31%''003[Y]M"
           "LN.-/\35\35\36\"\40\40/*(  8- )?0'D-#C$\26L\"\17^ )\21p.\17\1770\14\226@\30\246"
           "B\24\270G\24\313Q\31\336Y\33\365B\26\376 )\0\376|\0\376\3\0\362X\23\362V\20"
           "\362V\17\362W\20\362W\21\362U\15\362S\10\370 )\5\376n\0\376\326\0\376\326"
           "\0\376\326\0\376\326\0\376\326\0\376[\0\3672\11\362T\13\362T\13\362W\21\363"
           "\\\25\343S\20\314H\13\266E\20\242>\17\221>\26\200:\27r8\31a1\25P$\14F#\17"
           """5\27\10$\17\3\32\13\3\31\13\5\"\24\15K;4o^WM5-'\17\6\25\25\26\26\26\30"
           "GFJA@A122(  (  &(  &$-(  %0(  \37""3#\31""9\"\25G%\23X+\23i3\25{5\20\214=\23\235?\20"
           "\257B\16\306Q\30\333^!\357i,  \373\33\12\376\236\0\376\210\0\372\"\10\362^"
           "\30\362\\\27\362^\33\363b\40\363b\40\363`\37\366?\22\376\24\0\376\270\0\376"
           "\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376E\0\367A\24\363_\34\362"
           "^\32\363]\34\364b$\363m-\340f-\314]*\271Y-\244L%\222D\40\207C#y>$n=(  `;(  V"
           ":,  P7,  G2 )6%\35,  \34\25F4,  iWMS8.B&\35\12\11\14\1\1\1,  '(   )##0(  %9-&:-&?.$J4%Z;"
           "(  Z5\37g:!zA$\221Q-\243W*\261]+\272T\34\314]\40\335e#\354e!\371E\35\376;\0"
           "\376\326\0\376\221\0\373\40\11\365j%\365j$\364h$\364l*\364j'\366U\35\376"
           "\17\0\376\235\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\317"
           "\0\376#\0\366^%\364h\37\364c\32\376\11\0\376\17\0\366f%\360m*\336_\40\317"
           "]%\274S\37\247@\24\237A\30\224?\33\211?\40\204F,  w@,  i3\35f8%W0\40D#\26D(  \37"
           "P943\33\30""0\33\30\25\26\30\10\12\12""3-++\40\35 )\32\25""4\"\33@ )\40J-\40"
           "T1\37i<%\200L1\212N.\231W0\246[6\257Z1\303f3\321o7\335s8\353w6\366o,  \376"
           "\11\0\376\254\0\376\326\0\376\270\0\376\13\0\365k,  \365o )\365o-\365r0\365"
           "h!\372(  \11\376\200\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376"
           "\326\0\376\256\0\376\10\0\365d\40\366o(  \371A\24\376E\0\376\30\0\366X\27\365"
           "g!\354f\40\333\\\32\311V\36\274R!\254H\34\236C\31\223C!\212?\37\207A$\177"
           ">%f,  \33T#\21M#\25H(  \37D*&\25\1\1\16\0\0\17\21\20\25\26\25""941/$\37'\31\23"
           "/\36\26""8\37\25?\40\25M(  \33h:$tB+\203E%\222L&\243R )\264Z,  \312n:\325o7\341"
           "i )\362r1\371F!\376X\0\376\326\0\376\326\0\376\323\0\3763\0\367[,  \365s2\365"
           "w9\365u7\367Z$\376+\0\376\320\0\376\326\0\376\326\0\376\326\0\376\326\0\376"
           "\326\0\376\326\0\376t\0\3725\25\365p )\366]\31\376\27\0\376\256\0\376!\0\366"
           "^&\365q/\365m'\342b!\322`'\301\\(  \252L\37\231B\32\217C\34\207A\37w6\32n4"
           "\34h7#Y1!_>0eL@^I@5\36\23""0\31\14\0\0\0\1\1\1+&$(  \35\30/#\31> )\36E )\31I"
           "+\32^8$sA'\177D$\215P.\235R(  \255Z*\277d0\315h/\337w;\360\203G\366{<\376\10"
           "\0\376\257\0\376\326\0\376\326\0\376\326\0\376d\0\371@\36\365p.\366z<\366"
           "\200E\3736\35\376}\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376"
           "\326\0\376\322\0\376-\0\370^(  \366w3\372@\35\376g\0\376\326\0\376u\0\3735"
           "\33\366z:\365l&\354h$\337t<\317l;\273[,  \255W.\224D\33\204@\31\200F#xF )wN"
           "7vT@~cS~k`qbZPC9N?7\2\2\0\1\1\1*&&$\32\27\36\21\15(  \26\17""7\34\23E%\27e"
           "8\37xB%\203K*\220I\"\240N\40\257R\37\274R\33\320[\37\343g#\364k#\367A\15"
           "\376H\0\376\326\0\376\326\0\376\326\0\376\326\0\376\207\0\372#\12\364`\32"
           "\364c\34\366_\37\376\23\0\376\300\0\376\326\0\376\326\0\376\326\0\376\326"
           "\0\376\326\0\376\326\0\376\214\0\376\1\0\365j\"\365`\35\376\15\0\376\270"
           "\0\376\326\0\376\322\0\376U\0\371-\14\365i\"\364h\36\344a\34\322Z\35\273"
           "H\20\255L\34\231B\27\207=\24u2\15e*\13h8\35c>'\\A0|i\\\236\222\207\222\205"
           "}dWM\4\3\0\1\1\1.* )!\32\27\33\20\15%\25\17>'\36R7*oI5rA(  }=\37\231P-\253X"
           ".\271[+\306[%\332i )\353g\40\365s.\3731\30\376\203\0\376\326\0\376\326\0\376"
           "\326\0\376\326\0\376\223\0\373!\12\364j#\365l'\367G\30\376F\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\317\0\376+\0\366I\21\365"
           "j\37\370T\35\3768\0\376\326\0\376\326\0\376\326\0\376\316\0\3763\0\371>\30"
           "\365k$\356b\31\333]\34\312\\#\266O\35\245M\40\226N&\206G$}G+pB(  M(  \23A%\25"
           "XE6seY`REL<.\26\22\12\5\4\2""2-+'\34\31-\33\23""5!\26J+\36Y8 )jC.u<!\211D"
           "!\237X2\262b9\303l>\317e/\341m0\363o*\364a\27\376\3\0\376\241\0\376\326\0"
           "\376\326\0\376\326\0\376\326\0\376\244\0\374\31\10\367Z\37\367h*\3728\30"
           "\376n\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\233"
           "\0\374\36\14\376\3\0\366T\30\370F\27\376L\0\376\326\0\376\326\0\376\326\0"
           "\376\326\0\376\266\0\376\26\0\367U\40\366w3\345i(  \324c )\301\\ )\261[0\241"
           "Z3\222T1\206Q1\201V=rR>mSBfRCN=2\31\11\5\20\6\5\21\16\7\26\20\12C;6:,  $<'"
           "\35C+\37P/\37a6#n?'\203C!\225M$\244S )\262W(  \305c/\324b'\345]\25\365i\34\364"
           "^\23\376\3\0\376\247\0\376\326\0\376\326\0\376\326\0\376\326\0\376\316\0"
           "\376S\0\376+\0\376\24\0\373,  \21\376\203\0\376\326\0\376\326\0\376\326\0\376"
           "\326\0\376\326\0\376\322\0\376:\0\371N\37\376#\0\376'\0\370O\35\376>\0\376"
           "\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\211\0\376\1\0\366u3\355"
           "h#\332b$\314g3\263V'\245\\4\214H$}@\40|K3uR?nRCiSDbOC6$\32\"\22\12\2\1\1"
           "\25\15\11E837%\35-\34\24""4\37\26<\35\21N\37\14d*\16{5\23\215>\24\233?\23"
           "\261J\27\300K\20\330[\33\355`\27\363U\11\363[\17\373!\10\376\214\0\376\326"
           "\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\303\0\376\35\0\373"
           "!\13\376\224\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376s\0\372"
           " )\10\365c\40\376\13\0\376\203\0\376\23\0\376\15\0\376\267\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\376\326\0\376E\0\371D\31\365x5\337a!\313^%\260"
           "I\26\240H\33\222F\36}8\25t9\33U.\33U7'mWI\213yl\205p_nVD\0\0\0\2\2\2""0+"
           "*#\30\24$\25\20""1\35\25>!\26V*\30o3\27\200;\30\220C\34\242G\33\267P\36\314"
           "[$\335[\31\362Z\16\364g\36\364f\36\367@\14\376E\0\376\326\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\376\326\0\376\272\0\376\13\0\373\35\11\376\231"
           "\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376P\0\373#\10\372 )"
           "\10\376\5\0\376\266\0\376p\0\3712\21\376C\0\376\322\0\376\326\0\376\326\0"
           "\376\326\0\376\326\0\376\257\0\376\13\0\366w9\350t8\325k2\301a-\260\\/\237"
           "S+\217L*\177C'h;$aA-v^O\213zm\217|n\213uf\22\15\12\15\13\14;65-#!'\27\21"
           "+\23\13""7\30\13S&\22v9\32\206?\33\222>\27\244D\31\273O\32\322`&\345d\37"
           "\364f\35\364d\34\364h\40\364f\40\373\"\12\376\217\0\376\326\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\376\306\0\376\24\0\373!\14\376\224\0\376\326\0"
           "\376\326\0\376\326\0\376\326\0\376\326\0\376\312\0\376\210\0\376x\0\376\241"
           "\0\376\326\0\376\270\0\376\14\0\373*\22\376\210\0\376\326\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\376?\0\370Q\"\360\177E\331d )\311g4\274lB\245^"
           "7\215K(  \211Q2yL4kL9YE7`QFYJ<lZLF;6XMH\207{vsaZC.&2\32\20""8\33\15H\37\15"
           "a$\11\204:\24\227E\33\260S#\302W\34\321Q\23\350^\30\365p(  \365q-\370L\33\376"
           "\7\0\376\23\0\376\23\0\376\245\0\376\326\0\376\326\0\376\326\0\376\326\0"
           "\376\325\0\376J\0\371+\12\376u\0\376\326\0\376\326\0\376\326\0\376\326\0"
           "\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\303\0\376"
           "\23\0\371B\32\376Z\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376"
           "a\0\3719\21\363j&\337g,  \316i9\274e:\245V0\223P.\177B%h:$M0#0$\36""3,  (  .\""
           "\30UF;\27\17\13""8+$od_hWP]H>^E:hI9`7#`(  \17\2004\21\2178\17\250C\23\301O"
           "\30\327X\31\354Z\17\364^\21\367E\21\376\15\0\376\230\0\376c\0\3719\22\376"
           "\31\0\376\303\0\376\326\0\376\326\0\376\326\0\376\326\0\376\273\0\376\27"
           "\0\376\24\0\376\276\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\376\313\0\376H\0\371;\32\373.\26\376\206\0\376"
           "\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376C\0\367L\33\365s.\341d"
           "$\311Z$\273b6\250Z4\234Z:\221]C{Q<cE5;,  &*&$%\33\25aUL\0\0\0\7\6\5:42/#\37"
           ",  \34\25""0\33\23D%\31O )\30X&\17\1773\15\226@\23\253C\21\302K\24\331X\30\360"
           "]\24\366L\14\376\10\0\376\226\0\376\326\0\376\214\0\373#\11\372\"\10\376"
           "\211\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\250\0\376\27"
           "\0\375v\0\373\324\1\373\323\1\372\323\1\374\324\0\375\325\0\376\326\0\376"
           "\326\0\376\316\0\376A\0\3728\31\372,  \16\376P\0\376\322\0\376\326\0\376\326"
           "\0\376\326\0\376\326\0\376\263\0\376\15\0\365i&\365};\351z=\325o7\300d5\253"
           "Z0\234U0\213P2vI1eF5K9/:1+\33\24\16@94%\40\35\32\26\23?620!\34*\26\17""3"
           "\31\17H%\27U,  \31[ )\16y.\11\2238\12\253C\16\303L\21\334W\30\363b\32\372*\13"
           "\376z\0\376\326\0\376\326\0\376\270\0\376\13\0\3709\16\376Z\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\376\326\0\375\326\1\375\303\1\375\300\3\355\312"
           "\17\245\215!\237\200\15\334\267\3\367\317\0\373\323\0\375\325\0\376\310\0"
           "\3762\0\376-\0\376|\0\376\322\0\376\326\0\376\326\0\376\326\0\376\326\0\376"
           "\323\0\376?\0\371H$\365s/\366~>\355y:\331p6\307h3\262Z*\240Q%\214H!\200S"
           "6qN:cM@XMG\30\25\22\23\21\17;3,  -%\37F:45#\34""4\35\23I-\40Y7(  d7%j1\27{/\16"
           "\2268\15\253C\20\310M\20\336U\20\367C\17\376>\0\376\324\0\376\326\0\376\326"
           "\0\376\321\0\376*\0\370D\26\376L\0\376\326\0\376\326\0\376\326\0\375\325"
           "\0\376\326\1\376\326\0\375\326\6\352\314.\263\246l569#\40\40; )\1\224v\1\333"
           "\266\0\366\317\0\373\323\0\375\317\0\376\322\0\376\326\0\376\326\0\376\326"
           "\0\376\326\0\376\326\0\376\326\0\376g\0\3724\30\366\200B\365s/\365w3\357"
           "s/\330c$\312j3\267`-\245W*\223P*\201Q5nH1r]Opf_\"\37\33\0\0\0\36\31\23\33"
           "\25\17=502\"\33,  \30\17>'\34T7 )f?-u>'\212F )\250Q,  \265U*\312X\"\336W\26\373"
           "\40\12\376\223\0\376\326\0\376\326\0\376\326\0\376\326\0\376=\0\3729\32\376"
           "n\0\376\326\0\375\325\0\375\326\0\376\326\0\376\326\0\370\323\17\347\316"
           "H\341\327\250mkd\3\3\0'(  *\0\1\3\5\2\0<+\0\224v\0\332\265\0\366\317\0\372"
           "\323\0\375\325\0\376\326\0\376\326\0\376\326\0\376\326\0\376\207\0\376\1"
           "\0\365_\34\366z7\366~=\366z6\361u2\336j*\312b'\273b.\254].\226R+\200N0yU"
           "?\202l_\211~wQMI\"!\37\2\1\0\11\7\2.*&\40\27\21\37\20\11,  \27\15""8\35\20"
           "C\40\21` )\20v1\21\2319\16\260F\24\304Y!\340e&\374\25\10\376\256\0\376\326"
           "\0\376\326\0\376\326\0\376\326\0\376\200\0\376K\0\375\302\0\375\325\0\376"
           "\326\0\376\326\0\373\324\5\356\314\33\347\317Y\357\342\251\263\255\226\25"
           "\23\12\1\1\0!!#\21\22\22\0\0\0\0\0\0\6\2\0<*\0\230z\0\335\270\0\370\320\0"
           "\373\323\0\375\325\0\376\326\0\376\271\0\376\20\0\370['\365l\"\365d\36\366"
           "p.\366s+\363u.\341o.\316h,  \276b.\254Z )\227P%}H )wS;\210qa\227\213\202uniP"
           "NJ\26\24\13\30\30\20""62+&\35\26\"\26\14(  \30\14-\27\12""7\27\10V!\10p.\16"
           "\2165\13\2479\10\272C\16\330P\20\371#\7\376\206\0\376\326\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\375\325\0\376\326\0\376\326\0\367\321\7\347\305"
           "\26\337\3039\352\325s\355\337\246\220\204yGD9\4\3\0\0\0\0\16\16\16##%\0\0"
           "\0\0\0\0\0\0\0\0\0\0\5\2\0>-\0\230{\0\336\271\0\371\321\0\373\324\0\375\211"
           "\0\373%\14\365j#\371M\36\376\14\0\376\15\0\366s1\365{6\343u5\321n2\301h0"
           "\261b0\234X+xG&kF.u^N{mdME>1+%CC934+C@:3+$2'\35""6(  \35<(  \32D )\33]2\35t;\37"
           "\206<\31\251D\24\277N\30\322V\32\361K\22\376\34\0\376\262\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\375\325\0\366\316\4\335\272\21\312\260;\332\307"
           "y\346\327\236\343\327\265\32\22\21\203\200\177\6\5\0\1\1\0\0\0\0\2\2\2''"
           " )\6\6\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0<-\0\246\210\7\360\312\3\375\300"
           "\0\3765\0\376\7\0\376I\0\376\203\0\376A\0\370R\35\364u )\341l&\317f'\272U"
           "\32\257Z'\235W+o;\35_9\"[B1VF<\37\25\14\22\7\1KKA[[Snmea[QRF<A1&6\"\25""7"
           "\36\20Q+\30o:!\204A\40\240A\23\273G\20\313M\20\351^\27\3707\13\376\36\0\376"
           "\231\0\376\326\0\376\326\0\376\326\0\374\324\1\307\245\21\221\201:\245\233"
           "o\264\253\222\302\274\263\252\244\252\253\251\270\36\34\34\1\1\0\0\0\0\0"
           "\0\0\0\0\0\34\34\35\30\30\31\0\0\0\0\0\0\0\0\0\0\0\0\5\5\5\13\14\15\34\34"
           "\36ME/\342\277\10\376\326\0\376\315\0\376\271\0\376\311\0\376>\0\376I\0\371"
           "L\32\362o\"\336`\30\314]\36\275Z\"\252L\30\231M#xD*\\2\35K/\37E5+\"\32\20"
           "/&\36\33\34\23\32\32\25""52/4/'?5 )O?2J4%J0!eB0s?&~<\35\217:\21\262D\20\311"
           "U\35\342_\35\364`\24\367>\10\376\2\0\376C\0\376\246\0\376\326\0\374\324\0"
           "\305\245\10""91\10""0,  \30;8.GEDfenPPY\17\17\17\6\6\7\2\2\2\0\0\0\0\0\0\12"
           "\12\13,  ,  .\17\17\20\26\26\27\33\33\35\35\36\37\35\35\37\34\34\36\22\22\24"
           "i[\13\362\315\2\375\325\0\376\326\0\376\257\0\376,  \0\373:\27\376c\0\372="
           "\23\361p#\337j&\320e,  \300\\'\266^/\235S.\206W>\201ZDfM@N?80(  \"PGB87*47.:"
           "83+&\35.$\31""7(  \35= )\36""8!\23N.\36e8\"t8\32\2007\24\251K\34\304O\24\327"
           "V\25\362k#\365b\27\365h\35\370A\21\376\12\0\376\237\0\373\324\0\346\302\2"
           "O@\1\2\2\0\4\3\0\2\2\1\4\4\4\33\33\34++.(  (  *$$%\40\40!\36\36\40'' )DDH//1\40"
           "\40\"\16\16\17\7\7\7\1\1\1\0\0\0\1\1\0\245\213\4\371\322\0\375\325\0\376"
           "\314\0\376#\0\371E\31\376\11\0\376\201\0\373,  \15\356q&\335m+\313^$\272V!"
           "\263\\.\231T1o?'iE2H2(  9.*\14\11\10\34\33\31(  %\35""53(  B<53*!1%\35/\40\27""8"
           "#\32@(  \33P1#]1\36u:!\205A\"\243L#\300Q\31\321\\\36\350d\37\365k\"\365k\36"
           "\365o$\371<\21\376c\0\374\324\4\334\274\26w_\6\10\4\0\0\0\0\0\0\0\0\0\0\0"
           "\0\0\0\0\0\2\2\2\4\4\5\6\6\6\7\7\10\20\20\20**-\0\0\0\0\0\0\0\0\0\0\0\0\0"
           "\0\0\0\0\0(  \40\0\327\265\0\373\323\0\376\326\0\376\316\0\376<\0\373'\15\376"
           "C\0\376\222\0\373%\15\352p(  \333p0\312h/\275e3\263e6\227X3h>%]<(  R?4QGB\35"
           "\33\32\17\17\16\25\16\13\33\22\13""8.(  6+#B3,  Q@7cNDoSFrQAoC0|F.\212M0\237"
           "R-\272S!\315a*\340f%\364z6\365n$\365k\40\365<\24\355|3\350\323g\213|*?7\13"
           "\22\13\0\17\6\0\6\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\27\27\30"
           "\34\34\35\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0v`\0\363\315\0\375\325\0\376"
           "\326\0\376\326\0\376\311\0\376\215\0\376\303\0\376s\0\3728\25\346r.\324j"
           "*\306g0\265^+\260d9\217P-kB )`@.\\I?VNI$!\37\23\21\20I>7C82MD>F:4D7/SB8r\\"
           "R|_S}ZLqD2l6\37w8\33\211E%\245F\30\311f2\330p9\350n0\356l*\320zP\304\207"
           "\220qg_\227\221z'!\0,  (  \26\7\7\4\0\0\0\10\3\0\13\3\0\3\1\1\0\0\0\0\0\0\0\0"
           "\0\0\0\0\0\0\0$$%\14\14\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\34\22\4\275\233"
           "\1\372\323\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0"
           "\376,  \0\363b+\341x:\323r9\307o?\270e9\253_8\213N/a:%O0!<,  $4.,  \17\17\16\16"
           "\16\15RD>WICgZUXHC?.':&\35P7.hK@zWJ\200VFzE0\177B(  \204C%\226B\30\271U%\311"
           "e3\331d )\224Z:\200\177\217\277\277\337\265\263\313\40\37\32\11\10\0\22\21"
           "\17\17\17\16\2\2\2\4\5\5\11\11\12\37\32\31\7\6\6\0\0\0\0\0\0\0\0\0\5\5\5"
           "(  (   )\3\3\3\0\0\0\1\1\1\7\6\6\34\33\36VV[\217\210xK>\30\261\217\1\376\326\0"
           "\376\326\0\376\326\0\376\326\0\376\307\0\376d\0\3730\21\347t0\332r5\312h"
           "/\273_.\255Z-\237S )\211O1X0\33B&\26J8/`WRROLIFC\32\12\7(  \31\23L<:J82:%\37"
           """5\37\30A&\37S4 )c@4pE7vD/zA'\201@\40\220E\40\252G\26\301R\35\326d,  \177A"
           "!\16\16\17$$(   ) )/\17\17\20\21\21\22\27\27\31'' )\21\21\22\22\22\22\16\16\17"
           "\12\12\12\1\1\1\0\0\0\0\0\0\0\0\0\20\20\21\"\"#\0\0\0\0\0\0\10\6\5%#'st\205"
           "\273\272\323769\0\1\2\14\14\14jP\0\366\203\0\376r\0\376U\0\376\35\0\3727"
           "\23\356i#\337n-\320j.\302c,  \265]-\240N\"\225K#\207K+^5!;\37\22/\40\30""9"
           "0+#\37\32\40\36\31\35\14\10\26\6\2<,  (  F2.E/*K4,  V:0X7+\\:-f=,  j<'q:!\205E&\231"
           "V2\251U )\275X$\311Q\27\305X\35\40\13\2\0\0\0\0\0\0\4\4\4\5\5\5\16\17\17\31"
           "\31\32\1\1\1\0\0\0\0\0\0\10\3\0\4\1\0\4\1\0\0\0\0\0\0\0$$&\22\22\24\0\0\0"
           "\5\1\0\11\1\0\22\12\2,  (  !PLJ\25\24\20\11\11\10\23\24\25\5\5\5I\16\5\3232\24"
           "\371?\16\366\\\27\361p$\342f\37\323a\37\305_$\262O\31\260\\/\234Q'\210?\32"
           "\200G )pF1W<0\\KCjb\\he_mlfE6/>0*UEAQ>:@*$3\34\24""7\33\23@!\26R1#a: )c7#h"
           "7\40w?\"\216Q0\242\\3\270b0\307b*\324a\"\1779\21\1\1\0\0\0\0\0\0\0\0\0\0"
           "\23\23\24\11\11\11\0\0\0\0\0\0\35\22\0\241\201\0\234}\0\207j\1oY\2fR\3j["
           "\20iU\10sZ\3\216l\1\251\204\0\233|\0&\40\0\15\13\0\6\6\4\11\11\12\36\37\40"
           "\21\21\22\11\12\13\222E\30\365q$\362g\32\343_\26\322R\14\302L\11\272W\36"
           "\252M\33\234D\27\216C\32}8\23t;\36rJ7\202h\\\211zq\213\202~{wszxr;,  %:-'I"
           ";6B2+B-&@(  !9\33\23<\33\20L,  \37c?.g=+f7!l6\33\200B\"\222L'\247R&\272T\37\305"
           "O\26\277R\31*\21\3\1\0\0\0\0\0\1\1\2\30\31\32\2\3\3\1\0\0\3\1\0\205d\0\373"
           "\323\0\372\322\0\370\320\0\365\316\0\362\314\1\361\313\1\362\314\1\365\316"
           "\0\370\320\0\373\323\0\363\313\0XB\0\0\0\0\0\0\0\0\0\0\21\21\22\1\2\2\0\0"
           "\0\255E\17\362b\27\346h%\326X\25\307Q\21\272P\25\256M\31\235E\30\232N#\217"
           "J(  q3\30l3\34`8 )jNAkZQ`WP51+(  %\40>/*D72L@9M>7bNFpZQmSHpSG{]R}[LsL:j>*s@(  \200"
           "D%\207E#\235P'\267^/\275S\32\314[\36\263R\35\212<\21y5\21e\32\14g\36\17o"
           "I\2\220n\0\266\224\0\361\312\0\376\326\0\376\326\0\376\326\0\376\326\0\376"
           "\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\314\246"
           "\0WF\0-!\0\25\20\4\33\25\24\20\5\2""6\23\3\332V\21\345a\33\326U\22\313V\26"
           "\272H\14\263O\33\243F\24\224>\21\2068\16\177;\30n1\26c-\27I$\24K0%ZI?jbY"
           "LHA;81OD=ND=LA<G95TE=cQJgSHkSGqYLtTDqM<g<(  p>&}F )\206J*\224O )\256[/\264S\40"
           "\301Y!\315\\\35\332a\34\347i\40\363p%\371?\24\376\31\0\376\210\0\376\316"
           "\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0"
           "\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\326\0\376\316\0\361"
           "\236\0\337D\1\317%\13\324W\25\342Y\21\341V\16\327\\\32\310R\22\275P\26\261"
           "K\25\243C\20\233E\27\234P(  \213B\36w6\27g,  \23`-\31I$\26C(  \34ZI?ypgqoehg]1"
           " )!%\35\26/#\37&\32\30+\37\32&\33\25""0\"\32A,  #>(  \37O0#c=+mE0xG/\200H*\211"
           "N.\224Q-\243T,  \256V )\271Y'\301V\34\320b&\331a\40\345j&\357l#\370Q\24\373"
           "(  \14\376%\0\376Y\0\376}\0\376\225\0\376\246\0\376\257\0\376\263\0\376\263"
           "\0\376\260\0\376\251\0\376\231\0\376\206\0\376o\0\376N\0\376#\0\376\4\0\370"
           ">\16\364`\25\352^\24\337X\23\320K\15\310O\23\275L\26\262G\25\251H\32\234"
           "A\27\235J(  \221C\"\1778\34u4\32g-\27U%\24A\36\22""4\30\16""4!\32:1,  &$\34&"
           "%\32\10\3\1\26\11\4""7,  %?3,  L<4?0 )0\40\26""3\34\20/\26\13<\37\22U.\34Y/\33"
           "k9\"v<!~>\37\205?\35\217A\34\231D\31\250M\37\255E\22\271G\21\306O\26\321"
           "W\31\336b\36\346e\40\355^\21\363I\12\366<\17\370-\14\372!\11\372\27\6\372"
           "\23\5\373\21\4\373\22\6\372\26\11\372\31\11\371\37\11\370*\20\3673\20\366"
           "I\35\364Z\40\363g\37\353a\34\337U\20\327U\20\312O\20\300V\40\261H\26\242"
           "9\14\234;\16\2126\16\2047\25\2014\25\2007\26l(  \15X\33\7T!\17D\33\20""0\22"
           "\13$\16\11\"\24\20#\36\34\3\2\2\0\0\0 )\36\31*\33\25""3$\36 )\27\24,  \31\25"
           ".\35\25.\34\22""1\34\21/\31\20""4\36\23<\37\21U1\40T,  \27`0\27g1\25m2\24z"
           "9\32\2009\31\215A\34\224@\21\242H\25\261V%\265Q\35\301Y\37\313`*\320[\36"
           "\324U\20\331]\26\337d\36\340d\34\341f\36\341[\21\337X\20\340i$\341f!\340"
           "e\36\341`\30\341e\36\340^\33\333[\31\326X\31\317Z\35\311V\32\303P\26\271"
           "J\25\253@\20\250F\27\235?\22\223:\23\215;\24\2020\13~5\31o+\22f+\23h.\33"
           "a*\27M\"\25@\33\22H+\40VA6fVMng_MMC79/B0,  <*&6%\"\40\16\12\31\6\3!\15\6""0"
           "\36\27""8$\33""3\40\27,  \30\17+\25\13""5\33\17""4\30\14?\37\20I%\23U-\32c"
           "6\36d2\30n6\31p1\16s.\12|3\21\2037\21\226J\36\250U'\257X )\254N\33\253J\30"
           "\260N\33\260L\31\262I\23\266I\17\275N\23\300W\36\277Y\"\274T\35\275X$\275"
           "^/\275c5\267O\34\261P\40\256X.\240G\35\233E\35\216;\21\2066\17\1772\20\200"
           "7\30\206>\37\203=\35{8\35j.\26a+\26^,  \30i4\"m=,  g=0W6*Z@6oZO\215\200u\242"
           "\234\222\220\216\203mmaC.+H30R<:C,  *7\40\33""8\40\33E/*P93W@8T<2N5*P1'K-#"
           "F(  \34T2\40oL6\202\\D\200YAyM5~L.|D${@\40y<\32\202>\32\222N(  \232M#\241P&\253"
           "Y/\260X+\261\\.\250O\40\247I\30\263V%\274e7\270c3\261Z+\261^1\262_4\260c"
           ";\247T*\240P(  \232P,  \226M+\216I*\207J/~A'w:#p3\37~C.\210P=\213XI\200OBuE7"
           "l>1rH;rL@mKBlOCgODn[P\201uh\231\223\211\243\242\226\231\231\214L40M40[@<"
           "T84G+(  D )%M3-P92S=6Q>8[G?[D=Q:3R;/YA5eK>lP?sS@uR<zT={S:wJ0sC'wB%\204Q3\207"
           "P3\207L/\220T7\225S4\223Q2\212J*\203B\"\212K+\223Y;\216V7\217[;\225cC\222"
           "]@\214\\AxJ1qE-j@*h>*mA/pC1j=,  ^2#V*\36W-\"[9/[=5]A8Z=5P4,  D,  %>(  !@,  %<+$0\""
           "\34+\37\31""6-%IE?IJDPQJ,  \36\34%\27\25""3$!,  \34\31%\26\25'\31\27""3$\40:"
           "+ );20C96SGBZNH\\OIXKFbUOcTL\\MG`NFfRFmWKoXJv_RpUGoPBsTCtTEoN@pPBnM?gH;bF"
           "9]A4X?1W=0S9+V@3\\E7ZC4O:.B1&<-%7*\"2$\35""7%\36=&\37:$\36""3!\33""1\35\30"
           "/\36\31(  \35\31#\33\27#\32\27#\33\30%\35\32(  !\35&!\35%\40\35-'%3.,  3/,  *&%\""
           "\36\34\5\4\2\7\6\5\6\4\3\7\5\4\5\3\2\10\6\5\22\20\17\34\32\31\23\22\20\23"
           "\22\22""20/0.-*'%,   )'#!\40 )'%@<:\31\26\25?<:732_XW.**D?>'%$\21\21\22 )%$:5"
           "3\31\30\27+'%\34\32\30\27\25\24\30\26\25\32\25\24\34\25\23\33\30\27\34\33"
           "\33\27\26\26\27\25\25\30\25\24\27\24\21\22\16\15\24\21\17\20\16\14\30\23"
           "\20\35\26\23\"\31\27*!\37\37\34\32\25\23\21\36\33\31#\34\30'\40\33""40-3"
           "30>?=TUSddaffbYXUgec\215\211\207\230\225\221zuqQIE>6292.(  \40\31""2 )\"3*#"
           "90*B:3G?8C:3<1+4+#1'\40;1*F;4>6/2 )\"90 )OFA\\UO[TOUOJNJEOIEVQN_[Vic^mgcle"
           "`d\\W]VPYQKWPHYOG]SMf[Th^XcYRWMGNC;F;2;1 )2 )!2'\36""9.$G9/SD;WJ@RE;K>4H=4"
           "I@6IC<MLHUXT`ebqus\200\201\200wxu__[`a\\\203\201\177\232\224\221\213\204"
           "\201sjig]\\\\SO",  
          };
          
          
          ///We'll use the emberIcon struct
           SDL_Surface * iconSurface = SDL_CreateRGBSurfaceFrom(  emberIcon.pixel_data,   64,   64,   24,   64*3,  
           rmask,   gmask,   bmask,   0 );
           if (  iconSurface ) {
           SDL_WM_SetIcon(  iconSurface,   0 );
           }
          
          
          #endif
          
           setStandardValues(   );
          
           return true;
           }
           else
           {
           return false;
           }
          }
          
     713  void OgreSetup::setStandardValues(   )
          {
           /// Set default mipmap level (  NB some APIs ignore this )
           Ogre::TextureManager::getSingleton(   ).setDefaultNumMipmaps(  5 );
          
           /// Set default animation mode
           Ogre::Animation::setDefaultInterpolationMode(  Ogre::Animation::IM_SPLINE );
          
           ///remove padding for bounding boxes
           Ogre::MeshManager::getSingletonPtr(   )->setBoundsPaddingFactor(  0 );
          
           ///all new movable objects shall by default be unpickable; it's up to the objects themselved to make themselves pickable
           Ogre::MovableObject::setDefaultQueryFlags(  0 );
          }
          
          
     729  EmberPagingSceneManager* OgreSetup::chooseSceneManager(   )
          {
           /// Create new scene manager factory
           EmberPagingSceneManagerFactory* sceneManagerFactory = new EmberPagingSceneManagerFactory(   );
          
           /// Register our factory
           Ogre::Root::getSingleton(   ).addSceneManagerFactory(  sceneManagerFactory );
          
           EmberPagingSceneManager* sceneMgr = static_cast<EmberPagingSceneManager*>(  mRoot->createSceneManager(  Ogre::ST_EXTERIOR_REAL_FAR,   "EmberPagingSceneManager" ) );
          
           ///We need to call init scene since a lot of components used by the scene manager are thus created
           sceneMgr->InitScene(   );
          
           return sceneMgr;
          }
          
     745  void OgreSetup::parseWindowGeometry(  Ogre::ConfigOptionMap& config,   unsigned int& width,   unsigned int& height,   bool& fullscreen )
          {
           Ogre::ConfigOptionMap::iterator opt = config.find(  "Video Mode" );
           if (  opt != config.end(   ) ) {
           Ogre::String val = opt->second.currentValue;
           Ogre::String::size_type pos = val.find(  'x' );
           if (  pos != Ogre::String::npos ) {
          
           width = Ogre::StringConverter::parseUnsignedInt(  val.substr(  0,   pos ) );
           height = Ogre::StringConverter::parseUnsignedInt(  val.substr(  pos + 1 ) );
           }
           }
          
           ///now on to whether we should use fullscreen
           opt = config.find(  "Full Screen" );
           if (  opt != config.end(   ) ) {
           fullscreen = (  opt->second.currentValue == "Yes" );
           }
          
          }
          
          
          }

./components/ogre/OgreSetup.h

       1  //
          // C++ Interface: OgreSetup
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREOGRESETUP_H
          #define EMBEROGREOGRESETUP_H
          
          #include "EmberOgrePrerequisites.h"
          
          namespace EmberOgre {
          
      30  class EmberPagingSceneManager;
          
          /**
           A class used for setting up Ogre. Instead of creating the Ogre root object and the main render window direclty,   use this to guarantee that everything is set up correctly.
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
      36  class OgreSetup{
          public:
      38   OgreSetup(   );
          
      40   ~OgreSetup(   );
          
           /**
           * Creates the ogre base system.
           * @return
           */
      46   Ogre::Root* createOgreSystem(   );
          
           /**
           * Configures the application - returns false if the user chooses to abandon configuration.
           * @param
           * @return
           */
      53   bool configure(  void );
          
           /**
           * Gets the main render window.
           * @return
           */
      59   inline Ogre::RenderWindow* getRenderWindow(   ) const;
          
           /**
           * Gets the Ogre root object.
           * @return
           */
      65   inline Ogre::Root* getRoot(   ) const;
          
           /**
           * chooses and sets up the correct scene manager
           * @param
           */
      71   EmberPagingSceneManager* chooseSceneManager(   );
          
           /**
           * Shuts down the ogre system.
           */
      76   void shutdown(   );
          
          private:
          
           /**
           Holds the Ogre root object.
           */
      83   Ogre::Root* mRoot;
          
           /**
           Holds the main render window.
           */
      88   Ogre::RenderWindow* mRenderWindow;
          
          
           /**
           * Attempts to parse out the user selected geometry options for ogre.
           * @param config The option map,   usually found inside the currently selected RenderSystem.
           * @param width The width of the window in pixels.
           * @param height The height of the window in pixels.
           * @param fullscreen Whether fullscreen should be used or not.
           */
      98   void parseWindowGeometry(  Ogre::ConfigOptionMap& config,   unsigned int& width,   unsigned int& height,   bool& fullscreen );
          
           /**
           Sets standard values in the ogre environment.
           */
     103   void setStandardValues(   );
          
          };
          
     107  Ogre::Root* OgreSetup::getRoot(   ) const { return mRoot;}
     108  Ogre::RenderWindow* OgreSetup::getRenderWindow(   ) const { return mRenderWindow;}
          
          }
          
          #endif

./components/ogre/OpcodeCollisionDetector.cpp

       1  //
          // C++ Implementation: OpcodeCollisionDetector
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "OpcodeCollisionDetector.h"
          #include "ogreopcode/include/OgreCollisionManager.h"
          #include "ogreopcode/include/OgreEntityCollisionShape.h"
          #include "ogreopcode/include/OgreCollisionObject.h"
          
          #include "EmberOgrePrerequisites.h"
          #include "EmberEntityUserObject.h"
          
          #include "OpcodeCollisionDetectorVisualizer.h"
          
          #include "model/Model.h"
          #include "model/SubModel.h"
          namespace EmberOgre {
          
      37  OpcodeCollisionDetector::OpcodeCollisionDetector(  Model::Model* model ) : mModel(  model ),   mVisualizer(  0 )
          {
           buildCollisionObjects(   );
          }
          
      42  OpcodeCollisionDetector::~OpcodeCollisionDetector(   )
          {
           destroyCollisionObjects(   );
          }
          
      47  void OpcodeCollisionDetector::reload(   )
          {
           destroyCollisionObjects(   );
           buildCollisionObjects(   );
          }
          
          
      54  void OpcodeCollisionDetector::destroyCollisionObjects(   )
          {
           OgreOpcode::CollisionContext* collideContext = OgreOpcode::CollisionManager::getSingletonPtr(   )->getDefaultContext(   );
           for (  OpcodeCollisionDetector::CollisionObjectStore::iterator I = mCollisionObjects.begin(   ); I != mCollisionObjects.end(   ); ++I )
           {
           OgreOpcode::ICollisionShape* shape = (  *I )->getShape(   );
           collideContext->destroyObject(  *I );
           OgreOpcode::CollisionManager::getSingleton(   ).destroyShape(  shape );
           }
           mCollisionObjects.clear(   );
          
          }
          
      67  void OpcodeCollisionDetector::buildCollisionObjects(   )
          {
           OgreOpcode::CollisionContext* collideContext = OgreOpcode::CollisionManager::getSingletonPtr(   )->getDefaultContext(   );
           const Model::Model::SubModelSet& submodels = mModel->getSubmodels(   );
           for (  Model::Model::SubModelSet::const_iterator I = submodels.begin(   ); I != submodels.end(   ); ++I )
           {
           Ogre::Entity* entity = (  *I )->getEntity(   );
          // if (  entity->isVisible(   ) ) {
           std::string collideShapeName(  std::string(  "entity_" ) + entity->getName(   ) );
           OgreOpcode::EntityCollisionShape *collideShape = OgreOpcode::CollisionManager::getSingletonPtr(   )->createEntityCollisionShape(  collideShapeName.c_str(   ) );
           // if (  !collideShape->isInitialized(   ) ) {
           collideShape->load(  entity );
           // }
           OgreOpcode::CollisionObject* collideObject = collideContext->createObject(  collideShapeName );
          
           collideObject->setShape(  collideShape );
          
           collideContext->addObject(  collideObject );
          
           mCollisionObjects.push_back(  collideObject );
          // }
          // collideObject->setDebug(  true,   false,   false,   false );
           /* collideShape->setDebug(  true );
           collideShape->visualize(   );*/
           /*
           EmberEntityUserObject* userObject = new EmberEntityUserObject(  this,   getModel(   ),   (  *I )->getEntity(   ),   0 );
           (  *I )->getEntity(   )->setUserObject(  userObject );*/
           }
          }
          
      97  void OpcodeCollisionDetector::refit(   )
          {
           for (  OpcodeCollisionDetector::CollisionObjectStore::iterator I = mCollisionObjects.begin(   ); I != mCollisionObjects.end(   ); ++I )
           {
           (  *I )->refit(   );
           }
          }
          
          
     106  void OpcodeCollisionDetector::testCollision(  Ogre::Ray& ray,   CollisionResult& result )
          {
          
           for (  OpcodeCollisionDetector::CollisionObjectStore::iterator I = mCollisionObjects.begin(   ); I != mCollisionObjects.end(   ); ++I ) {
           OgreOpcode::ICollisionShape* collisionShape = (  *I )->getShape(   );
           OgreOpcode::CollisionPair pick_result;
          
           if (  collisionShape->rayCheck(  OgreOpcode::COLLTYPE_QUICK,   mModel->_getParentNodeFullTransform(   ),   ray,   1000.0f,   pick_result,   false ) ) {
           result.collided = true;
           result.distance = pick_result.distance;
           result.position = pick_result.contact;
           return;
           }
           }
          }
          
     122  void OpcodeCollisionDetector::setVisualize(  bool visualize )
          {
           if (  visualize ) {
           if (  !mVisualizer ) {
           mVisualizer = new OpcodeCollisionDetectorVisualizerInstance(  *this );
           }
           } else {
           delete mVisualizer;
           mVisualizer = 0;
           }
          }
          
     134  bool OpcodeCollisionDetector::getVisualize(   ) const
          {
           return mVisualizer != 0;
          }
          
          
          }

./components/ogre/OpcodeCollisionDetector.h

       1  //
          // C++ Interface: OpcodeCollisionDetector
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREOPCODECOLLISIONDETECTOR_H
          #define EMBEROGREOPCODECOLLISIONDETECTOR_H
          
          #include "EmberEntityUserObject.h"
          
          namespace OgreOpcode
          {
      30   class CollisionObject;
           namespace Details
           {
      33   class OgreOpcodeDebugger;
           }
          };
          
          namespace EmberOgre {
          
      39  class OpcodeCollisionDetector;
      40  class OpcodeCollisionDetectorVisualizerInstance;
          
          namespace Model
          {
      44  class Model;
          }
          
          /**
           @author Erik Hjortsberg <erik@katastrof.nu>
          */
      50  class OpcodeCollisionDetector
          : public ICollisionDetector
          {
          public:
           friend class OpcodeCollisionDetectorVisualizerInstance;
          
           OpcodeCollisionDetector(  Model::Model* model );
           virtual ~OpcodeCollisionDetector(   );
          
           virtual void testCollision(  Ogre::Ray& ray,   CollisionResult& result );
           virtual void refit(   );
           /**
           * Called when the entity changes,   such as a subentity being hidden or shown. Implementations must reload the collision data.
           */
           virtual void reload(   );
          
           virtual void setVisualize(  bool visualize );
           virtual bool getVisualize(   ) const;
          private:
           typedef std::vector<OgreOpcode::CollisionObject*> CollisionObjectStore;
           void buildCollisionObjects(   );
           void destroyCollisionObjects(   );
           CollisionObjectStore mCollisionObjects;
           Model::Model* mModel;
           OpcodeCollisionDetectorVisualizerInstance* mVisualizer;
          };
          }
          
          #endif

./components/ogre/OpcodeCollisionDetectorVisualizer.cpp

       1  //
          // C++ Implementation: OpcodeCollisionDetectorVisualizer
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik.hjortsberg@iteam.se>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #include "OpcodeCollisionDetectorVisualizer.h"
          #include "ogreopcode/include/OgreOpcodeDebugObject.h"
          #include "ogreopcode/include/OgreCollisionManager.h"
          #include "ogreopcode/include/OgreEntityCollisionShape.h"
          #include "ogreopcode/include/OgreCollisionObject.h"
          #include "OpcodeCollisionDetector.h"
          
          namespace EmberOgre {
          
          template<> EmberOgre::OpcodeCollisionDetectorVisualizer* Ember::Singleton<EmberOgre::OpcodeCollisionDetectorVisualizer>::ms_Singleton = 0;
          
      34  OpcodeCollisionDetectorVisualizer::OpcodeCollisionDetectorVisualizer(   )
          {
           mOpcodeDebugger = new OgreOpcode::Details::OgreOpcodeDebugger(  "OpcodeCollisionDetectorVisualizer",   OgreOpcode::CollisionManager::getSingletonPtr(   )->getSceneManager(   ) );
          
          }
          
      40  OpcodeCollisionDetectorVisualizer::~OpcodeCollisionDetectorVisualizer(   )
          {
           Ogre::Root::getSingleton(   ).removeFrameListener(  this );
           mOpcodeDebugger->clearAll(   );
           delete mOpcodeDebugger;
          }
          
      47  bool OpcodeCollisionDetectorVisualizer::frameStarted(  const Ogre::FrameEvent& event )
          {
           mOpcodeDebugger->clearAll(   );
           for (  VisualizerInstanceStore::iterator I = mInstances.begin(   ); I != mInstances.end(   ); ++I ) {
           (  *I )->visualize(  mOpcodeDebugger );
           }
           return true;
          }
          
      56  void OpcodeCollisionDetectorVisualizer::addInstance(  OpcodeCollisionDetectorVisualizerInstance* instance )
          {
           if (  !mInstances.size(   ) ) {
           Ogre::Root::getSingleton(   ).addFrameListener(  this );
           }
           mInstances.push_back(  instance );
          }
          
      64  void OpcodeCollisionDetectorVisualizer::removeInstance(  OpcodeCollisionDetectorVisualizerInstance* instance )
          {
           VisualizerInstanceStore::iterator I = std::find(  mInstances.begin(   ),   mInstances.end(   ),   instance );
           if (  I != mInstances.end(   ) ) {
           mInstances.erase(  I );
           }
           if (  !mInstances.size(   ) ) {
           mOpcodeDebugger->clearAll(   );
           Ogre::Root::getSingleton(   ).removeFrameListener(  this );
           }
          }
          
          
          
      78  OpcodeCollisionDetectorVisualizerInstance::OpcodeCollisionDetectorVisualizerInstance(  OpcodeCollisionDetector& detector ) : mDetector(  detector )
          {
           OpcodeCollisionDetectorVisualizer::getSingleton(   ).addInstance(  this );
          }
          
      83  OpcodeCollisionDetectorVisualizerInstance::~OpcodeCollisionDetectorVisualizerInstance(   )
          {
           for (  OpcodeCollisionDetector::CollisionObjectStore::iterator I = mDetector.mCollisionObjects.begin(   ); I != mDetector.mCollisionObjects.end(   ); ++I )
           {
           (  *I )->getShape(   )->clearViz(   );
           }
           OpcodeCollisionDetectorVisualizer::getSingleton(   ).removeInstance(  this );
          }
          
      92  void OpcodeCollisionDetectorVisualizerInstance::visualize(  OgreOpcode::Details::OgreOpcodeDebugger* debugger )
          {
           for (  OpcodeCollisionDetector::CollisionObjectStore::iterator I = mDetector.mCollisionObjects.begin(   ); I != mDetector.mCollisionObjects.end(   ); ++I )
           {
           (  *I )->getShape(   )->clearViz(   );
           (  *I )->getShape(   )->visualize(  debugger );
           }
          }
          
          
          }

./components/ogre/OpcodeCollisionDetectorVisualizer.h

       1  //
          // C++ Interface: OpcodeCollisionDetectorVisualizer
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik.hjortsberg@iteam.se>,   (  C ) 2007
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          #ifndef EMBEROGREOPCODECOLLISIONDETECTORVISUALIZER_H
          #define EMBEROGREOPCODECOLLISIONDETECTORVISUALIZER_H
          
          #include "framework/Singleton.h"
          #include <Ogre.h>
          
          namespace OgreOpcode
          {
      31   class CollisionObject;
           namespace Details
           {
      34   class OgreOpcodeDebugger;
           }
          };
          
          namespace EmberOgre {
          
      40  class OpcodeCollisionDetector;
      41  class OpcodeCollisionDetectorVisualizerInstance;
          
          /**
          Helps with visualizing the collision objects. Create and register instances of OpcodeCollisionDetectorVisualizerInstance to visualize entities.
          @see OpcodeCollisionDetectorVisualizerInstance
          */
      47  class OpcodeCollisionDetectorVisualizer : public Ember::Singleton<OpcodeCollisionDetectorVisualizer>,   public Ogre::FrameListener
          {
          public:
      50   friend class OpcodeCollisionDetectorVisualizerInstance;
           /**
           * Default ctor.
           */
      54   OpcodeCollisionDetectorVisualizer(   );
      55   virtual ~OpcodeCollisionDetectorVisualizer(   );
           /**
           * Methods from Ogre::FrameListener
           */
      59   virtual bool frameStarted(  const Ogre::FrameEvent& event );
          
           /**
           * Registers an instance of OpcodeCollisionDetectorVisualizerInstance to be rendered each frame.
           * @param instance An instance of OpcodeCollisionDetectorVisualizerInstance which in turn points to an instance of EmberPhysicalEntity.
           */
      65   void addInstance(  OpcodeCollisionDetectorVisualizerInstance* instance );
           /**
           * Removes an instance of OpcodeCollisionDetectorVisualizerInstance which will no longer be rendered each frame.
           * @param instance An instance of OpcodeCollisionDetectorVisualizerInstance which in turn points to an instance of EmberPhysicalEntity.
           */
      70   void removeInstance(  OpcodeCollisionDetectorVisualizerInstance* instance );
          protected:
           typedef std::vector<OpcodeCollisionDetectorVisualizerInstance*> VisualizerInstanceStore;
          
           /**
           * The debugger object responsible for rendering.
           */
      77   OgreOpcode::Details::OgreOpcodeDebugger* mOpcodeDebugger;
          
           /**
           * All the registered instances which will be rendered each frame.
           */
      82   VisualizerInstanceStore mInstances;
          };
          
      85  class OpcodeCollisionDetectorVisualizerInstance
          {
          public:
      88   OpcodeCollisionDetectorVisualizerInstance(  OpcodeCollisionDetector& detector );
      89   virtual ~OpcodeCollisionDetectorVisualizerInstance(   );
          
           /**
           * Called each frame by OpcodeCollisionDetectorVisualizer to let the object tell the debugger how to render this instance.
           * @param debugger
           */
      95   void visualize(  OgreOpcode::Details::OgreOpcodeDebugger* debugger );
          
          protected:
      98   OpcodeCollisionDetector& mDetector;
          };
          
          }
          
          #endif

./components/ogre/PersonEmberEntity.cpp

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #include "EmberEntity.h"
          #include "EmberPhysicalEntity.h"
          #include "model/Model.h"
          
          // #include "PersonEmberEntity.h"
          namespace EmberOgre {
          
      26  PersonEmberEntity::PersonEmberEntity(  const std::string& id,   Eris::TypeInfo* ty,   Eris::View* vw,   Ogre::SceneManager* sceneManager,   Ogre::SceneNode* nodeWithModel ) :
          EmberPhysicalEntity(  id,   ty,   vw,   sceneManager,   nodeWithModel )
          
          {
          }
          
      32  PersonEmberEntity::~PersonEmberEntity(   )
          {}
          
      35  void PersonEmberEntity::init(  const Atlas::Objects::Entity::RootEntity &ge )
          {
           EmberPhysicalEntity::init(  ge );
          // mModel->setQueryFlags(  EmberEntity::CM_PERSONS );
          }
          
      41  bool PersonEmberEntity::allowVisibilityOfMember(  EmberEntity* entity )
          {
           return false;
          }
          }

./components/ogre/PersonEmberEntity.h

       1  /*
           Copyright (  C ) 2004 Erik Hjortsberg
          
           This program is free software; you can redistribute it and/or modify
           it under the terms of the GNU 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 General Public License for more details.
          
           You should have received a copy of the GNU General Public License
           along with this program; if not,   write to the Free Software
           Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.
          */
          
          #ifndef PERSONDIMEENTITY_H
          #define PERSONDIMEENTITY_H
          #include "EmberOgrePrerequisites.h"
          
          namespace EmberOgre {
          
      25  class EmberPhysicalEntity;
      26  class PersonEmberEntity : public EmberPhysicalEntity {
          public:
          
      29   PersonEmberEntity(  const std::string& id,   Eris::TypeInfo* ty,   Eris::View* vw,   Ogre::SceneManager* sceneManager,   Ogre::SceneNode* nodeWithModel );
      30   virtual ~PersonEmberEntity(   );
          
      32   virtual bool allowVisibilityOfMember(  EmberEntity* entity );
          
          protected:
      35   virtual void init(  const Atlas::Objects::Entity::RootEntity &ge );
          
          
          };
          
          }
          #endif // PERSONDIMEENTITY_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/DRGNURBSSurface.h

       1  // DRGNURBSSurface.h: interface for the CDRGNURBSSurface class.
          // ------------------------------------------------------------------------------------
          // Copyright © 1999 Intel Corporation
          // All Rights Reserved
          //
          // Permission is granted to use,   copy,   distribute and prepare derivative works of this
          // software for any purpose and without fee,   provided,   that the above copyright notice
          // and this statement appear in all copies. Intel makes no representations about the
          // suitability of this software for any purpose. This software is provided "AS IS."
          //
          // Intel specifically disclaims all warranties,   express or implied,   and all liability,  
          // including consequential and other indirect damages,   for the use of this software,  
          // including liability for infringement of any proprietary rights,   and including the
          // warranties of merchantability and fitness for a particular purpose. Intel does not
          // assume any responsibility for any errors which may appear in this software nor any
          // responsibility to update it.
          // ------------------------------------------------------------------------------------
          //
          // PURPOSE:
          //
          // Declaration of the CDRGNURBSSurface class for rendering NURBS surfaces.
          // Accompanies the article "Rendering NURBS Surfaces in Real-Time". Please refer
          // to the article for an understanding of the methods in this class.
          // ------------------------------------------------------------------------------------
          //
          // Author: Dean Macri - Intel Developer Relations Divison -- Tools and Technology Group
          //
          ////////////////////////////////////////////////////////////////////////////////////////
          //
          // Yoinked from http://www.gamasutra.com/features/19991117/macri_pfv.htm
          // Hacked into an unholy mess for use with OGRE by Chris "Antiarc" Heald (  antiarc@captionthis.com )
          // Date: 11/9/2003
          //
          ////////////////////////////////////////////////////////////////////////////////////////
          
          
          #if !defined(  AFX_DRGNURBSSURFACE_H__0D6D594B_6F3B_11D3_BE36_00902752C5DF__INCLUDED_ )
          #define AFX_DRGNURBSSURFACE_H__0D6D594B_6F3B_11D3_BE36_00902752C5DF__INCLUDED_
          
          #if _MSC_VER > 1000
          #pragma once
          #endif
          
          #define SIMD_SIZE 1
          
          #define ALIGNED_NEW(  s,   t ) new t[s];
          #define ALIGNED_DELETE(  x ) do { if(  (  x ) ) { delete x; x = NULL; } } while (  0 )
          #define SAFE_RELEASE(  x ) do { if(  (  x ) ) { x->Release(   ); x = NULL; } } while (  0 )
          #define SAFE_DELETE(  x ) do { if(  (  x ) ) { delete x; x = NULL;} } while (  0 )
          
          // Some handy-dandy macros
          //
          #define CLAMP_UPPER(  x ) if (  x>1.0f ) { x = 1.0f; }
          #define CLAMP_LOWER(  x ) if (  x<0.0f ) { x = 0.0f; }
          
          struct Point4D
          {
           float x;
           float y;
           float z;
           float w;
          };
          
          struct splinePoint
          {
           float x;
           float y;
           float z;
          };
          
      71  class CDRGNURBSSurface
          {
          private:
           Point4D* m_pControlPoints;
           float* m_UBasisCoefficients;
           float* m_VBasisCoefficients;
           float* m_UKnots;
           float* m_VKnots;
           float* m_UBasis;
           float* m_dUBasis;
           float* m_VBasis;
           float* m_dVBasis;
           Point4D* m_UTemp;
           Point4D* m_dUTemp;
           int* m_TessUKnotSpan;
           int* m_TessVKnotSpan;
          
           int m_iUDegree,   m_iVDegree;
           int m_iUOrder,   m_iVOrder;
           int m_iUKnots,   m_iVKnots;
           int m_iUControlPoints,   m_iVControlPoints;
          
           int m_iUBasisSpans,   m_iVBasisSpans;
          
           int m_iUTessellations,   m_iVTessellations;
          
           splinePoint* m_pVertices;
          
      99   void Cleanup(  void );
     100   float ComputeCoefficient(  float* fKnots,   int iInterval,   int i,   int p,   int k );
     101   void ComputeBasisCoefficients(  void );
     102   void EvaluateBasisFunctions(  void );
          
          public:
     105   CDRGNURBSSurface(  void );
     106   virtual ~CDRGNURBSSurface(  void );
          
     108   bool Init(  int uDegree,   int vDegree,   int uControlPoints,   int vControlPoints,  
           Point4D* pControlPoints,   float* pUKnots,   float* pVKnots,  
           int iDefaultUTessellations = 10,   int iDefaultVTessellations = 10 );
          
     112   void UpdateControlPoints(  Point4D* pControlPoints );
          
     114   splinePoint getData(  int index );
     115   virtual void SetTessellations(  int iUTessellations,   int iVTessellations );
     116   virtual void TessellateSurface(  void );
     117   virtual int GetTriangleCount(  void );
          
          };
          
          #endif // !defined(  AFX_DRGNURBSSURFACE_H__0D6D594B_6F3B_11D3_BE36_00902752C5DF__INCLUDED_ )

./components/ogre/SceneManagers/EmberPagingSceneManager/include/EmberPagingLandScapeData2D_HeightField.h

       1  //
          // C++ Interface: EmberPagingLandScapeData2D_HeightField
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #ifndef EMBERPAGINGLANDSCAPEDATA2D_HEIGHTFIELD_H
          #define EMBERPAGINGLANDSCAPEDATA2D_HEIGHTFIELD_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeData2D.h"
          
          
          namespace EmberOgre
          {
          namespace Terrain {
      34   class TerrainPage;
          }
          /**
           * A specialized class for loading 2D Data from Mercator,   through an EmberOgre::TerrainPage class..
           */
          
      40   class EmberPagingLandScapeData2D_HeightField: public Ogre::PagingLandScapeData2D
           {
           public:
      43   EmberPagingLandScapeData2D_HeightField(  Ogre::PagingLandScapeData2DManager *pageMgr );
      44   virtual Ogre::String getName(   ) const {return Ogre::String(  "EmberHeightField" );}
      45   virtual ~EmberPagingLandScapeData2D_HeightField(   void  ) {};
          
      47   virtual const Ogre::Vector3 getNormal(   const Ogre::Real mX,   const Ogre::Real mZ  );
      48   virtual const Ogre::ColourValue getBase(   const Ogre::Real mX,   const Ogre::Real mZ  );
      49   virtual const Ogre::ColourValue getCoverage(   const Ogre::Real mX,   const Ogre::Real mZ  );
      50   virtual const Ogre::Real getShadow(   const Ogre::Real mX,   const Ogre::Real mZ,   const bool& positive  );
          
      52   virtual Ogre::PagingLandScapeData2D* newPage(   );
          
      54   virtual const Ogre::Real getMaxAbsoluteHeight(  void ) const;
           protected:
          
      57   virtual void _save(   void  );
      58   virtual bool _load(   const uint x,   const uint z  );
      59   virtual void _load(   void  );
      60   virtual void _unload(   void  );
          
           private:
      63   Terrain::TerrainPage* mTerrainPage;
           };
          
          }
          
          
          #endif
          

./components/ogre/SceneManagers/EmberPagingSceneManager/include/EmberPagingLandScapeTexture.h

       1  //
          // C++ Interface: EmberPagingLandScapeTexture
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #ifndef EMBERPAGINGLANDSCAPETEXTURE_H
          #define EMBERPAGINGLANDSCAPETEXTURE_H
          
          #include "../../../EmberOgrePrerequisites.h"
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeTexture.h"
          
          namespace EmberOgre
          {
          
      34  class EmberPagingLandScapeTexture : public Ogre::PagingLandScapeTexture
          {
          
          public:
      38   EmberPagingLandScapeTexture(  Ogre::PagingLandScapeTextureManager *pageMgr );
      39   virtual ~EmberPagingLandScapeTexture(   void  );
          
      41   virtual Ogre::String getName(   ) const {return Ogre::String(  "EmberTexture" );}
          
      43   virtual Ogre::PagingLandScapeTexture* newTexture(    );
      44   virtual bool isMaterialSupported(  bool recursive = true );
      45   void setOptions(  void );
          
          protected:
      48   virtual void _loadMaterial(   void  );
          
      50   virtual void _unloadMaterial(   void  );
          
          };
          
          }
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/EmberPagingSceneManager.h

       1  //
          // C++ Interface: EmberPagingSceneManager
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #ifndef EMBERPAGINGSCENEMANAGER_H
          #define EMBERPAGINGSCENEMANAGER_H
          
          #include "../../../EmberOgrePrerequisites.h"
          #include "OgrePagingLandScapeSceneManager.h"
          // #include "OgrePagingLandScapeOptions.h"
          
          
          namespace EmberOgre {
          namespace Terrain {
      34  class TerrainGenerator;
          }
      36  class EmberPagingSceneManager;
          
          namespace Model {
      39  class Model;
          }
          
      42  class IPageData
          {
           void createHeightData(  Ogre::Real* heightData );
           Ogre::MaterialPtr getMaterial(   );
          };
          
          
      49  class IPageDataProvider
          {
      51   IPageData* getPageData(  Ogre::Vector2 position );
          };
          
          
           /// Factory for OctreeSceneManager
      56   class EmberPagingSceneManagerFactory : public Ogre::SceneManagerFactory
           {
           protected:
      59   void initMetaData(  void ) const;
           public:
      61   EmberPagingSceneManagerFactory(   ) {}
      62   ~EmberPagingSceneManagerFactory(   ) {}
           /// Factory type name
      64   static const Ogre::String FACTORY_TYPE_NAME;
      65   Ogre::SceneManager* createInstance(  const Ogre::String& instanceName );
      66   void destroyInstance(  Ogre::SceneManager* instance );
           };
          
          /**
           * This is a specialization of Ogre::PagingLandScapeSceneManager.
           *
           * @see Ogre::PagingLandScapeSceneManager
           */
      74  class EmberPagingSceneManager : public Ogre::PagingLandScapeSceneManager {
          public:
          
          
          
           /** Things that need to be allocated once
           */
      81   void InitScene(   void  );
          
      83   EmberPagingSceneManager(  const Ogre::String &name );
          
          // EmberTerrainSceneManager(   );
          // virtual ~EmberTerrainSceneManager(   );
          
          // void attachPage(  Ogre::ushort pageX,   Ogre::ushort pageZ,   Ogre::TerrainPage* page,  float maxY,   float minY );
          // Ogre::TerrainPage* getTerrainPage(   const Ogre::Vector3 & pt  );
          
           /*
           * Resizes the octree. Do this after adding pages.
           */
          // void doResize(   );
          
           /*
           * The scenemanager stores the pages in vectors. This does not allow
           * for pages with negative indices.
           * But WF uses negative terrain coordinates.
           * Thus we need to offset the indices.
           */
          /* int getPageOffset(   );
          
           void setWorldGeometry(   const Ogre::String& filename  );
           void setWorldGeometry(   Ogre::TerrainOptions& options  );*/
          
          
           /* const Ogre::PagingLandScapeOptions * getOptions(   ) const
           {
           assert(  mOptions );
           return mOptions;
           }*/
          
          
           /**
           * Utility method for creating a new Model.
           * @param modelName the id of the model
           * @param modelDefinitionName the name of the model defition from which the model should be created
           * @return
           */
     121   Model::Model* createModel(  
     122   const Ogre::String& modelName,  
     123   const Ogre::String& modelDefinitionName  );
          
     125   void registerProvider(  IPageDataProvider* provider );
          
          protected:
          
           /*
           * @see EmberOgre::EmberTerrainSceneManager::getPageOffset(   )
           */
     132   Ogre::ushort mPageOffset;
          
          // /*
          // * Stitches the neighbours,   preventing gaps
          // */
          // void setupPageNeighbors(  Ogre::ushort pageX,   Ogre::ushort pageZ,   Ogre::TerrainPage* page );
          
           /*
           * Max and min values for the world. Used to resize the octree.
           */
           float mMaxX;
           float mMaxY;
           float mMaxZ;
           float mMinX;
           float mMinY;
           float mMinZ;
          
     149   IPageDataProvider* mProvider;
          
          
          private:
          };
          
          }
          
          #endif // EMBERPAGINGSCENEMANAGER_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/EmberPagingSceneManagerAdapter.h

       1  //
          // C++ Interface: EmberPagingSceneManagerAdapter
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #include "../../../EmberOgrePrerequisites.h"
          
          #include "../../../terrain/ISceneManagerAdapter.h"
          
          namespace Ogre
          {
      30  class PagingLandScapeOptions;
      31  class SceneManager;
          }
          
          namespace EmberOgre {
          
      36  class EmberPagingSceneManager;
          
      38  class EmberPagingSceneManagerAdapter : public Terrain::ISceneManagerAdapter
          {
          
          public:
          
      43   EmberPagingSceneManagerAdapter(  EmberPagingSceneManager* scenemanager );
          
          
      46   virtual int getPageSize(   );
      47   virtual Ogre::Real getHeightAt(  const Ogre::Real x,   const Ogre::Real z );
          
      49   virtual void setWorldPagesDimensions(  int numberOfPagesHeight,   int numberOfPagesWidth,   int heightOffsetInPages,   int widthOffsetInPages );
          
      51   virtual void setCamera(  Ogre::Camera* camera );
      52   virtual void setResourceGroupName(  const std::string& groupName );
      53   virtual void loadOptions(  const std::string& filePath );
      54   virtual void resize(  Ogre::AxisAlignedBox newSize,   int levels );
      55   virtual void loadScene(   );
          
      57   virtual void setOption(  const std::string& strKey,   const void* pValue );
      58   virtual void getOption(  const std::string& strKey,   void* pDestValue );
          
      60   virtual Ogre::SceneManager* getSceneManager(   ) const;
      61   virtual void reloadAllPages(   );
      62   virtual void reloadPage(  unsigned int x,   unsigned int z );
          
          private:
      65   EmberPagingSceneManager* mSceneManager;
      66   Ogre::PagingLandScapeOptions* getOptions(   );
          
          };
          
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgreDebugRectangle2D.h

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          
          #ifndef _DebugRectangle2D_H__
          #define _DebugRectangle2D_H__
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          #ifdef _VISIBILITYDEBUG
          
          #include "OgreSimpleRenderable.h"
          
          namespace Ogre
          {
          
           /** Allows the rendering of a simple 2D rectangle
           This class renders a simple 2D rectangle; this rectangle has no depth and
           therefore is best used with specific render queue and depth settings,  
           like RENDER_QUEUE_BACKGROUND and 'depth_write off' for backdrops,   and
           RENDER_QUEUE_OVERLAY and 'depth_check off' for fullscreen quads.
           */
      44   class DebugRectangle2D : public SimpleRenderable
           {
           protected:
           /** Override this method to prevent parent transforms (  rotation,  translation,  scale )
           */
      49   void getWorldTransforms(  Matrix4* xform ) const;
           /** @copydoc Renderable::getWorldOrientation */
      51   const Quaternion& getWorldOrientation(  void ) const;
           /** @copydoc Renderable::getWorldPosition */
      53   const Vector3& getWorldPosition(  void ) const;
          
           public:
          
      57   DebugRectangle2D(   );
      58   ~DebugRectangle2D(   );
          
           /** Sets the corners of the rectangle,   in relative coordinates.
           @param
           left Left position in screen relative coordinates,   -1 = left edge,   1.0 = right edge
           top Top position in screen relative coordinates,   1 = top edge,   -1 = bottom edge
           right Right position in screen relative coordinates
           bottom Bottom position in screen relative coordinates
           */
      67   void setCorners(  Real left,   Real top,   Real right,   Real bottom );
          
      69   Real getSquaredViewDepth(  const Camera* cam ) const { return 0; }
          
      71   Real getBoundingRadius(  void ) const { return 0; }
           /// Identity view and projection
          #ifdef PLSM2_EIHORT
      74   bool getUseIdentityProjection(  void ) const { return mUseIdentityProjection; }
          #else
      76   bool useIdentityProjection(  void ) const { return true; }
          #endif
           /// Identity view and projection
          #ifdef PLSM2_EIHORT
      80   bool getUseIdentityView(  void ) const { return mUseIdentityView; }
          #else
      82   bool useIdentityView(  void ) const { return true; }
          #endif
          
           };
          
          }// namespace
          
          #endif //_VISIBILITYDEBUG
          
          #endif // _DebugRectangle2D_H__
          

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgreOcclusionBoundingBox.h

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
           (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          #ifndef _OcclusionBoundingBox_H__
          #define _OcclusionBoundingBox_H__
          
          #include "OgrePrerequisites.h"
          
          #include "OgreSimpleRenderable.h"
          
          namespace Ogre
          {
          
           /** Allows the rendering of an opaque bounding box.
           @remarks
           This class builds a opaque renderable from a given aabb. A pointer to this class can be
           added to a render queue to display the bounding box of an object.
           */
      40   class OcclusionBoundingBox : public SimpleRenderable
           {
           protected:
           /** Override this method to prevent parent transforms (  rotation,  translation,  scale )
           */
      45   void getWorldTransforms(  Matrix4* xform ) const;
           /** @copydoc Renderable::getWorldOrientation */
      47   const Quaternion& getWorldOrientation(  void ) const;
           /** @copydoc Renderable::getWorldPosition */
      49   const Vector3& getWorldPosition(  void ) const;
          
           /** Builds the wireframe line list.
           */
      53   void setupBoundingBoxVertices(  const AxisAlignedBox& aab );
          
      55   Real mRadius;
          
           public:
          
      59   OcclusionBoundingBox(   );
      60   ~OcclusionBoundingBox(   );
          
      62   virtual PolygonMode getRenderDetail(   ) const;
          
           /** Builds the wireframe line list.
           @param
           aabb bounding box to build a wireframe from.
           */
      68   void setupBoundingBox(  const AxisAlignedBox& aabb );
          
      70   Real getSquaredViewDepth(  const Camera* cam ) const;
          
      72   Real getBoundingRadius(  void ) const { return mRadius; }
          
           };
          
          }// namespace
          
          #endif
          
          

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeAxisAlignedBoxSceneQuery.h

          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreeAxisAlignedBoxSceneQuery.h - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004 by Jon Anderson
          email : janders@users.sf.net
          ***************************************************************************/
          
          #ifndef PagingLandScapeAxisAlignedBoxSCENEQUERY_H
          #define PagingLandScapeAxisAlignedBoxSCENEQUERY_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgreSceneManager.h"
          
          namespace Ogre
          {
          
          /** PagingLandScape implementation of AxisAlignedBoxSceneQuery. */
          class _OgrePagingLandScapeExport PagingLandScapeAxisAlignedBoxSceneQuery : public DefaultAxisAlignedBoxSceneQuery
          {
          public:
      46   PagingLandScapeAxisAlignedBoxSceneQuery(  SceneManager* creator );
           virtual ~PagingLandScapeAxisAlignedBoxSceneQuery(  void );
          
           /** See RayScenQuery. */
           /** Finds any entities that intersect the AAB for the query. */
           void execute(  SceneQueryListener* listener );
          
           // Structure returned in the geometry field of the worldFragment for this
           // query. Cut'n'paste this into your client w/out the setters if using
           // this query from a client.
           struct CustomQueryResult
           {
           enum CustomQueryResultTypes { QUERY_EXTENTS_TYPE,   SUBSECTION_EXTENTS_TYPE,   VERTEX_TYPE };
          
           void SetQueryExtents(   int width,   int height  )
           {
           type_ = QUERY_EXTENTS_TYPE;
           data_.queryExtents_.width_ = width;
           data_.queryExtents_.height_ = height;
           }
           void SetSubsectionExtents(   int width,   int height,   short renderLevel,   int subX,   int subZ  )
           {
           type_ = SUBSECTION_EXTENTS_TYPE;
           data_.subExtents_.width_ = width;
           data_.subExtents_.height_ = height;
           data_.subExtents_.renderLevel_ = renderLevel;
           data_.subExtents_.subX_ = subX;
           data_.subExtents_.subZ_ = subZ;
           }
           void SetVertex(   const Vector3& vertex,   bool included  )
           {
           type_ = VERTEX_TYPE;
           // Can't use a Vector3 in a union,   so we'll break it up.
           data_.vertexData_.x_ = vertex.x;
           data_.vertexData_.y_ = vertex.y;
           data_.vertexData_.z_ = vertex.z;
           data_.vertexData_.included_ = included;
           }
          
           CustomQueryResultTypes type_;
           union
           {
           struct
           {
           int width_;
           int height_;
           } queryExtents_;
           struct
           {
           int width_;
           int height_;
           short renderLevel_;
           int subX_;
           int subZ_;
           } subExtents_;
           struct
           {
           Real x_;
           Real y_;
           Real z_;
           bool included_;
           } vertexData_;
           } data_;
           };
          };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeCallBackEvent.h

       1  #ifndef __PagingLandScapeCallBackEvent_H__
          #define __PagingLandScapeCallBackEvent_H__
          
          #include "Ogre.h"
          #include "OgrePagingLandScapeCallback.h"
          
          namespace Ogre
          {
           //---------------------------------------------------------------------
      10   class PagingLandscapeEvent
           {
           public:
      13   PagingLandscapeEvent(  const size_t pagex,   const size_t pagez,  
      14   const size_t tilex,   const size_t tilez,  
      15   const Real* heightData,   const AxisAlignedBox &Bbox ) :
           mPagex(  pagex ),  
           mPagez(  pagez ),  
           mTilex(  tilex ),  
           mTilez(  tilez ),  
           mHeightData(  heightData ),  
           mBbox(  Bbox )
           {
          
           };
      25   ~PagingLandscapeEvent(   ){};
          
      27   const size_t mPagex;
      28   const size_t mPagez;
      29   const size_t mTilex;
      30   const size_t mTilez;
      31   const Real* mHeightData;
      32   const AxisAlignedBox &mBbox;
          
           };
           typedef fastdelegate::FastDelegate1<PagingLandscapeEvent *> PagingLandscapeDelegate;
          }
          #endif //__PagingLandScapeCallBackEvent_H__

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeCallback.h

          // FastDelegate.h
          // Efficient delegates in C++ that generate only two lines of asm code!
          // Documentation is found at http://www.codeproject.com/cpp/FastDelegate.asp
          //
          // - Don Clugston,   Mar 2004.
          // Major contributions were made by Jody Hagins.
          // History:
          // 24-Apr-04 1.0 * Submitted to CodeProject.
          // 28-Apr-04 1.1 * Prevent most unsafe uses of evil static function hack.
          // * Improved syntax for horrible_cast (  thanks Paul Bludov ).
          // * Tested on Metrowerks MWCC and Intel ICL (  IA32 )
          // * Compiled,   but not run,   on Comeau C++ and Intel Itanium ICL.
          // 27-Jun-04 1.2 * Now works on Borland C++ Builder 5.5
          // * Now works on /clr "managed C++" code on VC7,   VC7.1
          // * Comeau C++ now compiles without warnings.
          // * Prevent the virtual inheritance case from being used on
          // VC6 and earlier,   which generate incorrect code.
          // * Improved warning and error messages. Non-standard hacks
          // now have compile-time checks to make them safer.
          // * implicit_cast used instead of static_cast in many cases.
          // * If calling a const member function,   a const class pointer can be used.
          // * MakeDelegate(   ) global helper function added to simplify pass-by-value.
          // * Added fastdelegate.clear(   )
          // 16-Jul-04 1.2.1* Workaround for gcc bug (  const member function pointers in templates )
          // 30-Oct-04 1.3 * Support for (  non-void ) return values.
          // * No more workarounds in client code!
          // MSVC and Intel now use a clever hack invented by John Dlugosz:
          // - The FASTDELEGATEDECLARE workaround is no longer necessary.
          // - No more warning messages for VC6
          // * Less use of macros. Error messages should be more comprehensible.
          // * Added include guards
          // * Added FastDelegate::empty(   ) to test if invocation is safe (  Thanks Neville Franks ).
          // * Now tested on VS 2006 Express Beta,   PGI C++
          // 24-Dec-04 1.4 * Added DelegateMemento,   to allow collections of disparate delegates.
          // * <,  >,  <=,  >= comparison operators to allow storage in ordered containers.
          // * Substantial reduction of code size,   especially the 'Closure' class.
          // * Standardised all the compiler-specific workarounds.
          // * MFP conversion now works for CodePlay (  but not yet supported in the full code ).
          // * Now compiles without warnings on _any_ supported compiler,   including BCC 5.5.1
          // * New syntax: FastDelegate< int (  char *,   double ) >.
          // 14-Feb-05 1.4.1* Now treats =0 as equivalent to .clear(   ),   ==0 as equivalent to .empty(   ). (  Thanks elfric ).
          // * Now tested on Intel ICL for AMD64,   VS2006 Beta for AMD64 and Itanium.
          // 30-Mar-05 1.5 * Safebool idiom: "if (  dg )" is now equivalent to "if (  !dg.empty(   ) )"
          // * Fully supported by CodePlay VectorC
          // * Bugfix for Metrowerks: empty(   ) was buggy because a valid MFP can be 0 on MWCC!
          // * More optimal assignment,  == and != operators for static function pointers.
          
          #ifndef FASTDELEGATE_H
          #define FASTDELEGATE_H
          #if _MSC_VER > 1000
          #pragma once
          #endif // _MSC_VER > 1000
          
          #include <memory.h> // to allow <,  > comparisons
          
          ////////////////////////////////////////////////////////////////////////////////
          // Configuration options
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          // Uncomment the following #define for optimally-sized delegates.
          // In this case,   the generated asm code is almost identical to the code you'd get
          // if the compiler had native support for delegates.
          // It will not work on systems where sizeof(  dataptr ) < sizeof(  codeptr ).
          // Thus,   it will not work for DOS compilers using the medium model.
          // It will also probably fail on some DSP systems.
          #define FASTDELEGATE_USESTATICFUNCTIONHACK
          
          // Uncomment the next line to allow function declarator syntax.
          // It is automatically enabled for those compilers where it is known to work.
          //#define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
          
          ////////////////////////////////////////////////////////////////////////////////
          // Compiler identification for workarounds
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          // Compiler identification. It's not easy to identify Visual C++ because
          // many vendors fraudulently define Microsoft's identifiers.
          #if defined(  _MSC_VER ) && !defined(  __MWERKS__ ) && !defined(  __VECTOR_C ) && !defined(  __ICL ) && !defined(  __BORLANDC__ )
          #define FASTDLGT_ISMSVC
          
          #if (  _MSC_VER <1300 ) // Many workarounds are required for VC6.
          #define FASTDLGT_VC6
          #pragma warning(  disable:4786 ) // disable this ridiculous warning
          #endif
          
          #endif
          
          // Does the compiler uses Microsoft's member function pointer structure?
          // If so,   it needs special treatment.
          // Metrowerks CodeWarrior,   Intel,   and CodePlay fraudulently define Microsoft's
          // identifier,   _MSC_VER. We need to filter Metrowerks out.
          #if defined(  _MSC_VER ) && !defined(  __MWERKS__ )
          #define FASTDLGT_MICROSOFT_MFP
          
          #if !defined(  __VECTOR_C )
          // CodePlay doesn't have the __single/multi/virtual_inheritance keywords
          #define FASTDLGT_HASINHERITANCE_KEYWORDS
          #endif
          #endif
          
          // Does it allow function declarator syntax? The following compilers are known to work:
          #if defined(  FASTDLGT_ISMSVC ) && (  _MSC_VER >=1310 ) // VC 7.1
          #define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
          #endif
          
          // Gcc(  2.95+ ),   and versions of Digital Mars,   Intel and Comeau in common use.
          #if defined (  __DMC__ ) || defined(  __GNUC__ ) || defined(  __ICL ) || defined(  __COMO__ )
          #define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
          #endif
          
          // It works on Metrowerks MWCC 3.2.2. From boost.Config it should work on earlier ones too.
          #if defined (  __MWERKS__ )
          #define FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
          #endif
          
          #ifdef __GNUC__ // Workaround GCC bug #8271
           // At present,   GCC doesn't recognize constness of MFPs in templates
          #define FASTDELEGATE_GCC_BUG_8271
          #endif
          
          
          
          ////////////////////////////////////////////////////////////////////////////////
          // General tricks used in this code
          //
          // (  a ) Error messages are generated by typdefing an array of negative size to
          // generate compile-time errors.
          // (  b ) Warning messages on MSVC are generated by declaring unused variables,   and
          // enabling the "variable XXX is never used" warning.
          // (  c ) Unions are used in a few compiler-specific cases to perform illegal casts.
          // (  d ) For Microsoft and Intel,   when adjusting the 'this' pointer,   it's cast to
          // (  char * ) first to ensure that the correct number of *bytes* are added.
          //
          ////////////////////////////////////////////////////////////////////////////////
          // Helper templates
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          
          namespace fastdelegate {
          namespace detail { // we'll hide the implementation details in a nested namespace.
          
          // implicit_cast< >
          // I believe this was originally going to be in the C++ standard but
          // was left out by accident. It's even milder than static_cast.
          // I use it instead of static_cast<> to emphasize that I'm not doing
          // anything nasty.
          // Usage is identical to static_cast<>
          template <class OutputClass,   class InputClass>
     152  inline OutputClass implicit_cast(  InputClass input ){
           return input;
          }
          
          // horrible_cast< >
          // This is truly evil. It completely subverts C++'s type system,   allowing you
          // to cast from any class to any other class. Technically,   using a union
          // to perform the cast is undefined behaviour (  even in C ). But we can see if
          // it is OK by checking that the union is the same size as each of its members.
          // horrible_cast<> should only be used for compiler-specific workarounds.
          // Usage is identical to reinterpret_cast<>.
          
          // This union is declared outside the horrible_cast because BCC 5.5.1
          // can't inline a function with a nested class,   and gives a warning.
          template <class OutputClass,   class InputClass>
     167  union horrible_union{
           OutputClass out;
           InputClass in;
          };
          
          template <class OutputClass,   class InputClass>
     173  inline OutputClass horrible_cast(  const InputClass input ){
           horrible_union<OutputClass,   InputClass> u;
           // Cause a compile-time error if in,   out and u are not the same size.
           // If the compile fails here,   it means the compiler has peculiar
           // unions which would prevent the cast from working.
           typedef int ERROR_CantUseHorrible_cast[sizeof(  InputClass )==sizeof(  u )
           && sizeof(  InputClass )==sizeof(  OutputClass ) ? 1 : -1];
           u.in = input;
           return u.out;
          }
          
          ////////////////////////////////////////////////////////////////////////////////
          // Workarounds
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          // Backwards compatibility: This macro used to be necessary in the virtual inheritance
          // case for Intel and Microsoft. Now it just forward-declares the class.
          #define FASTDELEGATEDECLARE(  CLASSNAME ) class CLASSNAME;
          
          // Prevent use of the static function hack with the DOS medium model.
          #ifdef __MEDIUM__
          #undef FASTDELEGATE_USESTATICFUNCTIONHACK
          #endif
          
          // DefaultVoid - a workaround for 'void' templates in VC6.
          //
          // (  1 ) VC6 and earlier do not allow 'void' as a default template argument.
          // (  2 ) They also doesn't allow you to return 'void' from a function.
          //
          // Workaround for (  1 ): Declare a dummy type 'DefaultVoid' which we use
          // when we'd like to use 'void'. We convert it into 'void' and back
          // using the templates DefaultVoidToVoid<> and VoidToDefaultVoid<>.
          // Workaround for (  2 ): On VC6,   the code for calling a void function is
          // identical to the code for calling a non-void function in which the
          // return value is never used,   provided the return value is returned
          // in the EAX register,   rather than on the stack.
          // This is true for most fundamental types such as int,   enum,   void *.
          // Const void * is the safest option since it doesn't participate
          // in any automatic conversions. But on a 16-bit compiler it might
          // cause extra code to be generated,   so we disable it for all compilers
          // except for VC6 (  and VC5 ).
          #ifdef FASTDLGT_VC6
          // VC6 workaround
          typedef const void * DefaultVoid;
          #else
          // On any other compiler,   just use a normal void.
          typedef void DefaultVoid;
          #endif
          
          // Translate from 'DefaultVoid' to 'void'.
          // Everything else is unchanged
          template <class T>
          struct DefaultVoidToVoid { typedef T type; };
          
          template <>
          struct DefaultVoidToVoid<DefaultVoid> { typedef void type; };
          
          // Translate from 'void' into 'DefaultVoid'
          // Everything else is unchanged
          template <class T>
          struct VoidToDefaultVoid { typedef T type; };
          
          template <>
          struct VoidToDefaultVoid<void> { typedef DefaultVoid type; };
          
          
          
          ////////////////////////////////////////////////////////////////////////////////
          // Fast Delegates,   part 1:
          //
          // Conversion of member function pointer to a standard form
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          // GenericClass is a fake class,   ONLY used to provide a type.
          // It is vitally important that it is never defined,   so that the compiler doesn't
          // think it can optimize the invocation. For example,   Borland generates simpler
          // code if it knows the class only uses single inheritance.
          
          // Compilers using Microsoft's structure need to be treated as a special case.
          #ifdef FASTDLGT_MICROSOFT_MFP
          
          #ifdef FASTDLGT_HASINHERITANCE_KEYWORDS
           // For Microsoft and Intel,   we want to ensure that it's the most efficient type of MFP
           // (  4 bytes ),   even when the /vmg option is used. Declaring an empty class
           // would give 16 byte pointers in this case....
           class __single_inheritance GenericClass;
          #endif
           // ...but for Codeplay,   an empty class *always* gives 4 byte pointers.
           // If compiled with the /clr option (  "managed C++" ),   the JIT compiler thinks
           // it needs to load GenericClass before it can call any of its functions,  
           // (  compiles OK but crashes at runtime! ),   so we need to declare an
           // empty class to make it happy.
           // Codeplay and VC4 can't cope with the unknown_inheritance case either.
     268   class GenericClass {};
          #else
     270   class GenericClass;
          #endif
          
          // The size of a single inheritance member function pointer.
          const int SINGLE_MEMFUNCPTR_SIZE = sizeof(  void (  GenericClass::* )(   ) );
          
          // SimplifyMemFunc< >::Convert(   )
          //
          // A template function that converts an arbitrary member function pointer into the
          // simplest possible form of member function pointer,   using a supplied 'this' pointer.
          // According to the standard,   this can be done legally with reinterpret_cast<>.
          // For (  non-standard ) compilers which use member function pointers which vary in size
          // depending on the class,   we need to use knowledge of the internal structure of a
          // member function pointer,   as used by the compiler. Template specialization is used
          // to distinguish between the sizes. Because some compilers don't support partial
          // template specialisation,   I use full specialisation of a wrapper struct.
          
          // general case -- don't know how to convert it. Force a compile failure
          template <int N>
          struct SimplifyMemFunc {
           template <class X,   class XFuncType,   class GenericMemFuncType>
           inline static GenericClass *Convert(  X *pthis,   XFuncType function_to_bind,  
           GenericMemFuncType &bound_func ) {
           // Unsupported member function type -- force a compile failure.
           // (  it's illegal to have a array with negative size ).
           typedef char ERROR_Unsupported_member_function_pointer_on_this_compiler[N-100];
           return 0;
           }
          };
          
          // For compilers where all member func ptrs are the same size,   everything goes here.
          // For non-standard compilers,   only single_inheritance classes go here.
          template <>
          struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE> {
           template <class X,   class XFuncType,   class GenericMemFuncType>
           inline static GenericClass *Convert(  X *pthis,   XFuncType function_to_bind,  
           GenericMemFuncType &bound_func ) {
          #if defined __DMC__
           // Digital Mars doesn't allow you to cast between abitrary PMF's,  
           // even though the standard says you can. The 32-bit compiler lets you
           // static_cast through an int,   but the DOS compiler doesn't.
           bound_func = horrible_cast<GenericMemFuncType>(  function_to_bind );
          #else
           bound_func = reinterpret_cast<GenericMemFuncType>(  function_to_bind );
          #endif
           return reinterpret_cast<GenericClass *>(  pthis );
           }
          };
          
          ////////////////////////////////////////////////////////////////////////////////
          // Fast Delegates,   part 1b:
          //
          // Workarounds for Microsoft and Intel
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          
          // Compilers with member function pointers which violate the standard (  MSVC,   Intel,   Codeplay ),  
          // need to be treated as a special case.
          #ifdef FASTDLGT_MICROSOFT_MFP
          
          // We use unions to perform horrible_casts. I would like to use #pragma pack(  push,   1 )
          // at the start of each function for extra safety,   but VC6 seems to ICE
          // intermittently if you do this inside a template.
          
          // __multiple_inheritance classes go here
          // Nasty hack for Microsoft and Intel (  IA32 and Itanium )
          template<>
          struct SimplifyMemFunc< SINGLE_MEMFUNCPTR_SIZE + sizeof(  int ) > {
           template <class X,   class XFuncType,   class GenericMemFuncType>
           inline static GenericClass *Convert(  X *pthis,   XFuncType function_to_bind,  
           GenericMemFuncType &bound_func ) {
           // We need to use a horrible_cast to do this conversion.
           // In MSVC,   a multiple inheritance member pointer is internally defined as:
           union {
           XFuncType func;
           struct {
           GenericMemFuncType funcaddress; // points to the actual member function
           int delta; // #BYTES to be added to the 'this' pointer
           }s;
           } u;
           // Check that the horrible_cast will work
           typedef int ERROR_CantUsehorrible_cast[sizeof(  function_to_bind )==sizeof(  u.s )? 1 : -1];
           u.func = function_to_bind;
           bound_func = u.s.funcaddress;
           return reinterpret_cast<GenericClass *>(  reinterpret_cast<char *>(  pthis ) + u.s.delta );
           }
          };
          
          // virtual inheritance is a real nuisance. It's inefficient and complicated.
          // On MSVC and Intel,   there isn't enough information in the pointer itself to
          // enable conversion to a closure pointer. Earlier versions of this code didn't
          // work for all cases,   and generated a compile-time error instead.
          // But a very clever hack invented by John M. Dlugosz solves this problem.
          // My code is somewhat different to his: I have no asm code,   and I make no
          // assumptions about the calling convention that is used.
          
          // In VC++ and ICL,   a virtual_inheritance member pointer
          // is internally defined as:
          struct MicrosoftVirtualMFP {
           void (  GenericClass::*codeptr )(   ); // points to the actual member function
           int delta; // #bytes to be added to the 'this' pointer
           int vtable_index; // or 0 if no virtual inheritance
          };
          // The CRUCIAL feature of Microsoft/Intel MFPs which we exploit is that the
          // m_codeptr member is *always* called,   regardless of the values of the other
          // members. (  This is *not* true for other compilers,   eg GCC,   which obtain the
          // function address from the vtable if a virtual function is being called ).
          // Dlugosz's trick is to make the codeptr point to a probe function which
          // returns the 'this' pointer that was used.
          
          // Define a generic class that uses virtual inheritance.
          // It has a trival member function that returns the value of the 'this' pointer.
          struct GenericVirtualClass : virtual public GenericClass
          {
           typedef GenericVirtualClass * (  GenericVirtualClass::*ProbePtrType )(   );
           GenericVirtualClass * GetThis(   ) { return this; }
          };
          
          // __virtual_inheritance classes go here
          template <>
          struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 2*sizeof(  int ) >
          {
          
           template <class X,   class XFuncType,   class GenericMemFuncType>
           inline static GenericClass *Convert(  X *pthis,   XFuncType function_to_bind,  
           GenericMemFuncType &bound_func ) {
           union {
           XFuncType func;
           GenericClass* (  X::*ProbeFunc )(   );
           MicrosoftVirtualMFP s;
           } u;
           u.func = function_to_bind;
           bound_func = reinterpret_cast<GenericMemFuncType>(  u.s.codeptr );
           union {
           GenericVirtualClass::ProbePtrType virtfunc;
           MicrosoftVirtualMFP s;
           } u2;
           // Check that the horrible_cast<>s will work
           typedef int ERROR_CantUsehorrible_cast[sizeof(  function_to_bind )==sizeof(  u.s )
           && sizeof(  function_to_bind )==sizeof(  u.ProbeFunc )
           && sizeof(  u2.virtfunc )==sizeof(  u2.s ) ? 1 : -1];
           // Unfortunately,   taking the address of a MF prevents it from being inlined,   so
           // this next line can't be completely optimised away by the compiler.
           u2.virtfunc = &GenericVirtualClass::GetThis;
           u.s.codeptr = u2.s.codeptr;
           return (  pthis->*u.ProbeFunc )(   );
           }
          };
          
          #if (  _MSC_VER <1300 )
          
          // Nasty hack for Microsoft Visual C++ 6.0
          // unknown_inheritance classes go here
          // There is a compiler bug in MSVC6 which generates incorrect code in this case!!
          template <>
          struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 3*sizeof(  int ) >
          {
           template <class X,   class XFuncType,   class GenericMemFuncType>
           inline static GenericClass *Convert(  X *pthis,   XFuncType function_to_bind,  
           GenericMemFuncType &bound_func ) {
           // There is an apalling but obscure compiler bug in MSVC6 and earlier:
           // vtable_index and 'vtordisp' are always set to 0 in the
           // unknown_inheritance case!
           // This means that an incorrect function could be called!!!
           // Compiling with the /vmg option leads to potentially incorrect code.
           // This is probably the reason that the IDE has a user interface for specifying
           // the /vmg option,   but it is disabled - you can only specify /vmg on
           // the command line. In VC1.5 and earlier,   the compiler would ICE if it ever
           // encountered this situation.
           // It is OK to use the /vmg option if /vmm or /vms is specified.
          
           // Fortunately,   the wrong function is only called in very obscure cases.
           // It only occurs when a derived class overrides a virtual function declared
           // in a virtual base class,   and the member function
           // points to the *Derived* version of that function. The problem can be
           // completely averted in 100% of cases by using the *Base class* for the
           // member fpointer. Ie,   if you use the base class as an interface,   you'll
           // stay out of trouble.
           // Occasionally,   you might want to point directly to a derived class function
           // that isn't an override of a base class. In this case,   both vtable_index
           // and 'vtordisp' are zero,   but a virtual_inheritance pointer will be generated.
           // We can generate correct code in this case. To prevent an incorrect call from
           // ever being made,   on MSVC6 we generate a warning,   and call a function to
           // make the program crash instantly.
           typedef char ERROR_VC6CompilerBug[-100];
           return 0;
           }
          };
          
          
          #else
          
          // Nasty hack for Microsoft and Intel (  IA32 and Itanium )
          // unknown_inheritance classes go here
          // This is probably the ugliest bit of code I've ever written. Look at the casts!
          // There is a compiler bug in MSVC6 which prevents it from using this code.
          template <>
          struct SimplifyMemFunc<SINGLE_MEMFUNCPTR_SIZE + 3*sizeof(  int ) >
          {
           template <class X,   class XFuncType,   class GenericMemFuncType>
           inline static GenericClass *Convert(  X *pthis,   XFuncType function_to_bind,  
           GenericMemFuncType &bound_func ) {
           // The member function pointer is 16 bytes long. We can't use a normal cast,   but
           // we can use a union to do the conversion.
           union {
           XFuncType func;
           // In VC++ and ICL,   an unknown_inheritance member pointer
           // is internally defined as:
           struct {
           GenericMemFuncType m_funcaddress; // points to the actual member function
           int delta; // #bytes to be added to the 'this' pointer
           int vtordisp; // #bytes to add to 'this' to find the vtable
           int vtable_index; // or 0 if no virtual inheritance
           } s;
           } u;
           // Check that the horrible_cast will work
           typedef int ERROR_CantUsehorrible_cast[sizeof(  XFuncType )==sizeof(  u.s )? 1 : -1];
           u.func = function_to_bind;
           bound_func = u.s.funcaddress;
           int virtual_delta = 0;
           if (  u.s.vtable_index ) { // Virtual inheritance is used
           // First,   get to the vtable.
           // It is 'vtordisp' bytes from the start of the class.
           const int * vtable = *reinterpret_cast<const int *const*>(  
           reinterpret_cast<const char *>(  pthis ) + u.s.vtordisp  );
          
           // 'vtable_index' tells us where in the table we should be looking.
           virtual_delta = u.s.vtordisp + *reinterpret_cast<const int *>(  
           reinterpret_cast<const char *>(  vtable ) + u.s.vtable_index );
           }
           // The int at 'virtual_delta' gives us the amount to add to 'this'.
           // Finally we can add the three components together. Phew!
           return reinterpret_cast<GenericClass *>(  
           reinterpret_cast<char *>(  pthis ) + u.s.delta + virtual_delta );
           };
          };
          #endif // MSVC 7 and greater
          
          #endif // MS/Intel hacks
          
          } // namespace detail
          
          ////////////////////////////////////////////////////////////////////////////////
          // Fast Delegates,   part 2:
          //
          // Define the delegate storage,   and cope with static functions
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          // DelegateMemento -- an opaque structure which can hold an arbitary delegate.
          // It knows nothing about the calling convention or number of arguments used by
          // the function pointed to.
          // It supplies comparison operators so that it can be stored in STL collections.
          // It cannot be set to anything other than null,   nor invoked directly:
          // it must be converted to a specific delegate.
          
          // Implementation:
          // There are two possible implementations: the Safe method and the Evil method.
          // DelegateMemento - Safe version
          //
          // This implementation is standard-compliant,   but a bit tricky.
          // A static function pointer is stored inside the class.
          // Here are the valid values:
          // +-- Static pointer --+--pThis --+-- pMemFunc-+-- Meaning------+
          // | 0 | 0 | 0 | Empty |
          // | !=0 |(  dontcare )| Invoker | Static function|
          // | 0 | !=0 | !=0* | Method call |
          // +--------------------+----------+------------+----------------+
          // * For Metrowerks,   this can be 0. (  first virtual function in a
          // single_inheritance class ).
          // When stored stored inside a specific delegate,   the 'dontcare' entries are replaced
          // with a reference to the delegate itself. This complicates the = and == operators
          // for the delegate class.
          
          // DelegateMemento - Evil version
          //
          // For compilers where data pointers are at least as big as code pointers,   it is
          // possible to store the function pointer in the this pointer,   using another
          // horrible_cast. In this case the DelegateMemento implementation is simple:
          // +--pThis --+-- pMemFunc-+-- Meaning---------------------+
          // | 0 | 0 | Empty |
          // | !=0 | !=0* | Static function or method call|
          // +----------+------------+-------------------------------+
          // * For Metrowerks,   this can be 0. (  first virtual function in a
          // single_inheritance class ).
          // Note that the Sun C++ and MSVC documentation explicitly state that they
          // support static_cast between void * and function pointers.
          
          class DelegateMemento {
          protected:
           // the data is protected,   not private,   because many
           // compilers have problems with template friends.
           typedef void (  detail::GenericClass::*GenericMemFuncType )(   ); // arbitrary MFP.
           detail::GenericClass *m_pthis;
           GenericMemFuncType m_pFunction;
          
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
           typedef void (  *GenericFuncPtr )(   ); // arbitrary code pointer
           GenericFuncPtr m_pStaticFunction;
          #endif
          
          public:
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
           DelegateMemento(   ) : m_pthis(  0 ),   m_pFunction(  0 ),   m_pStaticFunction(  0 ) {};
           void clear(   ) {
           m_pthis=0; m_pFunction=0; m_pStaticFunction=0;
           }
          #else
           DelegateMemento(   ) : m_pthis(  0 ),   m_pFunction(  0 ) {};
           void clear(   ) { m_pthis=0; m_pFunction=0; }
          #endif
          public:
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
           inline bool IsEqual (  const DelegateMemento &x ) const{
           // We have to cope with the static function pointers as a special case
           if (  m_pFunction!=x.m_pFunction ) return false;
           // the static function ptrs must either both be equal,   or both be 0.
           if (  m_pStaticFunction!=x.m_pStaticFunction ) return false;
           if (  m_pStaticFunction!=0 ) return m_pthis==x.m_pthis;
           else return true;
           }
          #else // Evil Method
           inline bool IsEqual (  const DelegateMemento &x ) const{
           return m_pthis==x.m_pthis && m_pFunction==x.m_pFunction;
           }
          #endif
           // Provide a strict weak ordering for DelegateMementos.
           inline bool IsLess(  const DelegateMemento &right ) const {
           // deal with static function pointers first
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
           if (  m_pStaticFunction !=0 || right.m_pStaticFunction!=0 )
           return m_pStaticFunction < right.m_pStaticFunction;
          #endif
           if (  m_pthis !=right.m_pthis ) return m_pthis < right.m_pthis;
           // There are no ordering operators for member function pointers,  
           // but we can fake one by comparing each byte. The resulting ordering is
           // arbitrary (  and compiler-dependent ),   but it permits storage in ordered STL containers.
           return memcmp(  &m_pFunction,   &right.m_pFunction,   sizeof(  m_pFunction ) ) < 0;
          
           }
           // BUGFIX (  Mar 2006 ):
           // We can't just compare m_pFunction because on Metrowerks,  
           // m_pFunction can be zero even if the delegate is not empty!
           inline bool operator ! (   ) const // Is it bound to anything?
           { return m_pthis==0 && m_pFunction==0; }
           inline bool empty(   ) const // Is it bound to anything?
           { return m_pthis==0 && m_pFunction==0; }
          public:
           DelegateMemento & operator = (  const DelegateMemento &right ) {
           SetMementoFrom(  right );
           return *this;
           }
           inline bool operator <(  const DelegateMemento &right ) {
           return IsLess(  right );
           }
           inline bool operator >(  const DelegateMemento &right ) {
           return right.IsLess(  *this );
           }
           DelegateMemento (  const DelegateMemento &right ) :
           m_pFunction(  right.m_pFunction ),   m_pthis(  right.m_pthis )
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
           ,   m_pStaticFunction (  right.m_pStaticFunction )
          #endif
           {}
          protected:
           void SetMementoFrom(  const DelegateMemento &right ) {
           m_pFunction = right.m_pFunction;
           m_pthis = right.m_pthis;
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
           m_pStaticFunction = right.m_pStaticFunction;
          #endif
           }
          };
          
          
          // ClosurePtr<>
          //
          // A private wrapper class that adds function signatures to DelegateMemento.
          // It's the class that does most of the actual work.
          // The signatures are specified by:
          // GenericMemFunc: must be a type of GenericClass member function pointer.
          // StaticFuncPtr: must be a type of function pointer with the same signature
          // as GenericMemFunc.
          // UnvoidStaticFuncPtr: is the same as StaticFuncPtr,   except on VC6
          // where it never returns void (  returns DefaultVoid instead ).
          
          // An outer class,   FastDelegateN<>,   handles the invoking and creates the
          // necessary typedefs.
          // This class does everything else.
          
          namespace detail {
          
          template < class GenericMemFunc,   class StaticFuncPtr,   class UnvoidStaticFuncPtr>
          class ClosurePtr : public DelegateMemento {
          public:
           // These functions are for setting the delegate to a member function.
          
           // Here's the clever bit: we convert an arbitrary member function into a
           // standard form. XMemFunc should be a member function of class X,   but I can't
           // enforce that here. It needs to be enforced by the wrapper class.
           template < class X,   class XMemFunc >
           inline void bindmemfunc(  X *pthis,   XMemFunc function_to_bind  ) {
           m_pthis = SimplifyMemFunc< sizeof(  function_to_bind ) >
           ::Convert(  pthis,   function_to_bind,   m_pFunction );
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
           m_pStaticFunction = 0;
          #endif
           }
           // For const member functions,   we only need a const class pointer.
           // Since we know that the member function is const,   it's safe to
           // remove the const qualifier from the 'this' pointer with a const_cast.
           // VC6 has problems if we just overload 'bindmemfunc',   so we give it a different name.
           template < class X,   class XMemFunc>
           inline void bindconstmemfunc(  const X *pthis,   XMemFunc function_to_bind ) {
           m_pthis= SimplifyMemFunc< sizeof(  function_to_bind ) >
           ::Convert(  const_cast<X*>(  pthis ),   function_to_bind,   m_pFunction );
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
           m_pStaticFunction = 0;
          #endif
           }
          #ifdef FASTDELEGATE_GCC_BUG_8271 // At present,   GCC doesn't recognize constness of MFPs in templates
           template < class X,   class XMemFunc>
           inline void bindmemfunc(  const X *pthis,   XMemFunc function_to_bind ) {
           bindconstmemfunc(  pthis,   function_to_bind );
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
           m_pStaticFunction = 0;
          #endif
           }
          #endif
           // These functions are required for invoking the stored function
           inline GenericClass *GetClosureThis(   ) const { return m_pthis; }
           inline GenericMemFunc GetClosureMemPtr(   ) const { return reinterpret_cast<GenericMemFunc>(  m_pFunction ); }
          
          // There are a few ways of dealing with static function pointers.
          // There's a standard-compliant,   but tricky method.
          // There's also a straightforward hack,   that won't work on DOS compilers using the
          // medium memory model. It's so evil that I can't recommend it,   but I've
          // implemented it anyway because it produces very nice asm code.
          
          #if !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
          
          // ClosurePtr<> - Safe version
          //
          // This implementation is standard-compliant,   but a bit tricky.
          // I store the function pointer inside the class,   and the delegate then
          // points to itself. Whenever the delegate is copied,   these self-references
          // must be transformed,   and this complicates the = and == operators.
          public:
           // The next two functions are for operator ==,   =,   and the copy constructor.
           // We may need to convert the m_pthis pointers,   so that
           // they remain as self-references.
           template< class DerivedClass >
           inline void CopyFrom (  DerivedClass *pParent,   const DelegateMemento &x ) {
           SetMementoFrom(  x );
           if (  m_pStaticFunction!=0 ) {
           // transform self references...
           m_pthis=reinterpret_cast<GenericClass *>(  pParent );
           }
           }
           // For static functions,   the 'static_function_invoker' class in the parent
           // will be called. The parent then needs to call GetStaticFunction(   ) to find out
           // the actual function to invoke.
           template < class DerivedClass,   class ParentInvokerSig >
           inline void bindstaticfunc(  DerivedClass *pParent,   ParentInvokerSig static_function_invoker,  
           StaticFuncPtr function_to_bind  ) {
           if (  function_to_bind==0 ) { // cope with assignment to 0
           m_pFunction=0;
           } else {
           bindmemfunc(  pParent,   static_function_invoker );
           }
           m_pStaticFunction=reinterpret_cast<GenericFuncPtr>(  function_to_bind );
           }
           inline UnvoidStaticFuncPtr GetStaticFunction(   ) const {
           return reinterpret_cast<UnvoidStaticFuncPtr>(  m_pStaticFunction );
           }
          #else
          
          // ClosurePtr<> - Evil version
          //
          // For compilers where data pointers are at least as big as code pointers,   it is
          // possible to store the function pointer in the this pointer,   using another
          // horrible_cast. Invocation isn't any faster,   but it saves 4 bytes,   and
          // speeds up comparison and assignment. If C++ provided direct language support
          // for delegates,   they would produce asm code that was almost identical to this.
          // Note that the Sun C++ and MSVC documentation explicitly state that they
          // support static_cast between void * and function pointers.
          
           template< class DerivedClass >
           inline void CopyFrom (  DerivedClass *pParent,   const DelegateMemento &right ) {
           SetMementoFrom(  right );
           }
           // For static functions,   the 'static_function_invoker' class in the parent
           // will be called. The parent then needs to call GetStaticFunction(   ) to find out
           // the actual function to invoke.
           // ******** EVIL,   EVIL CODE! *******
           template < class DerivedClass,   class ParentInvokerSig>
           inline void bindstaticfunc(  DerivedClass *pParent,   ParentInvokerSig static_function_invoker,  
           StaticFuncPtr function_to_bind ) {
           if (  function_to_bind==0 ) { // cope with assignment to 0
           m_pFunction=0;
           } else {
           // We'll be ignoring the 'this' pointer,   but we need to make sure we pass
           // a valid value to bindmemfunc(   ).
           bindmemfunc(  pParent,   static_function_invoker );
           }
          
           // WARNING! Evil hack. We store the function in the 'this' pointer!
           // Ensure that there's a compilation failure if function pointers
           // and data pointers have different sizes.
           // If you get this error,   you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK.
           typedef int ERROR_CantUseEvilMethod[sizeof(  GenericClass * )==sizeof(  function_to_bind ) ? 1 : -1];
           m_pthis = horrible_cast<GenericClass *>(  function_to_bind );
           // MSVC,   SunC++ and DMC accept the following (  non-standard ) code:
          // m_pthis = static_cast<GenericClass *>(  static_cast<void *>(  function_to_bind ) );
           // BCC32,   Comeau and DMC accept this method. MSVC7.1 needs __int64 instead of long
          // m_pthis = reinterpret_cast<GenericClass *>(  reinterpret_cast<long>(  function_to_bind ) );
           }
           // ******** EVIL,   EVIL CODE! *******
           // This function will be called with an invalid 'this' pointer!!
           // We're just returning the 'this' pointer,   converted into
           // a function pointer!
           inline UnvoidStaticFuncPtr GetStaticFunction(   ) const {
           // Ensure that there's a compilation failure if function pointers
           // and data pointers have different sizes.
           // If you get this error,   you need to #undef FASTDELEGATE_USESTATICFUNCTIONHACK.
           typedef int ERROR_CantUseEvilMethod[sizeof(  UnvoidStaticFuncPtr )==sizeof(  this ) ? 1 : -1];
           return horrible_cast<UnvoidStaticFuncPtr>(  this );
           }
          #endif // !defined(  FASTDELEGATE_USESTATICFUNCTIONHACK )
          
           // Does the closure contain this static function?
           inline bool IsEqualToStaticFuncPtr(  StaticFuncPtr funcptr ){
           if (  funcptr==0 ) return empty(   );
           // For the Evil method,   if it doesn't actually contain a static function,   this will return an arbitrary
           // value that is not equal to any valid function pointer.
           else return funcptr==reinterpret_cast<StaticFuncPtr>(  GetStaticFunction(   ) );
           }
          };
          
          
          } // namespace detail
          
          ////////////////////////////////////////////////////////////////////////////////
          // Fast Delegates,   part 3:
          //
          // Wrapper classes to ensure type safety
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          
          // Once we have the member function conversion templates,   it's easy to make the
          // wrapper classes. So that they will work with as many compilers as possible,  
          // the classes are of the form
          // FastDelegate3<int,   char *,   double>
          // They can cope with any combination of parameters. The max number of parameters
          // allowed is 8,   but it is trivial to increase this limit.
          // Note that we need to treat const member functions seperately.
          // All this class does is to enforce type safety,   and invoke the delegate with
          // the correct list of parameters.
          
          // Because of the weird rule about the class of derived member function pointers,  
          // you sometimes need to apply a downcast to the 'this' pointer.
          // This is the reason for the use of "implicit_cast<X*>(  pthis )" in the code below.
          // If CDerivedClass is derived from CBaseClass,   but doesn't override SimpleVirtualFunction,  
          // without this trick you'd need to write:
          // MyDelegate(  static_cast<CBaseClass *>(  &d ),   &CDerivedClass::SimpleVirtualFunction );
          // but with the trick you can write
          // MyDelegate(  &d,   &CDerivedClass::SimpleVirtualFunction );
          
          // RetType is the type the compiler uses in compiling the template. For VC6,  
          // it cannot be void. DesiredRetType is the real type which is returned from
          // all of the functions. It can be void.
          
          // Implicit conversion to "bool" is achieved using the safe_bool idiom,  
          // using member data pointers (  MDP ). This allows "if (  dg )..." syntax
          // Because some compilers (  eg codeplay ) don't have a unique value for a zero
          // MDP,   an extra padding member is added to the SafeBool struct.
          // Some compilers (  eg VC6 ) won't implicitly convert from 0 to an MDP,   so
          // in that case the static function constructor is not made explicit; this
          // allows "if (  dg==0 ) ..." to compile.
          
          //N=0
          template<class RetType=detail::DefaultVoid>
          class FastDelegate0 {
          private:
           typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
           typedef DesiredRetType (  *StaticFunctionPtr )(   );
           typedef RetType (  *UnvoidStaticFunctionPtr )(   );
           typedef RetType (  detail::GenericClass::*GenericMemFn )(   );
           typedef detail::ClosurePtr<GenericMemFn,   StaticFunctionPtr,   UnvoidStaticFunctionPtr> ClosureType;
           ClosureType m_Closure;
          public:
           // Typedefs to aid generic programming
           typedef FastDelegate0 type;
          
           // Construction and comparison functions
           FastDelegate0(   ) { clear(   ); }
           FastDelegate0(  const FastDelegate0 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           void operator = (  const FastDelegate0 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           bool operator ==(  const FastDelegate0 &x ) const {
           return m_Closure.IsEqual(  x.m_Closure ); }
           bool operator !=(  const FastDelegate0 &x ) const {
           return !m_Closure.IsEqual(  x.m_Closure ); }
           bool operator <(  const FastDelegate0 &x ) const {
           return m_Closure.IsLess(  x.m_Closure ); }
           bool operator >(  const FastDelegate0 &x ) const {
           return x.m_Closure.IsLess(  m_Closure ); }
           // Binding to non-const member functions
           template < class X,   class Y >
           FastDelegate0(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(   )  ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(   ) ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           // Binding to const member functions.
           template < class X,   class Y >
           FastDelegate0(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(   ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(   ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X *>(  pthis ),   function_to_bind ); }
           // Static functions. We convert them into a member function call.
           // This constructor also provides implicit conversion
           FastDelegate0(  DesiredRetType (  *function_to_bind )(   )  ) {
           bind(  function_to_bind ); }
           // for efficiency,   prevent creation of a temporary
           void operator = (  DesiredRetType (  *function_to_bind )(   )  ) {
           bind(  function_to_bind ); }
           inline void bind(  DesiredRetType (  *function_to_bind )(   ) ) {
           m_Closure.bindstaticfunc(  this,   &FastDelegate0::InvokeStaticFunction,  
           function_to_bind ); }
           // Invoke the delegate
           RetType operator(   ) (   ) const {
           return (  m_Closure.GetClosureThis(   )->*(  m_Closure.GetClosureMemPtr(   ) ) )(   ); }
           // Implicit conversion to "bool" using the safe_bool idiom
          private:
           typedef struct SafeBoolStruct {
           int a_data_pointer_to_this_is_0_on_buggy_compilers;
           StaticFunctionPtr m_nonzero;
           } UselessTypedef;
           typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
          public:
           operator unspecified_bool_type(   ) const {
           return empty(   )? 0: &SafeBoolStruct::m_nonzero;
           }
           // necessary to allow ==0 to work despite the safe_bool idiom
           inline bool operator==(  StaticFunctionPtr funcptr ) {
           return m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator!=(  StaticFunctionPtr funcptr ) {
           return !m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator ! (   ) const { // Is it bound to anything?
           return !m_Closure; }
           inline bool empty(   ) const {
           return !m_Closure; }
           void clear(   ) { m_Closure.clear(   );}
           // Conversion to and from the DelegateMemento storage class
           const DelegateMemento & GetMemento(   ) { return m_Closure; }
           void SetMemento(  const DelegateMemento &any ) { m_Closure.CopyFrom(  this,   any ); }
          
          private: // Invoker for static functions
           RetType InvokeStaticFunction(   ) const {
           return (  *(  m_Closure.GetStaticFunction(   ) ) )(   ); }
          };
          
          //N=1
          template<class Param1,   class RetType=detail::DefaultVoid>
          class FastDelegate1 {
          private:
           typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
           typedef DesiredRetType (  *StaticFunctionPtr )(  Param1 p1 );
           typedef RetType (  *UnvoidStaticFunctionPtr )(  Param1 p1 );
           typedef RetType (  detail::GenericClass::*GenericMemFn )(  Param1 p1 );
           typedef detail::ClosurePtr<GenericMemFn,   StaticFunctionPtr,   UnvoidStaticFunctionPtr> ClosureType;
           ClosureType m_Closure;
          public:
           // Typedefs to aid generic programming
           typedef FastDelegate1 type;
          
           // Construction and comparison functions
           FastDelegate1(   ) { clear(   ); }
           FastDelegate1(  const FastDelegate1 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           void operator = (  const FastDelegate1 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           bool operator ==(  const FastDelegate1 &x ) const {
           return m_Closure.IsEqual(  x.m_Closure ); }
           bool operator !=(  const FastDelegate1 &x ) const {
           return !m_Closure.IsEqual(  x.m_Closure ); }
           bool operator <(  const FastDelegate1 &x ) const {
           return m_Closure.IsLess(  x.m_Closure ); }
           bool operator >(  const FastDelegate1 &x ) const {
           return x.m_Closure.IsLess(  m_Closure ); }
           // Binding to non-const member functions
           template < class X,   class Y >
           FastDelegate1(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1 )  ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1 ) ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           // Binding to const member functions.
           template < class X,   class Y >
           FastDelegate1(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X *>(  pthis ),   function_to_bind ); }
           // Static functions. We convert them into a member function call.
           // This constructor also provides implicit conversion
           FastDelegate1(  DesiredRetType (  *function_to_bind )(  Param1 p1 )  ) {
           bind(  function_to_bind ); }
           // for efficiency,   prevent creation of a temporary
           void operator = (  DesiredRetType (  *function_to_bind )(  Param1 p1 )  ) {
           bind(  function_to_bind ); }
           inline void bind(  DesiredRetType (  *function_to_bind )(  Param1 p1 ) ) {
           m_Closure.bindstaticfunc(  this,   &FastDelegate1::InvokeStaticFunction,  
           function_to_bind ); }
           // Invoke the delegate
           RetType operator(   ) (  Param1 p1 ) const {
           return (  m_Closure.GetClosureThis(   )->*(  m_Closure.GetClosureMemPtr(   ) ) )(  p1 ); }
           // Implicit conversion to "bool" using the safe_bool idiom
          private:
           typedef struct SafeBoolStruct {
           int a_data_pointer_to_this_is_0_on_buggy_compilers;
           StaticFunctionPtr m_nonzero;
           } UselessTypedef;
           typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
          public:
           operator unspecified_bool_type(   ) const {
           return empty(   )? 0: &SafeBoolStruct::m_nonzero;
           }
           // necessary to allow ==0 to work despite the safe_bool idiom
           inline bool operator==(  StaticFunctionPtr funcptr ) {
           return m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator!=(  StaticFunctionPtr funcptr ) {
           return !m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator ! (   ) const { // Is it bound to anything?
           return !m_Closure; }
           inline bool empty(   ) const {
           return !m_Closure; }
           void clear(   ) { m_Closure.clear(   );}
           // Conversion to and from the DelegateMemento storage class
           const DelegateMemento & GetMemento(   ) { return m_Closure; }
           void SetMemento(  const DelegateMemento &any ) { m_Closure.CopyFrom(  this,   any ); }
          
          private: // Invoker for static functions
           RetType InvokeStaticFunction(  Param1 p1 ) const {
           return (  *(  m_Closure.GetStaticFunction(   ) ) )(  p1 ); }
          };
          
          //N=2
          template<class Param1,   class Param2,   class RetType=detail::DefaultVoid>
          class FastDelegate2 {
          private:
           typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
           typedef DesiredRetType (  *StaticFunctionPtr )(  Param1 p1,   Param2 p2 );
           typedef RetType (  *UnvoidStaticFunctionPtr )(  Param1 p1,   Param2 p2 );
           typedef RetType (  detail::GenericClass::*GenericMemFn )(  Param1 p1,   Param2 p2 );
           typedef detail::ClosurePtr<GenericMemFn,   StaticFunctionPtr,   UnvoidStaticFunctionPtr> ClosureType;
           ClosureType m_Closure;
          public:
           // Typedefs to aid generic programming
           typedef FastDelegate2 type;
          
           // Construction and comparison functions
           FastDelegate2(   ) { clear(   ); }
           FastDelegate2(  const FastDelegate2 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           void operator = (  const FastDelegate2 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           bool operator ==(  const FastDelegate2 &x ) const {
           return m_Closure.IsEqual(  x.m_Closure ); }
           bool operator !=(  const FastDelegate2 &x ) const {
           return !m_Closure.IsEqual(  x.m_Closure ); }
           bool operator <(  const FastDelegate2 &x ) const {
           return m_Closure.IsLess(  x.m_Closure ); }
           bool operator >(  const FastDelegate2 &x ) const {
           return x.m_Closure.IsLess(  m_Closure ); }
           // Binding to non-const member functions
           template < class X,   class Y >
           FastDelegate2(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2 )  ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2 ) ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           // Binding to const member functions.
           template < class X,   class Y >
           FastDelegate2(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X *>(  pthis ),   function_to_bind ); }
           // Static functions. We convert them into a member function call.
           // This constructor also provides implicit conversion
           FastDelegate2(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2 )  ) {
           bind(  function_to_bind ); }
           // for efficiency,   prevent creation of a temporary
           void operator = (  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2 )  ) {
           bind(  function_to_bind ); }
           inline void bind(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2 ) ) {
           m_Closure.bindstaticfunc(  this,   &FastDelegate2::InvokeStaticFunction,  
           function_to_bind ); }
           // Invoke the delegate
           RetType operator(   ) (  Param1 p1,   Param2 p2 ) const {
           return (  m_Closure.GetClosureThis(   )->*(  m_Closure.GetClosureMemPtr(   ) ) )(  p1,   p2 ); }
           // Implicit conversion to "bool" using the safe_bool idiom
          private:
           typedef struct SafeBoolStruct {
           int a_data_pointer_to_this_is_0_on_buggy_compilers;
           StaticFunctionPtr m_nonzero;
           } UselessTypedef;
           typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
          public:
           operator unspecified_bool_type(   ) const {
           return empty(   )? 0: &SafeBoolStruct::m_nonzero;
           }
           // necessary to allow ==0 to work despite the safe_bool idiom
           inline bool operator==(  StaticFunctionPtr funcptr ) {
           return m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator!=(  StaticFunctionPtr funcptr ) {
           return !m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator ! (   ) const { // Is it bound to anything?
           return !m_Closure; }
           inline bool empty(   ) const {
           return !m_Closure; }
           void clear(   ) { m_Closure.clear(   );}
           // Conversion to and from the DelegateMemento storage class
           const DelegateMemento & GetMemento(   ) { return m_Closure; }
           void SetMemento(  const DelegateMemento &any ) { m_Closure.CopyFrom(  this,   any ); }
          
          private: // Invoker for static functions
           RetType InvokeStaticFunction(  Param1 p1,   Param2 p2 ) const {
           return (  *(  m_Closure.GetStaticFunction(   ) ) )(  p1,   p2 ); }
          };
          
          //N=3
          template<class Param1,   class Param2,   class Param3,   class RetType=detail::DefaultVoid>
          class FastDelegate3 {
          private:
           typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
           typedef DesiredRetType (  *StaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3 );
           typedef RetType (  *UnvoidStaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3 );
           typedef RetType (  detail::GenericClass::*GenericMemFn )(  Param1 p1,   Param2 p2,   Param3 p3 );
           typedef detail::ClosurePtr<GenericMemFn,   StaticFunctionPtr,   UnvoidStaticFunctionPtr> ClosureType;
           ClosureType m_Closure;
          public:
           // Typedefs to aid generic programming
           typedef FastDelegate3 type;
          
           // Construction and comparison functions
           FastDelegate3(   ) { clear(   ); }
           FastDelegate3(  const FastDelegate3 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           void operator = (  const FastDelegate3 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           bool operator ==(  const FastDelegate3 &x ) const {
           return m_Closure.IsEqual(  x.m_Closure ); }
           bool operator !=(  const FastDelegate3 &x ) const {
           return !m_Closure.IsEqual(  x.m_Closure ); }
           bool operator <(  const FastDelegate3 &x ) const {
           return m_Closure.IsLess(  x.m_Closure ); }
           bool operator >(  const FastDelegate3 &x ) const {
           return x.m_Closure.IsLess(  m_Closure ); }
           // Binding to non-const member functions
           template < class X,   class Y >
           FastDelegate3(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3 )  ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3 ) ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           // Binding to const member functions.
           template < class X,   class Y >
           FastDelegate3(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X *>(  pthis ),   function_to_bind ); }
           // Static functions. We convert them into a member function call.
           // This constructor also provides implicit conversion
           FastDelegate3(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3 )  ) {
           bind(  function_to_bind ); }
           // for efficiency,   prevent creation of a temporary
           void operator = (  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3 )  ) {
           bind(  function_to_bind ); }
           inline void bind(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3 ) ) {
           m_Closure.bindstaticfunc(  this,   &FastDelegate3::InvokeStaticFunction,  
           function_to_bind ); }
           // Invoke the delegate
           RetType operator(   ) (  Param1 p1,   Param2 p2,   Param3 p3 ) const {
           return (  m_Closure.GetClosureThis(   )->*(  m_Closure.GetClosureMemPtr(   ) ) )(  p1,   p2,   p3 ); }
           // Implicit conversion to "bool" using the safe_bool idiom
          private:
           typedef struct SafeBoolStruct {
           int a_data_pointer_to_this_is_0_on_buggy_compilers;
           StaticFunctionPtr m_nonzero;
           } UselessTypedef;
           typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
          public:
           operator unspecified_bool_type(   ) const {
           return empty(   )? 0: &SafeBoolStruct::m_nonzero;
           }
           // necessary to allow ==0 to work despite the safe_bool idiom
           inline bool operator==(  StaticFunctionPtr funcptr ) {
           return m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator!=(  StaticFunctionPtr funcptr ) {
           return !m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator ! (   ) const { // Is it bound to anything?
           return !m_Closure; }
           inline bool empty(   ) const {
           return !m_Closure; }
           void clear(   ) { m_Closure.clear(   );}
           // Conversion to and from the DelegateMemento storage class
           const DelegateMemento & GetMemento(   ) { return m_Closure; }
           void SetMemento(  const DelegateMemento &any ) { m_Closure.CopyFrom(  this,   any ); }
          
          private: // Invoker for static functions
           RetType InvokeStaticFunction(  Param1 p1,   Param2 p2,   Param3 p3 ) const {
           return (  *(  m_Closure.GetStaticFunction(   ) ) )(  p1,   p2,   p3 ); }
          };
          
          //N=4
          template<class Param1,   class Param2,   class Param3,   class Param4,   class RetType=detail::DefaultVoid>
          class FastDelegate4 {
          private:
           typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
           typedef DesiredRetType (  *StaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 );
           typedef RetType (  *UnvoidStaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 );
           typedef RetType (  detail::GenericClass::*GenericMemFn )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 );
           typedef detail::ClosurePtr<GenericMemFn,   StaticFunctionPtr,   UnvoidStaticFunctionPtr> ClosureType;
           ClosureType m_Closure;
          public:
           // Typedefs to aid generic programming
           typedef FastDelegate4 type;
          
           // Construction and comparison functions
           FastDelegate4(   ) { clear(   ); }
           FastDelegate4(  const FastDelegate4 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           void operator = (  const FastDelegate4 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           bool operator ==(  const FastDelegate4 &x ) const {
           return m_Closure.IsEqual(  x.m_Closure ); }
           bool operator !=(  const FastDelegate4 &x ) const {
           return !m_Closure.IsEqual(  x.m_Closure ); }
           bool operator <(  const FastDelegate4 &x ) const {
           return m_Closure.IsLess(  x.m_Closure ); }
           bool operator >(  const FastDelegate4 &x ) const {
           return x.m_Closure.IsLess(  m_Closure ); }
           // Binding to non-const member functions
           template < class X,   class Y >
           FastDelegate4(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 )  ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 ) ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           // Binding to const member functions.
           template < class X,   class Y >
           FastDelegate4(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X *>(  pthis ),   function_to_bind ); }
           // Static functions. We convert them into a member function call.
           // This constructor also provides implicit conversion
           FastDelegate4(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 )  ) {
           bind(  function_to_bind ); }
           // for efficiency,   prevent creation of a temporary
           void operator = (  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 )  ) {
           bind(  function_to_bind ); }
           inline void bind(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 ) ) {
           m_Closure.bindstaticfunc(  this,   &FastDelegate4::InvokeStaticFunction,  
           function_to_bind ); }
           // Invoke the delegate
           RetType operator(   ) (  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 ) const {
           return (  m_Closure.GetClosureThis(   )->*(  m_Closure.GetClosureMemPtr(   ) ) )(  p1,   p2,   p3,   p4 ); }
           // Implicit conversion to "bool" using the safe_bool idiom
          private:
           typedef struct SafeBoolStruct {
           int a_data_pointer_to_this_is_0_on_buggy_compilers;
           StaticFunctionPtr m_nonzero;
           } UselessTypedef;
           typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
          public:
           operator unspecified_bool_type(   ) const {
           return empty(   )? 0: &SafeBoolStruct::m_nonzero;
           }
           // necessary to allow ==0 to work despite the safe_bool idiom
           inline bool operator==(  StaticFunctionPtr funcptr ) {
           return m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator!=(  StaticFunctionPtr funcptr ) {
           return !m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator ! (   ) const { // Is it bound to anything?
           return !m_Closure; }
           inline bool empty(   ) const {
           return !m_Closure; }
           void clear(   ) { m_Closure.clear(   );}
           // Conversion to and from the DelegateMemento storage class
           const DelegateMemento & GetMemento(   ) { return m_Closure; }
           void SetMemento(  const DelegateMemento &any ) { m_Closure.CopyFrom(  this,   any ); }
          
          private: // Invoker for static functions
           RetType InvokeStaticFunction(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 ) const {
           return (  *(  m_Closure.GetStaticFunction(   ) ) )(  p1,   p2,   p3,   p4 ); }
          };
          
          //N=5
          template<class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class RetType=detail::DefaultVoid>
          class FastDelegate5 {
          private:
           typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
           typedef DesiredRetType (  *StaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 );
           typedef RetType (  *UnvoidStaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 );
           typedef RetType (  detail::GenericClass::*GenericMemFn )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 );
           typedef detail::ClosurePtr<GenericMemFn,   StaticFunctionPtr,   UnvoidStaticFunctionPtr> ClosureType;
           ClosureType m_Closure;
          public:
           // Typedefs to aid generic programming
           typedef FastDelegate5 type;
          
           // Construction and comparison functions
           FastDelegate5(   ) { clear(   ); }
           FastDelegate5(  const FastDelegate5 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           void operator = (  const FastDelegate5 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           bool operator ==(  const FastDelegate5 &x ) const {
           return m_Closure.IsEqual(  x.m_Closure ); }
           bool operator !=(  const FastDelegate5 &x ) const {
           return !m_Closure.IsEqual(  x.m_Closure ); }
           bool operator <(  const FastDelegate5 &x ) const {
           return m_Closure.IsLess(  x.m_Closure ); }
           bool operator >(  const FastDelegate5 &x ) const {
           return x.m_Closure.IsLess(  m_Closure ); }
           // Binding to non-const member functions
           template < class X,   class Y >
           FastDelegate5(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 )  ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 ) ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           // Binding to const member functions.
           template < class X,   class Y >
           FastDelegate5(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X *>(  pthis ),   function_to_bind ); }
           // Static functions. We convert them into a member function call.
           // This constructor also provides implicit conversion
           FastDelegate5(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 )  ) {
           bind(  function_to_bind ); }
           // for efficiency,   prevent creation of a temporary
           void operator = (  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 )  ) {
           bind(  function_to_bind ); }
           inline void bind(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 ) ) {
           m_Closure.bindstaticfunc(  this,   &FastDelegate5::InvokeStaticFunction,  
           function_to_bind ); }
           // Invoke the delegate
           RetType operator(   ) (  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 ) const {
           return (  m_Closure.GetClosureThis(   )->*(  m_Closure.GetClosureMemPtr(   ) ) )(  p1,   p2,   p3,   p4,   p5 ); }
           // Implicit conversion to "bool" using the safe_bool idiom
          private:
           typedef struct SafeBoolStruct {
           int a_data_pointer_to_this_is_0_on_buggy_compilers;
           StaticFunctionPtr m_nonzero;
           } UselessTypedef;
           typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
          public:
           operator unspecified_bool_type(   ) const {
           return empty(   )? 0: &SafeBoolStruct::m_nonzero;
           }
           // necessary to allow ==0 to work despite the safe_bool idiom
           inline bool operator==(  StaticFunctionPtr funcptr ) {
           return m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator!=(  StaticFunctionPtr funcptr ) {
           return !m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator ! (   ) const { // Is it bound to anything?
           return !m_Closure; }
           inline bool empty(   ) const {
           return !m_Closure; }
           void clear(   ) { m_Closure.clear(   );}
           // Conversion to and from the DelegateMemento storage class
           const DelegateMemento & GetMemento(   ) { return m_Closure; }
           void SetMemento(  const DelegateMemento &any ) { m_Closure.CopyFrom(  this,   any ); }
          
          private: // Invoker for static functions
           RetType InvokeStaticFunction(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 ) const {
           return (  *(  m_Closure.GetStaticFunction(   ) ) )(  p1,   p2,   p3,   p4,   p5 ); }
          };
          
          //N=6
          template<class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class RetType=detail::DefaultVoid>
          class FastDelegate6 {
          private:
           typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
           typedef DesiredRetType (  *StaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 );
           typedef RetType (  *UnvoidStaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 );
           typedef RetType (  detail::GenericClass::*GenericMemFn )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 );
           typedef detail::ClosurePtr<GenericMemFn,   StaticFunctionPtr,   UnvoidStaticFunctionPtr> ClosureType;
           ClosureType m_Closure;
          public:
           // Typedefs to aid generic programming
           typedef FastDelegate6 type;
          
           // Construction and comparison functions
           FastDelegate6(   ) { clear(   ); }
           FastDelegate6(  const FastDelegate6 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           void operator = (  const FastDelegate6 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           bool operator ==(  const FastDelegate6 &x ) const {
           return m_Closure.IsEqual(  x.m_Closure ); }
           bool operator !=(  const FastDelegate6 &x ) const {
           return !m_Closure.IsEqual(  x.m_Closure ); }
           bool operator <(  const FastDelegate6 &x ) const {
           return m_Closure.IsLess(  x.m_Closure ); }
           bool operator >(  const FastDelegate6 &x ) const {
           return x.m_Closure.IsLess(  m_Closure ); }
           // Binding to non-const member functions
           template < class X,   class Y >
           FastDelegate6(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 )  ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 ) ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           // Binding to const member functions.
           template < class X,   class Y >
           FastDelegate6(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X *>(  pthis ),   function_to_bind ); }
           // Static functions. We convert them into a member function call.
           // This constructor also provides implicit conversion
           FastDelegate6(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 )  ) {
           bind(  function_to_bind ); }
           // for efficiency,   prevent creation of a temporary
           void operator = (  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 )  ) {
           bind(  function_to_bind ); }
           inline void bind(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 ) ) {
           m_Closure.bindstaticfunc(  this,   &FastDelegate6::InvokeStaticFunction,  
           function_to_bind ); }
           // Invoke the delegate
           RetType operator(   ) (  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 ) const {
           return (  m_Closure.GetClosureThis(   )->*(  m_Closure.GetClosureMemPtr(   ) ) )(  p1,   p2,   p3,   p4,   p5,   p6 ); }
           // Implicit conversion to "bool" using the safe_bool idiom
          private:
           typedef struct SafeBoolStruct {
           int a_data_pointer_to_this_is_0_on_buggy_compilers;
           StaticFunctionPtr m_nonzero;
           } UselessTypedef;
           typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
          public:
           operator unspecified_bool_type(   ) const {
           return empty(   )? 0: &SafeBoolStruct::m_nonzero;
           }
           // necessary to allow ==0 to work despite the safe_bool idiom
           inline bool operator==(  StaticFunctionPtr funcptr ) {
           return m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator!=(  StaticFunctionPtr funcptr ) {
           return !m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator ! (   ) const { // Is it bound to anything?
           return !m_Closure; }
           inline bool empty(   ) const {
           return !m_Closure; }
           void clear(   ) { m_Closure.clear(   );}
           // Conversion to and from the DelegateMemento storage class
           const DelegateMemento & GetMemento(   ) { return m_Closure; }
           void SetMemento(  const DelegateMemento &any ) { m_Closure.CopyFrom(  this,   any ); }
          
          private: // Invoker for static functions
           RetType InvokeStaticFunction(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 ) const {
           return (  *(  m_Closure.GetStaticFunction(   ) ) )(  p1,   p2,   p3,   p4,   p5,   p6 ); }
          };
          
          //N=7
          template<class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class Param7,   class RetType=detail::DefaultVoid>
          class FastDelegate7 {
          private:
           typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
           typedef DesiredRetType (  *StaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 );
           typedef RetType (  *UnvoidStaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 );
           typedef RetType (  detail::GenericClass::*GenericMemFn )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 );
           typedef detail::ClosurePtr<GenericMemFn,   StaticFunctionPtr,   UnvoidStaticFunctionPtr> ClosureType;
           ClosureType m_Closure;
          public:
           // Typedefs to aid generic programming
           typedef FastDelegate7 type;
          
           // Construction and comparison functions
           FastDelegate7(   ) { clear(   ); }
           FastDelegate7(  const FastDelegate7 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           void operator = (  const FastDelegate7 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           bool operator ==(  const FastDelegate7 &x ) const {
           return m_Closure.IsEqual(  x.m_Closure ); }
           bool operator !=(  const FastDelegate7 &x ) const {
           return !m_Closure.IsEqual(  x.m_Closure ); }
           bool operator <(  const FastDelegate7 &x ) const {
           return m_Closure.IsLess(  x.m_Closure ); }
           bool operator >(  const FastDelegate7 &x ) const {
           return x.m_Closure.IsLess(  m_Closure ); }
           // Binding to non-const member functions
           template < class X,   class Y >
           FastDelegate7(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 )  ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 ) ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           // Binding to const member functions.
           template < class X,   class Y >
           FastDelegate7(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X *>(  pthis ),   function_to_bind ); }
           // Static functions. We convert them into a member function call.
           // This constructor also provides implicit conversion
           FastDelegate7(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 )  ) {
           bind(  function_to_bind ); }
           // for efficiency,   prevent creation of a temporary
           void operator = (  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 )  ) {
           bind(  function_to_bind ); }
           inline void bind(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 ) ) {
           m_Closure.bindstaticfunc(  this,   &FastDelegate7::InvokeStaticFunction,  
           function_to_bind ); }
           // Invoke the delegate
           RetType operator(   ) (  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 ) const {
           return (  m_Closure.GetClosureThis(   )->*(  m_Closure.GetClosureMemPtr(   ) ) )(  p1,   p2,   p3,   p4,   p5,   p6,   p7 ); }
           // Implicit conversion to "bool" using the safe_bool idiom
          private:
           typedef struct SafeBoolStruct {
           int a_data_pointer_to_this_is_0_on_buggy_compilers;
           StaticFunctionPtr m_nonzero;
           } UselessTypedef;
           typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
          public:
           operator unspecified_bool_type(   ) const {
           return empty(   )? 0: &SafeBoolStruct::m_nonzero;
           }
           // necessary to allow ==0 to work despite the safe_bool idiom
           inline bool operator==(  StaticFunctionPtr funcptr ) {
           return m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator!=(  StaticFunctionPtr funcptr ) {
           return !m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator ! (   ) const { // Is it bound to anything?
           return !m_Closure; }
           inline bool empty(   ) const {
           return !m_Closure; }
           void clear(   ) { m_Closure.clear(   );}
           // Conversion to and from the DelegateMemento storage class
           const DelegateMemento & GetMemento(   ) { return m_Closure; }
           void SetMemento(  const DelegateMemento &any ) { m_Closure.CopyFrom(  this,   any ); }
          
          private: // Invoker for static functions
           RetType InvokeStaticFunction(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 ) const {
           return (  *(  m_Closure.GetStaticFunction(   ) ) )(  p1,   p2,   p3,   p4,   p5,   p6,   p7 ); }
          };
          
          //N=8
          template<class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class Param7,   class Param8,   class RetType=detail::DefaultVoid>
          class FastDelegate8 {
          private:
           typedef typename detail::DefaultVoidToVoid<RetType>::type DesiredRetType;
           typedef DesiredRetType (  *StaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 );
           typedef RetType (  *UnvoidStaticFunctionPtr )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 );
           typedef RetType (  detail::GenericClass::*GenericMemFn )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 );
           typedef detail::ClosurePtr<GenericMemFn,   StaticFunctionPtr,   UnvoidStaticFunctionPtr> ClosureType;
           ClosureType m_Closure;
          public:
           // Typedefs to aid generic programming
           typedef FastDelegate8 type;
          
           // Construction and comparison functions
           FastDelegate8(   ) { clear(   ); }
           FastDelegate8(  const FastDelegate8 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           void operator = (  const FastDelegate8 &x ) {
           m_Closure.CopyFrom(  this,   x.m_Closure ); }
           bool operator ==(  const FastDelegate8 &x ) const {
           return m_Closure.IsEqual(  x.m_Closure ); }
           bool operator !=(  const FastDelegate8 &x ) const {
           return !m_Closure.IsEqual(  x.m_Closure ); }
           bool operator <(  const FastDelegate8 &x ) const {
           return m_Closure.IsLess(  x.m_Closure ); }
           bool operator >(  const FastDelegate8 &x ) const {
           return x.m_Closure.IsLess(  m_Closure ); }
           // Binding to non-const member functions
           template < class X,   class Y >
           FastDelegate8(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 )  ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 ) ) {
           m_Closure.bindmemfunc(  detail::implicit_cast<X*>(  pthis ),   function_to_bind ); }
           // Binding to const member functions.
           template < class X,   class Y >
           FastDelegate8(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X*>(  pthis ),   function_to_bind ); }
           template < class X,   class Y >
           inline void bind(  const Y *pthis,   DesiredRetType (  X::* function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 ) const ) {
           m_Closure.bindconstmemfunc(  detail::implicit_cast<const X *>(  pthis ),   function_to_bind ); }
           // Static functions. We convert them into a member function call.
           // This constructor also provides implicit conversion
           FastDelegate8(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 )  ) {
           bind(  function_to_bind ); }
           // for efficiency,   prevent creation of a temporary
           void operator = (  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 )  ) {
           bind(  function_to_bind ); }
           inline void bind(  DesiredRetType (  *function_to_bind )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 ) ) {
           m_Closure.bindstaticfunc(  this,   &FastDelegate8::InvokeStaticFunction,  
           function_to_bind ); }
           // Invoke the delegate
           RetType operator(   ) (  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 ) const {
           return (  m_Closure.GetClosureThis(   )->*(  m_Closure.GetClosureMemPtr(   ) ) )(  p1,   p2,   p3,   p4,   p5,   p6,   p7,   p8 ); }
           // Implicit conversion to "bool" using the safe_bool idiom
          private:
           typedef struct SafeBoolStruct {
           int a_data_pointer_to_this_is_0_on_buggy_compilers;
           StaticFunctionPtr m_nonzero;
           } UselessTypedef;
           typedef StaticFunctionPtr SafeBoolStruct::*unspecified_bool_type;
          public:
           operator unspecified_bool_type(   ) const {
           return empty(   )? 0: &SafeBoolStruct::m_nonzero;
           }
           // necessary to allow ==0 to work despite the safe_bool idiom
           inline bool operator==(  StaticFunctionPtr funcptr ) {
           return m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator!=(  StaticFunctionPtr funcptr ) {
           return !m_Closure.IsEqualToStaticFuncPtr(  funcptr ); }
           inline bool operator ! (   ) const { // Is it bound to anything?
           return !m_Closure; }
           inline bool empty(   ) const {
           return !m_Closure; }
           void clear(   ) { m_Closure.clear(   );}
           // Conversion to and from the DelegateMemento storage class
           const DelegateMemento & GetMemento(   ) { return m_Closure; }
           void SetMemento(  const DelegateMemento &any ) { m_Closure.CopyFrom(  this,   any ); }
          
          private: // Invoker for static functions
           RetType InvokeStaticFunction(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 ) const {
           return (  *(  m_Closure.GetStaticFunction(   ) ) )(  p1,   p2,   p3,   p4,   p5,   p6,   p7,   p8 ); }
          };
          
          
          ////////////////////////////////////////////////////////////////////////////////
          // Fast Delegates,   part 4:
          //
          // FastDelegate<> class (  Original author: Jody Hagins )
          // Allows boost::function style syntax like:
          // FastDelegate< double (  int,   long ) >
          // instead of:
          // FastDelegate2< int,   long,   double >
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          #ifdef FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
          
          // Declare FastDelegate as a class template. It will be specialized
          // later for all number of arguments.
          template <typename Signature>
          class FastDelegate;
          
          //N=0
          // Specialization to allow use of
          // FastDelegate< R (    ) >
          // instead of
          // FastDelegate0 < R >
          template<typename R>
          class FastDelegate< R (    ) >
           // Inherit from FastDelegate0 so that it can be treated just like a FastDelegate0
           : public FastDelegate0 < R >
          {
          public:
           // Make using the base type a bit easier via typedef.
           typedef FastDelegate0 < R > BaseType;
          
           // Allow users access to the specific type of this delegate.
           typedef FastDelegate SelfType;
          
           // Mimic the base class constructors.
           FastDelegate(   ) : BaseType(   ) { }
          
           template < class X,   class Y >
           FastDelegate(  Y * pthis,  
           R (  X::* function_to_bind )(    ) )
           : BaseType(  pthis,   function_to_bind ) { }
          
           template < class X,   class Y >
           FastDelegate(  const Y *pthis,  
           R (  X::* function_to_bind )(    ) const )
           : BaseType(  pthis,   function_to_bind )
           { }
          
           FastDelegate(  R (  *function_to_bind )(    ) )
           : BaseType(  function_to_bind ) { }
           void operator = (  const BaseType &x ) {
           *static_cast<BaseType*>(  this ) = x; }
          };
          
          //N=1
          // Specialization to allow use of
          // FastDelegate< R (   Param1  ) >
          // instead of
          // FastDelegate1 < Param1,   R >
          template<typename R,   class Param1>
          class FastDelegate< R (   Param1  ) >
           // Inherit from FastDelegate1 so that it can be treated just like a FastDelegate1
           : public FastDelegate1 < Param1,   R >
          {
          public:
           // Make using the base type a bit easier via typedef.
           typedef FastDelegate1 < Param1,   R > BaseType;
          
           // Allow users access to the specific type of this delegate.
           typedef FastDelegate SelfType;
          
           // Mimic the base class constructors.
           FastDelegate(   ) : BaseType(   ) { }
          
           template < class X,   class Y >
           FastDelegate(  Y * pthis,  
           R (  X::* function_to_bind )(   Param1 p1  ) )
           : BaseType(  pthis,   function_to_bind ) { }
          
           template < class X,   class Y >
           FastDelegate(  const Y *pthis,  
           R (  X::* function_to_bind )(   Param1 p1  ) const )
           : BaseType(  pthis,   function_to_bind )
           { }
          
           FastDelegate(  R (  *function_to_bind )(   Param1 p1  ) )
           : BaseType(  function_to_bind ) { }
           void operator = (  const BaseType &x ) {
           *static_cast<BaseType*>(  this ) = x; }
          };
          
          //N=2
          // Specialization to allow use of
          // FastDelegate< R (   Param1,   Param2  ) >
          // instead of
          // FastDelegate2 < Param1,   Param2,   R >
          template<typename R,   class Param1,   class Param2>
          class FastDelegate< R (   Param1,   Param2  ) >
           // Inherit from FastDelegate2 so that it can be treated just like a FastDelegate2
           : public FastDelegate2 < Param1,   Param2,   R >
          {
          public:
           // Make using the base type a bit easier via typedef.
           typedef FastDelegate2 < Param1,   Param2,   R > BaseType;
          
           // Allow users access to the specific type of this delegate.
           typedef FastDelegate SelfType;
          
           // Mimic the base class constructors.
           FastDelegate(   ) : BaseType(   ) { }
          
           template < class X,   class Y >
           FastDelegate(  Y * pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2  ) )
           : BaseType(  pthis,   function_to_bind ) { }
          
           template < class X,   class Y >
           FastDelegate(  const Y *pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2  ) const )
           : BaseType(  pthis,   function_to_bind )
           { }
          
           FastDelegate(  R (  *function_to_bind )(   Param1 p1,   Param2 p2  ) )
           : BaseType(  function_to_bind ) { }
           void operator = (  const BaseType &x ) {
           *static_cast<BaseType*>(  this ) = x; }
          };
          
          //N=3
          // Specialization to allow use of
          // FastDelegate< R (   Param1,   Param2,   Param3  ) >
          // instead of
          // FastDelegate3 < Param1,   Param2,   Param3,   R >
          template<typename R,   class Param1,   class Param2,   class Param3>
          class FastDelegate< R (   Param1,   Param2,   Param3  ) >
           // Inherit from FastDelegate3 so that it can be treated just like a FastDelegate3
           : public FastDelegate3 < Param1,   Param2,   Param3,   R >
          {
          public:
           // Make using the base type a bit easier via typedef.
           typedef FastDelegate3 < Param1,   Param2,   Param3,   R > BaseType;
          
           // Allow users access to the specific type of this delegate.
           typedef FastDelegate SelfType;
          
           // Mimic the base class constructors.
           FastDelegate(   ) : BaseType(   ) { }
          
           template < class X,   class Y >
           FastDelegate(  Y * pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3  ) )
           : BaseType(  pthis,   function_to_bind ) { }
          
           template < class X,   class Y >
           FastDelegate(  const Y *pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3  ) const )
           : BaseType(  pthis,   function_to_bind )
           { }
          
           FastDelegate(  R (  *function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3  ) )
           : BaseType(  function_to_bind ) { }
           void operator = (  const BaseType &x ) {
           *static_cast<BaseType*>(  this ) = x; }
          };
          
          //N=4
          // Specialization to allow use of
          // FastDelegate< R (   Param1,   Param2,   Param3,   Param4  ) >
          // instead of
          // FastDelegate4 < Param1,   Param2,   Param3,   Param4,   R >
          template<typename R,   class Param1,   class Param2,   class Param3,   class Param4>
          class FastDelegate< R (   Param1,   Param2,   Param3,   Param4  ) >
           // Inherit from FastDelegate4 so that it can be treated just like a FastDelegate4
           : public FastDelegate4 < Param1,   Param2,   Param3,   Param4,   R >
          {
          public:
           // Make using the base type a bit easier via typedef.
           typedef FastDelegate4 < Param1,   Param2,   Param3,   Param4,   R > BaseType;
          
           // Allow users access to the specific type of this delegate.
           typedef FastDelegate SelfType;
          
           // Mimic the base class constructors.
           FastDelegate(   ) : BaseType(   ) { }
          
           template < class X,   class Y >
           FastDelegate(  Y * pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4  ) )
           : BaseType(  pthis,   function_to_bind ) { }
          
           template < class X,   class Y >
           FastDelegate(  const Y *pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4  ) const )
           : BaseType(  pthis,   function_to_bind )
           { }
          
           FastDelegate(  R (  *function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4  ) )
           : BaseType(  function_to_bind ) { }
           void operator = (  const BaseType &x ) {
           *static_cast<BaseType*>(  this ) = x; }
          };
          
          //N=5
          // Specialization to allow use of
          // FastDelegate< R (   Param1,   Param2,   Param3,   Param4,   Param5  ) >
          // instead of
          // FastDelegate5 < Param1,   Param2,   Param3,   Param4,   Param5,   R >
          template<typename R,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5>
          class FastDelegate< R (   Param1,   Param2,   Param3,   Param4,   Param5  ) >
           // Inherit from FastDelegate5 so that it can be treated just like a FastDelegate5
           : public FastDelegate5 < Param1,   Param2,   Param3,   Param4,   Param5,   R >
          {
          public:
           // Make using the base type a bit easier via typedef.
           typedef FastDelegate5 < Param1,   Param2,   Param3,   Param4,   Param5,   R > BaseType;
          
           // Allow users access to the specific type of this delegate.
           typedef FastDelegate SelfType;
          
           // Mimic the base class constructors.
           FastDelegate(   ) : BaseType(   ) { }
          
           template < class X,   class Y >
           FastDelegate(  Y * pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5  ) )
           : BaseType(  pthis,   function_to_bind ) { }
          
           template < class X,   class Y >
           FastDelegate(  const Y *pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5  ) const )
           : BaseType(  pthis,   function_to_bind )
           { }
          
           FastDelegate(  R (  *function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5  ) )
           : BaseType(  function_to_bind ) { }
           void operator = (  const BaseType &x ) {
           *static_cast<BaseType*>(  this ) = x; }
          };
          
          //N=6
          // Specialization to allow use of
          // FastDelegate< R (   Param1,   Param2,   Param3,   Param4,   Param5,   Param6  ) >
          // instead of
          // FastDelegate6 < Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   R >
          template<typename R,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6>
          class FastDelegate< R (   Param1,   Param2,   Param3,   Param4,   Param5,   Param6  ) >
           // Inherit from FastDelegate6 so that it can be treated just like a FastDelegate6
           : public FastDelegate6 < Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   R >
          {
          public:
           // Make using the base type a bit easier via typedef.
           typedef FastDelegate6 < Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   R > BaseType;
          
           // Allow users access to the specific type of this delegate.
           typedef FastDelegate SelfType;
          
           // Mimic the base class constructors.
           FastDelegate(   ) : BaseType(   ) { }
          
           template < class X,   class Y >
           FastDelegate(  Y * pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6  ) )
           : BaseType(  pthis,   function_to_bind ) { }
          
           template < class X,   class Y >
           FastDelegate(  const Y *pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6  ) const )
           : BaseType(  pthis,   function_to_bind )
           { }
          
           FastDelegate(  R (  *function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6  ) )
           : BaseType(  function_to_bind ) { }
           void operator = (  const BaseType &x ) {
           *static_cast<BaseType*>(  this ) = x; }
          };
          
          //N=7
          // Specialization to allow use of
          // FastDelegate< R (   Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7  ) >
          // instead of
          // FastDelegate7 < Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   R >
          template<typename R,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class Param7>
          class FastDelegate< R (   Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7  ) >
           // Inherit from FastDelegate7 so that it can be treated just like a FastDelegate7
           : public FastDelegate7 < Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   R >
          {
          public:
           // Make using the base type a bit easier via typedef.
           typedef FastDelegate7 < Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   R > BaseType;
          
           // Allow users access to the specific type of this delegate.
           typedef FastDelegate SelfType;
          
           // Mimic the base class constructors.
           FastDelegate(   ) : BaseType(   ) { }
          
           template < class X,   class Y >
           FastDelegate(  Y * pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7  ) )
           : BaseType(  pthis,   function_to_bind ) { }
          
           template < class X,   class Y >
           FastDelegate(  const Y *pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7  ) const )
           : BaseType(  pthis,   function_to_bind )
           { }
          
           FastDelegate(  R (  *function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7  ) )
           : BaseType(  function_to_bind ) { }
           void operator = (  const BaseType &x ) {
           *static_cast<BaseType*>(  this ) = x; }
          };
          
          //N=8
          // Specialization to allow use of
          // FastDelegate< R (   Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   Param8  ) >
          // instead of
          // FastDelegate8 < Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   Param8,   R >
          template<typename R,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class Param7,   class Param8>
          class FastDelegate< R (   Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   Param8  ) >
           // Inherit from FastDelegate8 so that it can be treated just like a FastDelegate8
           : public FastDelegate8 < Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   Param8,   R >
          {
          public:
           // Make using the base type a bit easier via typedef.
           typedef FastDelegate8 < Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   Param8,   R > BaseType;
          
           // Allow users access to the specific type of this delegate.
           typedef FastDelegate SelfType;
          
           // Mimic the base class constructors.
           FastDelegate(   ) : BaseType(   ) { }
          
           template < class X,   class Y >
           FastDelegate(  Y * pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8  ) )
           : BaseType(  pthis,   function_to_bind ) { }
          
           template < class X,   class Y >
           FastDelegate(  const Y *pthis,  
           R (  X::* function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8  ) const )
           : BaseType(  pthis,   function_to_bind )
           { }
          
           FastDelegate(  R (  *function_to_bind )(   Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8  ) )
           : BaseType(  function_to_bind ) { }
           void operator = (  const BaseType &x ) {
           *static_cast<BaseType*>(  this ) = x; }
          };
          
          
          #endif //FASTDELEGATE_ALLOW_FUNCTION_TYPE_SYNTAX
          
          ////////////////////////////////////////////////////////////////////////////////
          // Fast Delegates,   part 5:
          //
          // MakeDelegate(   ) helper function
          //
          // MakeDelegate(  &x,   &X::func ) returns a fastdelegate of the type
          // necessary for calling x.func(   ) with the correct number of arguments.
          // This makes it possible to eliminate many typedefs from user code.
          //
          ////////////////////////////////////////////////////////////////////////////////
          
          // Also declare overloads of a MakeDelegate(   ) global function to
          // reduce the need for typedefs.
          // We need seperate overloads for const and non-const member functions.
          // Also,   because of the weird rule about the class of derived member function pointers,  
          // implicit downcasts may need to be applied later to the 'this' pointer.
          // That's why two classes (  X and Y ) appear in the definitions. Y must be implicitly
          // castable to X.
          
          // Workaround for VC6. VC6 needs void return types converted into DefaultVoid.
          // GCC 3.2 and later won't compile this unless it's preceded by 'typename',  
          // but VC6 doesn't allow 'typename' in this context.
          // So,   I have to use a macro.
          
          #ifdef FASTDLGT_VC6
          #define FASTDLGT_RETTYPE detail::VoidToDefaultVoid<RetType>::type
          #else
          #define FASTDLGT_RETTYPE RetType
          #endif
          
          //N=0
          template <class X,   class Y,   class RetType>
          FastDelegate0<FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(   ) ) {
           return FastDelegate0<FASTDLGT_RETTYPE>(  x,   func );
          }
          
          template <class X,   class Y,   class RetType>
          FastDelegate0<FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(   ) const ) {
           return FastDelegate0<FASTDLGT_RETTYPE>(  x,   func );
          }
          
          //N=1
          template <class X,   class Y,   class Param1,   class RetType>
          FastDelegate1<Param1,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1 ) ) {
           return FastDelegate1<Param1,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          template <class X,   class Y,   class Param1,   class RetType>
          FastDelegate1<Param1,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1 ) const ) {
           return FastDelegate1<Param1,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          //N=2
          template <class X,   class Y,   class Param1,   class Param2,   class RetType>
          FastDelegate2<Param1,   Param2,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2 ) ) {
           return FastDelegate2<Param1,   Param2,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          template <class X,   class Y,   class Param1,   class Param2,   class RetType>
          FastDelegate2<Param1,   Param2,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2 ) const ) {
           return FastDelegate2<Param1,   Param2,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          //N=3
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class RetType>
          FastDelegate3<Param1,   Param2,   Param3,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3 ) ) {
           return FastDelegate3<Param1,   Param2,   Param3,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class RetType>
          FastDelegate3<Param1,   Param2,   Param3,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3 ) const ) {
           return FastDelegate3<Param1,   Param2,   Param3,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          //N=4
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class RetType>
          FastDelegate4<Param1,   Param2,   Param3,   Param4,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 ) ) {
           return FastDelegate4<Param1,   Param2,   Param3,   Param4,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class RetType>
          FastDelegate4<Param1,   Param2,   Param3,   Param4,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4 ) const ) {
           return FastDelegate4<Param1,   Param2,   Param3,   Param4,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          //N=5
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class RetType>
          FastDelegate5<Param1,   Param2,   Param3,   Param4,   Param5,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 ) ) {
           return FastDelegate5<Param1,   Param2,   Param3,   Param4,   Param5,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class RetType>
          FastDelegate5<Param1,   Param2,   Param3,   Param4,   Param5,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5 ) const ) {
           return FastDelegate5<Param1,   Param2,   Param3,   Param4,   Param5,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          //N=6
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class RetType>
          FastDelegate6<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 ) ) {
           return FastDelegate6<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class RetType>
          FastDelegate6<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6 ) const ) {
           return FastDelegate6<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          //N=7
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class Param7,   class RetType>
          FastDelegate7<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 ) ) {
           return FastDelegate7<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class Param7,   class RetType>
          FastDelegate7<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7 ) const ) {
           return FastDelegate7<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          //N=8
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class Param7,   class Param8,   class RetType>
          FastDelegate8<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   Param8,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 ) ) {
           return FastDelegate8<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   Param8,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          template <class X,   class Y,   class Param1,   class Param2,   class Param3,   class Param4,   class Param5,   class Param6,   class Param7,   class Param8,   class RetType>
          FastDelegate8<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   Param8,   FASTDLGT_RETTYPE> MakeDelegate(  Y* x,   RetType (  X::*func )(  Param1 p1,   Param2 p2,   Param3 p3,   Param4 p4,   Param5 p5,   Param6 p6,   Param7 p7,   Param8 p8 ) const ) {
           return FastDelegate8<Param1,   Param2,   Param3,   Param4,   Param5,   Param6,   Param7,   Param8,   FASTDLGT_RETTYPE>(  x,   func );
          }
          
          
           // clean up after ourselves...
          #undef FASTDLGT_RETTYPE
          
          } // namespace fastdelegate
          
          #endif // !defined(  FASTDELEGATE_H )
          

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeCamera.h

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright © 2000-2004 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          PagingLandScapeCamera.h - description
          -------------------
          begin : Fri Sep 27 2004
          copyright : (  C ) 2006 by Tuan Kuranes
          email : tuan.kuranes@free.fr
          
          ***************************************************************************/
          
          #ifndef PagingLandScapeCamera_H
          #define PagingLandScapeCamera_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeCamera.h"
          
          namespace Ogre
          {
           /** Specialized viewpoint from which an part of LandScape can be rendered.
           @remarks
           This class contains several specializations of the Ogre::Camera class. It
           implements the getRenderOperation method in order to return displayable geometry
           for debugging purposes. It also implements a visibility function that is more granular
           than the default.
           */
      49   class PagingLandScapeCamera : public PagingLandScapeOctreeCamera
           {
      51   friend class PagingLandScapePageManager;
          
           public:
          
           /* Standard Constructor */
      56   PagingLandScapeCamera(  const String& name,   SceneManager* sm );
           /* Standard destructor */
      58   ~PagingLandScapeCamera(  void );
          
           /** Returns the visibility of the box
           */
      62   bool isVisible(  const AxisAlignedBox &bounds ) const;
          
      64   void updatePaging(  const unsigned int x,   const unsigned int z );
          
      66   void resetPaging(  void );
          
           unsigned int mCurrentCameraPageX;
           unsigned int mCurrentCameraPageZ;
          
           unsigned int mCurrentCameraTileX;
           unsigned int mCurrentCameraTileZ;
          
           private:
           unsigned int mIniX;
           unsigned int mFinX;
          
           unsigned int mIniZ;
           unsigned int mFinZ;
          
           unsigned int mPreIniX;
           unsigned int mPreFinX;
          
           unsigned int mPreIniZ;
           unsigned int mPreFinZ;
          
      87   Vector3 mLastCameraPos;
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2D.h

       1  /***************************************************************************
           OgrePagingLandScapeData2D.h - description
           -------------------
           begin : Wen Mar 5 2003
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeDATA2D_H
          #define PAGINGLandScapeDATA2D_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeOptions.h"
          
          namespace Ogre
          {
           /**
           * Encapsulating 2D Data reading.
           */
      31   class PagingLandScapeData2D
           {
           public:
      34   PagingLandScapeData2D(  PagingLandScapeData2DManager *pageMgr );
          
      36   virtual ~PagingLandScapeData2D(  void );
          
      38   virtual PagingLandScapeData2D* newPage(   ) = 0;
          
      40   virtual String getName(   ) const= 0;
      41   virtual bool load(  const unsigned int mX,   const unsigned int mZ );
          
      43   virtual void load(  void );
          
      45   virtual void init(  void );
      46   virtual void uninit(  void );
          
      48   virtual void unload(  void );
          
          #ifndef _MAPSPLITTER
           /**
           * deform Height Data of the terrain.
           * \param &deformationPoint
           * Where modification is,   in world coordinates
           * \param &modificationHeight
           * What modification do to terrain
           * \param info
           * Give some info on tile to
           * help coordinate system change
           */
      61   const bool deformHeight(  const Vector3& deformationPoint,   Real &modificationHeight );
          
           /**
           *
           * deform Height Data of the terrain.
           * \param &x
           * x Position on 2d height grid
           * \param &z
           * z Position on 2d height grid
           * \param &modificationHeight
           * What modification do to terrain
           */
      73   const bool deformHeight(  const unsigned int x,   const unsigned int z,   Real &modificationHeight );
          
          
      76   bool setHeight(  const unsigned int x,   const unsigned int z,   const Real h );
      77   bool setHeight(  const unsigned int x,   const unsigned int z,   const unsigned int Pos,   const Real h );
           /**
           *
           * get smallest rectangle containing all deformation
           * done before an update. (  where rectangle is reseted. )
           *
           * \return Box struct describing rectangle
           *
           */
      86   Image::Box getDeformationRectangle(  void );
          
           /**
           *
           * Adjust smallest rectangle to make it contain the point
           * \param &x
           * x Position on 2d height grid
           * \param &z
           * z Position on 2d height grid
           */
      96   void adjustDeformationRectangle(  const unsigned int x,   const unsigned int z );
          
           /**
           *
           * Reset Deformation rectangle
           */
     102   void resetDeformationRectangle(  void );
          #endif // _MAPSPLITTER
          
     105   virtual const Vector3 getNormal(  const Real mX,   const Real mZ );
     106   virtual const ColourValue getBase(  const Real mX,   const Real mZ ) const
           {
           return ColourValue::White;
           };
          
     111   virtual const ColourValue getCoverage(  const Real mX,   const Real mZ ) const
           {
           return ColourValue::White;
           };
          
     116   virtual const Real getShadow(  const Real mX,   const Real mZ,   const bool& positive ) const
           {
           return 0.0f;
           };
           //-----------------------------------------------------------------------
     121   const Real getShiftX(   ) const
           {
           return mShiftX;
           }
           //-----------------------------------------------------------------------
     126   const Real getShiftZ(   ) const
           {
           return mShiftZ;
           }
           //-----------------------------------------------------------------------
     131   inline const Real getHeightAbsolute(  const Real x,   const Real z ) const
           {
           const Vector3 &invScale = mParent->getOptions(   )->invScale;
          
           // adjust x and z to be local to page
           int i_x = static_cast<int> (  x * invScale.x - mShiftX );
           int i_z = static_cast<int> (  z * invScale.z - mShiftZ );
          
           // due to Real imprecision on Reals,   we have to use boundaries here
           // otherwise we'll hit asserts.
           int size = static_cast<int> (  mSize-1 );
           if (  i_x > size )
           i_x = size;
           else if (  i_x < 0 )
           i_x = 0;
          
           if (  i_z > size )
           i_z = size;
           else if (  i_z < 0 )
           i_z = 0;
          
           const unsigned int u_x = static_cast<unsigned int> (  i_x );
           const unsigned int u_z = static_cast<unsigned int> (  i_z );
          
           const size_t arraypos = u_z * mSize + u_x;
           assert (  mHeightData && arraypos < mMaxArrayPos );
           return mHeightData[arraypos];
           }
          
          
     161   inline const Real getHeight(  const Real x,   const Real z ) const
           {
           assert (  z < mSize && x < mSize );
           assert (  mHeightData );
           const unsigned int Pos = static_cast< unsigned int > (  z * mSize + x );
           assert (  mMaxArrayPos > Pos );
           return mHeightData[ Pos ];
           };
          
     170   inline const Real getHeight(  const unsigned int x,   const unsigned int z ) const
           {
           assert (  mHeightData );
           assert (  z < mSize && x < mSize );
           const unsigned int Pos = static_cast <unsigned int> (  z * mSize + x );
           assert (  mMaxArrayPos > Pos );
           return mHeightData[ Pos ];
           };
          
     179   inline const Real getHeight(  const int x,   const int z ) const
           {
           assert (  mHeightData );
           assert (  static_cast< unsigned int >(  z ) < mSize && static_cast< unsigned int >(  x ) < mSize );
           const unsigned int Pos = static_cast< unsigned int >(  z * mSize + x );
           assert (  mMaxArrayPos > Pos );
           return mHeightData[ Pos ];
           };
          
     188   inline const Real getHeight(  const unsigned int pos ) const
           {
           assert (  mHeightData );
           assert (  mMaxArrayPos > pos );
           return mHeightData[ pos ];
           };
     194   inline const Real getMaxHeight(  void ) const
           {
           return mMaxheight;
           };
           // useful to know max height before data is loaded.
     199   virtual const Real getMaxAbsoluteHeight(  void ) const = 0;
          
     201   Real* getHeightData(  void )
           {
           return mHeightData;
           };
          
     206   bool isLoaded(  void ) const {return mIsLoaded;};
          
     208   void computePowerof2PlusOneSize(  void );
          
     210   virtual size_t getXDimension(  void ) const
           {
           return mXDimension;
           };
          
     215   virtual size_t getZDimension(  void ) const
           {
           return mZDimension;
           };
          
     220   virtual size_t getSize(  void ) const
           {
           return mSize;
           };
          
     225   void getCoordinates(  unsigned int& X,   unsigned int& Z ) const
           {
           X = mPageX;
           Z = mPageZ;
           };
     230   inline bool isCoord(  const unsigned int x,   const unsigned int z ) const {return (  mPageX == x && mPageZ == z );};
          
          
           protected:
     234   virtual void _save(  void ) = 0;
     235   virtual bool _load(  const unsigned int x,   const unsigned int z ) = 0;
     236   virtual void _load(  void ) = 0;
     237   virtual void _unload(  void ) = 0;
     238   bool _checkSize(  const size_t s );
          
           // computed Height Data (  scaled )
     241   Real *mHeightData;
           // maximum position in Array
           unsigned int mMaxArrayPos;
           // data side maximum size
     245   size_t mSize;
           // data source width
     247   size_t mXDimension;;
           // data source height
     249   size_t mZDimension;
           // image data maximum size
           unsigned int mMax;
           // maximum page/data2d height. (  scaled )
     253   Real mMaxheight;
           // if data loaded or not
     255   bool mIsLoaded;
          
           // if data modified or not
     258   bool mIsModified;
           // if data modified but not yet
           // readied by other objects (  texture or renderable )
           // to get modification to rect only once per frame.
     262   bool mIsRectModified;
          
           // page number
           unsigned int mPageX;
           // page number
           unsigned int mPageZ;
          
           // coordinate shift based on page number
     270   Real mShiftX;
           // coordinate shift based on page number
     272   Real mShiftZ;
     273   PagingLandScapeData2DManager *mParent;
          
           private :
     276   Image::Box mRect;
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2DManager.h

       1  /***************************************************************************
           OgrePagingLandScapeData2DManager.h - description
           -------------------
           begin : Mon Jun 16 2003
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeDATA2DMANAGER_H
          #define PAGINGLandScapeDATA2DMANAGER_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
      26   class PagingLandScapeData2DManager
           {
           public:
      29   PagingLandScapeData2DManager(  PagingLandScapeSceneManager * scnMgr,  
      30   PagingLandScapeOptions * opt  );
          
      32   ~PagingLandScapeData2DManager(  void );
          
      34   void load(  void );
      35   void clear(  void );
      36   void WorldDimensionChange(  void );
      37   void reset(  void );
          
      39   PagingLandScapeData2D* allocateData2D(   ) const;
          
      41   bool load(  const unsigned int dataX,   const unsigned int dataZ );
          
      43   bool reload(  const unsigned int dataX,   const unsigned int dataZ );
          
      45   void unload(  const unsigned int dataX,   const unsigned int dataZ );
          
      47   bool isLoaded(  const unsigned int dataX,   const unsigned int dataZ );
          
      49   const Real getHeight(  const unsigned int dataX,   const unsigned int dataZ,   const Real x,   const Real z );
          
      51   const Real getHeight(  const unsigned int dataX,   const unsigned int dataZ,   const unsigned int x,   const unsigned int z );
          
      53   const Real getHeightAtPage(  const unsigned int dataX,   const unsigned int dataZ,   const Real x,   const Real z );
          
      55   const Real getHeightAtPage(  const unsigned int dataX,   const unsigned int dataZ,   const int x,   const int z );
          
      57   bool setHeight(  const Vector3& deformationPoint,   const Real modificationHeight,   const PagingLandScapeTileInfo* info );
      58   bool deformHeight(  const Vector3& deformationPoint,   const Real modificationHeight,   const PagingLandScapeTileInfo* info );
          
          // bool addNewHeight(  const Sphere newSphere );
          //
          // bool removeNewHeight(  const Sphere oldSphere );
          
           //This function will return the max possible value of height base on the current 2D Data implementation
      65   const Real getMaxHeight(  const unsigned int x,   const unsigned int z );
          
      67   const Real getMaxHeight(  void ) const;
          
           /** Get the real world height at a particular position
           @remarks
           Method is used to get the terrain height at a world position based on x and z.
           This method just figures out what page the position is on and then asks the page node
           to do the dirty work of getting the height.
          
           @par
           the Real returned is the real world height based on the scale of the world. If the height could
           not be determined then -1 is returned and this would only occur if the page was not preloaded or loaded
          
           @param x x world position
           @param z z world position
           */
      82   const Real getInterpolatedWorldHeight(  const Real x,   const Real z,   Real *slope = NULL );
      83   const Real getWorldHeight(  const Real x,   const Real z );
          
      85   const ColourValue getCoverageAt(  const unsigned int dataX,   const unsigned int dataZ,   const Real x,   const Real z );
          
      87   const ColourValue getBaseAt(  const unsigned int dataX,   const unsigned int dataZ,   const Real x,   const Real z );
          
      89   const Real getShadowAt(  const unsigned int dataX,   const unsigned int dataZ,   const unsigned int x,   const unsigned int z,   const bool& positive );
          
      91   const Vector3 getNormalAt(  const unsigned int pageX,   const unsigned int pageZ,   const unsigned int x,   const unsigned int z );
      92   const Real getRealWorldSlope(  const Real x,   const Real z );
      93   const Vector3 getNormalAt(  const unsigned int pageX,   const unsigned int pageZ,   const unsigned int x,   const unsigned int z,   const unsigned int Lod );
          
      95   void setPageManager(  PagingLandScapeSceneManager *scnMgr );
          
          
      98   void registerDataType(  PagingLandScapeData2D* source )
           {
           mData2DTypeMap.push_back(  source );
          // LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,  
          // "PagingLandScape: Registered a new Data2DType for "
          // "type " + typeName );
           }
           // Walk the heightfield from location1 to location2 and find the max slope.
           // If maxSlope > 0 and a slope of greater than maxSlopeIn is found,   maxSlope is returned.
           // This is an expensive operation,   so use sparingly.
     108   Real getMaxSlope(  Vector3 location1,   Vector3 location2,   Real maxSlopeIn );
          
     110   PagingLandScapeData2D* getData2D(  const unsigned int i ,   const unsigned int j,  
     111   const bool alwaysReturn = true );
     112   PagingLandScapeData2D* getNewData2D(  const unsigned int i ,   const unsigned int j );
     113   void releaseData2D (  PagingLandScapeData2D*p  );
          
     115   PagingLandScapeOptions* getOptions(   ){return mOptions;}
     116   PagingLandScapeSceneManager *getSceneManager(   ){return mScnMgr;}
           protected:
     118   PagingLandScapeSceneManager * mScnMgr;
     119   PagingLandScapeOptions* mOptions;
          
          
           unsigned int mData2DType;
     123   String mData2DFormat;
          
           unsigned int mWidth;
           unsigned int mHeight;
          
          
     129   Real mMaxHeight;
           //PagingLandScapeData2DPages mData2D;
     131   PagingLandScapePageManager* mPageManager;
          
           /// Map of Data2d source type
     134   PagingLandScapeData2DMap mData2DTypeMap;
           /// The currently active page Data2d source
     136   PagingLandScapeData2D* mActiveData2DType;
          
     138   PagingLandScapeData2DList mActiveData2Ds;
     139   PagingLandScapeData2DList mFreeData2Ds;
     140   PagingLandScapeData2DArray mData2DPool;
           };
          
          } //namespace
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2D_HeightField.h

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightField.h - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeDATA2D_HEIGHTFIELD_H
          #define PAGINGLandScapeDATA2D_HEIGHTFIELD_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          
          namespace Ogre
          {
          
          /**
           * A specialized class for loading 2D Data from a HeightField file.
           */
          
      31  class PagingLandScapeData2D_HeightField: public PagingLandScapeData2D
          {
          public:
      34   PagingLandScapeData2D_HeightField(  PagingLandScapeData2DManager *dataMgr );
      35   virtual String getName(   ) const{return String(  "HeightField" );}
      36   virtual ~PagingLandScapeData2D_HeightField(  void );
          
      38   virtual const Vector3 getNormal(  const Real mX,   const Real mZ );
      39   virtual const ColourValue getBase(  const Real mX,   const Real mZ );
      40   virtual const ColourValue getCoverage(  const Real mX,   const Real mZ );
      41   virtual const Real getShadow(  const Real mX,   const Real mZ,   const bool& positive );
          
      43   const Real getMaxAbsoluteHeight(  void ) const;
      44   virtual PagingLandScapeData2D* newPage(   );
          protected:
          
      47   virtual void _save(  void );
      48   virtual bool _load(  const unsigned int x,   const unsigned int z );
      49   virtual void _load(  void );
      50   virtual void _unload(  void );
          
          private:
      53   Real getScale(   ) const;
      54   Real getInvScale(   ) const;
          
      56   Image* mImage;
      57   Image* mBase;
      58   Image* mShadow;
      59   Image* mCoverage;
          
           /// should be 4 bytes (  mImage is RGBA )
      62   size_t mBpp;
          };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2D_HeightFieldBlendNeighbor.h

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldBlendNeighbor.h - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeData2D_HeightFieldBlendNeighbor_H
          #define PagingLandScapeData2D_HeightFieldBlendNeighbor_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
           /**
           * A specialized class for loading 2D Data from a HeightField file.
           */
      29   class PagingLandScapeData2D_HeightFieldBlendNeighbor: public PagingLandScapeData2D
           {
           public:
      32   PagingLandScapeData2D_HeightFieldBlendNeighbor(  PagingLandScapeData2DManager *dataMgr );
      33   virtual String getName(   ) const{return String(  "HeightFieldBlendNeighbor" );}
      34   virtual ~PagingLandScapeData2D_HeightFieldBlendNeighbor(  void );
          
      36   virtual const Real getShadow(  const Real mX,   const Real mZ,   const bool& positive );
          
      38   virtual PagingLandScapeData2D* newPage(   );
      39   const Real getMaxAbsoluteHeight(  void ) const;
          
           protected:
      42   virtual void _save(  void );
      43   virtual bool _load(  const unsigned int x,   const unsigned int z );
      44   virtual void _load(  void );
      45   virtual void _unload(  void );
          
           private:
      48   Image * mShadow;
           unsigned int mBpp;// should be 2 bytes (  mImage is 16 bits )
           };
          
          }
          
          #endif //PagingLandScapeData2D_HeightFieldBlendNeighbor_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2D_HeightFieldN.h

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldN.h - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeData2D_HeightFieldN_H
          #define PagingLandScapeData2D_HeightFieldN_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          
          namespace Ogre
          {
          
          /**
           * A specialized class for loading 2D Data from a HeightField file.
           */
          
      31  class PagingLandScapeData2D_HeightFieldN: public PagingLandScapeData2D
          {
           public:
      34   PagingLandScapeData2D_HeightFieldN(  PagingLandScapeData2DManager *dataMgr );
      35   virtual String getName(   ) const{return String(  "HeightFieldN" );}
      36   virtual ~PagingLandScapeData2D_HeightFieldN(  void );
          
      38   virtual const Vector3 getNormal(  const Real mX,   const Real mZ );
      39   virtual const ColourValue getBase(  const Real mX,   const Real mZ );
      40   virtual const ColourValue getCoverage(  const Real mX,   const Real mZ );
      41   virtual const Real getShadow(  const Real mX,   const Real mZ,   const bool& positive );
          
      43   virtual PagingLandScapeData2D* newPage(   );
      44   const Real getMaxAbsoluteHeight(  void ) const;
          
           protected:
      47   virtual void _save(  void );
      48   virtual bool _load(  const unsigned int x,   const unsigned int z );
      49   virtual void _load(  void );
      50   virtual void _unload(  void );
          
           private:
      53   Image* mImage;
      54   Image* mBase;
      55   Image* mShadow;
      56   Image* mCoverage;
          
      58   size_t mBpp;// should be 4 bytes (  mImage is RGBA )
          };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2D_HeightFieldNTC.h

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldNTC.h - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeDATA2D_HEIGHTFIELDNTC_H
          #define PAGINGLandScapeDATA2D_HEIGHTFIELDNTC_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          
          namespace Ogre
          {
          
           /**
           * A specialized class for loading 2D Data from a compressed HeightField file.
           */
      30   class PagingLandScapeData2D_HeightFieldNTC: public PagingLandScapeData2D
           {
           public:
      33   PagingLandScapeData2D_HeightFieldNTC(  PagingLandScapeData2DManager *dataMgr );
      34   virtual String getName(   ) const{return String(  "HeightFieldNTC" );}
          
      36   ~PagingLandScapeData2D_HeightFieldNTC(  void );
          
          
      39   virtual const Vector3 getNormalAt(  const Real mX,   const Real mZ );
      40   virtual const ColourValue getBase(  const Real mX,   const Real mZ );
      41   virtual const ColourValue getCoverage(  const Real mX,   const Real mZ );
          
      43   virtual PagingLandScapeData2D* newPage(   );;
      44   const Real getMaxAbsoluteHeight(  void ) const;
          
           protected:
      47   virtual void _save(  void );
          
      49   virtual bool _load(  const unsigned int x,   const unsigned int z );
          
      51   virtual void _load(  void );
          
      53   virtual void _unload(  void );
          
           private:
      56   inline Real _decodeTC(  const Real encoded ) const;
      57   inline uchar _encodeTC(  const Real decoded ) const;
          
      59   Real input_max,   input_min;
          
      61   Image* mImage;
      62   size_t mBpp;// should be 4 bytes (  mImage is RGBA )
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2D_HeightFieldRaw.h

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldRaw.h - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeData2D_HeightFieldRaw_H
          #define PagingLandScapeData2D_HeightFieldRaw_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
           /**
           * A specialized class for loading 2D Data from a HeightField file.
           */
      29   class PagingLandScapeData2D_HeightFieldRaw: public PagingLandScapeData2D
           {
           public:
      32   PagingLandScapeData2D_HeightFieldRaw(  PagingLandScapeData2DManager *dataMgr );
      33   virtual String getName(   ) const{return String(  "HeightFieldRaw" );}
      34   virtual ~PagingLandScapeData2D_HeightFieldRaw(  void );
          
      36   virtual const Real getShadow(  const Real mX,   const Real mZ,   const bool& positive );
          
      38   virtual PagingLandScapeData2D* newPage(   );
      39   const Real getMaxAbsoluteHeight(  void ) const;
          
           protected:
      42   virtual void _save(  void );
      43   virtual bool _load(  const unsigned int x,   const unsigned int z );
      44   virtual void _load(  void );
      45   virtual void _unload(  void );
          
           private:
      48   Image * mShadow;
           unsigned int mBpp;// should be 2 bytes (  mImage is 16 bits )
           };
          
          }
          
          #endif //PagingLandScapeData2D_HeightFieldRaw_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2D_HeightFieldRawTC.h

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldRawTC.h - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeDATA2D_HEIGHTFIELDRawTC_H
          #define PAGINGLandScapeDATA2D_HEIGHTFIELDRawTC_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
           /**
           * A specialized class for loading 2D Data from a compressed HeightField file.
           */
      28   class PagingLandScapeData2D_HeightFieldRawTC: public PagingLandScapeData2D
           {
           public:
      31   PagingLandScapeData2D_HeightFieldRawTC(  PagingLandScapeData2DManager *dataMgr );
      32   virtual String getName(   ) const{return String(  "HeightFieldRawTC" );}
          
      34   virtual ~PagingLandScapeData2D_HeightFieldRawTC(  void );
          
      36   virtual const Vector3 getNormalAt(  const Real mX,   const Real mZ );
      37   virtual const ColourValue getBase(  const Real mX,   const Real mZ );
      38   virtual const ColourValue getCoverage(  const Real mX,   const Real mZ );
      39   virtual PagingLandScapeData2D* newPage(   );;
      40   const Real getMaxAbsoluteHeight(  void ) const;
          
          
           protected:
      44   virtual void _save(  void );
      45   virtual bool _load(  const unsigned int x,   const unsigned int z );
      46   virtual void _load(  void );
      47   virtual void _unload(  void );
          
           private:
      50   inline Real _decodeRawTC(  const Real encoded ) const;
      51   inline ushort _encodeRawTC(  const Real decoded ) const;
          
      53   Real input_max,   input_min;
      54   Image* mImage;
           unsigned int mBpp;// should be 4 bytes (  mImage is RGBA )
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2D_HeightFieldTC.h

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldTC.h - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeDATA2D_HEIGHTFIELDTC_H
          #define PAGINGLandScapeDATA2D_HEIGHTFIELDTC_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          
          namespace Ogre
          {
          
           /**
           * A specialized class for loading 2D Data from a compressed HeightField file.
           */
          
      31   class PagingLandScapeData2D_HeightFieldTC: public PagingLandScapeData2D
           {
           public:
      34   PagingLandScapeData2D_HeightFieldTC(  PagingLandScapeData2DManager *dataMgr );
          
      36   virtual ~PagingLandScapeData2D_HeightFieldTC(  void );
      37   virtual String getName(   ) const{return String(  "HeightFieldTC" );}
          
      39   virtual const ColourValue getBase(  const Real mX,   const Real mZ );
      40   virtual const ColourValue getCoverage(  const Real mX,   const Real mZ );
          
      42   virtual PagingLandScapeData2D* newPage(   );
      43   const Real getMaxAbsoluteHeight(  void ) const;
          
           protected:
      46   virtual void _save(  void );
      47   virtual bool _load(  const unsigned int x,   const unsigned int z );
      48   virtual void _load(  void );
      49   virtual void _unload(  void );
          
           private:
      52   inline Real _decodeTC(  const Real encoded ) const;
      53   inline uchar _encodeTC(  const Real decoded ) const;
          
      55   Real input_max,   input_min;
          
      57   Image* mImage;
      58   size_t mBpp;// should be 4 bytes (  mImage is RGBA )
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeData2D_Spline.h

       1  /***************************************************************************
           OgrePagingLandScapeData2D_Spline.h
           Header for a NURBS-based heightfield generator
           -------------------
           begin : Sat Nov 9 2003
           copyright : (  C ) 2003 Chris "Antiarc" Heald
           email : antiarc@captionthis.com
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeDATA2D_SPLINE_H
          #define PAGINGLandScapeDATA2D_SPLINE_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          #include "DRGNURBSSurface.h"
          
          namespace Ogre
          {
          
           /**
           * A specialized class for loading 2D Data from a Spline file.
           */
          
      33   class PagingLandScapeData2D_Spline: public PagingLandScapeData2D
           {
           public:
      36   PagingLandScapeData2D_Spline(  PagingLandScapeData2DManager *dataMgr );
          
      38   ~PagingLandScapeData2D_Spline(  void );
          
      40   virtual PagingLandScapeData2D* newPage(   );
      41   virtual String getName(   ) const{return String(  "Spline" );}
      42   const Real getMaxAbsoluteHeight(  void ) const;
          
           protected:
      45   virtual void _save(  void );
          
      47   virtual bool _load(  const unsigned int x,   const unsigned int z );
          
      49   virtual void _load(  void );
          
      51   virtual void _unload(  void );
          
           private:
           int degree;
          
      56   CDRGNURBSSurface* mSurface;
           Point4D* mPoints;
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeHorizon.h

       1  /***************************************************************************
           OgrePagingLandScapeHorizon.h - description
           -------------------
           begin : Sat Mar 08 2003
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeHorizon_H
          #define PagingLandScapeHorizon_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeHorizon
           {
           public:
      28   PagingLandScapeHorizon(  const PagingLandScapeOptions * const options );
      29   ~PagingLandScapeHorizon(  void );
          
      31   void registerMinMaxHeightPage(  const unsigned int pageX,   const unsigned int pageZ,   const Real minHeight,   const Real maxHeight );
          
      33   void registerMinMaxHeightTile(  const PagingLandScapeTileInfo* info,   const Real minHeight,   const Real maxHeight );
          
      35   bool IsPageVisible(  const PagingLandScapeCamera* cam,   const unsigned int destpageX,   const unsigned int destpageZ );
          
           /**
           *
           * \param cam Give info on current tile and camera height
           * \param *destinfo info on the tile we want to test visibility on,  
           * \return
           */
      43   bool IsTileVisible(  const PagingLandScapeCamera* cam,   const PagingLandScapeTileInfo* destinfo );
          
          
      46   MaterialPtr getVisibilityMaterial(  void );
          
      48   void AddVisibleTile(  const unsigned int Tilex,   const unsigned int Tilez,   const bool visible );
      49   void AddVisibleTile(  const PagingLandScapeTileInfo* info,   const bool visible );
          
      51   void update(  void );
      52   void prepare(  const PagingLandScapeCamera* cam );
          
           private :
          
           const PagingLandScapeOptions * const mOptions;
          
           bool calcVis(  const Vector3& src,   const Vector3& dest,   const Real* const heightMap,   const unsigned int mapWidth,   const unsigned int mapHeight );
          
           Real* mMaxPageHeights;
           Real* mMinPageHeights;
           unsigned int mPageWidth;
           unsigned int mPageHeight;
          
           unsigned int mNumTilesPage;
          
           Real* mMaxTileHeights;
           Real* mMinTileHeights;
           unsigned int mTileWidth;
           unsigned int mTileHeight;
          
           MaterialPtr mVisibilityMaterial;
           uchar* mVisData;
           Image mVisImage;
           TexturePtr mVisTex;
          
           bool material_enabled;
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeIndexBuffer.h

       1  /***************************************************************************
           OgrePagingLandScapeIndexBufferManager.h - description
           -------------------
           begin : Fri Feb 28 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeINDEXBUFFER_H
          #define PAGINGLandScapeINDEXBUFFER_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
      26   class PagingLandScapeIndexBufferManager
           {
           public:
          
          
      31   PagingLandScapeIndexBufferManager(  PagingLandScapeSceneManager * scnMgr );
          
      33   ~PagingLandScapeIndexBufferManager(  void );
          
      35   IndexData *getIndex(  const int LOD );
          
      37   void load(   );
      38   void clear(   );
          
          
           /** Utility method to generate stitching indexes on the edge of a tile
           @param neighbor The neighbor direction to stitch
           @param hiLOD The LOD of this tile
           @param loLOD The LOD of the neighbor
           @param omitFirstTri Whether the first triangle of the stitch (  always clockwise
           relative to the center of this tile ) is to be omitted because an
           adjoining edge is also being stitched
           @param omitLastTri Whether the last triangle of the stitch (  always clockwise
           relative to the center of this tile ) is to be omitted because an
           adjoining edge is also being stitched
           @param pIdx Pointer to a pointer to the index buffer to push the results
           into (  this pointer will be updated )
           @returns The number of indexes added
           */
      55   unsigned int stitchEdge(  const Neighbor neighbor,   const int hiLOD,   const int loLOD,   const bool omitFirstTri,   const bool omitLastTri,   void** ppIdx,   const bool is32bits ) const;
          
           /// Gets the index data for this tile based on current settings
      58   IndexData* getIndexData(  const int RenderLevel,   PagingLandScapeRenderable** Neighbors );
          
           /// Internal method for generating triangle list terrain indexes
      61   IndexData* generateTriListIndexes(  const bool northStitch,   const bool southStitch,   const bool eastStitch,   const bool westStitch,   const int RenderLevel,   PagingLandScapeRenderable** Neighbors ) const;
          
           //*******************
           //Added by Fiesch adapted from a post by tonyhnz
      65   IndexData* getRawIndexes(  int renderLevel );
          
      67   PagingLandScapeSceneManager *getSceneManager(   ){return mScnMgr;}
           protected:
          
      70   PagingLandScapeSceneManager *mScnMgr;
          
           /** Returns the index into the height array for the given coordinates. */
      73   inline ushort _index16(  int x,   int z ) const
           {
           return (  x + z * mTileSize );
           };
           /** Returns the index into the height array for the given coordinates. */
      78   inline unsigned int _index32(  int x,   int z ) const
           {
           return (  x + z * mTileSize );
           };
          
           unsigned int mTileSize;
          
      85   IndexArray mCache;
           /// Shared array of IndexData (  reuse indexes across tiles )
      87   LevelArray mLevelIndex;
           // Store the indexes for every combination
           unsigned int mNumIndexes;
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeIntersectionSceneQuery.h

          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeIntersectionSceneQuery.h - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004 by Jon Anderson
          email : janders@users.sf.net
          ***************************************************************************/
          
          #ifndef PagingLandScapeIntersectionSCENEQUERY_H
          #define PagingLandScapeIntersectionSCENEQUERY_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeIntersectionSceneQuery.h"
          #include "OgreSceneManager.h"
          
          namespace Ogre
          {
          
          /** PagingLandScapeOctree implementation of IntersectionSceneQuery. */
          class _OgrePagingLandScapeExport PagingLandScapeIntersectionSceneQuery :
           public PagingLandScapeOctreeIntersectionSceneQuery
          {
          public:
      48   PagingLandScapeIntersectionSceneQuery(  SceneManager* creator );
           virtual ~PagingLandScapeIntersectionSceneQuery(  void );
          
           /** See IntersectionSceneQuery. */
           void execute(  IntersectionSceneQueryListener* listener );
          };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeListener.h

          /*-----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright � 2000-2004 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------*/
          #ifndef __PagingLandScapePageSourceListener_H__
          #define __PagingLandScapePageSourceListener_H__
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
           /** Abstract class which classes can override to receive notifications
           when a page is ready to be added to the terrain manager.
           */
           class _OgrePagingLandScapeExport PagingLandScapeListener
           {
          
           public:
      37   PagingLandScapeListener(   ){};
           virtual ~PagingLandScapeListener(   ){};
           /** Listener method called when a new page is about to be constructed.
           @param pagex,   pagez The index of the page being constructed
           @param heightData Array of normalised height data (  0..1 ). The size of
           this buffer will conform to the scene manager page size. The listener
           may modify the data if it wishes.
           */
           virtual void pagePreloaded(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox ){};
           virtual void pageLoaded(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox ){};
           virtual void pageUnloaded(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox ){};
           virtual void pagePostunloaded(  const size_t pagex,   const size_t pagez ){};
           virtual void pageShow(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox ){};
           virtual void pageHide(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox ) {};
           virtual void tileLoaded(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox ){};
           virtual void tileUnloaded(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox ){};
           virtual void tileDeformed(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox ){};
           virtual void tileShow(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox ){};
           virtual void tileHide(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox ){};
           virtual void terrainReady(  void ) {};
          
           };
          }
          #endif //__PagingLandScapePageSourceListener_H__
          

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeListenerManager.h

          /*-----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright � 2000-2004 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------*/
          #ifndef __PagingLandScapePageSourceListenerManager_H__
          #define __PagingLandScapePageSourceListenerManager_H__
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeListener.h"
          #include "OgreSingleton.h"
          
          #include "OgrePagingLandScapeCallBackEvent.h"
          
          namespace Ogre
          {
           /** Simple manager class to hold onto a list of page source listeners
           across all sources.
           */
           class _OgrePagingLandScapeExport PagingLandScapeListenerManager
           {
           public:
      40   PagingLandScapeListenerManager(  PagingLandScapeSceneManager * scnMgr );
      41   ~PagingLandScapeListenerManager(  void );
          
           /** Register a class which will be called back whenever a new page is
           available.
           @remarks
           Since this method is static,   it applies to any page source which
           is in active use; there is no need to register one per source.
           */
      49   void addListener(  PagingLandScapeListener* pl );
          
           /** Unregister a class which will be called back whenever a new page is
           available.
           */
      54   void removeListener(  PagingLandScapeListener* pl );
          
           /// Fire event when Heightmap page Loaded Event
      57   void firePagePreloaded(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox );
          
           /// Fire event when Loaded is when page is textured and loaded in GPU.
      60   void firePageLoaded(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox );
          
           /// Fire event when Loaded is when page is untextured and unloaded in GPU.
      63   void firePageUnloaded(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox );
          
           /// Fire event when Heightmap page is unloaded
      66   void firePagePostunloaded(  const size_t pagex,   const size_t pagez );
          
           /// Fire event when page is visible
      69   void firePageShow(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox );
          
           /// Fire event when page is no more visible
      72   void firePageHide(  const size_t pagex,   const size_t pagez,   const Real* heightData,   const AxisAlignedBox &Bbox );
          
           /// Fire event when tile is Loaded in GPU
      75   void fireTileLoaded(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox );
          
           /// Fire event when tile is unLoaded in GPU
      78   void fireTileUnloaded(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox );
          
           /// Fire event when tile is deformed
      81   void fireTileDeformed(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox );
          
           /// Fire event when tile is visible
      84   void fireTileShow(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox );
          
           /// Fire event when tile is invisible
      87   void fireTileHide(  const size_t pagex,   const size_t pagez,   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox );
          
           /// Fire event when all tiles and page needed are loaded
      90   void fireTerrainReady(  void );
          
          
      93   bool setOption(  const String& strKey,   const void* pValue );
          
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
      97   void addTerrainListener(  PagingLandscapeDelegate* pl );
      98   void removeTerrainListener(  PagingLandscapeDelegate* pl );
          
          
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     103   void addPreloadPageListener(  PagingLandscapeDelegate* pl );
     104   void removePreloadPageListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     107   void addShowPageListener(  PagingLandscapeDelegate* pl );
     108   void removeShowPageListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     111   void addHidePageListener(  PagingLandscapeDelegate* pl );
     112   void removeHidePageListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     115   void addLoadPageListener(  PagingLandscapeDelegate* pl );
     116   void removeLoadPageListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     119   void addModifyPageListener(  PagingLandscapeDelegate* pl );
     120   void removeModifyPageListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     123   void addPostunloadPageListener(  PagingLandscapeDelegate* pl );
     124   void removePostunloadPageListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     127   void addUnloadPageListener(  PagingLandscapeDelegate* pl );
     128   void removeUnloadPageListener(  PagingLandscapeDelegate* pl );
          
          
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     133   void addShowTileListener(  PagingLandscapeDelegate* pl );
     134   void removeShowTileListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     137   void addHideTileListener(  PagingLandscapeDelegate* pl );
     138   void removeHideTileListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     141   void addLoadTileListener(  PagingLandscapeDelegate* pl );
     142   void removeLoadTileListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     145   void addModifyTileListener(  PagingLandscapeDelegate* pl );
     146   void removeModifyTileListener(  PagingLandscapeDelegate* pl );
           /** Register a delegate method which will be called back whenever terrain is ready (  no more queued objects. )
           */
     149   void addUnloadTileListener(  PagingLandscapeDelegate* pl );
     150   void removeUnloadTileListener(  PagingLandscapeDelegate* pl );
          
          
          
          
           protected:
          
           std::list<PagingLandscapeDelegate *> mTerrainReadyListeners;
          
           std::list<PagingLandscapeDelegate *> mShowPageListeners;
           std::list<PagingLandscapeDelegate *> mHidePageListeners;
           std::list<PagingLandscapeDelegate *> mPreloadPageListeners;
           std::list<PagingLandscapeDelegate *> mLoadPageListeners;
           std::list<PagingLandscapeDelegate *> mUnloadPageListeners;
           std::list<PagingLandscapeDelegate *> mPostunloadPageListeners;
           std::list<PagingLandscapeDelegate *> mModifyPageListeners;
          
          
           std::list<PagingLandscapeDelegate *> mShowTileListeners;
           std::list<PagingLandscapeDelegate *> mHideTileListeners;
           std::list<PagingLandscapeDelegate *> mLoadTileListeners;
           std::list<PagingLandscapeDelegate *> mUnloadTileListeners;
           std::list<PagingLandscapeDelegate *> mModifyTileListeners;
          
          
           };
          
          }
          
          #endif //__PagingLandScapePageSourceListener_H__

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeMeshDecal.h

          /*-----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright � 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------*/
          #ifndef __PagingLandScapeMeshDecal_H__
          #define __PagingLandScapeMeshDecal_H__
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
           /** Factory object for creating PagingLandScapeMeshDecal instances */
      31   class PagingLandScapeMeshDecalFactory : public MovableObjectFactory
           {
           protected:
      34   MovableObject* createInstanceImpl(   const String& name,   const NameValuePairList* params  );
           public:
      36   PagingLandScapeMeshDecalFactory(   ) {}
      37   ~PagingLandScapeMeshDecalFactory(   ) {}
          
      39   static String FACTORY_TYPE_NAME;
          
      41   const String& getType(  void ) const;
      42   void destroyInstance(   MovableObject* obj  );
           };
          
      45   class PagingLandScapeMeshDecal : public Renderable,   public MovableObject,   public SceneQueryListener
           {
           private:
      48   SceneManager* sceneMgr_;
      49   Vector3 position_;
      50   Quaternion orientation_;
      51   Vector2 size_;
      52   MaterialPtr material_;
          
      54   AxisAlignedBox AABB_;
      55   Real radius_;
          
      57   LightList lightList_;
          
      59   RenderOperation renderOp_;
      60   RaySceneQuery* rayQuery_;
      61   AxisAlignedBoxSceneQuery* AABBquery_;
          
      63   size_t declSize_;
          
           struct Vertex
           {
           Vertex(   Real x,   Real y,   Real z,   bool included  )
           : vertex_(   x,   y,   z  )
           ,   included_(   included  ) {}
           Vector3 vertex_;
           bool included_;
           };
          
           typedef std::vector<Vertex> VertexContainer;
           typedef std::vector<VertexContainer> SubSectionContainer;
      76   SubSectionContainer subSections_;
          
           struct SubExtent
           {
           int width_;
           int height_;
           int renderLevel_;
           };
          
           typedef std::vector<SubExtent> SubExtentContainer;
      86   SubExtentContainer subExtents_;
          
           unsigned int currentSubX_;
           unsigned int currentSubZ_;
          
           int width_;
           int height_;
          
           /**
           We'll use this flag to prevent rebuilding of the geometry every frame,   instead only rebuilding when the LOD has changed.
           */
      97   bool mDirty;
          
           /**
           A copy of the subextents from the last geometry generation,   to allow for dirty checks.
           */
     102   SubExtentContainer mOldSubExtents;
          
           public:
     105   PagingLandScapeMeshDecal(   const String& name,  
     106   const String& materialName,  
     107   const Vector2& size,  
     108   const String& sceneMgrInstanceName  );
     109   virtual ~PagingLandScapeMeshDecal(   );
          
           // Main public interface
     112   void SetSize(   const Vector2& size  );
          
     114   virtual void _notifyAttached(  Node* parent,   bool isTagPoint = false );
           private:
     116   void CreateGeometry(   );
     117   size_t GetNumVertices(   ) const;
     118   size_t GetNumIndices(   ) const;
     119   int GetRenderLevel(   int x,   int z  ) const
           {
           assert(   x >= 0 && x < width_  );
           assert(   z >= 0 && z < height_  );
           return subExtents_[z * width_ + x].renderLevel_;
           }
           template<class T> int CreateIndices(   HardwareIndexBufferSharedPtr ibuf  );
           template<class T> int MeshSubSection(   int x,   int z,   T*& indices,   int& indexOffset  );
           template<class T> int StitchEdge(   T*& indices,  
           const SubExtent& extents,  
           const int hiLOD,  
           const int loLOD,  
           const bool horizontal,  
           const bool forward,  
           const bool omitFirstTri,  
           const bool omitLastTri,  
           const int indexOffset  );
           // From MovableObject
           const String& getMovableType(   ) const
           {
           return PagingLandScapeMeshDecalFactory::FACTORY_TYPE_NAME;
           }
           const AxisAlignedBox& getBoundingBox(   ) const
           {
           return AABB_;
           }
     145   Real getBoundingRadius(   ) const
           {
           return radius_;
           }
     149   void _updateRenderQueue(   RenderQueue* queue  );
          
           // From Renderable
     152   const MaterialPtr& getMaterial(   ) const
           {
           return material_;
           }
           virtual void getRenderOperation(   RenderOperation& op  );
           virtual void getWorldTransforms(   Matrix4* xform  ) const;
           const Quaternion& getWorldOrientation(   ) const;
           const Vector3& getWorldPosition(   ) const;
           Real getSquaredViewDepth(   const Camera* cam  ) const;
           const LightList& getLights(   ) const
           {
           return lightList_;
           }
          
           // From SceneQueryListener
           bool queryResult(  MovableObject* object )
           {
           return false;
           }
           bool queryResult(  SceneQuery::WorldFragment* fragment );
           };
          }
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusion.h

       1  #ifndef __PagingLandScapeOcclusion_H
          #define __PagingLandScapeOcclusion_H
          
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          #include <stack>
          #include <list>
          
          #include "OgrePagingLandScapeOcclusionQuerySet.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          
          namespace Ogre
          {
          
      19   class Occlusion
           {
          
           public:
      23   Occlusion(  unsigned int visibilityThsd = 0 );
      24   ~Occlusion(   )
           {
           mQueryPool.deletePool (   );
           }
           //this is the algorithm from the paper
      29   void CHCtraversal(  PagingLandScapeOctree *octree,   VisibleObjectsBoundsInfo * const visibleBounds );
      30   void CHCtraversalConservative (  PagingLandScapeOctree *octree,   VisibleObjectsBoundsInfo * const visibleBounds );
          
      32   bool insideViewFrustum (  OcclusionElement& node );
      33   void pullUpVisibility(  OcclusionElement& n );
      34   bool isQueryResultIsVisible(  OcclusionElement& node );
      35   bool issueDrawQuery(  PagingLandScapeOctreeNode& n );
      36   void issueBboxQuery(  OcclusionElement& n );
      37   void queueDraw(  PagingLandScapeOctreeNode& n );
          
      39   const unsigned int getNodeCount(   ) const { return nodeCount; }
      40   unsigned int getFrame(   ) const {return mFrameId;};
      41   PagingLandScapeOctreeCamera *getCamera(   ) const {return mCurrentCam;};
          
          
           #ifdef _VISIBILITYDEBUG
           unsigned int object_cnt;
           unsigned int triangle_cnt;
           unsigned int traversed_nodes_cnt;
           unsigned int frustum_culled_nodes_cnt;
           unsigned int query_cnt;
           #endif //_VISIBILITYDEBUG
          
      52   bool nextFrame (  PagingLandScapeOctreeCamera *cam,  
      53   MovableObjectList *camInProgressVisibles,  
      54   bool onlyshadowcaster,  
      55   RenderQueue *q );
          
      57   void init (  PagingLandScapeOctreeSceneManager *scnMngr )
           {
           mScnMngr = scnMngr;
           };
          
      62   void initQueryPool(   )
           {
           if (  mIsQueryPoolNotInitiated )
           {
           mQueryPool.setRenderSystem (   );
           mQueryPool.setAutoextend (  true );
           mQueryPool.setPoolSize (  300 );
           mIsQueryPoolNotInitiated = false;
           }
           };
          
           #ifdef _VISIBILITYDEBUG
      74   void TreeOverlayDebugView(  PagingLandScapeOctree *octree,  
      75   PagingLandScapeOctreeSceneManager *mScnMgr );
           #endif //_VISIBILITYDEBUG
          
      78   PagingLandScapeOctreeSceneManager *mScnMngr;
          
      80   PagingLandScapeOctreeCamera *mCurrentCam;
      81   RenderQueue *mCurrentRenderQueue;
      82   bool mOnlyShadowCaster;
           unsigned int mFrameId;
          
      85   void setIfNotSolidScene(  const bool isNotSolid ) {mIsNotSolidScene = isNotSolid;};
      86   bool isNotSolidScene (   ) const {return mIsNotSolidScene;};
      87   void setNumberOfConservativeFrames (  const unsigned int frames ){mFrameConservativeVisibility = frames;}
      88   unsigned int getNumberOfConservativeFrames (   ) const {return mFrameConservativeVisibility;}
           private:
          
      91   bool mIsNotSolidScene;
           ///Keep a set of pre-allocated HW queries
      93   QuerySet mQueryPool;
           /// As it's initiated on first HW query use
      95   bool mIsQueryPoolNotInitiated;
          
           ///culling mode from frustum culling to coherent hierarchical Occlusion
           unsigned int mode;
          
           /// number of frame we consider a node visible after a query set it visible once.
           unsigned int mFrameConservativeVisibility;
           /// Number of pixel upon which a node is considered as visible
           unsigned int mVisibilityTreshold;
           /// store number of nodes in Tree
           unsigned int nodeCount;
          
           /// store queried elements that didn't return results
     108   QueriedOcclusionElement m_queryQueue;
          
           };
          
          }
          #endif //__PagingLandScapeOcclusion_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionCHCTraversal.h

       1  #ifndef __PagingLandScapeOcclusionCHCTraversal_H
          #define __PagingLandScapeOcclusionCHCTraversal_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeCamera.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
           // TREE TRAVERSAL classes
           // a OctreeNode with Geometry objects in the leaves
           // and a TreeNodeData struct at every node
      15   class CHCTraversal : public TraversalConst
           {
           public:
      18   virtual void onTree(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const;
      19   virtual void onLeaf(  PagingLandScapeOctreeNode& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const ;
          
      21   CHCTraversal(  FrontToBackNodeSorterPriorityQueue& vStack,   Occlusion& o );
          
           private:
      24   FrontToBackNodeSorterPriorityQueue& stack;
      25   Occlusion& occlusion;
           const unsigned int frameId;
      27   const bool mIsNotSolidScene;
           };
          }
          #endif //PagingLandScapeOcclusionCHCTraversal

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionCameraTraversal.h

       1  #ifndef __PagingLandScapeOcclusionCameraTraversal_H
          #define __PagingLandScapeOcclusionCameraTraversal_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeCamera.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
           //
      11   class RegisterCameraTraversal : public TraversalConst
           {
           private:
      14   PagingLandScapeOctreeCamera *cam;
          
           public:
      17   RegisterCameraTraversal(  PagingLandScapeOctreeCamera *c ) : cam (  c ) {};
      18   virtual void onTree(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const ;
      19   virtual void onLeaf(  PagingLandScapeOctreeNode& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const ;
           };
           //-----------------------------------------------------------------------
           //
      23   class UnregisterCameraTraversal : public TraversalConst
           {
           private:
      26   PagingLandScapeOctreeCamera *cam;
          
           public:
      29   UnregisterCameraTraversal(  PagingLandScapeOctreeCamera *c ) : cam (  c ) {};
      30   virtual void onTree(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const ;
      31   virtual void onLeaf(  PagingLandScapeOctreeNode& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const ;
           };
          
          }
          #endif //PagingLandScapeOcclusionCameraTraversal

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionDebugTraversal.h

       1  #ifndef __PagingLandScapeOcclusionTreeOverlayDebugTraversal_H
          #define __PagingLandScapeOcclusionTreeOverlayDebugTraversal_H
          
          
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          #ifdef _VISIBILITYDEBUG
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          
          namespace Ogre
          {
           //------------------------------------------------------
           //
      18   class TreeOverlayDebug : public TraversalConst
           {
           public:
      21   TreeOverlayDebug(  Occlusion& o,   PagingLandScapeOctreeSceneManager *scnMgr );
      22   virtual void onTree(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const ;
      23   virtual void onLeaf(  PagingLandScapeOctreeNode& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const ;
          
           private:
      26   Occlusion& occlusion;
      27   PagingLandScapeOctreeSceneManager *mScnMrg;
          
           };
          }
          
          #endif //_VISIBILITYDEBUG
          
          #endif //__PagingLandScapeOcclusionTreeOverlayDebugTraversal_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionElement.h

       1  #ifndef __PagingLandScapeOcclusionElement_H
          #define __PagingLandScapeOcclusionElement_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          
          namespace Ogre
          {
           struct VisibleObjectsBoundsInfo;
      10   class OcclusionElement
           {
           public :
      13   OcclusionElement(   );
      14   virtual ~OcclusionElement(   );
          
      16   VisibilityData *getNodeData(  PagingLandScapeOctreeCamera *cam );
      17   void addCamNodeData (  PagingLandScapeOctreeCamera *cam );
      18   void removeCamNodeData (  PagingLandScapeOctreeCamera *cam );
          
      20   virtual OcclusionElement* getParent (   ) = 0;
      21   virtual OcclusionBoundingBox* getOcclusionBoundingBox(   ) = 0;
      22   virtual bool isLeaf(   ) const = 0;
          
           //virtual void _addToRenderQueue(  Camera* cam,   RenderQueue* const q,   const bool onlyShadowCasters ) = 0;
           //virtual void _addAlreadyNotifiedToVisibles(  Camera* cam,   RenderQueue* const q,   const bool onlyShadowCasters ) = 0;
           //virtual void notifyNodeObjects(  Camera* cam ) = 0;
          
      28   virtual void traversal(  Traversal&,   VisibleObjectsBoundsInfo * const visibleBounds ) = 0;
      29   virtual void traversal(  const TraversalConst&,   VisibleObjectsBoundsInfo * const visibleBounds ) = 0;
      30   virtual void traversal(  const ConstTraversalConst&,   VisibleObjectsBoundsInfo * const visibleBounds ) const = 0;
          
      32   virtual const AxisAlignedBox &getCullBoundingBox(   ) const = 0;
      33   virtual const Vector3 &getHalfSize(   ) const = 0;
          
           #ifdef _VISIBILITYDEBUG
      36   DebugRectangle2D *getRectangle2d(  SceneManager *scnMgr );
           #endif //_VISIBILITYDEBUG
          
      39   void setRegisteredtoCam(  const bool flag )
           {
           mIsRegisteredToCam = flag;
           };
          
          
      45   virtual bool isOccluder (   ) const = 0;
          
           protected :
           /// if node has all camera information about occlusion
      49   bool mIsRegisteredToCam;
          
          
           private :
          
           typedef std::map<unsigned int,   VisibilityData* > NodeDataPerCamMap;
           typedef NodeDataPerCamMap::iterator NodeDataPerCamMapiterator;
      56   NodeDataPerCamMap nodeDataPerCam;
           #ifdef _VISIBILITYDEBUG
      58   DebugRectangle2D *mDebugRectangle2d;
           #endif //_VISIBILITYDEBUG
           };
          
          }//namespace Ogre
          
          #endif //__PagingLandScapeOcclusionElement_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionQuerySet.h

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
           (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          
          #ifndef __OgrePagingLandScapeOcclusionQuerySet_H__
          #define __OgrePagingLandScapeOcclusionQuerySet_H__
          
          #include "OgrePrerequisites.h"
          #include "OgreRenderSystem.h"
          #include "OgreRoot.h"
          
          #include "OgrePagingLandScapePoolSet.h"
          
          namespace Ogre
          {
          
           /** A collection of pre-allocated queries
           */
      40   class QuerySet : public PoolSet<HardwareOcclusionQuery>
           {
           protected:
          
      44   HardwareOcclusionQuery* allocate (   )
           {
           return mRenderSystem->createHardwareOcclusionQuery(   );
           }
      48   void deallocate (  HardwareOcclusionQuery *p )
           {
           mRenderSystem->destroyHardwareOcclusionQuery (  p );
           }
          
           public:
          
      55   void setRenderSystem (   )
           {
           mRenderSystem = Root::getSingleton (   ).getRenderSystem (   );
           }
          
           private:
      61   RenderSystem *mRenderSystem;
          
           };
          }
          
          #endif//__OgrePagingLandScapeOcclusionQuerySet_H__

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionSWTraversal.h

       1  #ifndef __PagingLandScapeOcclusionSWTraversal_H
          #define __PagingLandScapeOcclusionSWTraversal_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeCamera.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
           // TREE TRAVERSAL classes
           // a OctreeNode with Geometry objects in the leaves
           // and a TreeNodeData struct at every node
           //-----------------------------------------------------------------------
           // Basic Occlusion query use : stop and wait query result Culling
      17   class SWTraversal : public Traversal
           {
           private:
          
      21   Occlusion& occlusion;
           PagingLandScapeOctreeCamera::Visibility mCurrentVisibility;
      23   Vector3 camPos;
          
           public:
          
      27   SWTraversal (  Occlusion& o );
          
      29   virtual void onTree(  PagingLandScapeOctree&,   VisibleObjectsBoundsInfo * const visibleBounds  );
      30   virtual void onLeaf(  PagingLandScapeOctreeNode&,   VisibleObjectsBoundsInfo * const visibleBounds  );
      31   bool isVisible(  OcclusionElement & n );
      32   void traverseChildren(  PagingLandScapeOctree & n,   VisibleObjectsBoundsInfo * const visibleBounds  );
           };
          
          }
          #endif //PagingLandScapeOcclusionSWTraversal

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionSorter.h

       1  #ifndef _PagingLandScapeOcclusionSorterH
          #define _PagingLandScapeOcclusionSorterH
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          
          namespace Ogre
          {
          
           //comparator for priority queue
      11   class FrontToBackNodeSorterOperator
           {
          
           public:
      15   FrontToBackNodeSorterOperator(  const Vector3& position ) : pos(  position ) {};
           //-----------------------------------------------------------------------
      17   inline bool operator(   )(  OcclusionElement*& a,   OcclusionElement*& b ) const
           {
           // could check if both distance == 0 then order visible first// ?
           return vectorToBoxDistance (  *a,   pos ) > vectorToBoxDistance (  *b,   pos );
           }
           //-----------------------------------------------------------------------
      23   inline bool operator(   )(  const OcclusionElement*& a,   const OcclusionElement*& b ) const
           {
           // could check if both distance == 0 then order visible first ?
           return vectorToBoxDistance (  *a,   pos ) > vectorToBoxDistance (  *b,   pos );
           }
           //-----------------------------------------------------------------------
      29   Real vectorToBoxDistance(  const OcclusionElement &a,   const Vector3& point ) const
           {
           const Vector3 &boxMin = a.getCullBoundingBox (   ).getMinimum (   );
           const Vector3 halfSize (  (  a.getCullBoundingBox (   ).getMaximum (   ) - boxMin ) * 0.5 );
           // work in the box's coordinate system
           const Vector3 kDiff (  point - (  halfSize + boxMin ) );
           // compute squared distance and closest point on box
           Real fSqrDistance (  0.0 );
           for (  unsigned int i = 0; i < 3; i++ )
           {
           const Real kClosest = kDiff[i];
           const Real khalfSize = halfSize[i];
           if (  kClosest < -khalfSize )
           {
           const Real fDelta = kClosest + khalfSize;
           fSqrDistance += fDelta * fDelta;
           }
           else if (  kClosest > khalfSize )
           {
           const Real fDelta = kClosest - khalfSize;
           fSqrDistance += fDelta * fDelta;
           }
           }
           return fSqrDistance;
           }
          
           private:
      56   const Vector3 pos;
           };
          }//namespace Ogre
          
          #endif //_PagingLandScapeOcclusionSorterH

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionTraversal.h

       1  #ifndef __PagingLandScapeOcclusionTraversal_H
          #define __PagingLandScapeOcclusionTraversal_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include <OgreSceneManager.h>
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      11   class ConstTraversalConst
           {
          
           public:
      15   virtual ~ConstTraversalConst(   ) {}
      16   virtual void onTree(  const PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const = 0;
      17   virtual void onLeaf(  const PagingLandScapeOctreeNode&,   VisibleObjectsBoundsInfo * const visibleBounds  ) const = 0;
          
           protected:
      20   virtual void traverseChildren(  const PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds ) const;
           };
           //-----------------------------------------------------------------------
      23   class TraversalConst
           {
          
           public:
      27   virtual ~TraversalConst(   ) {}
      28   virtual void onTree(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) const = 0;
      29   virtual void onLeaf(  PagingLandScapeOctreeNode&,   VisibleObjectsBoundsInfo * const visibleBounds  ) const = 0;
          
           protected:
      32   virtual void traverseChildren(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds ) const ;
           };
           //-----------------------------------------------------------------------
      35   class Traversal
           {
          
           public:
      39   virtual ~Traversal(   ) {}
      40   virtual void onTree(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds  ) = 0;
      41   virtual void onLeaf(  PagingLandScapeOctreeNode&,   VisibleObjectsBoundsInfo * const visibleBounds  ) = 0;
          
           protected:
      44   virtual void traverseChildren(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds  );
           };
          }
          #endif //PagingLandScapeOcclusionTraversal

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionVFTraversal.h

       1  #ifndef __PagingLandScapeOcclusionViewFrustumCullingTraversal_H
          #define __PagingLandScapeOcclusionViewFrustumCullingTraversal_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeCamera.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
           // Basic View Frustum Culling using hierarchy info
           // as if an octree is fully in frustum,   all children are for sure visible
      14   class ViewFrustumCullingTraversal : public Traversal
           {
           public:
          
      18   ViewFrustumCullingTraversal (  Occlusion& o );
          
      20   virtual void onTree(  PagingLandScapeOctree&,   VisibleObjectsBoundsInfo * const visibleBounds  );
      21   virtual void onLeaf(  PagingLandScapeOctreeNode&,   VisibleObjectsBoundsInfo * const visibleBounds  );
           private:
          
      24   Occlusion& occlusion;
           PagingLandScapeOctreeCamera::Visibility mCurrentVisibility;
          
           };
          
           //-----------------------------------------------------------------------
           // Basic View Frustum Culling
      31   class ViewFrustumCullingTraversalDirect : public Traversal
           {
          
           public:
          
      36   ViewFrustumCullingTraversalDirect (  Occlusion& o );
          
      38   virtual void onTree(  PagingLandScapeOctree&,   VisibleObjectsBoundsInfo * const visibleBounds  );
      39   virtual void onLeaf(  PagingLandScapeOctreeNode&,   VisibleObjectsBoundsInfo * const visibleBounds  );
           private:
          
      42   Occlusion& occlusion;
           };
          }
          #endif //__PagingLandScapeOcclusionViewFrustumCullingTraversal_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOcclusionVisibilityData.h

       1  #ifndef __VisibilityData_H
          #define __VisibilityData_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
           //contains the additional data needed for the
           // Coherent Hierarchical Culling
      10   class VisibilityData
           {
           public:
           // ctor
      14   VisibilityData(   ):
           #ifdef _VISIBILITYDEBUG
           viewFrustumVisible (  false ),  
           #endif //_VISIBILITYDEBUG
           queryVisible (  true ),  
           lastQueryFrameId (  0 ),  
           frameID (  0 ),  
           query (  0 ),  
           notified (  false )
           {};
           //dtor
      25   ~VisibilityData(   ){assert (  query == 0 );};
          
           #ifdef _VISIBILITYDEBUG
           // frustum culled
      29   bool viewFrustumVisible;
           #endif //_VISIBILITYDEBUG
          
           // Visible on screen,   as certified by query result
      33   bool queryVisible;
           //last query result
           unsigned int lastQueryFrameId;
           //last render
           unsigned int frameID;
           // query associated to node
      39   HardwareOcclusionQuery *query;
           // Has been checked against renderer
           // (  if not too far,   or outside this render like shadows...  )
      42   bool notified;
           };
          }
          #endif //__VisibilityData_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOctree.h

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          PagingLandScapeOctree.h - description
          -------------------
          begin : Mon Sep 30 2002
          copyright : (  C ) 2002 by Jon Anderson
          email : janders@users.sf.net
          
          Enhancements 2003 - 2004 (  C ) The OGRE Team
          ***************************************************************************/
          
          #ifndef __PagingLandScapeOctree_H
          #define __PagingLandScapeOctree_H
          
          
          #include "OgreAxisAlignedBox.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          
          #include <list>
          
          namespace Ogre
          {
          
      48   class PagingLandScapeOctreeNode;
          
           typedef std::list < PagingLandScapeOctreeNode* > NodeList;
          
          
           /** PagingLandScapeOctree data structure for managing scene nodes.
           @remarks
           This is a loose PagingLandScapeOctree implementation,   meaning that each
           octant child of the PagingLandScapeOctree actually overlaps it's siblings by a factor
           of .5. This guarantees that any thing that is half the size of the parent will
           fit completely into a child,   with no splitting necessary.
           */
          
      61   class PagingLandScapeOctree : public OcclusionElement
           {
          
           public:
      65   PagingLandScapeOctree(   );
      66   ~PagingLandScapeOctree(  void );
          
      68   void reset(   );
          
      70   void setParent(  PagingLandScapeOctree * parent );
      71   void setSceneManager(  PagingLandScapeOctreeSceneManager * scn );
          
           /** Adds an PagingLandScapeOctree scene node to this PagingLandScapeOctree level.
           @remarks
           This is called by the PagingLandScapeOctreeSceneManager after
           it has determined the correct PagingLandScapeOctree to insert the node into.
           */
      78   void _addNode(  PagingLandScapeOctreeNode* nod );
          
           /** Removes an PagingLandScapeOctree scene node to this PagingLandScapeOctree level.
           */
      82   void _removeNode(  PagingLandScapeOctreeNode* nod );
          
           /** Returns the number of scene nodes attached to this PagingLandScapeOctree
           */
      86   inline size_t numNodes(  void ) const
           {
           return mNumNodes;
           };
          
          
          
           /** creates the wire frame bounding box for this octant
           */
      95   WireBoundingBox* getWireBoundingBox(  void );
          
           /** creates the opaque Cull bounding box (  bbox*2 ) for this octant
           */
      99   OcclusionBoundingBox* getOcclusionBoundingBox(   );
          
          
           /** 3D array of children of this PagingLandScapeOctree.
           @remarks
           Children are dynamically created as needed when nodes are inserted in the PagingLandScapeOctree.
           If,   later,   the all the nodes are removed from the child,   it is still kept around.
           */
           PagingLandScapeOctree* mChildren[ 2 ][ 2 ][ 2 ];
          
           /** Determines if this PagingLandScapeOctree is twice as big as the given box.
           @remarks
           This method is used by the PagingLandScapeOctreeSceneManager to determine if the given
           box will fit into a child of this PagingLandScapeOctree.
           */
     114   bool _isTwiceSize(  const AxisAlignedBox& box ) const;
          
           /** Determines if this PagingLandScapeOctree is twice as big as the given box.
           @remarks
           This method is used by the PagingLandScapeOctreeSceneManager to determine if the given
           box will fit into a child of this PagingLandScapeOctree.
           */
     121   bool _isTwiceCullSize(  const AxisAlignedBox& box ) const;
          
     123   bool _isNotCrossingAxes(  const AxisAlignedBox& box ) const;
          
           /** Returns the appropriate indexes for the child of this PagingLandScapeOctree into which the box will fit.
           @remarks
           This is used by the PagingLandScapeOctreeSceneManager to determine which child to traverse next when
           finding the appropriate PagingLandScapeOctree to insert the box. Since it is a loose PagingLandScapeOctree,   only the
           center of the box is checked to determine the octant.
           */
     131   PagingLandScapeOctree* _getChildWhereBoxFits(  const AxisAlignedBox& bx,   PagingLandScapeOctreeSceneManager *scn );
           /** Returns the appropriate indexes for the child of this PagingLandScapeOctree into which the box will fit.
           @remarks
           This is used by the PagingLandScapeOctreeSceneManager to determine which child to traverse next when
           finding the appropriate PagingLandScapeOctree to insert the box. Since it is a loose PagingLandScapeOctree,   only the
           center of the box is checked to determine the octant.
           */
     138   PagingLandScapeOctree *_getCullChildWhereBoxFits(  const AxisAlignedBox& bx,   PagingLandScapeOctreeSceneManager *scn );
           /** Creates the AxisAlignedBox used for culling this PagingLandScapeOctree.
           @remarks
           Since it's a loose PagingLandScapeOctree,   the culling bounds can be different than the actual bounds of the PagingLandScapeOctree.
           */
     143   void _getCullBounds(  AxisAlignedBox* bound ) const;
          
           /** Public list of SceneNodes attached to this particular PagingLandScapeOctree
           */
     147   NodeList mNodes;
     148   NodeList mMovingNodes;
     149   NodeList mStaticNodes;
          
     151   inline OcclusionElement* getParent (   ) {return mParent;};
          
     153   inline bool isLeaf(   ) const {return false;};
          
     155   inline void traversal(  Traversal &tr,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           tr.onTree (  *this,   visibleBounds );
           };
     159   inline void traversal(  const TraversalConst &tr,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           tr.onTree(  *this,   visibleBounds );
           };
     163   inline void traversal(  const ConstTraversalConst &tr,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           tr.onTree (  *this,   visibleBounds );
           };
          
           // check if need to traverse it.
     169   inline bool hasChildren(   ) const
           {
           return (  mNumNodes != 0 );
           };
          
     174   void setBoundingBox(  const Vector3 &min,   const Vector3 &max );
          
           #ifdef _VISIBILITYDEBUG
     177   void setDebugCorners(  PagingLandScapeOctreeSceneManager *scnMgr );
           #endif //_VISIBILITYDEBUG
          
     180   inline const AxisAlignedBox &getCullBoundingBox(   ) const {return mCullBox;};
     181   inline const AxisAlignedBox &getBoundingBox(   ) const {return mBox;};
     182   inline const Vector3 &getHalfSize(   ) const {return mHalfSize;};
     183   inline const Vector3 &getCullHalfSize(   ) const {return mCullHalfSize;};
          
     185   inline bool isOccluder (   ) const { return true; }
          
           protected:
          
           /** The bounding box of the PagingLandScapeOctree
           @remarks
           This is used for octant index determination and rendering,   but not culling
           */
     193   AxisAlignedBox mBox;
           /// Octree double size bounding box
     195   AxisAlignedBox mCullBox;
     196   WireBoundingBox* mWireBoundingBox;
           /** Vector containing the dimensions of this PagingLandScapeOctree
           */
     199   Vector3 mHalfSize;
           /** Vector containing the dimensions of this PagingLandScapeOctree / 2
           */
     202   Vector3 mCullHalfSize;
          
          
           /** Increments the overall node count of this PagingLandScapeOctree and all it's parents
           */
     207   inline void _ref(  void )
           {
           ++mNumNodes;
           if (  mParent != 0 )
           {
           mParent->_ref(   );
           }
           };
          
           /** Decrements the overall node count of this PagingLandScapeOctree and all it's parents
           */
     218   void _unref(  const bool removeChildren );
          
           ///number of SceneNodes in this PagingLandScapeOctree and all it's children.
     221   size_t mNumNodes;
           ///parent PagingLandScapeOctree
           PagingLandScapeOctree* mParent;
     224   PagingLandScapeOctreeSceneManager *mSceneMgr;
     225   OcclusionBoundingBox* mOcclusionBoundingBox;
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOctreeAxisAlignedBoxSceneQuery.h

          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreeAxisAlignedBoxSceneQuery.h - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004 by Jon Anderson
          email : janders@users.sf.net
          ***************************************************************************/
          
          #ifndef PagingLandScapeOctreeAxisAlignedBoxSCENEQUERY_H
          #define PagingLandScapeOctreeAxisAlignedBoxSCENEQUERY_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgreSceneManager.h"
          
          namespace Ogre
          {
          
          /** PagingLandScapeOctree implementation of AxisAlignedBoxSceneQuery. */
          class _OgrePagingLandScapeExport PagingLandScapeOctreeAxisAlignedBoxSceneQuery : public DefaultAxisAlignedBoxSceneQuery
          {
          public:
      46   PagingLandScapeOctreeAxisAlignedBoxSceneQuery(  SceneManager* creator );
           virtual ~PagingLandScapeOctreeAxisAlignedBoxSceneQuery(  void );
          
           /** See RayScenQuery. */
           /** Finds any entities that intersect the AAB for the query. */
           void execute(  SceneQueryListener* listener );
          };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOctreeCamera.h

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          PagingLandScapeOctreecamera.h - description
          -------------------
          begin : Fri Sep 27 2002
          copyright : (  C ) 2002 by Jon Anderson
          email : janders@users.sf.net
          
          Enhancements 2003 - 2004 (  C ) The OGRE Team
          ***************************************************************************/
          
          #ifndef PagingLandScapeOctreeCAMERA_H
          #define PagingLandScapeOctreeCAMERA_H
          
          #include "OgreCamera.h"
          #include "OgreHardwareBufferManager.h"
          #include "OgreSimpleRenderable.h"
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          /**
          *@author Jon Anderson
          */
          
          namespace Ogre
          {
          
      51   class PagingLandScapeOctree;
          
          
           /** Specialized viewpoint from which an PagingLandScapeOctree can be rendered.
           @remarks
           This class contains several specializations of the Ogre::Camera class. It
           implements the getRenderOperation method in order to return displayable geometry
           for debugging purposes. It also implements a visibility function that is more granular
           than the default.
           */
          
      62   class PagingLandScapeOctreeCamera : public Camera
           {
          
           public:
          
           /** Visibility types */
           enum Visibility
           {
           NONE,  
           PARTIAL,  
           FULL
           };
          
           /* Standard Constructor */
      76   PagingLandScapeOctreeCamera(  const String& name,   SceneManager* sm );
           /* Standard destructor */
      78   virtual ~PagingLandScapeOctreeCamera(  void );
          
           /** Returns the visibility of the box
           */
      82   Visibility getVisibility(  const AxisAlignedBox& bound ) const;
          
      84   bool isRegisteredInOcclusionSystem(   ) const;
      85   void setRegisteredInOcclusionSystem(  const bool registered );
          
      87   void updateRegistrationInOcclusionSystem(   );
          
      89   void setNextOcclusionMode(   );
      90   culling_modes getOcclusionMode(   ) const {return mOcclusionMode;};
      91   bool needRegistrationInOcclusionSystem(   ) const;
      92   void setOcclusionMode(  culling_modes occlusionMode );
          
      94   void setOcclusionModeAsString(  const String &cullingModeAsString );
      95   String getOcclusionModeAsString(   ) const;
          
      97   unsigned int getId(   )const {return mUniqueIdentification;}
      98   unsigned int getFrameId(   )const {return mFrameId;}
      99   bool nextFrame(  const unsigned int framesSceneId );
          
     101   void _addCHCRenderedFaces(  unsigned int numfaces )
           {
           mVisFacesLastCHCRender = numfaces;
           }
          
           private:
     107   void changeOcclusionMode(  culling_modes nextOcclusionMode );
          
           unsigned int mVisFacesLastCHCRender;
     110   bool isOcclusionSystemRegistered;
           unsigned int mUniqueIdentification;
           culling_modes mOcclusionMode;
          
           /// last rendered frame
           unsigned int mFrameId;
           unsigned int mFrameSceneId;
          
           static unsigned int s_camId;
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOctreeIntersectionSceneQuery.h

          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreeIntersectionSceneQuery.h - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004 by Jon Anderson
          email : janders@users.sf.net
          ***************************************************************************/
          
          #ifndef PagingLandScapeOctreeIntersectionSCENEQUERY_H
          #define PagingLandScapeOctreeIntersectionSCENEQUERY_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgreSceneManager.h"
          
          namespace Ogre
          {
          
          /** PagingLandScapeOctree implementation of IntersectionSceneQuery. */
          class _OgrePagingLandScapeExport PagingLandScapeOctreeIntersectionSceneQuery :
           public DefaultIntersectionSceneQuery
          {
          public:
      47   PagingLandScapeOctreeIntersectionSceneQuery(  SceneManager* creator );
           virtual ~PagingLandScapeOctreeIntersectionSceneQuery(  void );
          
           /** See IntersectionSceneQuery. */
           void execute(  IntersectionSceneQueryListener* listener );
          };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOctreeNode.h

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          PagingLandScapeOctreenode.h - description
          -------------------
          begin : Fri Sep 27 2002
          copyright : (  C ) 2002 by Jon Anderson
          email : janders@users.sf.net
          
          Enhancements 2003 - 2004 (  C ) The OGRE Team
          ***************************************************************************/
          #ifndef __PagingLandScapeOctreeNODE_H
          #define __PagingLandScapeOctreeNODE_H
          
          #include "OgreSceneNode.h"
          #include "OgrePagingLandScapePrerequisites.h"
          
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          
          namespace Ogre
          {
          
           /** Specialized SceneNode that is customized for working within an PagingLandScapeOctree. Each node
           * maintains it's own bounding box,   rather than merging it with all the children.
           *
           */
      51   class PagingLandScapeOctreeNode : public SceneNode,   public OcclusionElement
           {
           public:
           /** Standard constructor */
      55   PagingLandScapeOctreeNode(  SceneManager* creator );
           /** Standard constructor */
      57   PagingLandScapeOctreeNode(  SceneManager* creator,   const String& name );
           /** Standard destructor */
      59   ~PagingLandScapeOctreeNode(  void );
          
           /** Returns the PagingLandScapeOctree in which this PagingLandScapeOctreeNode resides
           */
      63   PagingLandScapeOctree* getOctant(  void )
           {
           return mOctant;
           };
          
           /** Sets the PagingLandScapeOctree in which this PagingLandScapeOctreeNode resides
           */
      70   void setOctant(  PagingLandScapeOctree* o )
           {
           mOctant = o;
           };
          
           /** Determines if the center of this node is within the given box
           */
      77   bool _isIn(  const AxisAlignedBox& box ) const;
          
           /** Adds all the attached scene nodes to the render queue
           */
      81   virtual void _addToRenderQueue(  Camera* cam,   RenderQueue* const q,   const bool onlyShadowCasters,   VisibleObjectsBoundsInfo * const visibleBounds );
          
      83   MovableObjectList *getVisibleNotifiedNodeObjects(  Camera* cam,  
      84   const bool onlyShadowCasters );
          
      86   bool notifyNodeObjects(  Camera* cam,  
      87   const bool onlyShadowCasters );
           /** Adds all the attached scene nodes to the render queue
           * with the particularity that it has already been notified by camera.
           */
      91   void _addAlreadyNotifiedToVisibles(   );
      92   void _addToVisibles(  Camera* cam,   const bool onlyShadowCasters );
           /** Sets up the LegacyRenderOperation for rendering this scene node as geometry.
           @remarks
           This will render the scene node as a bounding box.
           */
           //virtual void getRenderOperation(  RenderOperation& op );
          
           /** Returns the local bounding box of this PagingLandScapeOctreeNode.
           @remarks
           This is used to render the bounding box,   rather then the global.
           */
     103   AxisAlignedBox& _getLocalAABB(  void )
           {
           return mLocalAABB;
           };
           /** Adds a (  pre-created ) child scene node to this node. If it is attached to another node,  
           it must be detached first.
           @param child The Node which is to become a child node of this one
           */
     111   virtual void addChild(  Node* child );
           /** Drops the specified child from this node.
           @remarks
           Does not delete the node,   just detaches it from
           this parent,   potentially to be reattached elsewhere.
           There is also an alternate version which drops a named
           child from this node.
           */
     119   virtual Node* removeChild(  unsigned short index );
           /** Drops the specified child from this node.
           @remarks
           Does not delete the node,   just detaches it from
           this parent,   potentially to be reattached elsewhere.
           There is also an alternate version which drops a named
           child from this node.
           */
     127   virtual Node* removeChild(  Node* child );
          
           /** Drops the named child from this node.
           @remarks
           Does not delete the node,   just detaches it from
           this parent,   potentially to be reattached elsewhere.
           */
     134   virtual Node* removeChild(  const String& name );
           /** Removes all child Nodes attached to this node. Does not delete the nodes,   just detaches them from
           this parent,   potentially to be reattached elsewhere.
           */
     138   virtual void removeAllChildren(  void );
          
          
          
     142   virtual OcclusionElement* getParent (   ) {return mOctant;};
          
          
     145   inline const AxisAlignedBox &getCullBoundingBox(   ) const
           {
           return _getWorldAABB(   );
           };
          
          
     151   virtual const Vector3 &getHalfSize(   ) const
           {
           return mHalfSize;
           };
          
     156   virtual bool isLeaf(   ) const {return true;};
          
     158   virtual void traversal(  Traversal&tr,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           tr.onLeaf (  *this,   visibleBounds );
           };
     162   virtual void traversal(  const TraversalConst &tr,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           tr.onLeaf(  *this,   visibleBounds );
           };
     166   virtual void traversal(  const ConstTraversalConst &tr,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           tr.onLeaf (  *this,   visibleBounds );
           };
           /** creates the opaque bounding box for this octant
           */
     172   OcclusionBoundingBox* getOcclusionBoundingBox(   );
          
           #ifdef _VISIBILITYDEBUG
     175   void setDebugCorners(  PagingLandScapeOctreeSceneManager *scnMgr );
           #endif //_VISIBILITYDEBUG
          
           /** Adds an instance of a scene object to this node.
           @remarks
           Scene objects can include Entity objects,   Camera objects,   Light objects,  
           ParticleSystem objects etc. Anything that subclasses from MovableObject.
           */
     183   virtual void attachObject(  MovableObject* obj );
           /** Detaches the indexed object from this scene node.
           @remarks
           Detaches by index,   see the alternate version to detach by name. Object indexes
           may change as other objects are added / removed.
           */
     189   virtual MovableObject* detachObject(  unsigned short index );
           /** Detaches an object by pointer. */
     191   virtual void detachObject(  MovableObject* obj );
          
           /** Detaches the named object from this node and returns a pointer to it. */
     194   virtual MovableObject* detachObject(  const String& name );
          
           /** Detaches all objects attached to this node.
           */
     198   virtual void detachAllObjects(  void );
          
     200   virtual bool isOccluder (   ) const { return mIsOccluder; }
          
     202   bool isStaticNode(   ) const { return mIsStaticNode; }
          
     204   void setStaticCulling (  const bool staticNode ) { mIsStaticNode = staticNode; };
          
          
           protected:
           /** Internal method for updating the bounds for this PagingLandScapeOctreeNode.
           @remarks
           This method determines the bounds solely from the attached objects,   not
           any children. If the node has changed it's bounds,   it is removed from its
           current PagingLandScapeOctree,   and reinserted into the tree.
           */
     214   void _updateBounds(  void );
          
     216   void _removeNodeAndChildren(  void );
          
           ///local bounding box
     219   AxisAlignedBox mLocalAABB;
          
           ///PagingLandScapeOctree this node is attached to.
     222   PagingLandScapeOctree* mOctant;
     223   OcclusionBoundingBox* mOcclusionBoundingBox;
     224   Vector3 mHalfSize;
           /// if node need to in loose octree or normal octree
     226   bool mIsStaticNode;
           /// if node need to be drawn during query phase
     228   bool mIsOccluder;
           // if a pre-notified object is visible.
     230   MovableObjectList mNotifiedVisibles;
          
           };
          
          }
          
          
          #endif //__PagingLandScapeOctreeNODE_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOctreePlaneBoundedVolumeListSceneQuery.h

          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreePlaneBoundedVolumeListSceneQuery.h - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004 by Jon Anderson
          email : janders@users.sf.net
          ***************************************************************************/
          
          #ifndef PagingLandScapeOctreePlaneBoundedVolumeListSCENEQUERY_H
          #define PagingLandScapeOctreePlaneBoundedVolumeListSCENEQUERY_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgreSceneManager.h"
          
          namespace Ogre
          {
          
          /** PagingLandScapeOctree implementation of PlaneBoundedVolumeListSceneQuery. */
          class _OgrePagingLandScapeExport PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery : public DefaultPlaneBoundedVolumeListSceneQuery
          {
          public:
      46   PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery(  SceneManager* creator );
           virtual ~PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery(  void );
          
           /** See SceneQuery. */
           void execute(  SceneQueryListener* listener );
          };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOctreeRaySceneQuery.h

          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreeRaySceneQuery.h - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004 by Jon Anderson
          email : janders@users.sf.net
          ***************************************************************************/
          
          #ifndef PagingLandScapeOctreeRaySCENEQUERY_H
          #define PagingLandScapeOctreeRaySCENEQUERY_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgreSceneManager.h"
          
          namespace Ogre
          {
          
          /** PagingLandScapeOctree implementation of RaySceneQuery. */
          class _OgrePagingLandScapeExport PagingLandScapeOctreeRaySceneQuery : public DefaultRaySceneQuery
          {
          public:
      46   PagingLandScapeOctreeRaySceneQuery(  SceneManager* creator );
           virtual ~PagingLandScapeOctreeRaySceneQuery(  void );
          
           /** See RayScenQuery. */
           void execute(  RaySceneQueryListener* listener );
          };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOctreeSceneManager.h

       1  /***************************************************************************
          PagingLandScapeOctreescenemanager.h - description
          -------------------
          begin : Fri Sep 27 2002
          copyright : (  C ) 2002 by Jon Anderson
          email : janders@users.sf.net
          ***************************************************************************/
          
          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          
          #ifndef PagingLandScapeOctreeSCENEMANAGER_H
          #define PagingLandScapeOctreeSCENEMANAGER_H
          
          #include "OgreSceneManager.h"
          #include "OgreRenderOperation.h"
          #include "OgreSphere.h"
          
          #include <list>
          #include <algorithm>
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOcclusion.h"
          #include "OgreRenderable.h"
          
          #include "OgrePagingLandScapePoolSet.h"
          
          namespace Ogre
          {
          
           /// Factory for OctreeSceneManager
      56   class PagingLandScapeOctreeSceneManagerFactory : public SceneManagerFactory
           {
           protected:
      59   void initMetaData(  void ) const;
           public:
      61   PagingLandScapeOctreeSceneManagerFactory(   ) {}
      62   ~PagingLandScapeOctreeSceneManagerFactory(   ) {}
           /// Factory type name
      64   static const String FACTORY_TYPE_NAME;
      65   SceneManager* createInstance(  const String& instanceName );
      66   void destroyInstance(  SceneManager* instance );
           };
          
      69   class PagingLandScapeOctreeNode;
          
      71   class PagingLandScapeOctreeCamera;
      72   class PagingLandScapeOctreeIntersectionSceneQuery;
      73   class PagingLandScapeOctreeRaySceneQuery;
      74   class PagingLandScapeOctreeSphereSceneQuery;
      75   class PagingLandScapeOctreeAxisAlignedBoxSceneQuery;
      76   class PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery;
          
           /** A collection of pre-allocated octrees
           */
      80   class OctreeSet : public PoolSet<PagingLandScapeOctree>
           {
           protected:
      83   virtual PagingLandScapeOctree* allocate (   )
           {
           return new PagingLandScapeOctree(   );
           }
      87   virtual void deallocate (  PagingLandScapeOctree *p )
           {
           delete p;
           }
           };
          
          
           //typedef std::list < WireBoundingBox* > BoxList;
           //typedef std::list < OcclusionBoundingBox* > BoxList;
          
           //typedef std::list < unsigned long > ColorList;
           //typedef std::list < SceneNode* > SceneNodeList;
          
          
           /** Specialized SceneManager that divides the geometry into an PagingLandScapeOctree in order to facilitate spatial queries.
           @remarks
           For debugging purposes,   a special "CullCamera" can be defined. To use it,   call setUseCallCamera(  true ),  
           and create a camera named "CullCamera". All culling will be performed using that camera,   instead of the viewport
           camera,   allowing you to fly around and examine culling.
           */
          
     108   class PagingLandScapeOctreeSceneManager : public SceneManager
           {
     110   friend class PagingLandScapeOctreeIntersectionSceneQuery;
     111   friend class PagingLandScapeOctreeRaySceneQuery;
     112   friend class PagingLandScapeOctreeSphereSceneQuery;
     113   friend class PagingLandScapeOctreeAxisAlignedBoxSceneQuery;
     114   friend class PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery;
          
           public:
           static int intersect_call;
           /** Standard Constructor. Initializes the PagingLandScapeOctree to -500,  -500,  -500 to 500,  500,  500 with unlimited depth. */
     119   PagingLandScapeOctreeSceneManager(  const String &name );
           /** Standard Constructor */
     121   PagingLandScapeOctreeSceneManager(  const String &name,   AxisAlignedBox& box,   int max_depth );
           /** Standard destructor */
     123   virtual ~PagingLandScapeOctreeSceneManager(  void );
          
     125   inline PagingLandScapeOctree * getNewOctree(   )
           {
           return mOctreeSet.getPoolable(   );
           }
     129   inline void deleteOctree(  PagingLandScapeOctree * p )
           {
           p->reset (   );
           mOctreeSet.removePoolable (  p );
           }
          
     135   void shutdown(   );
           /// @copydoc SceneManager::getTypeName
     137   const String& getTypeName(  void ) const;
          
           /** Initializes the manager to the given box and depth.
           */
     141   void init(  const AxisAlignedBox& box,   int d );
          
           /** Creates a specialized PagingLandScapeOctreeNode */
     144   virtual SceneNode* createSceneNode(  void );
           /** Creates a specialized PagingLandScapeOctreeNode */
     146   virtual SceneNode* createSceneNode(  const String& name );
           /** Creates a specialized PagingLandScapeOctreeCamera */
     148   virtual Camera* createCamera(  const String& name );
     149   virtual void destroyCamera(  Camera *cam );
     150   virtual void destroyCamera(  const String& name );
     151   virtual void destroyAllCameras(  void );
          
     153   void addCamera(  Camera *cam );
          
           /** Deletes a scene node */
     156   virtual void destroySceneNode(  const String& name );
          
           /** Does nothing more */
     159   virtual void _updateSceneGraph(  Camera* cam );
          
           /** Recurses through the PagingLandScapeOctree determining which nodes are visible. */
          #ifdef PLSM2_EIHORT
     163   virtual void _findVisibleObjects(  Camera* cam,   VisibleObjectsBoundsInfo *visibleBounds,   bool onlyShadowCasters );
          #else
     165   virtual void _findVisibleObjects(  Camera* cam,   bool onlyShadowCasters );
          #endif
          
           /** Alerts each un-culled object,   notifying it that it will be drawn.
           * Useful for doing calculations only on nodes that will be drawn,   prior
           * to drawing them...
           */
           //virtual void _alertVisibleObjects(  void );
          
           /** Walks through the PagingLandScapeOctree,   adding any visible objects to the render queue.
           @remarks
           If any octant in the PagingLandScapeOctree if completely within the the view frustum,  
           all sub-children are automatically added with no visibility tests.
           */
     179   void walkPagingLandScapeOctree(  PagingLandScapeOctreeCamera * camera,   RenderQueue * const queue,  
           PagingLandScapeOctree * const octant,   const bool foundvisible,   const bool onlyShadowCasters );
          
           /** Checks the given PagingLandScapeOctreeNode,   and determines if it needs to be moved
           * to a different octant.
           */
     185   void _updatePagingLandScapeOctreeNode(  PagingLandScapeOctreeNode* nod );
          
           /** Removes the given PagingLandScapeOctree node */
     188   void _removePagingLandScapeOctreeNode(  PagingLandScapeOctreeNode* nod );
          
           /** Adds the PagingLandScapeOctree Node,   starting at the given PagingLandScapeOctree,   and recursing at max to the specified depth.
           */
     192   void _addPagingLandScapeOctreeNode(  PagingLandScapeOctreeNode* ocnod,   PagingLandScapeOctree* PagingLandScapeOctree,   int depth = 0 );
          
           /** Adds the PagingLandScapeOctree Node,   starting at the given PagingLandScapeOctree,   and recursing at max to the specified depth.
           */
     196   void _addPagingLandScapeOctreeMovableNode(  PagingLandScapeOctreeNode* ocnod,   PagingLandScapeOctree* PagingLandScapeOctree,   int depth = 0 );
          
           /** Adds the PagingLandScapeOctree Node,   starting at the given PagingLandScapeOctree,   and recursing at max to the specified depth.
           */
     200   void _addPagingLandScapeOctreeStaticNode(  PagingLandScapeOctreeNode* ocnod,   PagingLandScapeOctree* PagingLandScapeOctree,   int depth = 0 );
          
           /** Recurses the PagingLandScapeOctree,   adding any nodes intersecting with the box into the given list.
           It ignores the exclude scene node.
           */
     205   void findNodesIn(  const AxisAlignedBox& box,   std::list < SceneNode* > &list,  
           const SceneNode* const exclude = 0 );
          
           /** Recurses the PagingLandScapeOctree,   adding any nodes intersecting with the sphere into the given list.
           It ignores the exclude scene node.
           */
     211   void findNodesIn(  const Sphere& sphere,   std::list < SceneNode* > &list,  
           const SceneNode* const exclude = 0 );
          
           /** Recurses the PagingLandScapeOctree,   adding any nodes intersecting with the volume into the given list.
           It ignores the exclude scene node.
           */
     217   void findNodesIn(  const PlaneBoundedVolume& volume,   std::list < SceneNode* > &list,  
           const SceneNode* const exclude=0 );
          
           /** Recurses the PagingLandScapeOctree,   adding any nodes intersecting with the ray into the given list.
           It ignores the exclude scene node.
           */
     223   void findNodesIn(  const Ray& ray,   std::list < SceneNode* > &list,  
           const SceneNode* const exclude=0 );
          
           /** Sets the box visibility flag */
     227   void setShowBoxes(  bool b )
           {
           #ifdef _VISIBILITYDEBUG
           mShowBoxes = b;
           #endif //_VISIBILITYDEBUG
           };
          
           /** Sets the cull camera flag */
     235   void setUseCullCamera(  bool b )
           {
           #ifdef _VISIBILITYDEBUG
           mCullCamera = b;
           #endif //_VISIBILITYDEBUG
           };
          
           /** Resizes the PagingLandScapeOctree to the given size */
     243   void resize(  const AxisAlignedBox& box );
     244   void resize(  const AxisAlignedBox &box,   const int depth );
          
           /** Sets the given option for the SceneManager
           @remarks
           Options are:
           "Size",   AxisAlignedBox *;
           "CullCamera",   bool *;
           "Depth",   int *;
           "ShowPagingLandScapeOctree",   bool *;
           */
          
     255   virtual bool setOption(  const String& key,   const void* value );
          
           /** Gets the given option for the Scene Manager.
           @remarks
           See setOption
           */
     261   virtual bool getOption(  const String& key,   void* value );
          
     263   bool getOptionValues(  const String& key,   StringVector& refValueList );
     264   bool getOptionKeys(  StringVector& refKeys );
           /** Overridden from SceneManager */
     266   void clearScene(  void );
          
     268   AxisAlignedBoxSceneQuery* createAABBQuery(  const AxisAlignedBox& box,   unsigned long mask );
     269   SphereSceneQuery* createSphereQuery(  const Sphere& sphere,   unsigned long mask );
     270   PlaneBoundedVolumeListSceneQuery* createPlaneBoundedVolumeQuery(  const PlaneBoundedVolumeList& volumes,   unsigned long mask );
     271   RaySceneQuery* createRayQuery(  const Ray& ray,   unsigned long mask );
     272   IntersectionSceneQuery* createIntersectionQuery(  unsigned long mask );
          
     274   void directRenderSingleQueue(  RenderQueue *queue );
     275   void directRenderSingleObject(  Renderable *mo );
          
     277   void addVisible(  MovableObject *mo );
          
     279   const AxisAlignedBox &getBoundingBox(   )const {return mBox;};
          
     281   void registeredNodeInCamera(  OcclusionElement *on );
     282   void unregisteredNodeInCamera(  OcclusionElement *on );
          
     284   void registerCamera (  PagingLandScapeOctreeCamera *c );
     285   void unregisterCamera(  PagingLandScapeOctreeCamera *c );
          
           protected:
          
           /// The root PagingLandScapeOctree
     290   PagingLandScapeOctree* mPagingLandScapeOctree;
          
           typedef std::map<unsigned int,   MovableObjectList * > VisiblesPerCam;
     293   VisiblesPerCam mVisibles;
     294   MovableObjectList * mCamInProgressVisibles;
     295   PolygonMode mCamDetail;
     296   bool mCamClear;
          
           /// number of rendered objects
           int mNumObjects;
          
           /// max depth for the tree.
           int mMaxDepth;
          
           /// Size of the PagingLandScapeOctree
     305   AxisAlignedBox mBox;
          
          
           // OCCLUSION
     309   Occlusion mOcclusion;
          
           //DEBUG INFO
           #ifdef _VISIBILITYDEBUG
           /// box visibility flag
     314   bool mShowBoxes;
           /// list of boxes to be rendered
     316   MovableObjectList mBoxes;
           /// cull camera flag
     318   bool mCullCamera;
           /// cull camera flag
     320   bool mCullDebug;
          
     322   String mDebugText;
           #endif //_VISIBILITYDEBUG
          
          
     326   PagingLandScapeOctreeCamera *mCurrentOptionCamera;
          
     328   RenderTexture *mOcclusionDepth;
     329   Camera *mOcclusionCamera;
          
     331   void enableHardwareOcclusionTests(   );
     332   void disableHardwareOcclusionTests(   );
          
     334   OctreeSet mOctreeSet;
          
          
           };
          
          
          }
          
          #endif
          

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOctreeSphereSceneQuery.h

          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreeSphereSceneQuery.h - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004 by Jon Anderson
          email : janders@users.sf.net
          ***************************************************************************/
          
          #ifndef PagingLandScapeOctreeSphereSCENEQUERY_H
          #define PagingLandScapeOctreeSphereSCENEQUERY_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgreSceneManager.h"
          
          namespace Ogre
          {
          
          /** PagingLandScapeOctree implementation of SphereSceneQuery. */
          class _OgrePagingLandScapeExport PagingLandScapeOctreeSphereSceneQuery : public DefaultSphereSceneQuery
          {
          public:
      46   PagingLandScapeOctreeSphereSceneQuery(  SceneManager* creator );
           virtual ~PagingLandScapeOctreeSphereSceneQuery(  void );
          
           /** See SceneQuery. */
           void execute(  SceneQueryListener* listener );
          };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeOptions.h

       1  /***************************************************************************
           OgrePagingLandScapeOptions.h - description
           -------------------
           begin : Sun Mar 02 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeOPTIONS_H
          #define PAGINGLandScapeOPTIONS_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgreStringVector.h"
          #include "OgreConfigFile.h"
          #include "OgreMaterial.h"
          
          namespace Ogre
          {
           /**
           * A simple class for encapsulating parameters passed in when initializing *
           * a LandScapeRenderable
           */
      32   class PagingLandScapeOptions
           {
           public:
      35   PagingLandScapeOptions(  PagingLandScapeSceneManager * scnMgr );
          
      37   ~PagingLandScapeOptions(  void );
          
      39   void init(   );
      40   void setDefault(   );
          
      42   bool load(  DataStreamPtr& stream );
      43   bool load(  const String &filename,   ConfigFile& config );
      44   bool load(  const String &filename );
          
      46   void loadMap(  const String& mapName );
      47   void loadMapOptions(  const String& mapName );
      48   void insertMap(  const String& mapName );
          
      50   LandScapeFileNames* getLandScapeFileNames(  void )
           {
           return &mMapList;
           };
          
      55   bool setOption(  const String& strKey,   const void* pValue );
      56   bool getOption(  const String& strKey,   void* pDestValue );
          
      58   bool hasOption(  const String& strKey ) const ;
          
      60   bool getOptionValues(  const String & key,   StringVector &refValueList );
      61   bool getOptionKeys(  StringVector &refKeys );
          
      63   void getAvgColors(  void );
          
      65   LandScapeFileNames& getMapList(  void );
          
      67   const String& getMapFilename(  const String &currMapName ) const;
      68   const String& getPreviousMapName(  void ) const;
      69   const String& getNextMapName(  void ) const;
      70   const String& getCurrentMapName(  void ) const;
          
      72   void setCurrentMapName(  const String& mapName );
          
      74   const String& getCurrentTextureFormat(  void ) const;
      75   void setTextureFormat(  const String& format );
      76   void insertTextureFormat (  const String &format ) ;
          
      78   void setPrimaryCamera(  PagingLandScapeCamera* cam );
      79   void calculateCFactor(  void );
          
      81   String data2DFormat;
      82   String textureFormat;
          
      84   String TerrainName;
          
      86   String LandScape_filename;
      87   String LandScape_extension;
      88   String LandScape_export_filename;
      89   String LandScape_export_extension;
          
      91   String image_filename;
      92   bool ImageNameLoad;
          
          
           // MAP TOOL OPTIONS
      96   String OutDirectory;
      97   String TextureExtension;
      98   String TextureExportExtension;
          
     100   bool Paged;
     101   bool BaseMap;
     102   bool MiniMap;
     103   bool ColorMapSplit;
     104   bool ColorMapGenerate;
     105   bool LightMap;
     106   bool NormalMap;
     107   bool HeightMap;
     108   bool AlphaMaps;
     109   bool LitBaseMap;
     110   bool LitColorMapSplit;
     111   bool LitColorMapGenerate;
     112   bool InfiniteMap;
     113   bool CoverageMap;
     114   bool HeightNormalMap;
          
     116   Real HeightMapBlurFactor;
          
     118   String ColorMapName;
          
     120   bool lightmoved;
     121   Vector3 Sun;
     122   Real SunAngle;
     123   Real Amb;
     124   Real Diff;
          
     126   bool mUseLodMapCache;
          
           unsigned int Blur;
           // end of MAP TOOL OPTIONS
          
           unsigned int maxValue; //Compression range for the TC height field
           unsigned int minValue;
          
           unsigned int TileSize;
           unsigned int PageSize; //size of the page.
     136   Real invTileSizeMinusOne;
     137   Real invPageSizeMinusOne;
           unsigned int NumTiles;
           unsigned int NumPages;
          
           unsigned int world_height; //world page height,   from 0 to height,   in page number
           unsigned int world_width; //world page width,   from 0 to width,   in page number
          
     144   Real maxScaledZ; //world page height,   scaled
     145   Real maxScaledX; //world page width,   scaled
          
     147   Real maxUnScaledZ; //world page height,   scaled
     148   Real maxUnScaledX; //world page width,   scaled
          
          
     151   Real change_factor; //Determines the value of the change factor for loading/unloading LandScape Pages
           unsigned int max_adjacent_pages;
           unsigned int max_preload_pages;
     154   Real visible_renderables; //Numbers of visible renderables surrounding the camera
     155   Real renderable_factor; //Determines the distance of loading and unloading of renderables in renderable numbers
          
     157   Vector3 position; //Startup position of the terrain surface
     158   Vector3 scale;
     159   Vector3 invScale;
          
     161   Material::LodDistanceList lodMaterialDistanceList; //Distance for the material LOD change
     162   Real distanceLOD; //Distance for the LOD change
     163   Real LOD_factor;
     164   bool roughnessLod;
          
           unsigned int num_renderables; //Max number of renderables to use.
           unsigned int num_renderables_increment; //Number of renderables to add in case we run out of renderables
           unsigned int num_tiles; //Max number of tiles to use.
           unsigned int num_tiles_increment; //Number of renderables to add in case we run out of renderables
          
     171   Real cameraThreshold; //If the last camera position is >= the the scene is transverse again.
          
           unsigned int num_renderables_loading; //Max number of renderable to load in a single Frame.
           unsigned int maxRenderLevel;
          
           unsigned int NumMatHeightSplat;
     177   std::vector <ColourValue> matColor;
     178   std::vector <Real> matHeight;
     179   std::vector<String> SplatDetailMapNames;
          
     181   bool VertexCompression;
          
     183   bool hasVertexShader;
     184   bool hasFragmentShader;
     185   bool hasFragmentShader2;
           unsigned int numTextureUnits;
     187   bool isRenderGL;
          
     189   Real ScaledPageSizeX;
     190   Real ScaledPageSizeZ;
     191   Real ScaledHeightY;
          
          
           /// used to test all texture format without
           /// restrictions (  renderer or capabilities )
     196   bool TextureFormatDebug;
           /// Can terrain be deformed real-time
     198   bool Deformable;
           /// are deformation saved?
     200   bool saveDeformation;
          
          
           //used to get screen height...
           // should find another way...
     205   PagingLandScapeCamera* primaryCamera;
          
           /// At what point (  parametric ) should LOD morphing start
     208   Real lodMorphStart;
     209   bool lodMorph;
           unsigned int maxPixelError;
     211   Real CFactor;
          
           // MapSplitter Tool
           unsigned int RawHeight;
           unsigned int RawWidth;
          
     217   bool isRaw;
     218   bool Equalize;
     219   bool ZHorizon;
     220   bool SRTM_water;
          
           unsigned int MiniMapHeight;
           unsigned int MiniMapWidth;
          
           // Generate one or all maps ?
     226   bool mBatchMode;
          
           // Both
          
           /// ResourceGroupName
     231   String groupName;
     232   String cfgGroupName;
          
     234   bool lit;
     235   bool normals;
     236   bool colored;
          
     238   bool coverage_vertex_color;
     239   bool base_vertex_color;
     240   bool vertex_shadowed;
     241   bool vertex_instant_colored;
          
     243   bool BigImage;
     244   bool VisMap;
     245   bool MaxLodUnderCam;
          
     247   Real TextureStretchFactor;
          
           unsigned int RenderableLoadInterval;
           unsigned int PageLoadInterval;
          
           unsigned int TileInvisibleUnloadFrames;
           unsigned int PageInvisibleUnloadFrames;
          
           unsigned int NumSplatMapToSplit;
     256   std::vector<String> SplatMapNames;
          
           unsigned int NumTextureFormatSupported;
     259   std::vector<String> TextureFormatSupported;
          
     261   bool queryNoInterpolation;
     262   Real queryResolutionFactor;
          
     264   bool materialPerPage;
     265   bool textureModifiable;
          
     267   Vector3 BaseCameraViewpoint;
     268   Vector3 Baselookat;
          
     270   bool setUint (  unsigned int &u,   const String &ValuetoGet );
     271   bool setBool (  bool &b,   const String &ValuetoGet );
     272   bool setReal (  Real &r,  const String &ValuetoGet );
     273   bool setColourValue(  ColourValue &r,  const String &ValuetoGet );
     274   bool setString (  String &s,   const String &ValuetoGet );
          
     276   StringVector mResourceFilesystem;
     277   StringVector mResourceZip;
          
     279   PagingLandScapeSceneManager *mScnMgr;
          
     281   void setTileInfo(  PagingLandScapeTileInfo *t );
     282   PagingLandScapeTileInfo *getTileInfo(  const uint pageX,   const uint pageZ,  
     283   const uint tileX,   const uint tileZ );
     284   void loadMapInfo(   );
     285   void clearTileInfo(   );
     286   void saveMapInfo(   );
          
           private:
          
     290   void loadcfg (  const String &filename,   ConfigFile& config );
     291   ColourValue _getAvgColor(  const String& tex ) const;
     292   String mCurrentMap;
     293   LandScapeFileNames mMapList;
     294   StringVector mTextureFormats;
     295   bool isInit;
     296   ConfigFile *mConfig;
          
     298   std::deque<PagingLandScapeTileInfo*> mTileInfoCache;
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapePage.h

          /***************************************************************************
           OgrePagingLandScapePage.h - description
           -------------------
           begin : Sat Mar 08 2003
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapePAGE_H
          #define PAGINGLandScapePAGE_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
          
           class _OgrePagingLandScapeExport PagingLandScapePage
           {
           public:
           /** Sets the appropriate neighbor for this TerrainRenderable. Neighbors are necessary
           to know when to bridge between LODs.
           */
      33   void _setNeighbor(  const Neighbor& n,   PagingLandScapePage* p );
          
           /** Returns the page's scene node
           */
      37   SceneNode* getPageNode(   ) const { return mPageNode; }
          
           /** Returns the neighbor TerrainRenderable.
           */
      41   PagingLandScapePage* _getNeighbor(  const Neighbor& n ) const
           {
           return mNeighbors[ n ];
           };
          
      46   PagingLandScapeTile* getTile(  const unsigned int i ,   const unsigned int j ) const;
          
      48   PagingLandScapeTile* getTile(  const Vector3& pos );
      49   PagingLandScapePage(  PagingLandScapePageManager *pageMgr );
          
           virtual ~PagingLandScapePage(  void );
          
           /** Whole Map changes */
           void init(  const unsigned int tableX,   const unsigned int tableZ );
          
           /** Release the page,   but keep it reusable if Whole Map changes */
           void uninit(  void );
          
           /** Pre-loads the LandScape data using parameters int he given in the constructor. */
           void preload(  void );
          
           /** Loads the LandScape tiles using parameters int he given in the constructor. */
           void load(  void );
          
           /** Unloads the LandScape data,   then reloads it */
           void reload(  void );
          
           /** Loads the LandScape texture using parameters int he given in the constructor. */
           void loadTexture(  void );
          
           /** Unloads the LandScape texture,   but doesn't destroy the LandScape data. */
           void unloadTexture(  void );
          
           /** Unloads the LandScape data,   but doesn't destroy the LandScape page. */
           void unload(  void );
          
           /** Post Unloads the LandScape data,   but doesn't destroy the LandScape page. */
           void postUnload(  void );
          
           void unsetLoading(  void )
           {
           mIsLoading = false;
           };
          
           void unsetPreLoading(  void )
           {
           mIsPreLoading = false;
           };
          
           void unsetTextureLoading(  void )
           {
           mIsTextureLoading = false;
           };
          
           void unsetUnloading(  void )
           {
           mIsUnloading = false;
           };
          
           void unsetPostUnloading(  void )
           {
           mIsPostUnloading = false;
           };
          
           void unsetTextureunloading(  void )
           {
           mIsTextureunloading = false;
           };
          
           const bool isLoaded(  void ) const
           {
           return mIsLoaded;
           };
          
           const bool isPreLoaded(  void ) const
           {
           return mIsPreLoaded;
           };
          
           const bool isTextureLoaded(  void ) const
           {
           return mIsTextureLoaded;
           };
          
           const bool isLoadable(  void ) const
           {
           return mIsLoadable;
           };
          
           const bool unloadUntouched(  void );
           void touch(  void );
          
           bool isVisible(  void ) const
           {
           return mVisible;
           }
          
           /** Returns if the camera is over this LandScape page.
           */
           int isCameraIn(  const Vector3& pos ) const;
          
           bool _Notify(  const Vector3 &pos,   const PagingLandScapeCamera * const Cam );
           void _Show(  const bool do_show );
          
           void getCoordinates(  unsigned int& X,   unsigned int& Z ) const
           {
           X = mTableX;
           Z = mTableZ;
           };
          
          
           bool mIsLoading;
           bool mIsPreLoading;
           bool mIsTextureLoading;
          
          
           bool mIsUnloading;
           bool mIsPostUnloading;
           bool mIsTextureunloading;
          
           /** Sets the render queue group which the tiles should be rendered in. */
           void setRenderQueue(  uint8 qid );
          
           void _updateLod(  void );
          
           void setMapMaterial(  void );
          
           inline bool isCoord(  const unsigned int x,   const unsigned int z ){return (  mTableZ == z && mTableX == x );};
          
           SceneNode *getSceneNode(   ){return mPageNode;};
           const AxisAlignedBox &getWorldBbox(   ) const {return mBounds;};
           const Vector3 &getCenter(  void ) const {return mWorldPosition;};
          
           protected:
           SceneNode* mPageNode;
          
           PagingLandScapeTiles mTiles;
          
           bool mIsLoaded;
           bool mIsPreLoaded;
           bool mIsTextureLoaded;
          
           // if data needed for this page doesn't exists
           bool mIsLoadable;
          
           bool mVisible;
           // ensure page is not flickering due to shadow passes
           // as it unload instantly
           // but loading is queued
           // if not page not showed until mVisibletouch==0 it becomes invisible
           //size_t mVisibletouch;
          
           // Position of this Terrain Page in the Terrain Page Array
           unsigned int mTableX;
           unsigned int mTableZ;
          
           unsigned int mNumTiles;
          
           Real mIniX; //,   mEndX; // Max and Min values of the terrain
           Real mIniZ; //,   mEndZ;
          
           PagingLandScapePage* mNeighbors[4];
          
           // Change Zone values
           AxisAlignedBox mBounds;
           AxisAlignedBox mBoundsInt;
           AxisAlignedBox mBoundsExt;
           Vector3 mWorldPosition;
          
           PagingLandScapePageRenderable* mRenderable;
          
           unsigned int mTimeUntouched;
          
           PageState pageState;
           PageQueuingState pageQueingState;
           PagingLandScapePageManager *mParent;
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapePageManager.h

          /***************************************************************************
           OgrePagingLandScapePageManager.h - description
           -------------------
           begin : Sat May 01 2004
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapePAGEMANAGER_H
          #define PAGINGLandScapePAGEMANAGER_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgreSingleton.h"
          #include "OgreFrameListener.h"
          #include "OgrePagingLandScapeQueue.h"
          
          #include "OgrePagingLandScapePage.h"
          
          namespace Ogre
          {
           class _OgrePagingLandScapeExport PagingLandScapePageManager : public FrameListener
           {
           public:
          
           ///ctor
      35   PagingLandScapePageManager(  PagingLandScapeSceneManager * scnMgr );
           ///dtor
      37   ~PagingLandScapePageManager(  void );
          
           /// upon new landscape
      40   void load(  void );
           /// empty before loading a landscape or final deletion
      42   void clear(  void );
           /// reset paging but keep page pool in memory
      44   void reset(  void );
          
           /// used to load first page earlier than first updatePaging(   ) call
           /// say like just after scene manager setWorldGeom(   )
      48   void LoadFirstPage(  PagingLandScapeCamera* cam );
           /// Make sure page under camera is loaded,  
           /// that neighbor pages are preLoaded,   preLoading
           /// and process queues accordingly
      52   void updatePaging(  PagingLandScapeCamera* cam );
          
           // recursively call LOD update on all page and tiles
      55   void _updateLod(  void );
          
           // load everything around camera just now.
      58   void loadNow(  PagingLandScapeCamera *cam );
           // Make sure page gets into loaded page list when loaded from outside
           // ie "LoadNow" getOption
      61   void addLoadedPage(  PagingLandScapePage *p );
          
           /// if page is already instantiated get page at this pos,  
           /// otherwise allocate one,   if alwaysReturn is set true.
      65   PagingLandScapePage* getPage(  const unsigned int i ,   const unsigned int j,  
           const bool alwaysReturn = true );
           /// Instantiate a new page from pool.
      68   PagingLandScapePage* getNewPage(  const unsigned int i ,   const unsigned int j );
           /// Return a page to the pool.
      70   void releasePage (  PagingLandScapePage*p  );
          
           /// get Tile at absolute position in space,   return answer even when position is outside landscape
           /// when alwaysAnswer is true
      74   PagingLandScapeTile* getTile(  const Real posx,   const Real posz,   bool alwaysAnswer );
           /// get Tile at absolute position but unscaled by landscape scale in space,  
           /// return answer even when position is outside landscape
           /// when alwaysAnswer is true
      78   PagingLandScapeTile* getTileUnscaled(  const Real posx,   const Real posz,   bool alwaysAnswer );
           // get Tile at relative position (  in the page containing the tile page coordinate system ) in space,  
           /// return answer even when position is outside landscape
           /// when alwaysAnswer is true
      82   PagingLandScapeTile* getTile(  const Real posx,   const Real posz,  
           const unsigned int pagex,   const unsigned int pagez,  
           bool alwaysAnswer );
           // get Tile at relative position but unscaled by landscape scale (  in the page containing the tile page coordinate system ) in space,  
           /// return answer even when position is outside landscape
           /// when alwaysAnswer is true
      88   PagingLandScapeTile* getTileUnscaled(  const Real posx,   const Real posz,  
           const unsigned int pagex,   const unsigned int pagez,  
           bool alwaysAnswer );
           // get Tile at relative position but unscaled by landscape scale (  in the page containing the tile page coordinate system ) in space,  
           /// return answer even when position is outside landscape
           /// when alwaysAnswer is true
      94   PagingLandScapeTile* getTilePage (  unsigned int &posx,   unsigned int &posz,   const unsigned int pagex,   const unsigned int pagez );
          
      96   void getGlobalToPage(  Real& x,   Real& z ) const;
           /** Get the Page indices from a position
           @param posx the world position vector.
           @param posz the world position vector.
           @param x result placed in reference to the x index of the page
           @param z result placed in reference to the z index of the page
           */
     103   inline bool getPageIndices(  const Real posx,   const Real posz,   unsigned int& x,   unsigned int& z,   bool alwaysAnswer ) const
           {
           if (  alwaysAnswer )
           {
           getNearestPageIndicesUnscaled(  posx * mOptions->invScale.x,   posz* mOptions->invScale.z,   x,   z );
           return true;
           }
           else
           {
           return getRealPageIndicesUnscaled(  posx * mOptions->invScale.x,   posz* mOptions->invScale.z,   x,   z );
           }
           }
           /** Get the Page indices from a position,   returning page only if position is in.
           @param posx the world position vector but unscaled.
           @param posz the world position vector but unscaled.
           @param x result placed in reference to the x index of the page
           @param z result placed in reference to the z index of the page
           */
     121   inline bool getRealPageIndicesUnscaled(  const Real posx,   const Real posz,  
           unsigned int& x,   unsigned int& z )
           const
           {
           const Real lx = (  (  posx + mOptions->maxUnScaledX ) * mOptions->invPageSizeMinusOne );
           const Real lz = (  (  posz + mOptions->maxUnScaledZ ) * mOptions->invPageSizeMinusOne );
          
           // make sure indices are not negative or outside range of number of pages
           if (  lx >= mOptions->world_width || lx < static_cast <Real> (  0.0 ) ||
           lz >= mOptions->world_height || lz < static_cast <Real> (  0.0 )  )
           {
           return false;
           }
           else
           {
           x = static_cast< unsigned int > (  lx );
           z = static_cast< unsigned int > (  lz );
           return true;
           }
           }
           /** Get the Page indices from a position,   always returning a page.
           @param posx the world position vector but unscaled.
           @param posz the world position vector but unscaled.
           @param x result placed in reference to the x index of the page
           @param z result placed in reference to the z index of the page
           */
     147   void getNearestPageIndicesUnscaled(  const Real posx,   const Real posz,   unsigned int& x,   unsigned int& z ) const;
          
           /** Get the Tile indices from a position
           @param posx the world position vector.
           @param posz the world position vector.
           @param pagex the world position page number.
           @param pagez the world position page number.
           @param x result placed in reference to the x index of the page
           @param z result placed in reference to the z index of the page
           */
     157   bool getTileIndices(  const Real posx,   const Real posz,   const unsigned int pagex,   const unsigned int pagez,   unsigned int& x,   unsigned int& z,   bool alwaysAnswer ) const;
          
           /** Get the Tile indices from a position,   returning tile only if position is in.
           @param posx the world position vector but unscaled.
           @param posz the world position vector but unscaled.
           @param x result placed in reference to the x index of the page
           @param z result placed in reference to the z index of the page
           */
     165   inline bool getRealTileIndicesUnscaled(  const Real posx,   const Real posz,  
           const unsigned int pagex,   const unsigned int pagez,  
           unsigned int& x,   unsigned int& z ) const
           {
           // adjust x and z to be local to page
           const int pSize = mOptions->PageSize - 1;
           const int tilex = static_cast< int >(  (  posx - (  (  pagex * pSize ) - mOptions->maxUnScaledX ) ) * mOptions->invTileSizeMinusOne );
           const int tilez = static_cast< int >(  (  posz - (  (  pagez * pSize ) - mOptions->maxUnScaledZ ) ) * mOptions->invTileSizeMinusOne );
          
          
           const int tilesPerPage = static_cast< int >(  mOptions->NumTiles );
           //const int tilesPerPage = static_cast< int >(  mOptions->NumTiles(  pSize * inv_tSize ) - 1 );
          
           if (  tilex > tilesPerPage || tilex < 0 ||
           tilez > tilesPerPage || tilez < 0 )
           {
           return false;
           }
           else
           {
           x = static_cast< unsigned int >(  tilex );
           z = static_cast< unsigned int >(  tilez );
           return true;
           }
           }
          
           /** Get the Tile indices from a position,   returning tile only if position is in.
           @param posx the world position vector but unscaled.
           @param posz the world position vector but unscaled.
           @param x result placed in reference to the x index of the page
           @param z result placed in reference to the z index of the page
           */
     197   void getNearestTileIndicesUnscaled(  const Real posx,   const Real posz,   const unsigned int pagex,   const unsigned int pagez,   unsigned int& x,   unsigned int& z ) const;
          
     199   void setTerrainReady(  bool isready )
           {
           mTerrainReady = isready;
           };
          
          
     205   void removeFromQueues(  PagingLandScapePage* p );
          
     207   bool frameStarted(  const FrameEvent& evt );
     208   bool frameEnded(  const FrameEvent& evt );
          
     210   void setWorldGeometryRenderQueue(  uint8 qid );
     211   RenderQueueGroupID getRenderQueueGroupID(  void )
           {
           return mRenderQueueGroupID;
           };
          
     216   void setMapMaterial(  void );
     217   void WorldDimensionChange(  void );
          
          
          
           /// getter
     222   unsigned int getCurrentCameraPageX(  void ) const;
           /// getter
     224   unsigned int getCurrentCameraPageZ(  void ) const;
           /// getter
     226   unsigned int getCurrentCameraTileX(  void ) const;
           /// getter
     228   unsigned int getCurrentCameraTileZ(  void ) const;
           /// getter
     230   int getPagePreloadQueueSize(  void ) const;
           /// getter
     232   int getPageLoadQueueSize(  void ) const;
           /// getter
     234   int getPageTextureloadQueueSize(  void ) const;
           /// getter
     236   int getLoadedPageSize(  void ) const;
           /// getter
     238   int getPreLoadedPageSize(  void ) const;
           /// getter
     240   int getTextureLoadedPageSize(  void ) const;
           /// getter
     242   int getUnloadedPagesSize(  void ) const;
          
     244   RenderQueueGroupID getPageRenderQueue(   ){return mRenderQueueGroupID;};
          
     246   PagingLandScapeOptions* getOptions(   ){return mOptions;}
     247   PagingLandScapeSceneManager* getSceneManager(   ){return mSceneManager;}
          
     249   bool isEnabled (   )const {return mEnabled;}
     250   void setEnabled (  const bool enabled ){mEnabled = enabled;}
          
           protected:
          
           PagingLandScapeOptions* mOptions;
           PagingLandScapeSceneManager *mSceneManager;
          
          
          
           void processUnloadQueues(   );
           void processLoadQueues(   );
           void updateLoadedPages(   );
           void queuePageNeighbors (   );
          
           void makePageLoadedNow(  PagingLandScapePage* p );
           PagingLandScapePage* find_nearest(  const Vector3& pos,   const unsigned int x,   const unsigned int z,   PagingLandScapePageList& mQueue ) const;
          
           PagingLandScapeData2DManager* mData2d;
           PagingLandScapeTextureManager* mTexture;
           PagingLandScapeRenderableManager* mRenderablesMgr;
          
           /** LandScape pages for the terrain.
           */
           //PagingLandScapePages mPages;
          
           PagingLandScapeQueue <PagingLandScapePage> mPageLoadQueue;
           PagingLandScapeQueue <PagingLandScapePage> mPagePreloadQueue;
           PagingLandScapeQueue <PagingLandScapePage> mPageTextureloadQueue;
          
           PagingLandScapePageList mLoadedPages;
           PagingLandScapePageList mPreLoadedPages;
           PagingLandScapePageList mTextureLoadedPages;
          
           PagingLandScapePageList mActivePages;
           PagingLandScapePageList mFreePages;
           PagingLandScapePageArray mPagePool;
          
           unsigned int mWidth;
           unsigned int mHeight;
          
           int mNextQueueFrameCount;
           int mTimePreLoaded;
          
           int mPause;
          
           PagingLandScapeCamera* mCurrentcam;
           bool mTerrainReady;
           bool mOnFrame;
          
           unsigned int mRenderableLoadInterval;
           unsigned int mPageLoadInterval;
          
           RenderQueueGroupID mRenderQueueGroupID;
          
           //if not queued to be removed from frame listener
           //or SM is in paused State
           bool mEnabled;
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapePageRenderable.h

       1  /***************************************************************************
           OgrePagingLandScapePageRenderable.h - description
           -------------------
           begin : Thu Feb 27 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
           * *
           * This program is free software; you can redistribute it and/or modify *
           * it under the terms of the GNU General Public License as published by *
           * the Free Software Foundation; either version 2 of the License,   or *
           * (  at your option ) any later version. *
           * *
           ***************************************************************************/
          
          #ifndef PagingLandScapePageRenderable_H
          #define PagingLandScapePageRenderable_H
          
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          
          namespace Ogre
          {
          
           /** Represents a LandScape page in terms of vertexes.
           @remarks
           A LandScapeRenderable represents a Page used to render a
           block of LandScape using the procedural terrain approach for LOD.
           */
      33   class PagingLandScapePageRenderable : public Renderable,   public MovableObject
           {
           public:
          
           /** Initializes the LandScapeRenderable with the given options and the starting coordinates of this block.
           */
      39   PagingLandScapePageRenderable(  PagingLandScapePageManager *pageMgr,   const String& name,   const unsigned int pageX,   const unsigned int pageZ,   const AxisAlignedBox& bounds );
          
      41   virtual ~PagingLandScapePageRenderable(  void );
          
      43   void load(  void );
          
      45   void setMaterial(  const MaterialPtr& mat );
          
      47   const Real getMaxHeight(  void )
           {
           return (  mBounds.getMaximum(   ) ).y;
           };
          
      52   static PagingLandScapeOptions* mOpt;
          
           /////////Movable overridden object methods
          
           /** Updates the level of detail to be used for rendering this TerrainRenderable based on the passed in Camera */
      57   inline void _notifyCurrentCamera(  Camera* cam )
           {
           //if (  static_cast<PagingLandScapeCamera*> (  cam )->isVisible (  mBounds.getAllCorners(   ) ) )
           //{
           mVisible = true;
           // MovableObject::_notifyCurrentCamera(  cam );
           //}
           //else
           // mVisible = false;
           }
      67   void _updateRenderQueue(  RenderQueue* queue );
          
           /** Returns the type of the movable. */
      70   virtual const String& getMovableType(  void ) const
           {
           return mType;
           };
          
           /** Returns the bounding box of this TerrainRenderable */
      76   const AxisAlignedBox& getBoundingBox(  void ) const
           {
           return mBounds;
           };
          
           /////////Renderable object methods
           /**
           Constructs a RenderOperation to render the TerrainRenderable.
           @remarks
           Each TerrainRenderable has a block of vertices that represent the terrain. Index arrays are dynamically
           created for mipmap level,   and then cached.
           */
      88   virtual void getRenderOperation(  RenderOperation& rend );
          
      90   virtual const MaterialPtr& getMaterial(  void ) const
           {
           return mMaterial;
           };
          
      95   virtual void getWorldTransforms(  Matrix4* xform ) const;
          
      97   virtual const Quaternion& getWorldOrientation(  void ) const;
      98   virtual const Vector3& getWorldPosition(  void ) const;
          
           /** @copydoc Renderable::getLights */
     101   const LightList& getLights(  void ) const;
          
     103   virtual Technique* getTechnique(  void ) const;
          
     105   virtual Real getSquaredViewDepth(  const Camera* cam ) const;
          
     107   virtual Real getBoundingRadius(  void ) const;
          
           /// @see MovableObject
     110   uint32 getTypeFlags(  void ) const;
          
           protected:
          
     114   PagingLandScapePageManager *mParent;
          
     116   VertexData* mCurrVertexes;
     117   IndexData* mCurrIndexes;
          
           /// Bounding box of this tile
     120   AxisAlignedBox mBounds;
           /// The center point of this tile
     122   Vector3 mCenter;
           /// The MovableObject type
     124   static String mType;
           /// Current material used by this tile
     126   MaterialPtr mMaterial;
          
           unsigned int mX;
           unsigned int mZ;
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapePoolSet.h

          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          
          #ifndef __OgrePagingLandScapePoolSet_H__
          #define __OgrePagingLandScapePoolSet_H__
          
          #include <list>
          #include <vector>
          
          
          namespace Ogre
          {
           /** A collection of pre-allocated object instance of a same base class
           */
      37   template <class T> class PoolSet
           {
           protected:
          
           typedef std::list<T*> ActivePoolableList;
           typedef std::list<T*> FreePoolableList;
           typedef std::vector<T*> PoolablePool;
          
           public:
          
           /** Usual constructor
           @param
           poolSize The initial size of the object pool. Estimate of the number of objects
           which will be required,   and pass it using this parameter. The set will
           preallocate this number to avoid memory fragmentation. The default behaviour
           once this pool has run out is to double it.
           @see
           PoolSet::setAutoextend
           */
           PoolSet(  unsigned int poolSize = 0,   bool autoExtendPool = true ):
           mAutoExtendPool(  autoExtendPool ),  
           mAutoExtendFactor(  2.0f ),  
           mPoolSize(  poolSize )
           {
           assert (  mFreePoolables.empty(   ) );
           assert (  mActivePoolables.empty(   ) );
           assert (  mPoolablePool.empty(   ) );
          
           setPoolSize(  poolSize );
           }
           /**
           dtor
           */
           virtual ~PoolSet(   )
           {
           assert (  mPoolSize == 0 && mPoolablePool.empty(   ) );
           }
           /**
           empty totally the pool.
           */
      77   void deletePool(   )
           {
           // Free pool items
           for (  typename PoolablePool::iterator i = mPoolablePool.begin(   );
           i != mPoolablePool.end(   ); ++i )
           {
           deallocate (  *i );
           }
           mPoolablePool.clear(   );
           mFreePoolables.clear(   );
           mActivePoolables.clear(   );
           mPoolSize = 0;
           }
           /** Creates a new pooled object and adds it to this set.
           @remarks
           Behavior once the query pool has been exhausted depends on the
           PoolSet::setAutoextendPool option.
           @returns
           On success,   a pointer to a newly created Poolable is
           returned.
           @par
           On failure (  i.e. no more space and can't autoextend ),  
           <b>NULL</b> is returned.
           @see
           PoolSet::setAutoextend
           */
     103   T* getPoolable(   )
           {
           if (  mFreePoolables.empty(   ) )
           {
           if (  mAutoExtendPool )
           {
           autoExtend (   );
           }
           else
           {
           return 0;
           }
           }
           // Get a new Object
           T* newPoolable = mFreePoolables.front(   );
           mFreePoolables.pop_front(   );
           mActivePoolables.push_back(  newPoolable );
          
           return newPoolable;
           }
           /*
           Extend the pool Size by a mAutoExtendFactor factor (  default 2.0f )
           */
     126   void autoExtend(   )
           {
           unsigned int newSize = (  unsigned int )(  mPoolSize * mAutoExtendFactor );
           if (  newSize <= mPoolSize )
           newSize = mPoolSize + 1;
           setPoolSize (  newSize );
           }
           /*
           Extend the pool Size by this factor (  default is 2.0f )
           */
     136   void setExtendFactor(  const float factor )
           {
           assert(  factor >= 1.0f );// otherwise you'll make it smaller
           mAutoExtendFactor = factor;
           }
           /** Removes a pooled object from the set.
           @note
           This version is more efficient than removing by index.
           */
     145   void removePoolable(  T * const pPoolable )
           {
           mActivePoolables.remove (  pPoolable );
           mFreePoolables.push_back (  pPoolable );
           }
           /** Returns the number of active object which currently make up this set.
           */
     152   size_t getActivePoolablesSize(  void ) const
           {
           return static_cast< size_t >(  mActivePoolables.size(   ) );
           }
     156   ActivePoolableList &getActivePoolables(  void )
           {
           return mActivePoolables;
           }
           /** Tells the set whether to allow automatic extension of the pool of objects.
           @remarks
           A PoolSet stores a pool of pre-constructed queries which are used as needed when
           a new object is requested. This allows applications to create / remove objects efficiently
           without incurring construction / destruction costs. This method allows you to configure
           the behavior when a new object is requested but the object pool has been exhausted.
           @par
           The default behavior is to allow the pool to extend (  typically this allocates double the current
           pool of queries when the pool is expended ),   equivalent to calling this method with
           autoExtend = true. If you set the parameter to false however,   any attempt to create a new pooled object
           when the pool has expired will simply fail silently,   returning a null pointer.
           @param autoextend true to double the pool every time it runs out,   false to fail silently.
           */
     173   void setAutoextend(  bool autoextend )
           {
           mAutoExtendPool = autoextend;
           }
           /** Returns true if the object pool automatically extends.
           @see
           PoolSet::setAutoextend
           */
     181   bool getAutoextend(  void ) const
           {
           return mAutoExtendPool;
           }
           /** Adjusts the size of the pool of object available in this set.
           @remarks
           See the PoolSet::setAutoextend method for full details of the query pool. This method adjusts
           the preallocated size of the pool. If you try to reduce the size of the pool,   the set has the option
           of ignoring you if too many objects are already in use. Bear in mind that calling this method will
           incur significant construction / destruction calls so should be avoided in time-critical code. The same
           goes for auto-extension,   try to avoid it by estimating the pool size correctly up-front.
           @param
           size The new size for the pool.
           */
     195   void setPoolSize(  const unsigned int size )
           {
           // Never shrink below size(   )
           const size_t currSize = mPoolablePool.size(   );
          
           if(  currSize < size )
           {
           increasePool(  size );
           for (  size_t i = currSize; i < size; ++i )
           {
           // Add new items to the queue
           mFreePoolables.push_back (  mPoolablePool[i] );
           }
           mPoolSize = size;
           }
           }
           /** Returns the current size of the object pool.
           @returns
           The current size of the object pool.
           @see
           PoolSet::setAutoextend
           */
     217   unsigned int getPoolSize(  void ) const
           {
           return static_cast< unsigned int >(  mPoolablePool.size(   ) );
           }
           /** Empties this set of all Actives object (  but do not delete them ).
           */
     223   void clear(   )
           {
           // Insert actives into free list
           mFreePoolables.insert(  mFreePoolables.end(   ),   mActivePoolables.begin(   ),   mActivePoolables.end(   ) );
          
           // Remove all active instances
           mActivePoolables.clear(   );
           }
          
           protected:
           /** Active object list.
           @remarks
           This is a linked list of pointers to objects in the object pool.
           @par
           This allows very fast insertions and deletions from anywhere in the list to activate / deactivate objects
           (  required for particle systems etc ) as well as reuse of Poolable instances in the pool
           without construction & destruction which avoids memory thrashing.
           */
           ActivePoolableList mActivePoolables;
           /** Free object queue.
           @remarks
           This contains a list of the objects free for use as new instances
           as required by the set. Poolable instances are pre-constructed up to the estimated size in the
           mPoolablePool vector and are referenced on this deque at startup. As they get used this deque
           reduces,   as they get released back to to the set they get added back to the deque.
           */
           FreePoolableList mFreePoolables;
           /** Pool of objects instances for use and reuse in the active query list.
           @remarks
           This vector will be preallocated with the estimated size of the set,  and will extend as required.
           */
           PoolablePool mPoolablePool;
           /// The number of query in the pool.
           unsigned int mPoolSize;
           /// Flag indicating whether to auto extend pool
           bool mAutoExtendPool;
           // by how much we will auto extend current pool
           Real mAutoExtendFactor;
          
           /// method for increasing pool size
           void increasePool(  unsigned int size )
           {
           assert (  size > 0 );
           const size_t oldSize = mPoolablePool.size(   );
          
           // Increase size
           mPoolablePool.reserve(  size );
           mPoolablePool.resize(  size );
          
           // Create new queries
           for (  size_t i = oldSize; i < size; ++i )
           mPoolablePool[i] = allocate(   );
           }
           protected :
           virtual T* allocate(   ) = 0;
           virtual void deallocate(  T* p ) = 0;
          
           };
          
          }
          
          #endif//__OgrePagingLandScapePoolSet_H__

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapePrecompiledHeaders.h

       1  /***************************************************************************
          OgrePagingLandScapePrecompiledHeaders.cpp - description
          -------------------
          copyright : (  C ) 2006 Tuan Kuranes
          email : tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          #ifndef _PRECOMP_HEADERS
          #define _PRECOMP_HEADERS
          
          #ifdef _PRECOMPILED_HEADERS
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          // -------------------------------------------------------
          // Octree Scene Manager (   occlusion management inside  )
          // -------------------------------------------------------
          
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeCamera.h"
          
          #include "OgrePagingLandScapeOctreeAxisAlignedBoxSceneQuery.h"
          #include "OgrePagingLandScapeOctreeIntersectionSceneQuery.h"
          #include "OgrePagingLandScapeOctreePlaneBoundedVolumeListSceneQuery.h"
          #include "OgrePagingLandScapeOctreeRaySceneQuery.h"
          #include "OgrePagingLandScapeOctreeSphereSceneQuery.h"
          
          //hardware occlusion management
          
          
          #include "OgreOcclusionBoundingBox.h"
          #include "OgrePagingLandScapeOcclusionQuerySet.h"
          #include "OgrePagingLandScapeOcclusionSorter.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          #include "OgrePagingLandScapeOcclusionCameraTraversal.h"
          #include "OgrePagingLandScapeOcclusionDebugTraversal.h"
          
          #include "OgrePagingLandScapeOcclusionCHCTraversal.h"
          #include "OgrePagingLandScapeOcclusionSWTraversal.h"
          #include "OgrePagingLandScapeOcclusionVFTraversal.h"
          
          
          #include "OgrePagingLandScapeOcclusion.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          #include "OgrePagingLandScapeOcclusionVisibilityData.h"
          
          
          // -------------------------------------------------------
          // Paging Scene Manager
          // -------------------------------------------------------
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeCamera.h"
          
          #include "OgrePagingLandScapeRaySceneQuery.h"
          #include "OgrePagingLandScapeIntersectionSceneQuery.h"
          #include "OgrePagingLandScapeAxisAlignedBoxSceneQuery.h"
          
          // Horizon Culling
          #include "OgrePagingLandScapeHorizon.h"
          
          // Queues
          
          
          // pages
          #include "OgrePagingLandScapePage.h"
          #include "OgrePagingLandScapePageRenderable.h"
          #include "OgrePagingLandScapePageManager.h"
          
          
          // Tile Management (  page is constituted of tiles. )
          #include "OgrePagingLandScapeTile.h"
          #include "OgrePagingLandScapeTileInfo.h"
          #include "OgrePagingLandScapeTileManager.h"
          
          // IndexBuffer Caching to share it across tiles and LOD
          #include "OgrePagingLandScapeIndexBuffer.h"
          // Texture coordinates buffer cache to share it across pages
          #include "OgrePagingLandScapeTextureCoordinatesManager.h"
          
          // Renderable that constitutes tiles
          #include "OgrePagingLandScapeRenderable.h"
          #include "OgrePagingLandScapeRenderableManager.h"
          
          
          // Terrain Data Source management
          #include "OgrePagingLandScapeData2D.h"
          
          #include "OgrePagingLandScapeData2D_HeightField.h"
          #include "OgrePagingLandScapeData2D_HeightFieldTC.h"
          #include "OgrePagingLandScapeData2D_HeightFieldN.h"
          #include "OgrePagingLandScapeData2D_HeightFieldNTC.h"
          
          #include "OgrePagingLandScapeData2D_HeightFieldRaw.h"
          #include "OgrePagingLandScapeData2D_HeightFieldRawTC.h"
          
          #include "OgrePagingLandScapeData2D_Spline.h"
          
          #include "OgrePagingLandScapeData2DManager.h"
          
          
          // Terrain Texture Source management
          #include "OgrePagingLandScapeTexture.h"
          #include "OgrePagingLandScapeTexture_Splatting.h"
          #include "OgrePagingLandScapeTexture_BaseTexture.h"
          
          #include "OgrePagingLandScapeTextureManager.h"
          
          // User Call back system using listener pattern
          #include "OgrePagingLandScapeListenerManager.h"
          #include "OgrePagingLandScapeListener.h"
          #include "OgrePagingLandScapeCallback.h"
          #include "OgrePagingLandScapeCallbackEvent.h"
          
          //decals
          
          #include "OgrePagingLandScapeMeshDecal.h"
          
          //utils
          
          #include "OgrePagingLandscapePoolSet.h"
          #include "OgrePagingLandscapeQueue.h"
          
          #include "OgreDebugRectangle2D.h"
          #include "fileutils.h"
          
          #endif
          #endif //_PRECOMP_HEADERS

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapePrerequisites.h

       1  /***************************************************************************
           OgrePagingLandScapePrerequisites.h - description
           -------------------
           begin : Sun Oct 26 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
           * *
           * This program is free software; you can redistribute it and/or modify *
           * it under the terms of the GNU General Public License as published by *
           * the Free Software Foundation; either version 2 of the License,   or *
           * (  at your option ) any later version. *
           * *
           ***************************************************************************/
          
          #ifndef __PagingLandScapePrerequisites_H__
          #define __PagingLandScapePrerequisites_H__
          
          
          #include <OgrePrerequisites.h>
          
          #include <OgreHardwareBufferManager.h>
          #include <OgreTextureManager.h>
          #include <OgreHardwarePixelBuffer.h>
          #include <OgreAxisAlignedBox.h>
          
          //-----------------------------------------------------------------------
          // Options
          //-----------------------------------------------------------------------
          
          //#define _VISIBILITYDEBUG
          
          #if !(  OGRE_VERSION < (  (  1 << 16 ) | (  3 << 8 ) | 0 ) )
           #define PLSM2_EIHORT 1
          #endif
          
          //-----------------------------------------------------------------------
          // Forward declarations
          //-----------------------------------------------------------------------
          
          #include <vector>
          #include <map>
          #include <queue>
          #include <list>
          #include <stack>
          #include <limits>
          
          
          namespace Ogre
          {
          
          
           // Octree Scene management
          
           typedef std::list < MovableObject* > MovableObjectList;
           typedef std::list < Renderable* > RenderableList;
          
      60   class PagingLandScapeOctreeSceneManager;
      61   class PagingLandScapeOctreeNode;
           typedef std::list<PagingLandScapeOctreeNode*> NodeList;
      63   class PagingLandScapeOctree;
      64   class PagingLandScapeOctreeCamera;
          
           #ifdef _VISIBILITYDEBUG
      67   class DebugRectangle2D;
           #endif //_VISIBILITYDEBUG
          
           // hardware occlusion management
      71   class QuerySet;
      72   class Occlusion;
      73   class VisibilityData;
      74   class OcclusionElement;
      75   class Between;
      76   class Leaf;
          
          
           typedef enum culling_modes
           {
           // STANDARD_WALK = 0,  
           // VIEW_FRUSTUM,  
           VIEW_FRUSTUM_DIRECT,  
           //STOP_AND_WAIT,  
           CHC,  
           CHC_CONSERVATIVE,  
           NUM_CULLING_MODE
           };
      89   class OcclusionBoundingBox;
           typedef std::list<OcclusionElement*> OcclusionElementList;
           typedef std::list<PagingLandScapeOctreeNode*> PagingLandScapeOctreeNodeList;
          
      93   class FrontToBackNodeSorterOperator;
           //priority queue for the nodes to traversal
           typedef std::priority_queue<OcclusionElement*,  std::vector<OcclusionElement*>,  FrontToBackNodeSorterOperator> FrontToBackNodeSorterPriorityQueue;
           //queue for the nodes with running occlusion queries
           typedef std::queue<OcclusionElement*> QueriedOcclusionElement; //queue for the nodes with running occlusion queries
          
          
     100   class Traversal;
     101   class TraversalConst;
     102   class ConstTraversalConst;
          
     104   class CHCTraversal;
     105   class SWTraversal;
     106   class ViewFrustumCullingTraversal;
     107   class ViewFrustumCullingTraversalDirect;
     108   class TreeOverlayDebug;
          
          
          
          
          
           // Paging Scene Management
          
     116   class PagingLandScapeSceneManager;
     117   class PagingLandScapeOptions;
     118   class PagingLandScapeCamera;
           typedef std::list< PagingLandScapeCamera* > PagingLandScapeCameraList;
          
     121   class PagingLandScapeRaySceneQuery;
          
           // Basic Horizon Culling (  based on tile max and min height )
     124   class PagingLandScapeHorizon;
          
           // Page Scene Management
     127   class PagingLandScapePage;
     128   class PagingLandScapePageRenderable;
     129   class PagingLandScapePageManager;
          
          #define PAGE_INSIDE 0x00000001
          #define PAGE_CHANGE 0x00000002
          #define PAGE_OUTSIDE 0x00000004
          
          
          typedef enum PageState
          {
           inited,  
           Preloaded,  
           Textureloaded,  
           Loaded
          };
          
          typedef enum PageQueuingState
          {
           queuednone,  
           queuedPreload,  
           queuedTextureLoad,  
           queuedLoad
          };
          
           typedef std::list< PagingLandScapePage* > PagingLandScapePageList;
           typedef std::vector< PagingLandScapePage* > PagingLandScapePageArray;
           typedef PagingLandScapePageArray PagingLandScapePageRow;
           typedef std::vector< PagingLandScapePageRow > PagingLandScapePages;
          
           // Tile Management (  page is constituted of tiles. )
     158   class PagingLandScapeTile;
     159   class PagingLandScapeTileInfo;
     160   class PagingLandScapeTileManager;
           typedef std::list< PagingLandScapeTile* > PagingLandScapeTileList;
           typedef std::vector< PagingLandScapeTile* > PagingLandScapeTileRow;
           typedef std::vector< PagingLandScapeTileRow > PagingLandScapeTiles;
          
          
           // IndexBuffer Caching to share it across tiles and LOD
     167   class PagingLandScapeIndexBufferManager;
           typedef std::map< unsigned int,   IndexData* > IndexMap;
           typedef std::vector< IndexData* > IndexArray;
           typedef std::vector< IndexMap* > LevelArray;
          
           // Renderable that constitutes tiles
     173   class PagingLandScapeRenderable;
     174   class PagingLandScapeRenderableSet;
     175   class PagingLandScapeRenderableManager;
           typedef std::vector< PagingLandScapeRenderable* > PagingLandScapeRenderableVector;
          
           // Texture coordinates buffer cache
     179   class PagingLandScapeTextureCoordinatesManager;
          
           // Terrain Data Source management
     182   class PagingLandScapeData2D;
     183   class PagingLandScapeData2DManager;
           typedef std::vector< PagingLandScapeData2D* > PagingLandScapeData2DArray;
           typedef std::list< PagingLandScapeData2D* > PagingLandScapeData2DList;
          
           typedef std::vector< PagingLandScapeData2D* > PagingLandScapeData2DRow;
           typedef std::vector< PagingLandScapeData2DRow > PagingLandScapeData2DPages;
          
           typedef std::vector<PagingLandScapeData2D*> PagingLandScapeData2DMap;
          
           // Terrain Texture Source management
     193   class PagingLandScapeTexture;
     194   class PagingLandScapeTextureManager;
          
           typedef std::vector< PagingLandScapeTexture* > PagingLandScapeTextureArray;
           typedef std::list< PagingLandScapeTexture* > PagingLandScapeTextureList;
          
           typedef std::vector< PagingLandScapeTexture* > PagingLandScapeTextureRow;
           typedef std::vector< PagingLandScapeTextureRow > PagingLandScapeTexturePages;
          
           typedef std::vector<PagingLandScapeTexture*> PagingLandScapeTextureMap;
          
          
           typedef std::vector< HardwareVertexBufferSharedPtr> HardwareTextureBuffersRow;
           typedef std::vector< HardwareTextureBuffersRow> HardwareTextureBuffersCol;
          
           // User Call back system using listener pattern
     209   class PagingLandScapeListenerManager;
     210   class PagingLandScapeListener;
     211   class PagingLandscapeEvent;
          
           // Multi-map management
           typedef std::map< String,   String > LandScapeFileNames;
          
           // Vertex Shader Hardware Morphing
           #define MORPH_CUSTOM_PARAM_ID 77
          
           // LOD
           enum Neighbor
           {
           NORTH = 0,  
           SOUTH,  
           EAST,  
           WEST
           };
          
           #define STITCH_NORTH_SHIFT 0
           #define STITCH_SOUTH_SHIFT 8
           #define STITCH_WEST_SHIFT 16
           #define STITCH_EAST_SHIFT 24
          
           #define STITCH_NORTH 128 << STITCH_NORTH_SHIFT
           #define STITCH_SOUTH 128 << STITCH_SOUTH_SHIFT
           #define STITCH_WEST 128 << STITCH_WEST_SHIFT
           #define STITCH_EAST 128 << STITCH_EAST_SHIFT
          
          }
          //-----------------------------------------------------------------------
          // Windows Settings
          //-----------------------------------------------------------------------
          
          #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
          # ifdef PLUGIN_PAGINGLANDSCAPE2_EXPORTS
          # define _OgrePagingLandScapeExport __declspec(  dllexport )
          # else
          # define _OgrePagingLandScapeExport __declspec(  dllimport )
          # endif
          #else
          # define _OgrePagingLandScapeExport
          #endif
          
          //STL trick to call delete in a for_each
          struct delete_object
          {
     256   template <typename T>
           void operator(   )(  T *ptr ){ delete ptr; ptr = 0;}
          };
          
          
          #ifndef ogre_restrict
          #ifdef __INTEL_COMPILER
          #define ogre_restrict restrict
          #elif _MSC_VER >= 1400
          #define ogre_restrict __restrict
          #else
          #define ogre_restrict
          #endif
          #endif
          
          
          // DEBUGGING
          
          #ifdef _PLSM2_RELEASE_ASSERT
           #undef assert
           extern "C"
           {
     278   _CRTIMP void __cdecl _assert(  const char*,   const char*,   unsigned );
           }
           #define assert(  exp ) (  void )(  (  exp ) || (  _assert(  #exp,   __FILE__,   __LINE__ ),   0 ) )
          #endif //_PLSM2_RELEASE_ASSERT
          
          #endif //__PagingLandScapePrerequisites_H__

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeQueue.h

          /***************************************************************************
           OgrePagingLandScapeQueue.h - description
           -------------------
           begin : Mon Aug 04 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 General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLANDSCAPEQUEUE_H
          #define PAGINGLANDSCAPEQUEUE_H
          
          #include <queue>
          #include <list>
          
          #include "Ogre.h"
          #include "OgreSceneNode.h"
          #include "OgreVector3.h"
          
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      32   inline Real vectorToBoxDistance(  const AxisAlignedBox &bbox,   const Vector3& point )
           {
           const Vector3 &boxMin = bbox.getMinimum (   );
           const Vector3 halfSize (  (  bbox.getMaximum (   ) - boxMin ) * 0.5 );
           // work in the box's coordinate system
           const Vector3 kDiff (  point - (  halfSize + boxMin ) );
           // compute squared distance and closest point on box
           Real fSqrDistance (  0.0 );
           for (  unsigned int i = 0; i < 3; i++ )
           {
           const Real kClosest = kDiff[i];
           const Real khalfSize = halfSize[i];
           if (  kClosest < -khalfSize )
           {
           const Real fDelta = kClosest + khalfSize;
           fSqrDistance += fDelta * fDelta;
           }
           else if (  kClosest > khalfSize )
           {
           const Real fDelta = kClosest - khalfSize;
           fSqrDistance += fDelta * fDelta;
           }
           }
           return fSqrDistance;
           }
           //-----------------------------------------------------------------------
           template <class T>
      59   class distanceToBoxSort
           {
           public:
           //-----------------------------------------------------------------------
      63   distanceToBoxSort(  const Vector3 &camPos ) : mCamPos(  camPos )
           {};
           //-----------------------------------------------------------------------
      66   bool operator(   )(  T* x,   T* y )
           {
          
           return (  x->getCenter(   ) - mCamPos ).squaredLength(   ) <
           (  y->getCenter(   ) - mCamPos ).squaredLength(   );
          
           //return vectorToBoxDistance (  x->getWorldBbox(   ),   mCamPos ) <
           // vectorToBoxDistance (  y->getWorldBbox(   ),   mCamPos );
           }
           private:
      76   const Vector3 mCamPos;
           };
           //-----------------------------------------------------------------------
           /** This class holds classes T given to it by the plugin in a FIFO queue. */
           template<class T>
      81   class PagingLandScapeQueue
           {
          
           public:
          
           //typedef std::queue<T *,   std::list<T *> > MsgQueType;
           typedef std::list<T *> MsgQueType;
          
           //-----------------------------------------------------------------------
      90   PagingLandScapeQueue(    )
           {
           };
           //-----------------------------------------------------------------------
      94   virtual ~PagingLandScapeQueue(    )
           {
           mQueue.clear (   );
           };
           //-----------------------------------------------------------------------
      99   void clear (   )
           {
           mQueue.clear (   );
           };
           //-----------------------------------------------------------------------
     104   void push(   T* e  )
           {
           assert (   std::find(  mQueue.begin(   ),   mQueue.end(   ),   e ) == mQueue.end(   ) );
           // Insert the element at the end of the queue
           mQueue.push_back (   e  );
           };
           //-----------------------------------------------------------------------
           typename MsgQueType::iterator begin(   )
           {
           return mQueue.begin (   );
           };
           //-----------------------------------------------------------------------
           typename MsgQueType::iterator end(   )
           {
     118   return mQueue.end (   );
           };
           //-----------------------------------------------------------------------
           typename MsgQueType::iterator erase(  typename MsgQueType::iterator it )
           {
     123   return mQueue.erase (  it );
           };
           //-----------------------------------------------------------------------
           void remove (  T* e )
           {
           mQueue.remove (  e );
           };
           //-----------------------------------------------------------------------
           void sortNearest(  const Vector3 &pos )
           {
           mQueue.sort (  distanceToBoxSort <T>(  pos ) );
           };
           //-----------------------------------------------------------------------
           T *find_nearest(  const Vector3 &pos )
           {
           T *p = 0;
           Real mindist = std::numeric_limits<Real>::max (   );
           typename MsgQueType::iterator q,   qend = mQueue.end (   );
           for (  q = mQueue.begin (   );
           q != qend;
           ++q )
           {
           const Real res = (  pos - (  *q )->getCenter(   ) ).squaredLength(   );
           //const Real res = vectorToBoxDistance (  (  *q )->getSceneNode(   )->_getWorldAABB(   ),   pos );
           if (  res < mindist )
           {
           mindist = res;
           p = (  *q );
           }
           }
           if (  p )
           mQueue.remove (  p );
           return p;
           };
           //-----------------------------------------------------------------------
           T *find_nearest(  const unsigned int x,   const unsigned int z )
           {
           T *p = 0;
           unsigned int mindist = 0;
           typename MsgQueType::iterator q,   qend = mQueue.end (   );
           for (  q = mQueue.begin (   );
           q != qend;
           ++q )
           {
           unsigned int lx,   lz;
           (  *q )->getCoordinates(  lx,   lz );
          
           const unsigned int res = abs (  static_cast <int> (  lx - x ) ) + abs (  static_cast <int> (  lz - z ) );
           if (  res < mindist )
           {
           mindist = res;
           p = (  *q );
           }
           }
           if (  p )
           mQueue.remove (  p );
           return p;
           };
           //-----------------------------------------------------------------------
           T *find_farest(  const unsigned int x,   const unsigned int z )
           {
           T *p = 0;
           unsigned int maxdist = -1;
           typename MsgQueType::iterator q,   qend = mQueue.end (   );
           for (  q = mQueue.begin (   );
           q != qend;
           ++q )
           {
           unsigned int lx,   lz;
           (  *q )->getCoordinates(  lx,   lz );
          
           const unsigned int res = abs (  (  int )(  lx - x ) ) + abs (  (  int )(  lz - z ) );
           if (  res > maxdist )
           {
           maxdist = res;
           p = (  *q );
           }
           }
          
           if (  p )
           mQueue.remove (  p );
           return p;
           };
           //-----------------------------------------------------------------------
           T* pop(    )
           {
           T* tmp = 0;
           if (   !mQueue.empty (   )  )
           {
           // Queue is not empty so get a pointer to the
           // first message in the queue
           tmp = mQueue.front(    );
          
           // Now remove the pointer from the message queue
           mQueue.pop_front(    );
           }
           return tmp;
           };
           //-----------------------------------------------------------------------
           size_t getSize(   ) const
           {
           return mQueue.size (   );
           };
           //-----------------------------------------------------------------------
           bool empty(   ) const
           {
           return mQueue.empty(    );
           };
           //-----------------------------------------------------------------------
           MsgQueType *getQueue(   )
           {
           return &mQueue;
           }
          
           protected:
           MsgQueType mQueue;
          
           };
          
          } //namespace
          
          #endif //PAGINGLANDSCAPEQUEUE_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeRaySceneQuery.h

       1  /***************************************************************************
          OgrePagingLandScapeRaySceneQuery.h - description
          -------------------
          begin : Fri Sep 10 2003
          copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
          email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeRAYSCENEQUERY_H
          #define PAGINGLandScapeRAYSCENEQUERY_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeRaySceneQuery.h"
          
          namespace Ogre
          {
          
          
           /** PagingLandScape's specialisation of RaySceneQuery.
           if RSQ_Height bit mask is set,   RSQ_Terrain and RSQ_Entity bits will be ignored
           Otherwise data will be returned based on the mask
           */
      32   class PagingLandScapeRaySceneQuery : public PagingLandScapeOctreeRaySceneQuery
           {
          
           public:
      36   PagingLandScapeRaySceneQuery(  SceneManager* creator ) : PagingLandScapeOctreeRaySceneQuery(  creator )
           {
           mSupportedWorldFragments.insert(  SceneQuery::WFT_SINGLE_INTERSECTION );
           //mLastResult = new RaySceneQueryResult(   );
           }
          
          // virtual ~PagingLandScapeRaySceneQuery(  void )
          // {
          // clearFragmentList(   );
          // //delete mLastResult;
          // //mLastResult = 0;
          // }
          
           /** See RaySceneQuery. */
      50   void execute(  RaySceneQueryListener * listener );
           /** Executes the query,   returning the results back in one list.
           @remarks
           This method executes the scene query as configured,   gathers the results
           into one structure and returns a reference to that structure. These
           results will also persist in this query object until the next query is
           executed,   or clearResults(   ) is called. An more lightweight version of
           this method that returns results through a listener is also available.
           */
           //virtual RaySceneQueryResult& execute(  void );
          
           //void clearResults(  void );
          
           protected:
           //JEFF
           //PagingLandScapeTile* getNonDividedTile(  PagingLandScapeTile* tile,   const Vector3& origin );
      66   inline Vector3 getHeightAt(  const Vector3& origin ) const;
          
           //std::vector< SceneQuery::WorldFragment* > fragmentList;
          
          // void clearFragmentList(  void )
          // {
          // std::vector< SceneQuery::WorldFragment* >::iterator cur,   end = fragmentList.end(   );
          // for (  cur = fragmentList.begin(   ); cur < end; ++cur )
          // {
          // SceneQuery::WorldFragment* frag = (  *cur );
          // if (  frag )
          // {
          // delete frag;
          // frag = 0;
          // }
          // }
          // fragmentList.clear(   );
           // }
          
           private:
      86   WorldFragment mWorldFrag;
          
           };
          
          } // namespace Ogre
          
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeRenderable.h

       1  /***************************************************************************
           OgrePagingLandScapeRenderable.h - description
           -------------------
           begin : Thu Feb 27 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
           * *
           * This program is free software; you can redistribute it and/or modify *
           * it under the terms of the GNU General Public License as published by *
           * the Free Software Foundation; either version 2 of the License,   or *
           * (  at your option ) any later version. *
           * *
           ***************************************************************************/
          
          #ifndef PAGINGLandScapeRENDERABLE_H
          #define PAGINGLandScapeRENDERABLE_H
          
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          
          namespace Ogre
          {
          
           /** Represents a LandScape tile in terms of vertexes.
           @remarks
           A LandScapeRenderable represents a tile used to render a
           block of LandScape using the procedural terrain approach for LOD.
           */
      33   class PagingLandScapeRenderable : public Renderable,   public MovableObject
           {
           public:
          
           /** Sets the appropriate neighbor for this TerrainRenderable. Neighbors are necessary
           to know when to bridge between LODs.
           */
      40   void _setNeighbor(  Neighbor n,   PagingLandScapeRenderable* t )
           {
           mNeighbors[ n ] = t;
           };
          
           /** Returns the neighbor TerrainRenderable.
           */
      47   PagingLandScapeRenderable* _getNeighbor(  Neighbor n ) const
           {
           return mNeighbors[ n ];
           }
          
           /** Returns RenderLevel of current TerrainRenderable.
           */
      54   int getRenderLevel(   ) const
           {
           return mRenderLevel < 0 ? 0 : mRenderLevel;
           }
          
           /// The current LOD level
           int mRenderLevel;
          
           // if a neighbour changes its RenderLevel.
           // get a new Index buffer.
      64   void update(   );
          
           /** Initializes the LandScapeRenderable with the given options and the starting coordinates of this block.
           */
      68   PagingLandScapeRenderable(  PagingLandScapeRenderableManager *renderableMgr );
          
      70   ~PagingLandScapeRenderable(  void );
          
      72   void init(  PagingLandScapeTileInfo* info );
      73   void uninit(  void );
          
      75   bool load(  void );
          
      77   void setNeedUpdate(  void )
           {
           mNeedReload = true;
           };
      81   void adjustDeformationRectangle(  unsigned int x,   unsigned int z );
          
      83   void unload(  void );
          
      85   void setMaterial(  const MaterialPtr& mat );
          
      87   const bool isLoaded(  void )
           {
           assert (  (  mIsLoaded && mParentNode ) || (  !mIsLoaded && mParentNode == 0 )  );
           return mIsLoaded;
           };
          
      93   const Real getMaxHeight(  void )
           {
           return (  mBounds.getMaximum(   ) ).y;
           };
          
      98   inline void setInUse (  bool InUse )
           {
           mInUse = InUse;
           }
          
           /////////Movable overridden object methods
          
           /** Updates the level of detail to be used for rendering this TerrainRenderable based on the passed in Camera */
     106   virtual void _notifyCurrentCamera(  Camera* cam );
          
     108   virtual void _updateRenderQueue(  RenderQueue* queue );
          
           /** Returns the type of the movable. */
     111   virtual const String& getMovableType(  void ) const
           {
           return mType;
           };
          
           /** Returns the bounding box of this TerrainRenderable */
     117   const AxisAlignedBox& getBoundingBox(  void ) const
           {
           return mBounds;
           };
          
           /////////Renderable object methods
           /**
           Constructs a RenderOperation to render the TerrainRenderable.
           @remarks
           Each TerrainRenderable has a block of vertices that represent the terrain. Index arrays are dynamically
           created for mipmap level,   and then cached.
           */
     129   virtual void getRenderOperation(  RenderOperation& rend );
          
     131   virtual const MaterialPtr& getMaterial(  void ) const
           {
           return mMaterial;
           };
          
     136   virtual void getWorldTransforms(  Matrix4* xform ) const;
          
     138   virtual const Quaternion& getWorldOrientation(  void ) const;
     139   virtual const Vector3& getWorldPosition(  void ) const;
          
           /** @copydoc Renderable::getLights */
     142   const LightList& getLights(  void ) const;
          
     144   virtual Technique* getTechnique(  void ) const;
          
     146   virtual Real getSquaredViewDepth(  const Camera* cam ) const;
          
           /** Overridden from MovableObject */
     149   Real getBoundingRadius(  void ) const { return mBoundingRadius; }
          
           /// Overridden from Renderable to allow the morph LOD entry to be set
     152   void _updateCustomGpuParameter(  const GpuProgramParameters::AutoConstantEntry& constantEntry,   GpuProgramParameters* params ) const;
          
     154   void setMaxLod (  const bool setmaxlod ) {mForcedMaxLod = setmaxlod;};
          
           /// @see MovableObject
     157   uint32 getTypeFlags(  void ) const;
          
           /** Internal method called to notify the object that it has been attached to a node.
           */
     161   virtual void _notifyAttached(  Node* parent,   bool isTagPoint = false );
          
     163   bool isInUse(   ) const {return mInUse;};
          
     165   IndexData* getRawIndexData(  const int renderlevel );
     166   void getRawVertexData(  Vector3* pVerts );
     167   const unsigned int getVertexCount(   );
          
     169   bool mQueued;
     170   PagingLandScapeTile *mParentTile;
          
          
           protected:
          
     175   VertexData* mCurrVertexes;
     176   IndexData* mCurrIndexes;
          
           /// Bounding box of this tile
     179   AxisAlignedBox mBounds;
           /// The center point of this tile
     181   Vector3 mCenter;
           /// The MovableObject type
     183   static String mType;
           /// Current material used by this tile
     185   MaterialPtr mMaterial;
          
           /// Connection to tiles four neighbors
           PagingLandScapeRenderable* mNeighbors [ 4 ];
          
     190   IndexData*mIndex;
           unsigned int mNumIndex;
          
     193   bool mInUse;
     194   bool mIsLoaded;
     195   bool mNeedReload;
          
     197   ushort mMaterialLODIndex;
          
           // for loading
     200   PagingLandScapeTileInfo* mInfo;
          
           // Morph
           /** Returns the vertex coord for the given coordinates */
     204   inline Real _vertex(  const int x,   const int z,   const int n ) const;
     205   Real* mHeightfield;
           /// The previous 'next' LOD level down,   for frame coherency
           int mLastNextLevel;
           /// The morph factor between this and the next LOD level down
     209   Real mLODMorphFactor;
          
           /// List of squared distances at which LODs change
     212   std::vector<Real>* mMinLevelDistSqr;
          
           /// Optional set of delta buffers,   used to morph from one LOD to the next
     215   HardwareVertexBufferSharedPtr* mDeltaBuffers;
          
           /// Array of LOD indexes specifying which LOD is the next one down
           /// (  deals with clustered error metrics which cause LODs to be skipped )
           int mNextLevelDown[10];
          
           // distance between center renderable and camera.
     222   Real mDistanceToCam;
          
     224   void fillNextLevelDown(   );
     225   void _calculateMinLevelDist2(  const Real C );
           /// Create a blank delta buffer for use in morphing
     227   HardwareVertexBufferSharedPtr createDeltaBuffer(  void ) const;
          
           // did LOD level changes this frame
     230   bool mChangedRenderLevel;
          
     232   Vector3 _getvertex(  const int x,   const int z ) const;
          
     234   PagingLandScapeRenderableManager *mParent;
          
           /// The bounding radius of this renderable
     237   Real mBoundingRadius;
           private :
          
          
     241   Image::Box mRect;
     242   bool mIsRectModified;
     243   bool mForcedMaxLod;
     244   Vector4 mCustomGpuParameters;
          
           /// Whether light list need to re-calculate
           mutable bool mLightListDirty;
           /// Cached light list
           mutable LightList mLightList;
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeRenderableManager.h

       1  /***************************************************************************
          OgrePagingLandScapeRenderableManager.h - description
          -------------------
          begin : Mon Jun 16 2003
          copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
          email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeRENDERABLEMANAGER_H
          #define PAGINGLandScapeRENDERABLEMANAGER_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeQueue.h"
          #include "OgrePagingLandScapeIndexBuffer.h"
          
          #include "OgrePagingLandScapeTileInfo.h"
          
          #include "OgrePagingLandScapePoolSet.h"
          
          namespace Ogre
          {
          
          
          
           /** Class to manage A collection of pre-allocated PagingLandScapeRenderable
           */
      36   class PagingLandScapeRenderableSet : public PoolSet<PagingLandScapeRenderable>
           {
           public:
          
      40   PagingLandScapeRenderableSet(   );
      41   void setRenderableManager (  PagingLandScapeRenderableManager *rMgr )
           {
           mRenderableManager = rMgr;
           }
           protected:
          
      47   PagingLandScapeRenderable* allocate (   );
      48   void deallocate (  PagingLandScapeRenderable *r );
          
          
           private:
      52   PagingLandScapeRenderableManager *mRenderableManager;
          
           };
           /** Class to manage the PagingLandScapeRenderables (  Pool and Loading Queue )
           @remarks
           This class is used as a store of PagingLandScapeRenderables and the are reference and dereference in order to not being created and
           destroyed every time the plug-in need to change the LOD.
           */
      60   class PagingLandScapeRenderableManager
           {
           public:
           /** Initializes the PagingLandScapeRenderableManager with the
           * given options and allocate the necessary memory.
           */
      66   PagingLandScapeRenderableManager (  PagingLandScapeSceneManager * scnMgr );
          
      68   virtual ~PagingLandScapeRenderableManager(  void );
          
           /** Retrieve a free renderable.
           */
      72   PagingLandScapeRenderable* getRenderable(  void );
          
           /** Make a renderable free.
           */
      76   void freeRenderable(  PagingLandScapeRenderable* rend );
          
           /** Set this renderable to be loaded
           */
      80   void queueRenderableLoading(  PagingLandScapeTile* tile );
          
           /** Set this renderable to be unloaded
           */
      84   void unqueueRenderable(  PagingLandScapeTile* tile );
          
           /** Load a set of renderables
           */
      88   bool executeRenderableLoading(  const Vector3 &Cameraposition );
          
      90   size_t numRenderables(  void ) const;
      91   size_t numFree(  void ) const;
      92   size_t numLoading(  void ) const;
          
      94   void InitTextureCoordinatesBuffers(  void );
      95   void freeTextureCoordinatesBuffers(  void );
      96   HardwareVertexBufferSharedPtr getTextureCoordinatesBuffers(  const unsigned int tilex,   const unsigned int tilez );
      97   void setTextureCoordinatesBuffers(  const unsigned int tilex,   const unsigned int tilez,   const HardwareVertexBufferSharedPtr& data );
          
      99   unsigned int numVisibles(  void ) const
           {
           return mLastRenderablesVisibles;
           };
     103   void resetVisibles(  void )
           {
           mLastRenderablesVisibles = mRenderablesVisibles;
           mRenderablesVisibles = 0;
           };
     108   void addVisible(  void )
           {
           mRenderablesVisibles++;
           };
          
          
     114   void load(  void );
     115   void clear(  void );
          
           /// unload some Tiles/renderables if no more in use
     118   void processTileUnload(   );
          
     120   inline PagingLandScapeOptions* getOptions(   ){return mOptions;}
     121   inline PagingLandScapeSceneManager* getSceneManager(   ){return mSceneManager;}
           protected:
          
     124   PagingLandScapeOptions* mOptions;
     125   PagingLandScapeSceneManager *mSceneManager;
          
          
     128   void _addBatch(  const unsigned int num );
          
          
           ///Keep a set of pre-allocated PagingLandscapeRenderables.
     132   PagingLandScapeRenderableSet mRenderablePool;
          
           /** Queue to batch the process of loading the Renderables.
           This avoid the plug-in to load a lot of renderables in a single Frame,  
           dropping the FPS.
           */
     138   PagingLandScapeQueue< PagingLandScapeTile > mTilesLoadRenderableQueue;
          
           unsigned int mRenderablesVisibles;
           unsigned int mLastRenderablesVisibles;
           unsigned int mNumRenderablesIncrement;
           unsigned int mNumRenderableLoading;
          
           unsigned int mRenderableLoadInterval;
           int mLoadInterval;
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeSceneManager.h

          /***************************************************************************
           OgrePagingLandScapeSceneManager.h - description
           -------------------
           begin : Mon May 12 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeSCENEMANAGER_H
          #define PAGINGLandScapeSCENEMANAGER_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "OgreStringVector.h"
          
          #include "OgrePagingLandScapeData2DManager.h"
          
          namespace Ogre
          {
          
           /// Factory for OctreeSceneManager
      32   class PagingLandScapeSceneManagerFactory : public SceneManagerFactory
           {
           protected:
      35   void initMetaData(  void ) const;
           public:
      37   PagingLandScapeSceneManagerFactory(   ) {}
      38   ~PagingLandScapeSceneManagerFactory(   ) {}
           /// Factory type name
      40   static const String FACTORY_TYPE_NAME;
      41   SceneManager* createInstance(  const String& instanceName );
      42   void destroyInstance(  SceneManager* instance );
           };
          
          
          
           /** This is a basic SceneManager for organizing PagingLandScapeRenderables into a total LandScape.
           It loads a LandScape from a .cfg file that specifies what textures/scale/mipmaps/etc to use.
           */
      50   class PagingLandScapeSceneManager : public PagingLandScapeOctreeSceneManager
           {
      52   friend class PagingLandScapeRaySceneQuery;
           public:
      54   PagingLandScapeSceneManager(  const String &name );
      55   ~PagingLandScapeSceneManager(  void );
          
      57   void shutdown(   );
           /// @copydoc SceneManager::getTypeName
      59   const String& getTypeName(  void ) const;
          
           /** Creates a specialized Camera */
      62   virtual Camera * createCamera(  const String &name );
      63   virtual void destroyCamera(  Camera *cam );
      64   virtual void destroyCamera(  const String& name );
      65   virtual void destroyAllCameras(  void );
          
           /** Sets the source of the 'world' geometry,   i.e. the large,   mainly static geometry
           making up the world e.g. rooms,   LandScape etc.
           @remarks
           Depending on the type of SceneManager (  subclasses will be specialised
           for particular world geometry types ) you have requested via the Root or
           SceneManagerEnumerator classes,   you can pass a filename to this method and it
           will attempt to load the world-level geometry for use. If you try to load
           an inappropriate type of world data an exception will be thrown. The default
           SceneManager cannot handle any sort of world geometry and so will always
           throw an exception. However subclasses like BspSceneManager can load
           particular types of world geometry e.g. "q3dm1.bsp".
           */
      79   virtual void setWorldGeometry(  const String& filename );
          
           /** Sets the source of the 'world' geometry,   i.e. the large,   mainly
           static geometry making up the world e.g. rooms,   LandScape etc.
           @remarks
           Depending on the type of SceneManager (  subclasses will be
           specialised for particular world geometry types ) you have
           requested via the Root or SceneManagerEnumerator classes,   you
           can pass a stream to this method and it will attempt to load
           the world-level geometry for use. If the manager can only
           handle one input format the typeName parameter is not required.
           The stream passed will be read (  and it's state updated ).
           @param stream Data stream containing data to load
           @param typeName String identifying the type of world geometry
           contained in the stream - not required if this manager only
           supports one type of world geometry.
           */
      96   virtual void setWorldGeometry(  DataStreamPtr& stream,  
           const String& typeName = StringUtil::BLANK );
          
          
           /** Things that need to be allocated once
           */
     102   void InitScene(  void );
          
           /** Empties the entire scene,   including all SceneNodes,   Cameras,   Entities and Lights etc.
           */
     106   void clearScene(  void );
          
           /** Empties only the Terrain Scene pages,   tiles,   textures and so on
           */
     110   void resetScene(  void );
          
           /** Loads the LandScape using current parameters
           */
     114   void loadScene(  void );
          
           /** Method for setting a specific option of the Scene Manager. These options are usually
           specific for a certain implementation of the Scene Manager class,   and may (  and probably
           will ) not exist across different implementations.
           @param
           strKey The name of the option to set
           @param
           pValue A pointer to the value - the size should be calculated by the scene manager
           based on the key
           @return
           On success,   true is returned.
           @par
           On failure,   false is returned.
           */
     129   bool setOption(  const String& strKey,   const void* pValue );
          
           /** Method for getting the value of an implementation-specific Scene Manager option.
           @param
           strKey The name of the option
           @param
           pDestValue A pointer to a memory location where the value will
           be copied. Currently,   the memory will be allocated by the
           scene manager,   but this may change
           @return
           On success,   true is returned and pDestValue points to the value of the given
           option.
           @par
           On failiure,   false is returned and pDestValue is set to NULL.
           */
     144   bool getOption(  const String& strKey,   void* pDestValue );
          
           /** Method for verifying wether the scene manager has an implementation-specific
           option.
           @param
           strKey The name of the option to check for.
           @return
           If the scene manager contains the given option,   true is returned.
           @remarks
           If it does not,   false is returned.
           */
     155   bool hasOption(  const String& strKey ) const;
          
           /** Method for getting all possible values for a specific option. When this list is too large
           (  i.e. the option expects,   for example,   aOgre::Real ),   the return value will be true,   but the
           list will contain just one element whose size will be set to 0.
           Otherwise,   the list will be filled with all the possible values the option can
           accept.
           @param
           strKey The name of the option to get the values for.
           @param
           refValueList A reference to a list that will be filled with the available values.
           @return
           On success (  the option exists ),   true is returned.
           @par
           On failiure,   false is returned.
           */
     171   bool getOptionValues(  const String& key,   StringVector& refValueList );
          
           /** Method for getting all the implementation-specific options of the scene manager.
           @param
           refKeys A reference to a list that will be filled with all the available options.
           @return
           On success,   true is returned.
           On failiure,   false is returned.
           */
     180   bool getOptionKeys(  StringVector &refKeys );
          
           /** Internal method for updating the scene graph ie the tree of SceneNode instances managed by this class.
           @remarks
           This must be done before issuing objects to the rendering pipeline,   since derived transformations from
           parent nodes are not updated until required. This SceneManager is a basic implementation which simply
           updates all nodes from the root. This ensures the scene is up to date but requires all the nodes
           to be updated even if they are not visible. Subclasses could trim this such that only potentially visible
           nodes are updated.
           */
     190   void _updateSceneGraph(  Camera* cam );
          
           /** Sends visible objects found in _findVisibleObjects to the rendering engine.
           */
           //void _renderVisibleObjects(  void );
          
           /** Internal method which parses the scene to find visible objects to render.
           @remarks
           If you're implementing a custom scene manager,   this is the most important method to
           override since it's here you can apply your custom world partitioning scheme. Once you
           have added the appropriate objects to the render queue,   you can let the default
           SceneManager objects _renderVisibleObjects handle the actual rendering of the objects
           you pick.
           @par
           Any visible objects will be added to a rendering queue,   which is indexed by material in order
           to ensure objects with the same material are rendered together to minimise render state changes.
           */
           //void _findVisibleObjects(  Camera * cam,   bool onlyShadowCasters );
          
           /** Creates an AxisAlignedBoxSceneQuery for this scene manager.
           @remarks
           This method creates a new instance of a query object for this scene manager,  
           for an axis aligned box region. See SceneQuery and AxisAlignedBoxSceneQuery
           for full details.
           Currently this only supports custom geometry results. It ignores the y
           coords of the AABB.
           @par
           The instance returned from this method must be destroyed by calling
           SceneManager::destroyQuery when it is no longer required.
           @param box Details of the box which describes the region for this query.
           @param mask The query mask to apply to this query; can be used to filter out
           certain objects; see SceneQuery for details.
           */
     223   AxisAlignedBoxSceneQuery* createAABBQuery(  const AxisAlignedBox& box,   unsigned long mask = 0xFFFFFFFF );
          
          
           /** Creates a RaySceneQuery for this scene manager.
           @remarks
           This method creates a new instance of a query object for this scene manager,  
           looking for objects which fall along a ray. See SceneQuery and RaySceneQuery
           for full details.
           @par
           The instance returned from this method must be destroyed by calling
           SceneManager::destroyQuery when it is no longer required.
           @param ray Details of the ray which describes the region for this query.
           @param mask The query mask to apply to this query; can be used to filter out
           certain objects; see SceneQuery for details.
           */
     238   RaySceneQuery* createRayQuery(  const Ray& ray,   unsigned long mask = 0xFFFFFFFF );
          
           /** Creates an IntersectionSceneQuery for this scene manager.
           @remarks
           This method creates a new instance of a query object for locating
           intersecting objects. See SceneQuery and IntersectionSceneQuery
           for full details.
           @par
           The instance returned from this method must be destroyed by calling
           SceneManager::destroyQuery when it is no longer required.
           @param mask The query mask to apply to this query; can be used to filter out
           certain objects; see SceneQuery for details.
           */
           //IntersectionSceneQuery* createIntersectionQuery(  unsigned long mask );
          
           /** intersectSegment
           @remarks
           Intersect mainly with LandScape
           @param start
           begining of the segment
           @param end
           where it ends
           @param result
           where it intersects with terrain
           */
     263   bool intersectSegment(  const Ogre::Vector3& start,   const Ogre::Vector3& end,   Ogre::Vector3* result );
          
           /** intersectSegment
           @remarks
           Intersect mainly with LandScape
           @param start
           begining of the segment
           @param dir
           direction of the ray
           @param result
           where it intersects with terrain
           */
     275   bool intersectSegmentTerrain(  const Ogre::Vector3& begin,   const Ogre::Vector3& dir,   Ogre::Vector3* result );
           /** load
           * @remarks load heights only LandScape,   need brush and brush scale to be set before
           * @param &impact where load take place,   where BrushArray is centered
           */
     280   void setHeight (  const Ogre::Vector3 &impact );
           /** deform
           * @remarks deform only LandScape,   need brush and brush scale to be set before
           * @param &impact where deformation take place,   where BrushArray is centered
           */
     285   void deformHeight(  const Ogre::Vector3& impact );
           /** paint
           * @remarks paint only LandScape,   need channel,   brush and brush scale to be set before
           * @param impact where painting take place
           * @param isAlpha if we want to paint alpha or color
           */
     291   void paint (  const Ogre::Vector3 &impact );
           /** getAreaHeight
           * @remarks used to fill user allocated array with values.
           * @param impact where array is centered
           */
     296   void getAreaHeight(  const Ogre::Vector3& impact );
          
           /** renderBaseTextures(   )
           * @remarks Performs render to texture for all pages to create base textures from
           * splatting shader. If alternate material is specified,   will use it instead of
           * the actual material assigned to the page. This is necessary when terrain is lit
           * and/or compressed.
           */
     304   void renderBaseTextures(  const String& alternateMatName );
          
           /** Overridden from SceneManager */
     307   void setWorldGeometryRenderQueue(  uint8 qid );
          
     309   void PagingLandScapeOctreeResize(  void );
          
     311   void WorldDimensionChange(  void );
          
           //-----------------------------------------------------------------------
           inline Ogre::Real _OgrePagingLandScapeExport getHeightAt(  const Ogre::Real x,   const Ogre::Real z )
           {
           return mData2DManager->getInterpolatedWorldHeight(  x,   z );
           }
           //-----------------------------------------------------------------------
           inline Ogre::Real _OgrePagingLandScapeExport getSlopeAt(  const Ogre::Real x,   const Ogre::Real z )
           {
           Ogre::Real slope;
           // return mData2DManager->getRealWorldSlope(  x,   z );
     323   mData2DManager->getInterpolatedWorldHeight(  x,   z,   &slope );
           return slope;
           }
          
     327   _OgrePagingLandScapeExport void getWorldSize(  Real *worldSizeX,  Ogre::Real *worldSizeZ );
     328   _OgrePagingLandScapeExport float getMaxSlope(  Vector3 location1,   Ogre::Vector3 location2,   float maxSlopeIn );
          
     330   inline PagingLandScapeOptions * getOptions(   )
           {
           assert(  mOptions );
           return mOptions;
           }
          
     336   inline PagingLandScapeHorizon * getHorizon(   )
           {
           assert(  mHorizon );
           return mHorizon;
           }
     341   inline PagingLandScapeTileManager * getTileManager(   )
           {
           assert(  mTileManager );
           return mTileManager;
           }
     346   inline PagingLandScapePageManager * getPageManager(   )
           {
           assert(  mPageManager );
           return mPageManager;
           }
     351   inline PagingLandScapeData2DManager * getData2DManager(   )
           {
           assert(  mData2DManager );
           return mData2DManager;
           }
     356   inline PagingLandScapeListenerManager * getListenerManager(   )
           {
           assert(  mListenerManager );
           return mListenerManager;
           }
     361   inline PagingLandScapeTextureManager * getTextureManager(   )
           {
           assert(  mTextureManager );
           return mTextureManager;
           }
     366   inline PagingLandScapeIndexBufferManager * getIndexesManager(   )
           {
           assert(  mIndexesManager );
           return mIndexesManager;
           }
     371   inline PagingLandScapeRenderableManager * getRenderableManager(   )
           {
           assert(  mRenderableManager );
           return mRenderableManager;
           }
     376   inline PagingLandScapeTextureCoordinatesManager* getTextureCoordinatesManager(   )
           {
           assert(  mTexCoordManager );
           return mTexCoordManager;
           }
     381   inline PagingLandScapeIndexBufferManager* getIndexBufferManager(   )
           {
           assert(  mIndexesManager );
           return mIndexesManager;
           }
          
          
           protected:
          // EntityList& getEntities(  void )
          // {
          // return mEntities;
          // }
          
           /** All the plugin options are handle here.
           */
           PagingLandScapeOptions* mOptions;
          
           /** LandScape 2D Data manager.
           This class encapsulate the 2d data loading and unloading
           */
           PagingLandScapeData2DManager* mData2DManager;
          
           /** LandScape Texture manager.
           This class encapsulate the texture loading and unloading
           */
           PagingLandScapeTextureManager* mTextureManager;
          
           /** LandScape tiles manager to avoid creating a deleting terrain tiles.
           They are created at the plugin start and destroyed at the plugin unload.
           */
           PagingLandScapeTileManager* mTileManager;
          
           /** LandScape Renderable manager to avoid creating a deleting renderables.
           They are created at the plugin start and destroyed at the plug in unload.
           */
           PagingLandScapeRenderableManager* mRenderableManager;
           /** LandScape pages Index Buffer sharing across pages for the terrain.
           */
           PagingLandScapeIndexBufferManager* mIndexesManager;
           /** LandScape pages texture coordinates sharing across pages for the terrain.
           */
           PagingLandScapeTextureCoordinatesManager* mTexCoordManager;
           /** LandScape pages for the terrain.
           */
           PagingLandScapePageManager* mPageManager;
          
           /** Horizon visibility testing.
           */
           PagingLandScapeHorizon* mHorizon;
          
           /** Dispatch scene manager events.
           */
           PagingLandScapeListenerManager* mListenerManager;
          
           bool mNeedOptionsUpdate;
          
           //JEFF - flag to indicate if the world geometry was setup
           bool mWorldGeomIsSetup;
           bool mWorldGeomIsInit;
          
           PagingLandScapeTileInfo* mImpactInfo;
           Ogre::Vector3 mImpact;
           Ogre::Vector3 mBrushCenter;
           unsigned int mBrushSize;
           Ogre::Real mBrushScale;
          
           Ogre::Real* mCraterArray;
           Ogre::Real* mBrushArray;
          
           unsigned int mBrushArrayHeight;
           unsigned int mBrushArrayWidth;
          
           bool textureFormatChanged;
          
           MovableObjectFactory* mMeshDecalFactory;
          
           // re-create the default Crater brush.
           void resizeCrater (   );
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture.h

       1  /***************************************************************************
           OgrePagingLandScapeTexture.h - description
           -------------------
           begin : Fri Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE_H
          #define PAGINGLandScapeTEXTURE_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
          # define SAND 0
          # define GRASS 1
          # define ROCK 2
          # define SNOW 3
          
           /**
           * A simple class for encapsulating Texture generation.
           */
      34   class PagingLandScapeTexture
           {
           public:
      37   PagingLandScapeTexture(  PagingLandScapeTextureManager *pageMgr,  
      38   const String materialName,  
           const unsigned int numTexture = 0,  
      40   bool isSplatMode = false );
          
           // Method that must be overridden
      43   virtual String getName (  void ) const {return mMaterialBaseName;};
      44   virtual PagingLandScapeTexture *newTexture(   )
           {
           return new PagingLandScapeTexture(  mParent,   mMaterialBaseName );
           };
          
           // Method that can be overridden
      50   virtual ~PagingLandScapeTexture(  void );
          
      52   virtual void bindCompressionSettings(  GpuProgramParametersSharedPtr params );
      53   virtual void bindCompressionSettings(   );
          
      55   virtual void load(  unsigned int mX,   unsigned int mZ );
      56   virtual void update(  void );
      57   virtual void unload(  void );
          
      59   virtual bool isMaterialSupported(  bool recursive = true );
      60   virtual void setOptions(  void );
          
          
      63   virtual const unsigned int getNumChannels (  void ) const
           {
           return mNumTexture;
           };
      67   virtual const unsigned int getNumChannelsperTexture (  const size_t i ) const
           {
           return static_cast<unsigned int>(  mNumChannelperTexture[i] );
           };
          
           // Real Method
      73   bool getCastsShadows(  void ) const {return false;}
          
      75   bool isLoaded(  void ) const;
          
      77   void setNeedUpdate(  void );
      78   void updated(  void );
      79   bool needUpdate(  void ) const;
          
      81   const MaterialPtr& getMaterial(  void ) const;
          
      83   void paint (  const unsigned int x,  
           const unsigned int z,  
      85   const Real paintForce );
          
          
      88   void adjustDeformationRectangle(  unsigned int x,   unsigned int z );
      89   void adjustPaintRectangle(  unsigned int x,   unsigned int z );
          
      91   virtual void lightUpdate(   );
          
      93   void getCoordinates(  unsigned int& X,   unsigned int& Z )
           {
           X = mDataX;
           Z = mDataZ;
           };
      98   inline bool isCoord(  const unsigned int x,   const unsigned int z )
           {
           return (  mDataX == x && mDataZ == z );
           };
          
     103   const String &getMaterialName(   );
          
           protected:
          
     107   void compute(  PagingLandScapeData2D* data,  
     108   const Image::Box& dataRect,  
     109   const Image::Box& textureRect );
          
          
     112   void computePointAlpha(  const unsigned int imagePos,  
     113   const Real height,  
     114   const Real slope ) ;
          
     116   void computePointColor(  const unsigned int imagePos,  
     117   const Real height,  
     118   const Real slope ) ;
          
     120   void paintPoint (  const unsigned int imagePos,  
     121   const Real paintForce );
          
     123   void upload(  const Image::Box& textureRect );
          
     125   void setNumTexture(   );
          
           // Method that can be overridden
     128   virtual void _loadMaterial(  void );
           // Method that can be overridden
     130   virtual void _unloadMaterial(  void );
           // Method that can be overridden
     132   virtual void _save(  void );
          
          
          
           // properties that can be accessed from children
          
     138   bool mIsSplatMode;
     139   bool mIsBaseMode;
          
          
     142   bool mIsLoaded;
     143   bool mIsModified;
           //! Pointer to ogre material
     145   MaterialPtr mMaterial;
           //! what page it correspond to
           unsigned int mDataX,   mDataZ;
          
     149   Image::Box mPaintRect;
     150   bool mIsPaintRectModified;
     151   Image::Box mDeformRect;
     152   bool mIsDeformRectModified;
     153   PagingLandScapeTextureManager *mParent;
          
           // Edit,   deform and update
           unsigned int mNumTexture;
     157   std::vector<unsigned int> mNumChannelperTexture;
     158   std::vector<Image> mImages;
     159   std::vector<TexturePtr> mTextures;
     160   std::vector<HardwarePixelBufferSharedPtr> mBuffers;
     161   std::vector<bool> doTextureNeedUpdate;
     162   std::vector<bool> isTextureModified;
          
           // special case alpha loading Image as A8 only.
     165   void loadAlphaTexture(  const String& filename,   const unsigned int channel );
           // loading Image,   buffer and texture in channels
     167   void loadColorTexture(  const String& TexName,   const unsigned int channel );
           // loading Image,   buffer and texture.
     169   void loadTexture(  const String &filename,   Image &img );
           // Dynamic Lighting
     171   void computeLightMap (   ) const;
     172   Image mShadow;
     173   Image mLightImage;
     174   TexturePtr mLightTexture;
     175   HardwarePixelBufferSharedPtr mLightBuffer;
     176   bool mPositiveShadow;
     177   bool mIsShaderShadowed;
     178   bool mIsShadowed;
          
           // Name that helps building textures names on each page
     181   String mMaterialBaseName;
          
           private :
     184   void loadTexturesToModify(   );
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTextureCoordinatesManager.h

       1  /***************************************************************************
          OgrePagingLandScapeRenderableManager.h - description
          -------------------
          begin : Mon Jun 16 2003
          copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
          email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTextureCoordinatesMANAGER_H
          #define PAGINGLandScapeTextureCoordinatesMANAGER_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
           /** Class to manage the creation,   destruction and use of PagingLandScapeRenderables.
           @remarks
           This class is used as a store of PagingLandScapeTexturecoordinatesBuffer shared between Page
           */
      29   class PagingLandScapeTextureCoordinatesManager
           {
           public:
           /** Initializes the PagingLandScapeTextureCoordinatesManager with the
           * given options and allocate the necessary memory.
           */
      35   PagingLandScapeTextureCoordinatesManager(  PagingLandScapeSceneManager * scnMgr );
      36   virtual ~PagingLandScapeTextureCoordinatesManager(  void );
      37   void load(  void );
      38   void clear(  void );
          
      40   HardwareVertexBufferSharedPtr getBuffer(  const unsigned int tilex,   const unsigned int tilez );
          
      42   PagingLandScapeOptions* getOptions(   ){return mOptions;}
           protected:
          
      45   PagingLandScapeOptions* mOptions;
          
           unsigned int mPageSize;
           unsigned int mTileSize;
          
      50   HardwareTextureBuffersCol mTexBuffs;
           };
          
          }
          
          #endif //PAGINGLandScapeTextureCoordinatesMANAGER_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTextureManager.h

       1  /***************************************************************************
           OgrePagingLandScapeTextureManager.h - description
           -------------------
           begin : Fri Apr 16 2004
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTUREMANAGER_H
          #define PAGINGLandScapeTEXTUREMANAGER_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
      26   class PagingLandScapeTextureManager
           {
           public:
          
      30   PagingLandScapeTextureManager(  PagingLandScapeSceneManager * scnMgr );
          
      32   virtual ~PagingLandScapeTextureManager(  void );
          
      34   void load(  void );
      35   void clear(  void );
      36   void WorldDimensionChange(  void );
      37   PagingLandScapeTexture* allocateTexture(   ) const;
      38   void reset(  void );
          
      40   void load(  const unsigned int texX,   const unsigned int texZ );
      41   void reload(  const unsigned int dataX,   const unsigned int dataZ );
      42   void unload(  const unsigned int texX,   const unsigned int texZ );
          
      44   bool isLoaded(  const unsigned int texX,   const unsigned int texZ );
          
          
      47   const MaterialPtr& getMaterial(  const unsigned int texX,   const unsigned int texZ );
          
          
      50   MaterialPtr getMapMaterial(  void );
      51   void setMapMaterial(  void );
          
      53   void setPaintChannelValues (  const std::vector<Real> *theChannelModifList )
           {
           channelModifList = theChannelModifList;
           };
      57   void paint (  const Vector3 &currpoint,  
      58   const Real paintForce,  
      59   const PagingLandScapeTileInfo *info );
          
      61   void deformHeight (  const Vector3 &currpoint,  
      62   const PagingLandScapeTileInfo *info );
          
      64   String getNextTextureFormat(   );
      65   String getCurrentTextureFormat(   );
          
      67   void registerTextureFormats(   );
      68   void clearTextureFormats (   );
      69   void registerTextureType(  PagingLandScapeTexture* source )
           {
           mTextureTypeMap.push_back(  source );
           }
          
      74   PagingLandScapeTexture* getTexture(  const unsigned int i,   const unsigned int j,  
      75   const bool alwaysReturn = true );
      76   PagingLandScapeTexture* getNewTexture(  const unsigned int i,   const unsigned int j );
      77   void releaseTexture (  PagingLandScapeTexture*p  );
          
      79   unsigned int getNumChannels(   );
      80   unsigned int getNumChannelsperTexture(  const size_t i );
          
          
      83   inline PagingLandScapeSceneManager *getSceneManager(   ){return mSceneManager;}
      84   inline PagingLandScapeOptions* getOptions(   ){return mOptions;}
          
          
           unsigned int mPageSize;
      88   Image mImage;
      89   std::vector<Real> heights;
      90   std::vector<Real> dividers;
      91   std::vector<ColourValue> colors;
          
      93   const std::vector<Real> *channelModifList;
           protected:
          
           // Common var for all textures
      97   void setPageSize(   );
      98   void clearData (   );
          
           //
          
     102   PagingLandScapeSceneManager *mSceneManager;
     103   PagingLandScapeOptions* mOptions;
          
          
           unsigned int mTextureType;
     107   String mTextureFormat;
          
           unsigned int mWidth;
           unsigned int mHeight;
          
           unsigned int mTexturePageSize;
          
           //PagingLandScapeTexturePages mTexture;
          
     116   MaterialPtr mMapMaterial;
          
           unsigned int mPaintChannel;
     119   ColourValue mPaintColor;
          
          
          
     123   PagingLandScapeTextureMap mTextureTypeMap;
           /// The currently active page Data2d source
     125   PagingLandScapeTexture* mActiveTextureType;
          
     127   PagingLandScapeTextureList mActiveTextures;
     128   PagingLandScapeTextureList mFreeTextures;
     129   PagingLandScapeTextureArray mTexturePool;
           };
          
          } //namespace
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_BaseTexture.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_BaseTexture.h - description
           -------------------
           begin : Mon Apr 26 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE_BASETEXTURE_H
          #define PAGINGLandScapeTEXTURE_BASETEXTURE_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_BaseTexture : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_BaseTexture(  PagingLandScapeTextureManager *textureMgr );
      29   String getName(   ) const{return String(  "BaseTexture" );}
      30   void setOptions(  void );
      31   ~PagingLandScapeTexture_BaseTexture(  void );
          
      33   PagingLandScapeTexture* newTexture(   );
      34   bool isMaterialSupported(   );
          
           protected:
      37   void _loadMaterial(  void );
          
           private:
      40   Image BaseImage;
      41   uchar *_BuildBaseTexture(   ) const;
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_BaseTexture2.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_BaseTexture2.h - description
           -------------------
           begin : Mon Apr 26 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeTexture_BaseTexture2_H
          #define PagingLandScapeTexture_BaseTexture2_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_BaseTexture2 : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_BaseTexture2(  PagingLandScapeTextureManager *textureMgr );
      29   String getName(   ) const{return String(  "BaseTexture2" );}
      30   void setOptions(  void );
      31   ~PagingLandScapeTexture_BaseTexture2(  void );
          
      33   PagingLandScapeTexture* newTexture(   );
      34   bool isMaterialSupported(   );
          
           };
          }
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Image.h

       1  /***************************************************************************
           OgrePagingLandScapeTexture_Image.h - description
           -------------------
           begin : Fri Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE_IMAGE_H
          #define PAGINGLandScapeTEXTURE_IMAGE_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_Image : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_Image(  PagingLandScapeTextureManager *textureMgr );
      29   ~PagingLandScapeTexture_Image(  void );
          
      31   String getName(   ) const
           {
           return String(  "ImagePaging" );
           }
          
      36   PagingLandScapeTexture* newTexture(   );
      37   bool isMaterialSupported(   );
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_InstantBaseTexture.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_InstantBaseTexture.h - description
           -------------------
           begin : Mon Apr 26 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeTexture_InstantBaseTexture_H
          #define PagingLandScapeTexture_InstantBaseTexture_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
      26   class PagingLandScapeTexture_InstantBaseTexture : public PagingLandScapeTexture
           {
           public:
          
      30   PagingLandScapeTexture_InstantBaseTexture(  PagingLandScapeTextureManager *textureMgr );
      31   ~PagingLandScapeTexture_InstantBaseTexture(  void );
          
      33   String getName(   ) const{return String(  "InstantBaseTexture" );}
          
          
      36   void paint (  const unsigned int x,   const unsigned int z,  
      37   const Real paintForce,   const ColourValue &mPaintColor );
          
      39   PagingLandScapeTexture* newTexture(   );
      40   bool isMaterialSupported(   );
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_InstantBaseTextureEdit.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_InstantBaseTextureEdit.h - description
           -------------------
           begin : Mon Apr 26 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeTexture_InstantBaseTextureEdit_H
          #define PagingLandScapeTexture_InstantBaseTextureEdit_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
          
      27   class PagingLandScapeTexture_InstantBaseTextureEdit : public PagingLandScapeTexture
           {
           public:
          
      31   PagingLandScapeTexture_InstantBaseTextureEdit(  PagingLandScapeTextureManager *textureMgr );
      32   virtual ~PagingLandScapeTexture_InstantBaseTextureEdit(  void );
          
      34   virtual String getName(   ) const{return String(  "InstantBaseTextureEdit" );}
          
      36   virtual PagingLandScapeTexture* newTexture(   );
      37   virtual bool isMaterialSupported(   );
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_InstantBaseTextureShadowed.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_InstantBaseTexture.h - description
           -------------------
           begin : Mon Apr 26 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeTexture_InstantBaseTextureShadowed_H
          #define PagingLandScapeTexture_InstantBaseTextureShadowed_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
          
      26   class PagingLandScapeTexture_InstantBaseTextureShadowed : public PagingLandScapeTexture
           {
           public:
          
      30   PagingLandScapeTexture_InstantBaseTextureShadowed(  PagingLandScapeTextureManager *textureMgr );
      31   ~PagingLandScapeTexture_InstantBaseTextureShadowed(  void );
          
      33   String getName(   ) const{return String(  "InstantBaseTextureShadowed" );}
          
      35   void paint (  const unsigned int x,   const unsigned int z,  
      36   const Real paintForce,   const ColourValue &mPaintColor );
          
          
      39   PagingLandScapeTexture* newTexture(   );
      40   bool isMaterialSupported(   );
          
           protected:
      43   void _loadMaterial(  void );
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_None.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_SplattingShader.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2005 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE_NONE_H
          #define PAGINGLandScapeTEXTURE_NONE_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeTexture.h"
          
          namespace Ogre
          {
          
      27   class PagingLandScapeTexture_None : public PagingLandScapeTexture
           {
           public:
      30   PagingLandScapeTexture_None(  PagingLandScapeTextureManager *textureMgr ) :
           PagingLandScapeTexture(  textureMgr,   "None",   0,   false )
           {
           mIsLoaded = true;
           mIsModified = false;
           };
      36   ~PagingLandScapeTexture_None(  void )
           {
           };
          
      40   String getName(   ) const
           {
           return String(  "None" );
           }
      44   PagingLandScapeTexture* newTexture(   )
           {
           return new PagingLandScapeTexture_None(  mParent );
           };
      48   void load(  uint mX,   uint mZ )
           {
           mDataX = mX;
           mDataZ = mZ;
           mIsLoaded = true;
           mIsModified = false;
           };
      55   void unload(  void ) { };
          
           protected:
      58   void _loadMaterial(  void ) { };
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Splatting.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_Splatting.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE_SPLATTING_H
          #define PAGINGLandScapeTEXTURE_SPLATTING_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_Splatting : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_Splatting(  PagingLandScapeTextureManager *textureMgr );
      29   String getName(   ) const{return String(  "Splatting" );}
          
      31   void setOptions(  void );
      32   ~PagingLandScapeTexture_Splatting(  void );
          
      34   PagingLandScapeTexture* newTexture(   );
      35   bool isMaterialSupported(   );
          
           protected:
          
      39   void _loadMaterial(  void );
          
           private:
          
      43   void _BuildPoint(  const unsigned int i,   const int j,  
      44   ColourValue& out,   std::vector<Real> &alpha );
          
      46   inline void _InterpolateAlpha(  std::vector<Real> &alpha,   const Real percentaje,  
           const int index1,   const int index2 );
          
      49   bool bAlpha1NotUsed,   bAlpha2NotUsed,   bAlpha3NotUsed,   bAlpha4NotUsed;
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Splatting2.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_Splatting.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE_SPLATTING2_H
          #define PAGINGLandScapeTEXTURE_SPLATTING2_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_Splatting2 : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_Splatting2(  PagingLandScapeTextureManager *textureMgr );
      29   String getName(   ) const{return String(  "Splatting2" );}
          
      31   ~PagingLandScapeTexture_Splatting2(  void );
          
      33   void setOptions(  void );
          
      35   PagingLandScapeTexture* newTexture(   );
      36   bool isMaterialSupported(   );
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Splatting2Edit.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_Splatting.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeTexture_Splatting2Edit_H
          #define PagingLandScapeTexture_Splatting2Edit_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_Splatting2Edit : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_Splatting2Edit(  PagingLandScapeTextureManager *textureMgr );
          
      30   String getName(   ) const{return String(  "Splatting2Edit" );}
      31   ~PagingLandScapeTexture_Splatting2Edit(  void );
      32   void setOptions(  void );
          
      34   PagingLandScapeTexture* newTexture(   );
      35   bool isMaterialSupported(   );
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Splatting3.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_Splatting.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PagingLandScapeTexture_Splatting3_H
          #define PagingLandScapeTexture_Splatting3_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_Splatting3 : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_Splatting3(  PagingLandScapeTextureManager *textureMgr );
      29   String getName(   ) const{return String(  "Splatting3" );}
          
      31   void setOptions(  void );
          
      33   ~PagingLandScapeTexture_Splatting3(   );
          
      35   PagingLandScapeTexture* newTexture(   );
      36   bool isMaterialSupported(   );
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Splatting4.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_Splatting4.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE4_SPLATTING_H
          #define PAGINGLandScapeTEXTURE4_SPLATTING_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_Splatting4 : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_Splatting4(  PagingLandScapeTextureManager *textureMgr );
      29   String getName(   ) const{return String(  "Splatting4" );}
      30   void setOptions(  void );
      31   ~PagingLandScapeTexture_Splatting4(  void );
          
      33   PagingLandScapeTexture* newTexture(   );
      34   bool isMaterialSupported(   );
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Splatting5.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_Splatting5.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE5_SPLATTING_H
          #define PAGINGLandScapeTEXTURE5_SPLATTING_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeTexture.h"
          
          namespace Ogre
          {
          
      27   class PagingLandScapeTexture_Splatting5 : public PagingLandScapeTexture
           {
           public:
      30   PagingLandScapeTexture_Splatting5(  PagingLandScapeTextureManager *textureMgr );
      31   String getName(   ) const{return String(  "Splatting5" );}
      32   void setOptions(  void );
      33   ~PagingLandScapeTexture_Splatting5(  void );
          
      35   PagingLandScapeTexture* newTexture(   );
      36   bool isMaterialSupported(   );
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Splatting6.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_Splatting4.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE6_SPLATTING_H
          #define PAGINGLandScapeTEXTURE6_SPLATTING_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_Splatting6 : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_Splatting6(  PagingLandScapeTextureManager *textureMgr );
      29   String getName(   ) const{return String(  "Splatting6" );}
      30   void setOptions(  void );
      31   ~PagingLandScapeTexture_Splatting6(  void );
          
      33   PagingLandScapeTexture* newTexture(   );
      34   bool isMaterialSupported(   );
          
           };
          
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Splatting7.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_Splatting7.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE7_SPLATTING_H
          #define PAGINGLandScapeTEXTURE7_SPLATTING_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_Splatting7 : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_Splatting7(  PagingLandScapeTextureManager *textureMgr );
          
      30   ~PagingLandScapeTexture_Splatting7(  void );
      31   String getName(   ) const{return String(  "Splatting7" );}
      32   PagingLandScapeTexture* newTexture(   );
      33   bool isMaterialSupported(   );
          
      35   void setOptions(  void );
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_Splatting7Edit.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_Splatting7Edit.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE7Edit_SPLATTING_H
          #define PAGINGLandScapeTEXTURE7Edit_SPLATTING_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          namespace Ogre
          {
      25   class PagingLandScapeTexture_Splatting7Edit : public PagingLandScapeTexture
           {
           public:
      28   PagingLandScapeTexture_Splatting7Edit(  PagingLandScapeTextureManager *textureMgr );
          
      30   String getName(   ) const{return String (  "Splatting7Edit" );};
          
      32   void setOptions(  void );
          
      34   ~PagingLandScapeTexture_Splatting7Edit(  void );
          
      36   PagingLandScapeTexture* newTexture(   );
      37   bool isMaterialSupported(   );
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_SplattingShader.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_SplattingShader.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE_SPLATTINGSHADER_H
          #define PAGINGLandScapeTEXTURE_SPLATTINGSHADER_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeTexture.h"
          
          namespace Ogre
          {
          
      27   class PagingLandScapeTexture_SplattingShader : public PagingLandScapeTexture
           {
           public:
      30   PagingLandScapeTexture_SplattingShader(  PagingLandScapeTextureManager *textureMgr );
      31   String getName(   ) const{return String(  "SplattingShader" );}
          
      33   ~PagingLandScapeTexture_SplattingShader(  void );
          
      35   PagingLandScapeTexture* newTexture(   );
      36   bool isMaterialSupported(   );
          
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTexture_SplattingShaderEdit.h

       1  /***************************************************************************
          OgrePagingLandScapeTexture_SplattingShader.h - description
           -------------------
           begin : Mon Apr 16 2004
           copyright : (  C ) 2002-2006 by Jose A Milan & Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTEXTURE_SPLATTINGSHADEREDIT_H
          #define PAGINGLandScapeTEXTURE_SPLATTINGSHADEREDIT_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeTexture.h"
          
          namespace Ogre
          {
          
      27   class PagingLandScapeTexture_SplattingShaderEdit : public PagingLandScapeTexture
           {
           public:
      30   PagingLandScapeTexture_SplattingShaderEdit(  PagingLandScapeTextureManager *textureMgr );
      31   String getName(   ) const{return String(  "SplattingShaderEdit" );}
          
      33   ~PagingLandScapeTexture_SplattingShaderEdit(  void );
      34   PagingLandScapeTexture* newTexture(   );
      35   bool isMaterialSupported(   );
           };
          }
          
          #endif //PAGINGLandScapeTEXTURE_SPLATTINGSHADEREDIT_H

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTile.h

          /***************************************************************************
           OgrePagingLandScapeTile.h - description
           -------------------
           begin : Sun Jun 08 2003
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTILE_H
          #define PAGINGLandScapeTILE_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeTileInfo.h"
          
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeTileManager.h"
          #include "OgrePagingLandScapeRenderable.h"
          
          namespace Ogre
          {
          
          class _OgrePagingLandScapeExport PagingLandScapeTile
          {
          public:
      34   inline PagingLandScapeTileInfo* getInfo(  void )
           {
           return mInfo;
           };
          
           /** Sets the appropriate neighbor for this TerrainRenderable. Neighbors are necessary
           to know when to bridge between LODs.
           */
      42   void _setNeighbor(  Neighbor n,   PagingLandScapeTile* t );
          
           /** Returns the neighbor TerrainRenderable.
           */
      46   inline PagingLandScapeTile* _getNeighbor(  Neighbor n )
           {
           return mNeighbors[ n ];
           };
          
           /** intersectSegment
           @remarks
           Intersect mainly with LandScape
           @param start
           beginning of the segment
           @param end
           where it ends
           @param result
           where it intersects with terrain
           */
      61   bool intersectSegmentFromAbove(  const Vector3& start,   const Vector3& dir,   Vector3* result );
      62   bool intersectSegmentFromBelow(  const Vector3& start,   const Vector3& dir,   Vector3* result );
          
           /** updateTerrain
           @remarks
           Make the Tile reload its vertices and normals
           (  upon a modification of the height data )
           */
      69   void updateTerrain(  void );
          
      71   inline PagingLandScapeRenderable* getRenderable(  void )
           {
           return mRenderable;
           }
          
      76   void _linkRenderableNeighbor(  void );
      77   void _updateLod(  void );
          
      79   PagingLandScapeTile(  PagingLandScapeTileManager *pageMgr );
          
      81   ~PagingLandScapeTile(  void );
          
      83   void init(  SceneNode* PageNode,   const int tableX,   const int tableZ,   const int tileX,   const int tileZ );
      84   void load(  void );
      85   void unload(  void );
      86   void uninit(  void );
          
      88   void _Notify(  const Vector3 &pos,   const PagingLandScapeCamera * const Cam );
          
      90   inline bool isLoaded(  void )
           {
           return mLoaded;
           };
      94   inline bool isLoading(  void )
           {
           return mLoading;
           };
      98   inline void setLoading(  bool value )
           {
           mLoading = value;
           };
          
     103   void setInUse (  bool InUse )
           {
           assert (  mInit );
           if (  mRenderable )
           mRenderable->setInUse (  InUse );
           }
          
     110   inline bool isVisible(  void )
           {
           return mVisible;
           }
          
           /// make tile visible not being unload or invisible until a certain time.
     116   inline void touch (   )
           {
           mTimeUntouched = mParent->getOptions(   )->TileInvisibleUnloadFrames;
           }
          
     121   void setRenderQueueGroup(  uint8 qid );
          
     123   SceneNode *getSceneNode(   )
           {
           return mTileSceneNode;
           };
     127   const AxisAlignedBox &getWorldBbox(   ) const
           {
           return mWorldBounds;
           };
     131   inline const AxisAlignedBox &getCullWorldBbox(   ) const
           {
           return mWorldBoundsExt;
           };
     135   inline const Vector3 &getCenter(  void ) const
           {
           return mWorldPosition;
           };
          
     140   const bool unloadUntouched (   );
          
          protected:
           //movable object variables
           AxisAlignedBox mWorldBounds;
           AxisAlignedBox mWorldBoundsExt;
           Vector3 mWorldPosition;
          
           // if the tile is initialized
           bool mInit;
           // if the renderable is loaded
           bool mLoaded;
           // if the renderable is loading
           bool mLoading;
          
           PagingLandScapeRenderable* mRenderable;
          
           SceneNode* mTileSceneNode;
           SceneNode* mParentSceneNode;
          
           PagingLandScapeTile* mNeighbors[4];
          
           PagingLandScapeTileInfo *mInfo;
           bool mVisible;
           unsigned int mTimeUntouched;
          
           PagingLandScapeTileManager *mParent;
          };
          
          } //namespace
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTileInfo.h

       1  /***************************************************************************
          OgrePagingLandScapeTileInfo.h - description
          -------------------
          begin : Sat Jan 31 2004
          copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
          email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTILEINFO_H
          #define PAGINGLandScapeTILEINFO_H
          
          namespace Ogre
          {
           /** This class holds the Tile info
           @remarks
           This will avoid to pass a lot of data to the Renderable class.
           */
      27   class
           PagingLandScapeTileInfo
           {
           public:
      31   PagingLandScapeTileInfo(  const uint pageX,   const uint pageZ,  
      32   const uint tileX,   const uint tileZ )
           :
           mMinLevelDistSqr(  0 ),  
           mPageX (  pageX ),  
           mPageZ (  pageZ ),  
           mTileX (  tileX ),  
           mTileZ (  tileZ )
           {
           }
      41   ~PagingLandScapeTileInfo(   )
           {
           delete mMinLevelDistSqr;
           }
          
           //This is the Page Index in the Page Array
           unsigned short int mPageX;
           unsigned short int mPageZ;
          
           //This is the tile Index in the Tile Array
           unsigned short int mTileX;
           unsigned short int mTileZ;
          
           /// List of squared distances at which LODs change
           // costly to compute,   so we cache it there.
      56   std::vector<Real>* mMinLevelDistSqr;
           };
          }
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/OgrePagingLandScapeTileManager.h

       1  /***************************************************************************
           OgrePagingLandScapeTileManager.h - description
           -------------------
           begin : Mon Jun 16 2003
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #ifndef PAGINGLandScapeTILEMANAGER_H
          #define PAGINGLandScapeTILEMANAGER_H
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeQueue.h"
          
          namespace Ogre
          {
          
          
      28   class PagingLandScapeTileManager
           {
           public:
          
      32   PagingLandScapeTileManager(  PagingLandScapeSceneManager * scnMgr );
          
      34   virtual ~PagingLandScapeTileManager(  void );
          
           /** Retrieve a free tile.
           */
      38   PagingLandScapeTile* getTile(  void );
          
           /** Make a tile free.
           */
      42   void freeTile(  PagingLandScapeTile* tile );
          
      44   void reset(  void );
          
      46   unsigned int numTiles(  void ) const;
          
      48   size_t numFree(  void ) const;
          
          
      51   void load(  void );
      52   void clear(  void );
          
           // unload invisible tiles after option::mTileInvisibleUnloadFrames tick
           // without being visible.
      56   void unloadUntouched(   );
          
      58   inline PagingLandScapeOptions* getOptions(   )
           {
           return mOptions;
           }
          
      63   inline PagingLandScapeSceneManager* getSceneManager(   )
           {
           return mSceneManager;
           }
          
           protected:
          
      70   PagingLandScapeOptions* mOptions;
      71   PagingLandScapeSceneManager *mSceneManager;
          
      73   void _addBatch(  const unsigned int num );
          
      75   PagingLandScapeTileRow mTiles;
          
      77   PagingLandScapeQueue< PagingLandScapeTile > mQueue;
          
           unsigned int mNumTiles;
          
           };
          
          } //namespace
          
          #endif

./components/ogre/SceneManagers/EmberPagingSceneManager/include/fileutils.h

       1  /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          /**
          @file
          fileutils.h
          @brief
          Utility function to manage directories
          */
          #ifndef fileutils_H
          #define fileutils_H
          
          #ifdef __cplusplus
          extern "C" {
          #endif
          /**
          * check if directory exists or not*
          * \param *Dirname name of the directory
          * \return true if exists
          */
      26  bool DirExists(  const char *Dirname );
          /**
           * change the current directory and return old one
           * as a MALLOC'ED by system ONE
           * \param *Dirname
           * \return
           */
      33  char* ChangeToDir(  const char* Dirname );
          /**
           * Reestablish directory to current one before changing
           * and free the char* MALLOC'ED by system when changing.
           * \param *oldDirname
           */
      39  void RetablishDir(  char* oldDirname );
          
          #ifdef __cplusplus
          }/* end extern C definitions */
          #endif
          
          #endif //fileutils_H

./components/ogre/SceneManagers/EmberPagingSceneManager/src/DRGNURBSSurface.cpp

       1  // DRGNURBSSurface.cpp: implementation of the CDRGNURBSSurface class.
          // ------------------------------------------------------------------------------------
          // Copyright © 1999 Intel Corporation
          // All Rights Reserved
          //
          // Permission is granted to use,   copy,   distribute and prepare derivative works of this
          // software for any purpose and without fee,   provided,   that the above copyright notice
          // and this statement appear in all copies. Intel makes no representations about the
          // suitability of this software for any purpose. This software is provided "AS IS."
          //
          // Intel specifically disclaims all warranties,   express or implied,   and all liability,  
          // including consequential and other indirect damages,   for the use of this software,  
          // including liability for infringement of any proprietary rights,   and including the
          // warranties of merchantability and fitness for a particular purpose. Intel does not
          // assume any responsibility for any errors which may appear in this software nor any
          // responsibility to update it.
          // ------------------------------------------------------------------------------------
          //
          // PURPOSE:
          //
          // Implementation of the CDRGNURBSSurface class for rendering NURBS surfaces.
          // Accompanies the article "Rendering NURBS Surfaces in float-Time". Please refer
          // to the article for an understanding of the methods in this class.
          // ------------------------------------------------------------------------------------
          //
          // Author: Dean Macri - Intel Developer Relations Divison -- Tools and Technology Group
          // Please contact me at dean.p.macri@intel.com with questions,   suggestions,   etc.
          //
          ////////////////////////////////////////////////////////////////////////////////////////
          //
          // Yoinked from http://www.gamasutra.com/features/19991117/macri_pfv.htm
          // Hacked into an unholy mess for use with OGRE by Chris "Antiarc" Heald (  antiarc@captionthis.com )
          // Date: 11/9/2003
          //
          ////////////////////////////////////////////////////////////////////////////////////////
          
          //////////////////////////////////////////////////////////////////////
          // Construction/Destruction
          //////////////////////////////////////////////////////////////////////
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "DRGNURBSSurface.h"
          #include <stdlib.h>
          #include <math.h>
          #include <string.h>
          
      48  CDRGNURBSSurface::CDRGNURBSSurface(   )
          {
          
           m_pControlPoints = NULL;
           m_UKnots = NULL;
           m_VKnots = NULL;
           m_UBasisCoefficients = NULL;
           m_VBasisCoefficients = NULL;
           m_UBasis = NULL;
           m_dUBasis = NULL;
           m_VBasis = NULL;
           m_dVBasis = NULL;
           m_UTemp = NULL;
           m_dUTemp = NULL;
           m_TessUKnotSpan = NULL;
           m_TessVKnotSpan = NULL;
          
           m_iUTessellations = 0;
           m_iVTessellations = 0;
          
           m_pVertices = NULL;
          }
          
          // -----------------------------------------------------------------------
          //
          // Free up anything we've allocated
          //
          // -----------------------------------------------------------------------
      76  void CDRGNURBSSurface::Cleanup(  void )
          {
           ALIGNED_DELETE(  m_pControlPoints );
           ALIGNED_DELETE(  m_UKnots );
           ALIGNED_DELETE(  m_VKnots );
           ALIGNED_DELETE(  m_UBasisCoefficients );
           ALIGNED_DELETE(  m_VBasisCoefficients );
           ALIGNED_DELETE(  m_UBasis );
           ALIGNED_DELETE(  m_dUBasis );
           ALIGNED_DELETE(  m_VBasis );
           ALIGNED_DELETE(  m_dVBasis );
           ALIGNED_DELETE(  m_UTemp );
           ALIGNED_DELETE(  m_dUTemp );
           ALIGNED_DELETE(  m_pVertices );
           SAFE_DELETE(  m_TessUKnotSpan );
           SAFE_DELETE(  m_TessVKnotSpan );
          }
          
      94  CDRGNURBSSurface::~CDRGNURBSSurface(   )
          {
           Cleanup(   ); // Free everything :- )
          }
          
          // -----------------------------------------------------------------------
          //
          // Initialize a CDRGNURBSSurface object. This will normally only be called
          // once for a particular object but it's safe to call it more than once.
          //
          // -----------------------------------------------------------------------
     105  bool CDRGNURBSSurface::Init(  int uDegree,  
           int vDegree,  
           int uControlPoints,  
           int vControlPoints,  
           Point4D *pControlPoints,  
           float *pUKnots,  
           float *pVKnots,  
           int iDefaultUTessellations,  
           int iDefaultVTessellations
            )
          {
           // In case we've already been initialized.
           Cleanup(   );
          
           // Copy the stuff we're given
           //
           m_iUDegree = uDegree;
           m_iVDegree = vDegree;
           m_iUControlPoints = uControlPoints;
           m_iVControlPoints = vControlPoints;
          
           //
           // Compute some other useful quantities
           //
           m_iUOrder = m_iUDegree + 1;
           m_iVOrder = m_iVDegree + 1;
           m_iUKnots = m_iUOrder + m_iUControlPoints;
           m_iVKnots = m_iVOrder + m_iVControlPoints;
          
           // Calculate how many valid spans exist in the Knot vectors
           m_iUBasisSpans = m_iUKnots - 2 * m_iUDegree;
           m_iVBasisSpans = m_iVKnots - 2 * m_iVDegree;
          
          
           //
           // Allocate some memory for the control points,   knots,   and basis stuff
           //
           m_pControlPoints = ALIGNED_NEW(  m_iUControlPoints * m_iVControlPoints,   Point4D );
           m_UKnots = ALIGNED_NEW(  m_iUKnots,   float );
           m_VKnots = ALIGNED_NEW(  m_iVKnots,   float );
          
           // For each span in the knot vector,   there will be m_iUOrder (  and m_iVOrder )
           // Basis polynomials that are non-zero. Each of those polynomials will
           // have m_iUOrder coefficients,   hence m_iUBasisSpans * m_iUOrder * m_iUOrder
           m_UBasisCoefficients = ALIGNED_NEW(  m_iUOrder * m_iUOrder * m_iUBasisSpans,   float );
           m_VBasisCoefficients = ALIGNED_NEW(  m_iVOrder * m_iVOrder * m_iVBasisSpans,   float );
           m_UTemp = ALIGNED_NEW(  m_iVOrder,   Point4D );
           m_dUTemp = ALIGNED_NEW(  m_iVOrder,   Point4D );
          
           //
           // Copy the incoming data to the internal structures. If the incoming control
           // points are NOT stored as pre-weighted points,   then you'll need to loop over
           // the points and multiply x,   y,   and z by the w value (  so that the actual,  
           // stored control point is {x*w,   y*w,   z*w,   w} )
           //
           memcpy(  m_pControlPoints,   pControlPoints,   m_iUControlPoints * m_iVControlPoints * sizeof(  Point4D ) );
           memcpy(  m_UKnots,   pUKnots,   m_iUKnots * sizeof(  float ) );
           memcpy(  m_VKnots,   pVKnots,   m_iVKnots * sizeof(  float ) );
          
           ComputeBasisCoefficients(   );
          
           SetTessellations(  iDefaultUTessellations,   iDefaultVTessellations );
          
           return true;
          }
          
          // -----------------------------------------------------------------------
          //
          // Change the number of tessellations used to render the object
          //
          // -----------------------------------------------------------------------
     176  void CDRGNURBSSurface::SetTessellations(  int iUTessellations,   int iVTessellations )
          {
           if(  (  iUTessellations != m_iUTessellations ) ||
           (  iVTessellations != m_iVTessellations ) )
           {
           m_iUTessellations = iUTessellations;
           m_iVTessellations = iVTessellations;
          
           //
           // Free anything we've already allocated
           //
           ALIGNED_DELETE(  m_UBasis );
           ALIGNED_DELETE(  m_VBasis );
           ALIGNED_DELETE(  m_dUBasis );
           ALIGNED_DELETE(  m_dVBasis );
           SAFE_DELETE(  m_TessUKnotSpan );
           SAFE_DELETE(  m_TessVKnotSpan );
          
           //
           // Allocate memory for the basis functions,   etc
           //
           m_UBasis = ALIGNED_NEW(  m_iUOrder * SIMD_SIZE * (  m_iUTessellations+1 ),   float );
           m_VBasis = ALIGNED_NEW(  m_iVOrder * SIMD_SIZE * (  m_iVTessellations+1 ),   float );
           m_dUBasis = ALIGNED_NEW(  m_iUOrder * SIMD_SIZE * (  m_iUTessellations+1 ),   float );
           m_dVBasis = ALIGNED_NEW(  m_iVOrder * SIMD_SIZE * (  m_iVTessellations+1 ),   float );
          
           m_TessUKnotSpan = new int[ m_iUTessellations+1 ];
           m_TessVKnotSpan = new int[ m_iVTessellations+1 ];
          
           ALIGNED_DELETE(  m_pVertices );
          
           int iVertices = (  (  iUTessellations+1 ) * (  iVTessellations+1 ) ); //2 * (  iVTessellations + 1 );
           m_pVertices = ALIGNED_NEW(  iVertices,   splinePoint );
          
           //
           // Re-evaluate the basis functions
           //
           EvaluateBasisFunctions(   );
           }
          }
          
          // -----------------------------------------------------------------------
          // float CDRGNURBSSurface::ComputeCoefficient(  float *fKnots,   int iInterval,   int i,   int p,   int k )
          //
          //
          // Determines the polynomial coefficients from the knot vector
          //
          // Remember that the b-spline basis functions of degree p on knot interval
          // i = (  Bi,  p ) defined on a knot vector u = {U0,   U1,   ...,   Um} are defined:
          //
          // Bi,  0(  u ) = 1 if Ui <= u < Ui+1
          // 0 otherwise
          //
          // u - Ui Ui+p+1 - u
          // Bi,  p(  u ) = ---------- * Bi,  p-1(  u ) + ------------- * Bi+1,  p-1(  u )
          // Ui+p - Ui Ui+p+1 - Ui+1
          //
          //
          // For some degree p on interval i,   there exist p+1 polynomials of
          // degree p of the form:
          //
          // Ci,  p,  0 + Ci,  p,  1 * u^1 + Ci,  p,  2 * u^2 + ... + Ci,  p,  p * u^p
          //
          // I derived a recursive formula for these constant coefficients as
          //
          // Ci,  0,  0 = Bi,  0(  u ) (  i.e. Ci,  0,  0 will be either 0 or 1 )
          //
          // For p > 0
          // Ui+p+1 * Ci+1,  p-1,  0 UiCi,  p-1,  0
          // Ci,  p,  0 = --------------------- - ------------
          // Ui+p+1 - Ui+1 Ui+p - Ui
          //
          // Ci,  p-1,  p-1 Ci+1,  p-1,  p-1
          // Ci,  p,  p = ------------ - ---------------
          // Ui+p - Ui Ui+p+1 - Ui+1
          //
          // For 0<k<p
          // Ci,  p-1,  k-1 - Ui * Ci,  p-1,  k Ci+1,  p-1,  k-1 - Ui+p+1 * Ci+1,  p-1,  k
          // Ci,  p,  k = ---------------------------- - ------------------------------------
          // Ui+p - Ui Ui+p+1 - Ui+1
          //
          //
          // From this,   for a pth degree b-spline,   for each interval i,   there are
          // p+1 b-spline basis functions that are non-zero and each one has p+1
          // coefficients. Note that Ci,  p,  k is dependent on u only for determining the
          // knot span,   i,   that we're computing the coefficients for.
          // The next two functions compute those coefficients for the various intervals
          // -----------------------------------------------------------------------
     264  float CDRGNURBSSurface::ComputeCoefficient(  float *fKnots,   int iInterval,   int i,   int p,   int k )
          {
           float fResult = 0.0f;
          
           if(  p == 0 )
           {
           if(  i == iInterval )
           fResult = 1.0f;
           }
           else if(  k == 0 )
           {
           if(  fKnots[i+p] != fKnots[i] )
           fResult -= fKnots[i] * ComputeCoefficient(  fKnots,   iInterval,   i,   p-1,   0 ) / (  fKnots[i+p] - fKnots[i] );
           if(  fKnots[i+p+1] != fKnots[i+1] )
           fResult += fKnots[i+p+1] * ComputeCoefficient(  fKnots,   iInterval,   i+1,   p-1,   0 ) / (  fKnots[i+p+1] - fKnots[i+1] );
           }
           else if(  k == p )
           {
           if(  fKnots[i+p] != fKnots[i] )
           fResult += ComputeCoefficient(  fKnots,   iInterval,   i,   p-1,   p-1 ) / (  fKnots[i+p] - fKnots[i] );
           if(  fKnots[i+p+1] != fKnots[i+1] )
           fResult -= ComputeCoefficient(  fKnots,   iInterval,   i+1,   p-1,   p-1 ) / (  fKnots[i+p+1] - fKnots[i+1] );
           }
           else if(  k > p )
           {
           fResult = 0.0f;
           }
           else
           {
           float C1,   C2;
           if(  fKnots[i+p] != fKnots[i] )
           {
           C1 = ComputeCoefficient(  fKnots,   iInterval,   i,   p-1,   k-1 );
           C2 = ComputeCoefficient(  fKnots,   iInterval,   i,   p-1,   k );
           fResult += (  C1 - fKnots[i] * C2 ) / (  fKnots[i+p] - fKnots[i] );
           }
           if(  fKnots[i+p+1] != fKnots[i+1] )
           {
           C1 = ComputeCoefficient(  fKnots,   iInterval,   i+1,   p-1,   k-1 );
           C2 = ComputeCoefficient(  fKnots,   iInterval,   i+1,   p-1,   k );
           fResult -= (  C1 - fKnots[i+p+1] * C2 ) / (  fKnots[i+p+1] - fKnots[i+1] );
           }
          
           }
          
           return fResult;
          }
          
          
          // -----------------------------------------------------------------------
          // void CDRGNURBSSurface::ComputeBasisCoefficients(  void )
          //
          // See the comment from the function above,   ComputeCoefficient(   )
          // -----------------------------------------------------------------------
     318  void CDRGNURBSSurface::ComputeBasisCoefficients(  void )
          {
           int i,   j,   k;
          
           //
           // Start with U. For each Basis span calculate coefficients
           // for m_iUOrder polynomials each having m_iUOrder coefficients
           //
          
           for(  i=0; i<m_iUBasisSpans; i++ )
           {
           for(  j=0; j<m_iUOrder; j++ )
           {
           for(  k=0; k<m_iUOrder; k++ )
           {
           m_UBasisCoefficients[ (  i * m_iUOrder + j ) * m_iUOrder + k ] =
           ComputeCoefficient(  m_UKnots,   i + m_iUDegree,   i + j,   m_iUDegree,   k );
           }
           }
           }
          
           for(  i=0; i<m_iVBasisSpans; i++ )
           {
           for(  j=0; j<m_iVOrder; j++ )
           {
           for(  k=0; k<m_iVOrder; k++ )
           {
           m_VBasisCoefficients[ (  i * m_iVOrder + j ) * m_iVOrder + k ] =
           ComputeCoefficient(  m_VKnots,   i + m_iVDegree,   i + j,   m_iVDegree,   k );
           }
           }
           }
          
          }
          
          // -----------------------------------------------------------------------
          // void CDRGNURBSSurface::EvaluateBasisFunctions(  void )
          //
          // Evaluate the polynomials for the basis functions and store the results.
          // First derivatives are calculated as well.
          // -----------------------------------------------------------------------
     359  void CDRGNURBSSurface::EvaluateBasisFunctions(  void )
          {
           int i,   j,   k,   idx;
           float u,   uinc;
           float v,   vinc;
          
           //
           // First evaluate the U basis functions and derivitives at uniformly spaced u values
           //
           idx = 0;
           u = m_UKnots[idx+m_iUDegree];
           uinc = (  m_UKnots[m_iUKnots-m_iUOrder] - m_UKnots[m_iUDegree] )/(  m_iUTessellations );
          
           for(  i=0; i<=m_iUTessellations; i++ )
           {
           while(  (  idx < m_iUKnots - m_iUDegree*2 - 2 ) && (  u >= m_UKnots[idx+m_iUDegree+1] ) )
           idx++;
          
           m_TessUKnotSpan[i] = idx+m_iUDegree;
          
           //
           // Evaluate using Horner's method
           //
           for(  j=0; j<m_iUOrder; j++ )
           {
           m_UBasis[(  i*m_iUOrder+j ) * SIMD_SIZE] = m_UBasisCoefficients[ (  idx * m_iUOrder + j ) * m_iUOrder + m_iUDegree ];
           m_dUBasis[(  i*m_iUOrder+j ) * SIMD_SIZE] = m_UBasis[(  i*m_iUOrder+j ) * SIMD_SIZE] * m_iUDegree;
           for(  k=m_iUDegree-1; k>=0; k-- )
           {
           m_UBasis[(  i*m_iUOrder+j )*SIMD_SIZE] = m_UBasis[ (  i*m_iUOrder+j )*SIMD_SIZE ] * u +
           m_UBasisCoefficients[ (  idx * m_iUOrder + j ) * m_iUOrder + k ];
           if(  k>0 )
           {
           m_dUBasis[(  i*m_iUOrder+j )*SIMD_SIZE] = m_dUBasis[(  i * m_iUOrder+j )*SIMD_SIZE] * u +
           m_UBasisCoefficients[ (  idx * m_iUOrder + j ) * m_iUOrder + k ] * k;
           }
           }
           //
           // Make three copies. This isn't necessary if we're using straight C
           // code but for the Pentium III optimizations,   it is.
           //
           }
          
           u += uinc;
           }
          
           //
           // Finally evaluate the V basis functions at uniformly spaced v values
           //
           idx = 0;
           v = m_VKnots[idx+m_iVDegree];
           vinc = (  m_VKnots[m_iVKnots-m_iVOrder] - m_VKnots[m_iVDegree] )/(  m_iVTessellations );
          
           for(  i=0; i<=m_iVTessellations; i++ )
           {
           while(  (  idx < m_iVKnots - m_iVDegree*2 - 2 ) && (  v >= m_VKnots[idx+m_iVDegree+1] ) )
           idx++;
          
           m_TessVKnotSpan[i] = idx+m_iVDegree;
          
           //
           // Evaluate using Horner's method
           //
           for(  j=0; j<m_iVOrder; j++ )
           {
           m_VBasis[(  i*m_iVOrder+j )*SIMD_SIZE] = m_VBasisCoefficients[ (  idx * m_iVOrder + j ) * m_iVOrder + m_iVDegree ];
           m_dVBasis[(  i*m_iVOrder+j )*SIMD_SIZE] = m_VBasis[(  i*m_iVOrder+j )*SIMD_SIZE] * m_iVDegree;
           for(  k=m_iVDegree-1; k>=0; k-- )
           {
           m_VBasis[(  i*m_iVOrder+j )*SIMD_SIZE] = m_VBasis[ (  i*m_iVOrder+j )*SIMD_SIZE ] * v +
           m_VBasisCoefficients[ (  idx * m_iVOrder + j ) * m_iVOrder + k ];
           if(  k>0 )
           {
           m_dVBasis[(  i*m_iVOrder+j )*SIMD_SIZE] = m_dVBasis[(  i * m_iVOrder+j )*SIMD_SIZE] * v +
           m_VBasisCoefficients[ (  idx * m_iVOrder + j ) * m_iVOrder + k ] * k;
           }
           }
           }
           v += vinc;
           }
          }
          
          // -----------------------------------------------------------------------
          //
          // Tessellate the surface into triangles and submit them as a triangle
          // strip to Direct3D.
          //
          // -----------------------------------------------------------------------
     447  void CDRGNURBSSurface::TessellateSurface(   )
          {
           int u,   v;
           int k,   l;
           int uKnot,   vKnot;
           Point4D *UTemp = m_UTemp,   *dUTemp = m_dUTemp;
           Point4D Pw;
           float rhw;
           int iVertices;
           Point4D *pControlPoints = m_pControlPoints;
           int iCPOffset;
           float VBasis,   dVBasis;
           int idx,   uidx;
          
           if(  (  m_iUTessellations == 0 ) || (  m_iVTessellations == 0 ) )
           return;
          
           iVertices = 2 * (  m_iVTessellations + 1 );
          
           // Step over the U and V coordinates and generate triangle strips to render
           //
           for(  u=0; u<=m_iUTessellations; u++ )
           {
           // What's the current knot span in the U direction?
           uKnot = m_TessUKnotSpan[u];
          
           // Calculate the offset into the pre-calculated basis functions array
           uidx = u * m_iUOrder * SIMD_SIZE;
           vKnot = -1;
          
           // Create one row of vertices
           for(  v=0; v<=m_iVTessellations; v++ )
           {
           idx = u * m_iUTessellations + v;
           if(  vKnot != m_TessVKnotSpan[v] )
           {
           vKnot = m_TessVKnotSpan[v];
           //
           // If our knot span in the V direction has changed,   then calculate some
           // temporary variables. These are the sum of the U-basis functions times
           // the control points (  times the weights because the control points have
           // the weights factored in ).
           //
           for(  k=0; k<=m_iVDegree; k++ )
           {
           iCPOffset = (  uKnot - m_iUDegree ) * m_iVControlPoints + (  vKnot - m_iVDegree );
           UTemp[k].x = m_UBasis[uidx] * pControlPoints[ iCPOffset + k ].x;
           UTemp[k].y = m_UBasis[uidx] * pControlPoints[ iCPOffset + k ].y;
           UTemp[k].z = m_UBasis[uidx] * pControlPoints[ iCPOffset + k ].z;
           UTemp[k].w = m_UBasis[uidx] * pControlPoints[ iCPOffset + k ].w;
           dUTemp[k].x = m_dUBasis[uidx] * pControlPoints[ iCPOffset + k ].x;
           dUTemp[k].y = m_dUBasis[uidx] * pControlPoints[ iCPOffset + k ].y;
           dUTemp[k].z = m_dUBasis[uidx] * pControlPoints[ iCPOffset + k ].z;
           dUTemp[k].w = m_dUBasis[uidx] * pControlPoints[ iCPOffset + k ].w;
          
           for(  l=1; l<=m_iUDegree; l++ )
           {
           iCPOffset += m_iVControlPoints;
           UTemp[k].x += m_UBasis[uidx+l * SIMD_SIZE] * pControlPoints[ iCPOffset + k].x;
           UTemp[k].y += m_UBasis[uidx+l * SIMD_SIZE] * pControlPoints[ iCPOffset + k].y;
           UTemp[k].z += m_UBasis[uidx+l * SIMD_SIZE] * pControlPoints[ iCPOffset + k].z;
           UTemp[k].w += m_UBasis[uidx+l * SIMD_SIZE] * pControlPoints[ iCPOffset + k].w;
           dUTemp[k].x += m_dUBasis[uidx+l * SIMD_SIZE] * pControlPoints[ iCPOffset + k ].x;
           dUTemp[k].y += m_dUBasis[uidx+l * SIMD_SIZE] * pControlPoints[ iCPOffset + k ].y;
           dUTemp[k].z += m_dUBasis[uidx+l * SIMD_SIZE] * pControlPoints[ iCPOffset + k ].z;
           dUTemp[k].w += m_dUBasis[uidx+l * SIMD_SIZE] * pControlPoints[ iCPOffset + k ].w;
           }
           }
           }
          
           // Compute the point in the U and V directions
           VBasis = m_VBasis[ (  v * m_iVOrder )*SIMD_SIZE ];
           dVBasis = m_dVBasis[ (  v * m_iVOrder )*SIMD_SIZE ];
           Pw.x = VBasis * UTemp[0].x;
           Pw.y = VBasis * UTemp[0].y;
           Pw.z = VBasis * UTemp[0].z;
           Pw.w = VBasis * UTemp[0].w;
           for(  k=1; k<=m_iVDegree; k++ )
           {
           VBasis = m_VBasis[ (  v * m_iVOrder + k )*SIMD_SIZE ];
           dVBasis = m_dVBasis[ (  v * m_iVOrder + k )*SIMD_SIZE ];
           Pw.x += VBasis * UTemp[k].x;
           Pw.y += VBasis * UTemp[k].y;
           Pw.z += VBasis * UTemp[k].z;
           Pw.w += VBasis * UTemp[k].w;
           }
          
           // rhw is the factor to multiply by inorder to bring the 4-D points back into 3-D
           rhw = 1.0f / Pw.w;
           Pw.x = Pw.x * rhw;
           Pw.y = Pw.y * rhw;
           Pw.z = Pw.z * rhw;
          
           // Store the vertex position.
           m_pVertices[idx].x = Pw.x;
           m_pVertices[idx].y = Pw.y;
           m_pVertices[idx].z = Pw.z;
           }
           }
          
          }
          
          // -----------------------------------------------------------------------
     550  splinePoint CDRGNURBSSurface::getData(  int index )
          {
           return m_pVertices[index];
          }
          // -----------------------------------------------------------------------
          //
          // Implementation of the base class method.
          //
          // -----------------------------------------------------------------------
     559  int CDRGNURBSSurface::GetTriangleCount(   )
          {
           return 2 * m_iUTessellations * m_iVTessellations;
          }
          
          // -----------------------------------------------------------------------
          //
          // Change the control points of the surface. This method doesn't do any
          // error checking,   so it assumes the array passed in contains as many
          // control points as where used when the surface was initialized.
          //
          // -----------------------------------------------------------------------
     571  void CDRGNURBSSurface::UpdateControlPoints(  Point4D *pControlPoints )
          {
           memcpy(  m_pControlPoints,   pControlPoints,   m_iUControlPoints * m_iVControlPoints * sizeof(  Point4D ) );
          }
          
          
          

./components/ogre/SceneManagers/EmberPagingSceneManager/src/EmberPagingLandScapeData2D_HeightField.cpp

       1  //
          // C++ Implementation: EmberPagingLandScapeData2D_HeightField
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #include "EmberOgrePrerequisites.h"
          #include "OgrePagingLandScapeOptions.h"
          
          #include "OgrePagingLandScapeData2DManager.h"
          
          #include "EmberPagingLandScapeData2D_HeightField.h"
          #include "EmberPagingSceneManager.h"
          
          #include "EmberOgre.h"
          #include "terrain/TerrainPage.h"
          #include "terrain/TerrainGenerator.h"
          
          
          using namespace Ogre;
          namespace EmberOgre
          {
          
      41  EmberPagingLandScapeData2D_HeightField::EmberPagingLandScapeData2D_HeightField(  Ogre::PagingLandScapeData2DManager *pageMgr )
          : Ogre::PagingLandScapeData2D(  pageMgr ),   mTerrainPage(  0 )
          {
           ///set it to something,   so it doesn't default to a crazy number (  like 5.79555e+022 ) since that will break stuff later on
           ///in regards to calculating the distance to the tile (  especially in PagingLandScapeTile::_Notify )
           mMaxheight = 1;
          }
          
      49  bool EmberPagingLandScapeData2D_HeightField::_load(   const Ogre::uint x,   const Ogre::uint z  )
          {
           assert(  !mTerrainPage );
           Terrain::TerrainGenerator* terrainGenerator = EmberOgre::getSingleton(   ).getTerrainGenerator(   );
           mXDimension = mZDimension = terrainGenerator->getPageSize(   );
          
           mMaxArrayPos = mSize * mSize;
           mHeightData = new Real[mMaxArrayPos];
           mTerrainPage = terrainGenerator->getTerrainPage(  Ogre::Vector2(  x,  z ) );
           //should always return a TerrainPage*
           assert(  mTerrainPage );
          
           mTerrainPage->createHeightData(  mHeightData );
          
          
           ///make sure it's not 0
           mMaxheight = std::max<float>(  mTerrainPage->getMaxHeight(   ),   1.0f );
           mMax = static_cast <unsigned int> (  mSize * mTerrainPage->getMaxHeight(   ) );
           return true;
          }
          
      70  PagingLandScapeData2D* EmberPagingLandScapeData2D_HeightField::newPage(    )
          {
           return new EmberPagingLandScapeData2D_HeightField(  mParent );
          }
          
          
      76  const ColourValue EmberPagingLandScapeData2D_HeightField::getBase (  const Real mX,   const Real mZ )
          {
          
           return ColourValue::White;
          
          }
          
           //-----------------------------------------------------------------------
      84  const ColourValue EmberPagingLandScapeData2D_HeightField::getCoverage (  const Real mX,   const Real mZ )
          {
          
           return ColourValue::Blue;
          }
          
           //-----------------------------------------------------------------------
      91  const Real EmberPagingLandScapeData2D_HeightField::getShadow (  const Real mX,   const Real mZ,  
      92   const bool &positive )
          {
          
           return 0.0f;
          
          }
          
           //-----------------------------------------------------------------------
     100  const Vector3 EmberPagingLandScapeData2D_HeightField::getNormal (  const Real x,   const Real z )
          {
           float height;
           WFMath::Vector<3> normal;
           EmberOgre::getSingleton(   ).getTerrainGenerator(   )->getTerrain(   ).getHeightAndNormal(  x,   -z,   height,   normal );
           return Atlas2Ogre(  normal );
          // return Ogre::PagingLandScapeData2D::getNormal(  x,   z );
          }
           //-----------------------------------------------------------------------
     109  void EmberPagingLandScapeData2D_HeightField::_save(   )
          {
           S_LOG_VERBOSE(  "Saving terrain page at x: " << mPageX << " z:" << mPageZ << "." );
          }
           //-----------------------------------------------------------------------
           //-----------------------------------------------------------------------
     115  void EmberPagingLandScapeData2D_HeightField::_load(   )
          {
           S_LOG_VERBOSE(  "Loading (  _load(   ) ) terrain page at x: " << mPageX << " z:" << mPageZ << "." );
          }
           //-----------------------------------------------------------------------
     120  void EmberPagingLandScapeData2D_HeightField::_unload(   )
          {
           S_LOG_VERBOSE(  "Unloading terrain page at x: " << mPageX << " z:" << mPageZ << "." );
           mTerrainPage = 0;
          }
          
     126  const Ogre::Real EmberPagingLandScapeData2D_HeightField::getMaxAbsoluteHeight(  void ) const
          {
           ///return a totally arbitrary high enough value
           return 250.0f;
           //return mMaxheight;
          }
          
          
          
          };

./components/ogre/SceneManagers/EmberPagingSceneManager/src/EmberPagingLandScapeTexture.cpp

       1  //
          // C++ Implementation: EmberPagingLandScapeTexture
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #include "EmberPagingLandScapeTexture.h"
          #include "EmberOgre.h"
          #include "terrain/TerrainPage.h"
          #include "terrain/TerrainGenerator.h"
          
          namespace EmberOgre
          {
          
      32   EmberPagingLandScapeTexture::EmberPagingLandScapeTexture(  Ogre::PagingLandScapeTextureManager *pageMgr )
           : Ogre::PagingLandScapeTexture(  pageMgr,   "EmberTexture",   1,   false )
           {
           }
          
      37   EmberPagingLandScapeTexture::~EmberPagingLandScapeTexture(   void  )
           {
           }
          
      41   Ogre::PagingLandScapeTexture* EmberPagingLandScapeTexture::newTexture(    )
           {
           return new EmberPagingLandScapeTexture(  mParent );
           }
          
      46   bool EmberPagingLandScapeTexture::isMaterialSupported(  bool recursive )
           {
           //TODO: check for stuff here
           return true;
           }
          
      52   void EmberPagingLandScapeTexture::setOptions(  void )
           {
           }
          
      56   void EmberPagingLandScapeTexture::_loadMaterial(    )
           {
           Terrain::TerrainGenerator* terrainGenerator = EmberOgre::getSingleton(   ).getTerrainGenerator(   );
           Terrain::TerrainPage* page = terrainGenerator->getTerrainPage(  Ogre::Vector2(  mDataX,   mDataZ ) );
           assert(  page );
           if (  page ) {
           mMaterial = page->getMaterial(   );
           }
          
           }
          
      67   void EmberPagingLandScapeTexture::_unloadMaterial(   )
           {
           S_LOG_VERBOSE(  "Unloading terrain material." );
           }
          
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/EmberPagingSceneManager.cpp

       1  //
          // C++ Implementation: EmberPagingSceneManager
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2005
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #include "EmberPagingSceneManager.h"
          #include "EmberOgrePrerequisites.h"
          
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeTextureManager.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "EmberPagingLandScapeData2D_HeightField.h"
          #include "EmberPagingLandScapeTexture.h"
          #include "model/Model.h"
          
          namespace EmberOgre {
          
           const Ogre::String EmberPagingSceneManagerFactory::FACTORY_TYPE_NAME = "EmberPagingSceneManager";
           //-----------------------------------------------------------------------
      38   void EmberPagingSceneManagerFactory::initMetaData(  void ) const
           {
           mMetaData.typeName = FACTORY_TYPE_NAME;
           mMetaData.description = "Uses the PagingLandscapeSceneManager.";
           mMetaData.sceneTypeMask = Ogre::ST_EXTERIOR_REAL_FAR; // support all types
           mMetaData.worldGeometrySupported = false;
           }
           //-----------------------------------------------------------------------
      46   Ogre::SceneManager* EmberPagingSceneManagerFactory::createInstance(  
      47   const Ogre::String& instanceName )
           {
           return new EmberPagingSceneManager(  instanceName );
           }
           //-----------------------------------------------------------------------
      52   void EmberPagingSceneManagerFactory::destroyInstance(  Ogre::SceneManager* instance )
           {
           delete instance;
           }
          
          
      58   EmberPagingSceneManager::EmberPagingSceneManager(  const Ogre::String &name ): PagingLandScapeSceneManager(  name )
           {
           if (  !mOptions )
           mOptions = new Ogre::PagingLandScapeOptions(  this );
           }
          
          
           //-----------------------------------------------------------------------
      66   void EmberPagingSceneManager::InitScene (   )
           {
           PagingLandScapeSceneManager::InitScene (   );
          
           getData2DManager(   )->registerDataType (  new EmberPagingLandScapeData2D_HeightField (  getData2DManager(   ) ) );
           getTextureManager(   )->registerTextureType (  new EmberPagingLandScapeTexture (  getTextureManager(   ) ) );
          
           }
          
      75   void EmberPagingSceneManager::registerProvider(  IPageDataProvider* provider )
           {
           mProvider = provider;
           }
          
      80   Model::Model* EmberPagingSceneManager::createModel(  
      81   const Ogre::String& modelName,  
      82   const Ogre::String& modelDefinitionName  )
           {
           // delegate to factory implementation
           Ogre::NameValuePairList params;
           params["modeldefinition"] = modelDefinitionName;
           return static_cast<Model::Model*>(  
           createMovableObject(  modelName,   Model::ModelFactory::FACTORY_TYPE_NAME,  
           &params ) );
          
           }
          
          }
          

./components/ogre/SceneManagers/EmberPagingSceneManager/src/EmberPagingSceneManagerAdapter.cpp

       1  //
          // C++ Implementation: EmberPagingSceneManagerAdapter
          //
          // Description:
          //
          //
          // Author: Erik Hjortsberg <erik@katastrof.nu>,   (  C ) 2006
          //
          // This program is free software; you can redistribute it and/or modify
          // it under the terms of the GNU 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 General Public License for more details.
          //
          // You should have received a copy of the GNU General Public License
          // along with this program; if not,   write to the Free Software
          // Foundation,   Inc.,   675 Mass Ave,   Cambridge,   MA 02139,   USA.//
          //
          
          #include "EmberPagingSceneManagerAdapter.h"
          
          #include "EmberPagingSceneManager.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapePageManager.h"
          #include "OgrePagingLandScapePage.h"
          
          namespace EmberOgre {
          
      33   Ogre::PagingLandScapeOptions* EmberPagingSceneManagerAdapter::getOptions(   )
           {
           return mSceneManager->getOptions(   );
           }
          
      38   EmberPagingSceneManagerAdapter::EmberPagingSceneManagerAdapter(  EmberPagingSceneManager* scenemanager ) : mSceneManager(  scenemanager )
           {
           }
          
      42   int EmberPagingSceneManagerAdapter::getPageSize(   )
           {
           return getOptions(   )->PageSize;
           }
          
      47   Ogre::Real EmberPagingSceneManagerAdapter::getHeightAt(  const Ogre::Real x,   const Ogre::Real z )
           {
           return mSceneManager->getHeightAt(  x,   z );
           }
          
          
      53   void EmberPagingSceneManagerAdapter::setWorldPagesDimensions(  int numberOfPagesHeight,   int numberOfPagesWidth,   int heightOffsetInPages,   int widthOffsetInPages )
           {
           ///in order position (  0,  0 ) to be aligned to the centre of the terrain we must offset the position of the terrain a bit
           getOptions(   )->position.z = (  (  numberOfPagesHeight * 0.5f ) - heightOffsetInPages ) * getOptions(   )->PageSize;
           getOptions(   )->position.x = (  (  numberOfPagesWidth * 0.5f ) - widthOffsetInPages ) * getOptions(   )->PageSize;
          
           getOptions(   )->world_height = numberOfPagesHeight;
           getOptions(   )->world_width = numberOfPagesWidth;
          
           ///update the options
           getOptions(   )->NumPages = getOptions(   )->world_height * getOptions(   )->world_width;
           getOptions(   )->maxUnScaledZ = getOptions(   )->world_height * (  getOptions(   )->PageSize - 1 ) * 0.5f;
           getOptions(   )->maxUnScaledX = getOptions(   )->world_width * (  getOptions(   )->PageSize - 1 ) * 0.5f;
          
           getOptions(   )->maxScaledZ = getOptions(   )->scale.z * getOptions(   )->maxUnScaledZ;
           getOptions(   )->maxScaledX = getOptions(   )->scale.x * getOptions(   )->maxUnScaledX;
          
           }
          
      72   void EmberPagingSceneManagerAdapter::resize(  Ogre::AxisAlignedBox newSize,   int levels )
           {
           mSceneManager->resize(  newSize,   levels );
           }
          
      77   void EmberPagingSceneManagerAdapter::setCamera(  Ogre::Camera* camera )
           {
           mSceneManager->setOption(  "primaryCamera",   camera );
           }
          
      82   void EmberPagingSceneManagerAdapter::setResourceGroupName(  const std::string& groupName )
           {
           mSceneManager->setOption(  "GroupName",   &groupName );
           mSceneManager->getOptions(   )->groupName = groupName;
           mSceneManager->getOptions(   )->cfgGroupName = groupName;
           }
          
      89   void EmberPagingSceneManagerAdapter::loadOptions(  const std::string& filePath )
           {
           mSceneManager->getOptions(   )->loadMapOptions(  filePath );
          
           mSceneManager->getOptions(   )->setTextureFormat(  "EmberTexture" );
           }
          
      96   void EmberPagingSceneManagerAdapter::loadScene(   )
           {
           mSceneManager->loadScene(   );
           mSceneManager->getOptions(   )->setOption(  "LoadNow",   0 );
           }
          
     102   void EmberPagingSceneManagerAdapter::setOption(  const std::string& strKey,   const void* pValue )
           {
           mSceneManager->setOption(  strKey,   pValue );
           }
          
     107   void EmberPagingSceneManagerAdapter::getOption(  const std::string& strKey,   void* pDestValue )
           {
           mSceneManager->getOption(  strKey,   pDestValue );
           }
          
     112   Ogre::SceneManager* EmberPagingSceneManagerAdapter::getSceneManager(   ) const
           {
           return mSceneManager;
           }
          
     117   void EmberPagingSceneManagerAdapter::reloadAllPages(   )
           {
           mSceneManager->getPageManager(   )->load(   );
           }
          
     122   void EmberPagingSceneManagerAdapter::reloadPage(  unsigned int x,   unsigned int z )
           {
           Ogre::Vector2 position(  x,  z );
           setOption(  "PageUpdate",   &position );
           Ogre::PagingLandScapePage* page= mSceneManager->getPageManager(   )->getPage(  x,   z,   false );
           if (  page ) {
          // page->reload(   );
           page->unload(   );
           page->load(   );
           }
           }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgreDebugRectangle2D.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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 "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreDebugRectangle2D.h"
          #ifdef _VISIBILITYDEBUG
          
          #include "OgreHardwareBufferManager.h"
          #include "OgreCamera.h"
          
          #include "OgreRoot.h"
          
          namespace Ogre {
          #define POSITION_BINDING 0
          
      39   DebugRectangle2D::DebugRectangle2D(   ) : SimpleRenderable (   )
           {
          #ifdef PLSM2_EIHORT
           mUseIdentityProjection = true;
           mUseIdentityView = true;
          #endif
           mRenderOp.indexData = new IndexData(   );
           mRenderOp.vertexData = new VertexData(   );
           mRenderOp.operationType = RenderOperation::OT_LINE_LIST;
           mRenderOp.indexData->indexCount = 8;
           mRenderOp.vertexData->vertexCount = 4;
           mRenderOp.vertexData->vertexStart = 0;
           mRenderOp.useIndexes = true;
          
          
           VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
           VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
          
           decl->addElement(  POSITION_BINDING,   0,   VET_FLOAT3,   VES_POSITION );
           const size_t offset = VertexElement::getTypeSize(  VET_FLOAT3 );
           decl->addElement (  POSITION_BINDING,   offset,   VET_COLOUR,   VES_DIFFUSE );
          
          
           mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton(   ).createIndexBuffer(  
           HardwareIndexBuffer::IT_16BIT,  
           mRenderOp.indexData->indexCount,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY );
          
           HardwareVertexBufferSharedPtr vbuf =
           HardwareBufferManager::getSingleton(   ).createVertexBuffer(  
           decl->getVertexSize(  POSITION_BINDING ),  
           mRenderOp.vertexData->vertexCount,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY );
          
           // Bind buffer
           bind->setBinding(  POSITION_BINDING,   vbuf );
          
           SimpleRenderable::setBoundingBox(  AxisAlignedBox(  -1000 * Vector3::UNIT_SCALE,  
           1000 * Vector3::UNIT_SCALE ) );
          
           SimpleRenderable::setRenderQueueGroup (  RENDER_QUEUE_OVERLAY );
          
           // set basic white material
           SimpleRenderable::setMaterial(  "BaseWhiteNoLighting" );
           }
          
      85   DebugRectangle2D::~DebugRectangle2D(   )
           {
           delete mRenderOp.vertexData;
           delete mRenderOp.indexData;
           }
          
      91   void DebugRectangle2D::setCorners(  Real left,   Real top,   Real right,   Real bottom )
           {
           VertexDeclaration * const decl = mRenderOp.vertexData->vertexDeclaration;
           const VertexElement* poselem = decl->findElementBySemantic(  VES_POSITION );
           const VertexElement* colorelem = decl->findElementBySemantic(  VES_DIFFUSE );
          
          
           HardwareVertexBufferSharedPtr vbuf =
           mRenderOp.vertexData->vertexBufferBinding->getBuffer(  POSITION_BINDING );
          
          
           const size_t vertexSize = vbuf->getVertexSize (   );
           float *pPos;
           RGBA *pColor;
           Root * const root = Root::getSingletonPtr(   );
          
           uchar* pMain = static_cast<uchar *>(  
           vbuf->lock(  HardwareBuffer::HBL_DISCARD ) );
          
          
          // #define V3(  AX,   AY,   AZ,   ACOLOR ) poselem->baseVertexPointerToElement(  pMain,   &pPos ); \
          // *pPos++ = AX; *pPos++ = AY; *pPos++ = AZ; \
          // pMain += vertexSize;
          
          #define V3(  A_X,   A_Y,   A_Z,   ACOLOR ) poselem->baseVertexPointerToElement(  pMain,   &pPos ); \
           *pPos++ = static_cast <float> (  A_X ); \
           *pPos++ = static_cast <float> (  A_Y ); \
           *pPos++ = static_cast <float> (  A_Z ); \
           colorelem->baseVertexPointerToElement(  pMain,   &pColor ); \
           root->convertColourValue (  ACOLOR,   pColor ); \
           pMain += vertexSize;
          
           V3(  left,   top,   -1.0f,   ColourValue::White )
           V3(  left,   bottom,   -1.0f,   ColourValue::White )
           V3(  right,   bottom,   -1.0f,   ColourValue::White )
           V3(  right,   top,   -1.0f,   ColourValue::White )
          
           vbuf->unlock(   );
          
          
          
           HardwareIndexBufferSharedPtr iBuf = mRenderOp.indexData->indexBuffer;
           ushort* pIdx = static_cast<ushort*>(  
           iBuf->lock(  0,   iBuf->getSizeInBytes(   ),  HardwareBuffer::HBL_DISCARD ) );
          
          
           *pIdx++ = static_cast<ushort> (  0 ); *pIdx++ = static_cast<ushort> (  1 ); // line 1
           *pIdx++ = static_cast<ushort> (  1 ); *pIdx++ = static_cast<ushort> (  2 ); // line 2
           *pIdx++ = static_cast<ushort> (  2 ); *pIdx++ = static_cast<ushort> (  3 ); // line 3
     140   *pIdx++ = static_cast<ushort> (  3 ); *pIdx++ = static_cast<ushort> (  0 ); // line 4
          
           iBuf->unlock(   );
           }
          
           // Override this method to prevent parent transforms (  rotation,  translation,  scale )
     146   void DebugRectangle2D::getWorldTransforms(  Matrix4* xform ) const
           {
           // return identity matrix to prevent parent transforms
           *xform = Matrix4::IDENTITY;
           }
     151   //-----------------------------------------------------------------------
           const Quaternion& DebugRectangle2D::getWorldOrientation(  void ) const
           {
           return Quaternion::IDENTITY;
           }
           //-----------------------------------------------------------------------
           const Vector3& DebugRectangle2D::getWorldPosition(  void ) const
           {
           return Vector3::ZERO;
           }
          
          
          }
          #endif //_VISIBILITYDEBUG

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgreOcclusionBoundingBox.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
           (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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 "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "Ogre.h"
          #include "OgreOcclusionBoundingBox.h"
          
          #include "OgreSimpleRenderable.h"
          #include "OgreHardwareBufferManager.h"
          #include "OgreCamera.h"
          
          namespace Ogre {
           #define POSITION_BINDING 0
          
           //-----------------------------------------------------------------------
      39   OcclusionBoundingBox::OcclusionBoundingBox(   )
           {
           mRenderOp.indexData = new IndexData(   );
           mRenderOp.vertexData = new VertexData(   );
           mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
           mRenderOp.indexData->indexCount = 36;
           mRenderOp.vertexData->vertexCount = 24;
           mRenderOp.vertexData->vertexStart = 0;
           mRenderOp.useIndexes = true;
          
           VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
           VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
          
           decl->addElement(  POSITION_BINDING,   0,   VET_FLOAT3,   VES_POSITION );
           //const size_t offset = VertexElement::getTypeSize(  VET_FLOAT3 );
           //decl->addElement (  POSITION_BINDING,   offset,   VET_COLOUR,   VES_DIFFUSE );
          
          
           mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton(   ).createIndexBuffer(  
           HardwareIndexBuffer::IT_16BIT,  
           mRenderOp.indexData->indexCount,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY );
          
           HardwareVertexBufferSharedPtr vbuf =
           HardwareBufferManager::getSingleton(   ).createVertexBuffer(  
           decl->getVertexSize(  POSITION_BINDING ),  
           mRenderOp.vertexData->vertexCount,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY );
          
           // Bind buffer
           bind->setBinding(  POSITION_BINDING,   vbuf );
          
           this->setPolygonModeOverrideable (  false );
           //Renderable::getPolygonMode (   );
          
           // set basic white material
           this->setMaterial(  "BaseWhiteNoLightNoDepthCheckWrite" );
           }
           //-----------------------------------------------------------------------
      78   PolygonMode OcclusionBoundingBox:: getRenderDetail(   ) const
           {
           //return PM_WIREFRAME;
           return PM_SOLID;
           }
          
           //-----------------------------------------------------------------------
      85   OcclusionBoundingBox::~OcclusionBoundingBox(   )
           {
           delete mRenderOp.indexData;
           delete mRenderOp.vertexData;
           }
           //-----------------------------------------------------------------------
      91   void OcclusionBoundingBox::setupBoundingBox(  const AxisAlignedBox& aabb )
           {
           // init the vertices to the aabb
           setupBoundingBoxVertices(  aabb );
          
           // setup the bounding box of this SimpleRenderable
           setBoundingBox(  aabb );
          
           }
           //-----------------------------------------------------------------------
           // Override this method to prevent parent transforms (  rotation,  translation,  scale )
     102   void OcclusionBoundingBox::getWorldTransforms(  Matrix4* xform ) const
           {
           // return identity matrix to prevent parent transforms
           *xform = Matrix4::IDENTITY;
           }
           //-----------------------------------------------------------------------
     108   const Quaternion& OcclusionBoundingBox::getWorldOrientation(  void ) const
           {
           return Quaternion::IDENTITY;
           }
           //-----------------------------------------------------------------------
     113   const Vector3& OcclusionBoundingBox::getWorldPosition(  void ) const
           {
           return Vector3::ZERO;
           }
           //-----------------------------------------------------------------------
     118   void OcclusionBoundingBox::setupBoundingBoxVertices(  const AxisAlignedBox& aab )
           {
           const Vector3 &max = aab.getMaximum(   );
           const Vector3 &min = aab.getMinimum(   );
          
           const Real sqLen = std::max(  max.squaredLength(   ),  
           min.squaredLength(   ) );
           mRadius = Math::Sqrt(  sqLen );
          
          
           VertexDeclaration * const decl = mRenderOp.vertexData->vertexDeclaration;
           const VertexElement* poselem = decl->findElementBySemantic(  VES_POSITION );
           //const VertexElement* colorelem = decl->findElementBySemantic(  VES_DIFFUSE );
          
          
           HardwareVertexBufferSharedPtr vbuf =
           mRenderOp.vertexData->vertexBufferBinding->getBuffer(  POSITION_BINDING );
          
           const size_t vertexSize = vbuf->getVertexSize (   );
           float *pPos;
           //RGBA *pColor;
           //Root * const root = Root::getSingletonPtr(   );
          
           uchar* pMain = static_cast<uchar *>(  
           vbuf->lock(  HardwareBuffer::HBL_DISCARD ) );
          
          
           //generate 8 corners of the bbox
           // RightHanded
          
           #define V3(  A_X,   A_Y,   A_Z,   ACOLOR ) poselem->baseVertexPointerToElement(  pMain,   &pPos ); \
           *pPos++ = static_cast <float> (  A_X ); \
           *pPos++ = static_cast <float> (  A_Y ); \
           *pPos++ = static_cast <float> (  A_Z ); \
           pMain += vertexSize;
          
          // #define V3(  AX,   AY,   AZ,   ACOLOR ) poselem->baseVertexPointerToElement(  pMain,   &pPos ); \
          // *pPos++ = AX; *pPos++ = AY; *pPos++ = AZ; \
          // colorelem->baseVertexPointerToElement(  pMain,   &pColor ); \
          // root->convertColourValue (  ACOLOR,   pColor ); \
          // pMain += vertexSize;
          
           V3(  min.x,   max.y,   max.z,   ColourValue::White ) // 1
           V3(  min.x,   min.y,   max.z,   ColourValue::White ) // 2
           V3(  max.x,   max.y,   max.z,   ColourValue::White ) // 3
           V3(  max.x,   min.y,   max.z,   ColourValue::White ) // 4
           V3(  max.x,   max.y,   min.z,   ColourValue::White ) // 5
           V3(  max.x,   min.y,   min.z,   ColourValue::White ) // 6
           V3(  min.x,   max.y,   min.z,   ColourValue::White ) // 7
           V3(  min.x,   min.y,   min.z,   ColourValue::White ) // 8
          
          
           vbuf->unlock(   );
          
          
           HardwareIndexBufferSharedPtr iBuf = mRenderOp.indexData->indexBuffer;
           ushort* pIdx = static_cast<ushort*>(  
           iBuf->lock(  0,   iBuf->getSizeInBytes(   ),  HardwareBuffer::HBL_DISCARD ) );
          
           *pIdx++ = static_cast<ushort> (  0 ); *pIdx++ = static_cast<ushort> (  1 ); *pIdx++ = static_cast<ushort> (  2 );
           *pIdx++ = static_cast<ushort> (  1 ); *pIdx++ = static_cast<ushort> (  3 ); *pIdx++ = static_cast<ushort> (  2 );
           *pIdx++ = static_cast<ushort> (  2 ); *pIdx++ = static_cast<ushort> (  3 ); *pIdx++ = static_cast<ushort> (  4 );
           *pIdx++ = static_cast<ushort> (  3 ); *pIdx++ = static_cast<ushort> (  5 ); *pIdx++ = static_cast<ushort> (  4 );
           *pIdx++ = static_cast<ushort> (  6 ); *pIdx++ = static_cast<ushort> (  5 ); *pIdx++ = static_cast<ushort> (  7 );
           *pIdx++ = static_cast<ushort> (  5 ); *pIdx++ = static_cast<ushort> (  7 ); *pIdx++ = static_cast<ushort> (  6 );
           *pIdx++ = static_cast<ushort> (  6 ); *pIdx++ = static_cast<ushort> (  7 ); *pIdx++ = static_cast<ushort> (  0 );
           *pIdx++ = static_cast<ushort> (  7 ); *pIdx++ = static_cast<ushort> (  1 ); *pIdx++ = static_cast<ushort> (  0 );
           *pIdx++ = static_cast<ushort> (  4 ); *pIdx++ = static_cast<ushort> (  6 ); *pIdx++ = static_cast<ushort> (  0 );
           *pIdx++ = static_cast<ushort> (  4 ); *pIdx++ = static_cast<ushort> (  0 ); *pIdx++ = static_cast<ushort> (  2 );
           *pIdx++ = static_cast<ushort> (  1 ); *pIdx++ = static_cast<ushort> (  7 ); *pIdx++ = static_cast<ushort> (  3 );
           *pIdx++ = static_cast<ushort> (  7 ); *pIdx++ = static_cast<ushort> (  5 ); *pIdx++ = static_cast<ushort> (  3 );
     189  
           iBuf->unlock(   );
           }
           //-----------------------------------------------------------------------
           Real OcclusionBoundingBox::getSquaredViewDepth(  const Camera* cam ) const
           {
           const Vector3 &min = mBox.getMinimum(   );
           const Vector3 &max = mBox.getMaximum(   );
           const Vector3 mid = (  (  max - min ) * 0.5f ) + min;
           const Vector3 dist = cam->getDerivedPosition(   ) - mid;
          
           return dist.squaredLength(   );
           }
          }
          

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeAxisAlignedBoxSceneQuery.cpp

          /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeAxisAlignedBoxSceneQuery.cpp - description
          -------------------
          begin : Sat Oct 15,   2006
          copyright : (  C ) 2006 by Steven Klug
          email : stevenklug@san.rr.com
          
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeAxisAlignedBoxSceneQuery.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgreEntity.h"
          
          #include "OgrePagingLandScapeTile.h"
          #include "OgrePagingLandScapePage.h"
          #include "OgrePagingLandScapePageManager.h"
          
          using namespace Ogre;
          
          namespace Ogre
          {
           // NOTE: Creating some of my own conversion functions here even though
           // these are somewhat duplicating code in the page manager. It was
           // more for the exercise of getting clear in my head the differences
           // between world coords,   page local coords,   page numbers,   tiles,   etc.
           // May convert back to the ones in the page manager eventually,   though
           // these may offer some speed advantages as some redundant calculations
           // (  invPageSize,   etc. ) are only done once in the main query.
          
           //-----------------------------------------------------------------------
           // Scale a coordinate from world space to page number and coord for local
           // unscaled page space.
           inline
      63   bool WorldToPage(   Real coord,   Real scale,   Real maxUnScaled,   uint pageSize,   Real invPageSize,   uint worldExtent,  
           uint& pageNumber,   Real& localPageCoord  )
           {
           // scale position from world to page scale
           Real unscaled = (  coord / scale ) + maxUnScaled;
          
           // get Page
           Real value = unscaled * invPageSize;
           uint maxPage = static_cast<int>(   worldExtent  );
           // Set output params.
           pageNumber = static_cast<int>(   value  );
           if(   value < 0.0  )
           {
           pageNumber = 0;
           localPageCoord = 0.0;
           return false;
           }
           else if(   pageNumber >= maxPage  )
           {
           pageNumber = maxPage - 1;
           localPageCoord = pageNumber * pageSize + pageSize - 1;
           return false;
           }
           else
           {
           localPageCoord = unscaled - (   pageNumber * pageSize  );
           return true;
           }
           }
          
           //-----------------------------------------------------------------------
           inline
      95   Real PageToWorld(   uint pageNumber,   Real localPageCoord,   Real scale,   Real maxUnScaled,   uint pageSize  )
           {
           Real unscaled = localPageCoord + pageNumber * pageSize;
           return (   unscaled - maxUnScaled  ) * scale;
           }
          
           //-----------------------------------------------------------------------
           // Scale a coordinate from local page space to tile number.
           inline
     104   uint PageToTile(   int localPageCoord,   Real invTileSize,   uint maxNumTiles  )
           {
           // get Tile
           uint value = static_cast< uint > (  localPageCoord * invTileSize );
           return (   value < 0  ) ? 0 : (  value >= maxNumTiles ? maxNumTiles - 1: value );
           }
          
           //-----------------------------------------------------------------------
           //-----------------------------------------------------------------------
           //-----------------------------------------------------------------------
           // Operations and data for render levels (  lod levels ).
     115   class RenderLevel
           {
           int renderLevel_;
           int lodStep_;
     119   uint lodMask_;
           public:
           //-----------------------------------------------------------------------
     122   RenderLevel(   )
           {
           SetRenderLevel(   0  );
           }
           //-----------------------------------------------------------------------
     127   RenderLevel(   int renderLevel  )
           {
           SetRenderLevel(   renderLevel  );
           }
           //-----------------------------------------------------------------------
     132   void SetRenderLevel(   int renderLevel  )
           {
           renderLevel_ = renderLevel;
           lodStep_ = 1 << renderLevel;
           lodMask_ = ~(   lodStep_ - 1  );
           }
           //-----------------------------------------------------------------------
     139   int GetRenderLevel(   ) const
           {
           return renderLevel_;
           }
           //-----------------------------------------------------------------------
     144   int GetLodStep(   ) const
           {
           return lodStep_;
           }
           //-----------------------------------------------------------------------
     149   uint GetLodMask(   ) const
           {
           return lodMask_;
           }
           //-----------------------------------------------------------------------
     154   bool operator < (   const RenderLevel& rhs  ) const
           {
           return renderLevel_ < rhs.renderLevel_;
           }
           //-----------------------------------------------------------------------
           // Step the input coordinate by the lodStep.
     160   int LodStep(   int localPageCoord  ) const
           {
           return localPageCoord + lodStep_;
           }
           //-----------------------------------------------------------------------
           // Return the floor of the passed in coord based on valid LOD.
     166   int Floor(   int localPageCoord  ) const
           {
           return localPageCoord & lodMask_;
           }
           //-----------------------------------------------------------------------
           // Return the ceiling of the passed in coord based on valid LOD.
     172   int Ceil(   int localPageCoord  ) const
           {
           if(   Floor(   localPageCoord  ) == localPageCoord  )
           return localPageCoord; // Already at ceiling.
           else
           return Floor(   localPageCoord + lodStep_  );
           }
           //-----------------------------------------------------------------------
     180   int GetLodLevel(   ) const
           {
           return lodStep_;
           }
           };
          
           //-----------------------------------------------------------------------
           //-----------------------------------------------------------------------
           //-----------------------------------------------------------------------
           // Object responsible for caching tile changes specific to lod stepping.
     190   class LodTracker
           {
     192   const Vector3 scale_;
     193   const Real maxUnScaledX_;
     194   const Real maxUnScaledZ_;
     195   const uint pageSize_;
     196   const Real invPageSize_;
     197   const uint tileSize_;
     198   const Real invTileSize_;
     199   const uint maxNumTiles_;
     200   PagingLandScapePageManager* pageMgr_;
     201   PagingLandScapeData2DManager* dataMgr_;
          
     203   const PagingLandScapePage* page_;
     204   const PagingLandScapeData2D* pageData_;
     205   PagingLandScapeTile* tile_;
     206   RenderLevel renderLevel_;
     207   uint pageX_;
     208   uint pageZ_;
           public:
           //-----------------------------------------------------------------------
           LodTracker(   Vector3 scale,  
           Real maxUnScaledX,  
           Real maxUnScaledZ,  
           uint pageSize,  
           uint tileSize,  
           uint maxNumTiles,  
           PagingLandScapePageManager* pageMgr,  
           PagingLandScapeData2DManager* dataMgr  )
           : scale_(   scale  )
           ,   maxUnScaledX_(   maxUnScaledX  )
           ,   maxUnScaledZ_(   maxUnScaledZ  )
           ,   pageSize_(   pageSize  )
           ,   invPageSize_(   1.0f / pageSize  )
           ,   tileSize_(   tileSize  )
           ,   invTileSize_(   1.0f / tileSize  )
           ,   maxNumTiles_(   maxNumTiles  )
           ,   pageMgr_(   pageMgr  )
           ,   dataMgr_(   dataMgr  )
           ,   page_(   0  )
           ,   pageData_(   0  )
           ,   tile_(   0  )
           ,   pageX_(   0  )
           ,   pageZ_(   0  ) {}
          
           //-----------------------------------------------------------------------
     236   uint GetTileSize(   ) const
           {
           return tileSize_;
           }
           //-----------------------------------------------------------------------
     241   Real GetInvTileSize(   ) const
           {
           return invTileSize_;
           }
           //-----------------------------------------------------------------------
     246   uint GetMaxNumTiles(   ) const
           {
           return maxNumTiles_;
           }
           //-----------------------------------------------------------------------
     251   const RenderLevel& GetRenderLevel(   ) const
           {
           return renderLevel_;
           }
           //-----------------------------------------------------------------------
     256   const PagingLandScapePage* GetPage(   ) const
           {
           return page_;
           }
           //-----------------------------------------------------------------------
     261   uint GetPageX(   ) const
           {
           return pageX_;
           }
           //-----------------------------------------------------------------------
     266   uint GetPageZ(   ) const
           {
           return pageZ_;
           }
           //-----------------------------------------------------------------------
           // Returns true if the vertex is included,   or false if it is removed
           // by LOD. Requires local page coordinates.
     273   bool GetWorldVertex(   int localPageX,   int localPageZ,   Vector3& vertex  )
           {
           UpdateWithLocalPage(   localPageX,   localPageZ  );
           bool included = (   renderLevel_.Floor(   localPageX  ) == localPageX &&
           renderLevel_.Floor(   localPageZ  ) == localPageZ  );
           if(   page_ && page_->isLoaded(   ) && pageData_  )
           {
           // TODO: Do we really need to include the real data when the vertex
           // has been removed by lod? Or can we just stuff a dummy result in
           // here to fill out the array?
           vertex.y = pageData_->getHeight(   localPageX,   localPageZ  );
           page_->getCoordinates(   pageX_,   pageZ_  );
           vertex.x = PageToWorld(   pageX_,   localPageX,   scale_.x,   maxUnScaledX_,   pageSize_  );
           vertex.z = PageToWorld(   pageZ_,   localPageZ,   scale_.z,   maxUnScaledZ_,   pageSize_  );
           }
           return included;
           }
           //-----------------------------------------------------------------------
           // Set the current page. Must be called before Update(   ).
     292   void SetPage(   const PagingLandScapePage* page  )
           {
           page_ = page;
           if(   page_ && page_->isLoaded(   )  )
           {
           page_->getCoordinates(   pageX_,   pageZ_  );
           pageData_ = dataMgr_->getData2D(   pageX_,   pageZ_,   false  );
           }
           }
           //-----------------------------------------------------------------------
           // Sets the page using the page coordinates.
     303   void SetPage(   int pageX,   int pageZ  )
           {
           const PagingLandScapePage* page = pageMgr_->getPage(   pageX,   pageZ,   false  );
           if(   !page || !page->isLoaded(   )  )
           {
           assert(   false  );
           return; // TODO: Currently the AABB must be on the currently loaded landscape.
           }
           SetPage(   page  );
           }
           //-----------------------------------------------------------------------
           // Update using page local tile coordinates.
     315   void UpdateTile(   int tileX,   int tileZ  )
           {
           PagingLandScapeTile* tile = page_->getTile(   tileX,   tileZ  );
           if(   tile != tile_  )
           {
           tile_ = tile;
           bool tileLoaded = tile_ && tile_->isLoaded(   ) && tile_->getRenderable(   );
           renderLevel_.SetRenderLevel(   (  tileLoaded ) ? tile_->getRenderable(   )->getRenderLevel(   ) : 0  );
           }
           }
           //-----------------------------------------------------------------------
           // Update our lodStep and lodMask for the current tile,   given the page
           // local coordinates of a vertex.
     328   void UpdateWithLocalPage(   int localPageX,   int localPageZ  )
           {
           int tileX = PageToTile(   localPageX,   invTileSize_,   maxNumTiles_  );
           int tileZ = PageToTile(   localPageZ,   invTileSize_,   maxNumTiles_  );
          
           UpdateTile(   tileX,   tileZ  );
           }
           };
          
           //-----------------------------------------------------------------------
           // Loop over every edge tile. Determine which the lowest lod on each edge
           // and use that to adjust the extents.
           // TODO: This routine is expensive,   and is only needed when LOD is involved.
           // Optimize? Ironic since LOD is supposed to make things faster.
     342   void AdjustEdgesForLod(   LodTracker& lodTracker,  
           int minPageX,   int minPageZ,   int maxPageX,   int maxPageZ,  
           int& localPageMinX,   int& localPageMinZ,   int& localPageMaxX,   int& localPageMaxZ  )
           {
           int minTileZ = PageToTile(   localPageMinZ,  
           lodTracker.GetInvTileSize(   ),  
           lodTracker.GetMaxNumTiles(   )  );
           int maxTileZ = PageToTile(   localPageMaxZ,  
           lodTracker.GetInvTileSize(   ),  
           lodTracker.GetMaxNumTiles(   )  );
           int minTileX = PageToTile(   localPageMinX,  
           lodTracker.GetInvTileSize(   ),  
           lodTracker.GetMaxNumTiles(   )  );
           int maxTileX = PageToTile(   localPageMaxX,  
           lodTracker.GetInvTileSize(   ),  
           lodTracker.GetMaxNumTiles(   )  );
           int westRenderLevel = 0;
           int eastRenderLevel = 0;
           for(   int pageZ = minPageZ; pageZ <= maxPageZ; ++pageZ  )
           {
           int endTileZ = (   pageZ == maxPageZ  ) ? maxTileZ : lodTracker.GetMaxNumTiles(   ) - 1;
           for(   int tileZ = (   pageZ == minPageZ  ) ? minTileZ : 0;
           tileZ <= endTileZ;
           ++tileZ  )
           {
           // West edge
           lodTracker.SetPage(   minPageX,   pageZ  );
           lodTracker.UpdateTile(   minTileX,   tileZ  );
           int renderLevel = lodTracker.GetRenderLevel(   ).GetRenderLevel(   );
           if(   renderLevel > westRenderLevel  )
           westRenderLevel = renderLevel;
           // East edge
           lodTracker.SetPage(   maxPageX,   pageZ  );
           lodTracker.UpdateTile(   maxTileX,   tileZ  );
           renderLevel = lodTracker.GetRenderLevel(   ).GetRenderLevel(   );
           if(   renderLevel > eastRenderLevel  )
           eastRenderLevel = renderLevel;
           }
           }
          
           int northRenderLevel = 0;
           int southRenderLevel = 0;
           for(   int pageX = minPageX; pageX <= maxPageX; ++pageX  )
           {
           int endTileX = (   pageX == maxPageX  ) ? maxTileX : lodTracker.GetMaxNumTiles(   ) - 1;
           for(   int tileX = (   pageX == minPageX  ) ? minTileX : 0;
           tileX <= endTileX;
           ++tileX  )
           {
           // North edge
           lodTracker.SetPage(   pageX,   minPageZ  );
           lodTracker.UpdateTile(   tileX,   minTileZ  );
           int renderLevel = lodTracker.GetRenderLevel(   ).GetRenderLevel(   );
           if(   renderLevel > northRenderLevel  )
           northRenderLevel = renderLevel;
           // South edge
           lodTracker.SetPage(   pageX,   maxPageZ  );
           lodTracker.UpdateTile(   tileX,   maxTileZ  );
           renderLevel = lodTracker.GetRenderLevel(   ).GetRenderLevel(   );
           if(   renderLevel > southRenderLevel  )
           southRenderLevel = renderLevel;
           }
           }
           // Use the lods we found to adjust the min and max local coords.
           RenderLevel renderLevel(   westRenderLevel  );
           localPageMinX = renderLevel.Floor(   localPageMinX  );
           renderLevel.SetRenderLevel(   eastRenderLevel  );
           localPageMaxX = renderLevel.Ceil(   localPageMaxX  );
           renderLevel.SetRenderLevel(   northRenderLevel  );
           localPageMinZ = renderLevel.Floor(   localPageMinZ  );
           renderLevel.SetRenderLevel(   southRenderLevel  );
           localPageMaxZ = renderLevel.Ceil(   localPageMaxZ  );
           }
          
           //-----------------------------------------------------------------------
     417   void DoTileSubSection(   LodTracker& lodTracker,  
           SceneQuery::WorldFragment& worldFragment,  
           PagingLandScapeAxisAlignedBoxSceneQuery::CustomQueryResult& queryResult,  
           SceneQueryListener* listener,  
           int localPageMinX,   int localPageMinZ,   int localPageMaxX,   int localPageMaxZ,  
           uint subX,   uint subZ  )
           {
           lodTracker.UpdateWithLocalPage(   localPageMinX,   localPageMinZ  );
          
           // Send the width and height of this sub-section.
           queryResult.SetSubsectionExtents(   localPageMaxX - localPageMinX + 1,  
           localPageMaxZ - localPageMinZ + 1,  
           lodTracker.GetRenderLevel(   ).GetRenderLevel(   ),  
           subX,   subZ  );
           listener->queryResult(   &worldFragment  );
          
           for(   int z = localPageMinZ; z <= localPageMaxZ; ++z  )
           {
           for(   int x = localPageMinX; x <= localPageMaxX; ++x  )
           {
           Vector3 vertex;
           bool included = lodTracker.GetWorldVertex(   x,   z,   vertex  );
           queryResult.SetVertex(   vertex,   included  );
           listener->queryResult(   &worldFragment  );
           }
           }
           }
          }
          
          namespace Ogre
          {
          
          //---------------------------------------------------------------------
          PagingLandScapeAxisAlignedBoxSceneQuery::PagingLandScapeAxisAlignedBoxSceneQuery(  SceneManager* creator )
           : DefaultAxisAlignedBoxSceneQuery(  creator )
          {
          }
          
          //---------------------------------------------------------------------
          PagingLandScapeAxisAlignedBoxSceneQuery::~PagingLandScapeAxisAlignedBoxSceneQuery(  void )
          {
          }
          
          //---------------------------------------------------------------------
          // Well return via callbacks a set of rectangular tile sub-sections.
          // All fragments returned via callback use a WFT_CUSTOM_GEOMETRY type.
          // The CustomQueryResult structure defined above is what is passed
          // in the void* geometry field. The type_ field of the CustomQuery
          // result determins what is being sent in the fragment as follows:
          //
          // QUERY_EXTENTS_TYPE: Sent as the first result,   this gives the width
          // and height (  in tile subsections ) of the entire query result. The
          // render level in this case is not defined.
          //
          // SUBSECTION_EXTENTS_TYPE: Sent before each sub-section's vertex
          // data. This contains the height,   width,   and render level of the
          // subsequent vertex data.
          //
          // VERTEX_TYPE: This is the actual vertex data,   and whether the vertex
          // is included when displayed at the tile's current render level.
          //
          // The seemingly complex way of returning the data is so that the same
          // stitching algorithm used by PLSM can be used by the client in
          // creating a mesh out of the data.
          //---------------------------------------------------------------------
          void PagingLandScapeAxisAlignedBoxSceneQuery::execute(  SceneQueryListener* listener )
          {
           if(   !(   getQueryTypeMask(   ) & SceneManager::WORLD_GEOMETRY_TYPE_MASK  )  )
           {
           OGRE_EXCEPT(   Exception::ERR_INVALIDPARAMS,  
           "PagingLandScapeSceneManager only supports WORLD_GEOMETRY_TYPE_MASK for AxisAlignedBoxSceneQueries",  
           "PagingLandScapeAxisAlignedBoxSceneQuery::execute" );
           }
           PagingLandScapeSceneManager* mgr = static_cast< PagingLandScapeSceneManager* >(  mParentSceneMgr );
          
           // Currently we ignore the y coords of the bounding box and assume they
           // want all the vertices in the xz square.
          
           // Determine page that each corner of AABB is on.
           Vector3 min = mAABB.getMinimum(   );
           Vector3 max = mAABB.getMaximum(   );
          
           // Pre-gather some constants.
           const PagingLandScapeOptions* options = mgr->getOptions(   );
           const Vector3& scale = options->scale;
           const Real maxUnScaledX = options->maxUnScaledX;
           const Real maxUnScaledZ = options->maxUnScaledZ;
           const uint pageSize = options->PageSize - 1;
           const Real invPageSize = 1.0f / pageSize;
           const uint tileSize = options->TileSize - 1;
           const Real invTileSize = 1.0f / tileSize;
           const uint maxNumTiles = options->NumTiles;
           const uint worldWidth = options->world_width;
           const uint worldHeight = options->world_height;
           // Note that for efficiency here,   I'm not allocating a new WorldFragment
           // every time,   so clients will have to use the subscribtion mechanism to
           // get the results,   as the execute(   ) that returns the SceneQueryResult
           // will contain a collection of only the last result. TODO: The ogre
           // RegionSceneQuery could be modified to only do heap allocation when
           // the subscription mechanism isn't being used by the client.
           WorldFragment worldFragment;
           worldFragment.fragmentType = SceneQuery::WFT_CUSTOM_GEOMETRY;
           CustomQueryResult result;
           worldFragment.geometry = &result;
          
           // Calculate page min/max.
           uint minPageX;
           Real localPageMinXReal;
           bool minXInWorld;
           uint minPageZ;
           Real localPageMinZReal;
           bool minZInWorld;
           uint maxPageX;
           Real localPageMaxXReal;
           bool maxXInWorld;
           uint maxPageZ;
           Real localPageMaxZReal;
           bool maxZInWorld;
          
           minXInWorld = WorldToPage(   min.x,   scale.x,   maxUnScaledX,   pageSize,   invPageSize,   worldWidth,   minPageX,   localPageMinXReal  );
           minZInWorld = WorldToPage(   min.z,   scale.z,   maxUnScaledZ,   pageSize,   invPageSize,   worldHeight,   minPageZ,   localPageMinZReal  );
           maxXInWorld = WorldToPage(   max.x,   scale.x,   maxUnScaledX,   pageSize,   invPageSize,   worldWidth,   maxPageX,   localPageMaxXReal  );
           maxZInWorld = WorldToPage(   max.z,   scale.z,   maxUnScaledZ,   pageSize,   invPageSize,   worldHeight,   maxPageZ,   localPageMaxZReal  );
          
           // At least one corner of the bounding box must be inside the world,   or
           // we return no results.
           if(   !(   minXInWorld && minZInWorld  ) || !(   maxXInWorld && maxZInWorld  ) ||
           !(   minXInWorld && maxZInWorld  ) || !(   maxXInWorld && minZInWorld  )  )
           return;
          
           // Determine the width and height of the query in terms of tile sub-sections.
           // We need to make sure we return enough vertices so the entire bounding box
           // fits within. That means for lodded tiles we may need to move to the
           // next valid vertex,   however,   satisfying this requirement should never change
           // the query extents because every tile has valid vertices at its edges.
           int localPageMinX = static_cast<int>(   localPageMinXReal  );
           int localPageMinZ = static_cast<int>(   localPageMinZReal  );
           int localPageMaxX = static_cast<int>(   Math::Ceil(   localPageMaxXReal  )  );
           int localPageMaxZ = static_cast<int>(   Math::Ceil(   localPageMaxZReal  )  );
          
           LodTracker lodTracker(   scale,  
           maxUnScaledX,  
           maxUnScaledZ,  
           pageSize,  
           tileSize,  
           maxNumTiles,  
           mgr->getPageManager(   ),  
           mgr->getData2DManager(   )  );
          
           // TODO: Expensive routine. Can we do away with it or optimze it somehow?
           AdjustEdgesForLod(   lodTracker,  
           minPageX,   minPageZ,   maxPageX,   maxPageZ,  
           localPageMinX,   localPageMinZ,   localPageMaxX,   localPageMaxZ  );
          
           // Pre-calculate the width and height of the whole query in terms of how many
           // tile sub-sections we'll have.
           int middleTiles = (   static_cast<int>(   maxPageX  ) - static_cast<int>(   minPageX  ) - 1  ) *
           (   pageSize / tileSize  ); // Get the contribution from the middle pages.
           int leftTiles = (   maxNumTiles - PageToTile(   localPageMinX,  
           invTileSize,  
           maxNumTiles  )  ); // Get contribution from the left side.
           int rightTiles = PageToTile(   localPageMaxX - 1,  
           invTileSize,  
           maxNumTiles  ) + 1; // Get contribution from the right side.
           int calcWidth = leftTiles + middleTiles + rightTiles;
          
           middleTiles = (   static_cast<int>(   maxPageZ  ) - static_cast<int>(   minPageZ  ) - 1  ) *
           (   pageSize / tileSize  ); // Get the contribution from the middle pages.
           leftTiles = (   maxNumTiles - PageToTile(   localPageMinZ,  
           invTileSize,  
           maxNumTiles  )  ); // Get contribution from the left side.
           rightTiles = PageToTile(   localPageMaxZ - 1,  
           invTileSize,  
           maxNumTiles  ) + 1; // Get contribution from the right side.
           int calcHeight = leftTiles + middleTiles + rightTiles;
          
           //Real calcWidth = (   maxPageX == minPageX  ) ? localPageMaxX - localPageMinX + 1 :
           // (   pageSize - localPageMinX  ) + localPageMaxX + 1 +
           // (   maxPageX - minPageX - 1  ) * pageSize;
           //Real calcHeight = (   maxPageZ == minPageZ  ) ? localPageMaxZ - localPageMinZ + 1 :
           // (   pageSize - localPageMinZ  ) + localPageMaxZ + 1 +
           // (   maxPageZ - minPageZ - 1  ) * pageSize;
           // Notify our caller about the width and height,   using custom geometry type.
           result.SetQueryExtents(   calcWidth,   calcHeight  );
           listener->queryResult(   &worldFragment  );
          
           uint subZ = 0;
           for(   uint pageZ = minPageZ; pageZ <= maxPageZ; ++pageZ  )
           {
           // Determine Z tile range on this page.
           uint tileBeginZ = (   pageZ == minPageZ  ) ?
           PageToTile(   localPageMinZ,   invTileSize,   maxNumTiles  ) : 0;
           uint tileEndZ = (   pageZ == maxPageZ  ) ?
           PageToTile(   localPageMaxZ - 1,   invTileSize,   maxNumTiles  ) : maxNumTiles - 1;
           for(   uint tileZ = tileBeginZ; tileZ <= tileEndZ; ++tileZ,   ++subZ  )
           {
           uint subX = 0;
           for(   uint pageX = minPageX; pageX <= maxPageX; ++pageX  )
           {
           lodTracker.SetPage(   pageX,   pageZ  );
          
           // Determine X tile range on this page.
           uint tileBeginX = (   pageX == minPageX  ) ? PageToTile(   localPageMinX,   invTileSize,   maxNumTiles  ) : 0;
           uint tileEndX = (   pageX == maxPageX  ) ? PageToTile(   localPageMaxX - 1,   invTileSize,   maxNumTiles  ) : maxNumTiles - 1;
          
           for(   uint tileX = tileBeginX; tileX <= tileEndX; ++tileX,   ++subX  )
           {
           // Determine the Z local page coord range for this tile.
           uint localPageBeginZ = (   pageZ == minPageZ  ) && (   tileZ == tileBeginZ  ) ?
           localPageMinZ : tileZ * tileSize;
           uint localPageEndZ = (   pageZ == maxPageZ  ) && (   tileZ == tileEndZ  ) ?
           localPageMaxZ : (   tileZ + 1  ) * tileSize;
          
           // Determine the X local page coord range for this tile.
           uint localPageBeginX = (   pageX == minPageX  ) && (   tileX == tileBeginX  ) ?
           localPageMinX : tileX * tileSize;
           uint localPageEndX = (   pageX == maxPageX  ) && (   tileX == tileEndX  ) ?
           localPageMaxX : (   tileX + 1  ) * tileSize;
          
           DoTileSubSection(   lodTracker,   worldFragment,   result,   listener,  
           localPageBeginX,   localPageBeginZ,   localPageEndX,   localPageEndZ,  
           subX,   subZ  );
           }
           }
           }
           }
          }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeCamera.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright © 2000-2004 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          PagingLandScapeCamera.cpp - description
          -------------------
          begin : Fri Sep 27 2002
          copyright : (  C ) 2002 by Jon Anderson
          email : janders@users.sf.net
          
          Enhancements 2003 - 2004 (  C ) The OGRE Team
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          
          
          #include "OgreCamera.h"
          
          #include "OgrePagingLandScapeCamera.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeSceneManager.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      49   PagingLandScapeCamera::PagingLandScapeCamera(  const String& name,   SceneManager* sm ) :
           PagingLandScapeOctreeCamera(  name,   sm ),  
          
           mCurrentCameraPageX(  0 ),  
           mCurrentCameraPageZ(  0 ),  
           mCurrentCameraTileX(  0 ),  
           mCurrentCameraTileZ(  0 ),  
           mIniX(  0 ),  
           mFinX(  0 ),  
           mIniZ(  0 ),  
           mFinZ(  0 ),  
           mPreIniX(  0 ),  
           mPreFinX(  0 ),  
           mPreIniZ(  0 ),  
           mPreFinZ(  0 ),  
           mLastCameraPos (  Vector3(  std::numeric_limits<Real>::max (   ),  
           0.0f,  
           std::numeric_limits<Real>::max (   ) ) )
           {
           // initialized after the Camera::Camera(   ).
           mLastViewport = 0;
           }
           //-----------------------------------------------------------------------
      72   PagingLandScapeCamera::~PagingLandScapeCamera(   )
           {
          
           }
           //-----------------------------------------------------------------------
      77   void PagingLandScapeCamera::resetPaging(   )
           {
           mCurrentCameraPageX = 0;
           mCurrentCameraPageZ = 0;
           mCurrentCameraTileX = 0;
           mCurrentCameraTileZ = 0;
           mIniX = 0;
           mFinX = 0;
           mIniZ = 0;
           mFinZ = 0;
           mPreIniX = 0;
           mPreFinX = 0;
           mPreIniZ = 0;
           mPreFinZ = 0;
           mLastCameraPos = Vector3 (  std::numeric_limits<Real>::max (   ),  
           0.0f,  
           std::numeric_limits<Real>::max (   ) );
           updatePaging (  0,   0 );
          // Real dist = Camera::getDerivedPosition(   ).squaredLength(   )
          // + mParent->getOptions(   )->cameraThreshold
          // mLastCameraPos.x = dist;
          // mLastCameraPos.y = dist;
          // mLastCameraPos.z = dist;
           }
           //-----------------------------------------------------------------------
     102   void PagingLandScapeCamera::updatePaging (  const unsigned int x,   const unsigned int z )
           {
           // We must load the next visible LandScape pages,  
           // check the LandScape boundaries
          
           mCurrentCameraPageX = x;
           mCurrentCameraPageZ = z;
           const PagingLandScapeOptions * const opt =
           static_cast <PagingLandScapeSceneManager*> (  mSceneMgr )->getOptions (   );
           const unsigned int w = opt->world_width;
           const unsigned int h = opt->world_height;
           const unsigned int adjpages = opt->max_adjacent_pages;
           const unsigned int prepages = opt->max_preload_pages;
          
           // Load Windowing
           unsigned int lx = x;
           if (  static_cast<int> (  x - adjpages ) >= 0 )
           {
           mIniX = x - adjpages;
           }
           else
           {
           mIniX = 0;
           lx -= x - adjpages;
           }
           if (  lx + adjpages < w )
           {
           mFinX = lx + adjpages;
           }
           else
           {
           mFinX = w - 1;
           mIniX = (  static_cast <int> (  mIniX + (  w - (  lx + adjpages ) ) ) > 0 )? mIniX + (  w - (  lx + adjpages ) ):0;
           }
          
           unsigned int lz = z;
           if (  static_cast<int> (  z - adjpages ) >= 0 )
           {
           mIniZ = z - adjpages;
           }
           else
           {
           mIniZ = 0;
           lz -= z - adjpages;
           }
           if (  lz + adjpages < h )
           {
           mFinZ = lz + adjpages;
           }
           else
           {
           mFinZ = h - 1;
           mIniZ = (  static_cast <int> (  mIniZ + (  h - (  lz + adjpages ) ) ) > 0 )? mIniZ + (  h - (  lz + adjpages ) ):0;
           }
          
           // Pre-load Windowing
           lx = x;
           if (  static_cast<int> (  x - prepages ) > 0 )
           {
           mPreIniX = x - prepages;
           }
           else
           {
           mPreIniX = 0;
           lx -= x - prepages;
           }
           if (  x + prepages < w )
           {
           mPreFinX = x + prepages;
           }
           else
           {
           mPreFinX = w - 1;
           mPreIniX = (  static_cast <int> (  mPreIniX + (  w - (  lx + prepages ) ) ) > 0 )? mPreIniX + (  w - (  lx + prepages ) ):0;
           }
          
           lz = z;
           if (  static_cast<int> (  z - prepages ) > 0 )
           {
           mPreIniZ = z - prepages;
           }
           else
           {
           mPreIniZ = 0;
           lz -= z - prepages;
           }
           if (  lz + prepages < h )
           {
           mPreFinZ = lz + prepages;
           }
           else
           {
           mPreFinZ = h - 1;
           mPreIniZ = (  static_cast <int> (  mPreIniZ + (  h - (  lz + prepages ) ) ) > 0 )? mPreIniZ + (  h - (  lz + prepages ) ):0;
           }
           //(  static_cast <PagingLandScapeSceneManager*> (  getSceneManager(   ) )->resize(   ) );
           }
           //-----------------------------------------------------------------------
          
     201   bool PagingLandScapeCamera::isVisible(  const AxisAlignedBox &bound ) const
           {
          
           // Null boxes always invisible
           assert (  !bound.isNull(   ) );
           // Infinite boxes always visible
           assert (  !bound.isInfinite(   ) );
          
          
           // Get centre of the box
           const Vector3 &centre (  bound.getCenter(   ) );
           // Get the half-size of the box
           const Vector3 &halfSize =(  bound.getHalfSize(   ) );
          
           // For each plane,   see if all points are on the negative side
           // If so,   object is not visible
           const bool infinite_far_clip = (  mFarDist == 0 );
           for (  unsigned int plane = 0; plane < 6; ++plane )
           {
           // Skip far plane if infinite view frustum
           if (  plane == FRUSTUM_PLANE_FAR && infinite_far_clip )
           continue;
          
           const Plane::Side side = mFrustumPlanes[plane].getSide(  centre,   halfSize );
           if (  side == Plane::NEGATIVE_SIDE )
           {
           // ALL corners on negative side therefore out of view
           return false;
           }
          
           }
           return true;
           }
          
          }
          
          
          
          

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2D.cpp

       1  /***************************************************************************
          OgrePagingLandScapeData2D.cpp - description
          -------------------
          begin : Wen Mar 06 2003
          copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
          email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreSphere.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeOptions.h"
          
          
          #ifndef _MAPSPLITTER
          
          #include "OgreAxisAlignedBox.h"
          #include "OgreMovableObject.h"
          #include "OgreSimpleRenderable.h"
          
          
          #include "OgrePagingLandScapePageManager.h"
          #include "OgrePagingLandScapeTile.h"
          #include "OgrePagingLandScapeRenderable.h"
          
          #endif// _MAPSPLITTER
          
          namespace Ogre
          {
      47   PagingLandScapeData2D::PagingLandScapeData2D(  PagingLandScapeData2DManager *pageMgr ):
           mParent(  pageMgr ),  
           mHeightData (  0 ),  
           mIsLoaded (  false ),  
           mIsModified (  false ),  
           mIsRectModified (  false ),  
           mRect (  0,   0,   0,   0,   0,   1 )
           {
           }
           //-----------------------------------------------------------------------
      57   PagingLandScapeData2D::~PagingLandScapeData2D(   )
           {
           unload (   );
           }
           //-----------------------------------------------------------------------
      62   void PagingLandScapeData2D::init(   )
           {
           //
           }
           //-----------------------------------------------------------------------
      67   void PagingLandScapeData2D::uninit(   )
           {
           PagingLandScapeData2D::unload (   );
           }
           //-----------------------------------------------------------------------
      72   bool PagingLandScapeData2D::load(  const unsigned int x,   const unsigned int z )
           {
           if (  !mIsLoaded )
           {
           mIsModified = false;
           mIsRectModified = false;
           mRect = Image::Box (  0,   0,   0,   0,   0,   1 );
          
           mPageX = x;
           mPageZ = z;
          
           mSize = mParent->getOptions(   )->PageSize;
          
           mShiftX = (  mPageX * (  mSize - 1 ) ) - mParent->getOptions(   )->maxUnScaledX;
           mShiftZ = (  mPageZ * (  mSize - 1 ) ) - mParent->getOptions(   )->maxUnScaledZ;
          
           const bool isLoadable = _load (  x,   z );
           mIsLoaded = true;
           return isLoadable;
           }
           return true;
           }
           //-----------------------------------------------------------------------
      95   void PagingLandScapeData2D::load(   )
           {
           if (  !mIsLoaded )
           {
           _load(   );
           mIsLoaded = true;
           }
           }
           //-----------------------------------------------------------------------
     104   void PagingLandScapeData2D::unload(   )
           {
           if (  mIsLoaded )
           {
           if (  mIsModified && mParent->getOptions(   )->saveDeformation )
           _save (   );
           delete[] mHeightData;
           mHeightData = 0;
           _unload(   );
           mIsLoaded = false;
           #ifndef _MAPSPLITTER
           resetDeformationRectangle (   );
           #endif
           }
           }
           //-----------------------------------------------------------------------
     120   void PagingLandScapeData2D::computePowerof2PlusOneSize(   )
           {
           mSize = mParent->getOptions(   )->PageSize;
           const size_t p2size = mSize - 1;
          
           size_t pagex = mXDimension / p2size;
           if (  mXDimension - (  pagex * p2size ) > 1 )
           pagex++;
           mXDimension = pagex * p2size + 1;
          
           size_t pagez = mZDimension / p2size;
           if (  mZDimension - (  pagez * p2size ) > 1 )
           pagez++;
           mZDimension = pagez * p2size + 1;
           }
           //-----------------------------------------------------------------------
     136   bool PagingLandScapeData2D::_checkSize(  const size_t s )
           {
           // ispow2 - 1
           const int p = static_cast <unsigned int> (  s - 1 );
           // ispow2
           return (  (  p & (  p - 1 ) ) == 0 );
           }
          
          #ifndef _MAPSPLITTER
           //-----------------------------------------------------------------------
     146   void PagingLandScapeData2D::resetDeformationRectangle (   )
           {
           mRect.left = 0;
           mRect.right = 0;
           mRect.top = 0;
           mRect.bottom = 0;
           mIsRectModified = false;
           }
           //-----------------------------------------------------------------------
     155   Image::Box PagingLandScapeData2D::getDeformationRectangle (   )
           {
           return mRect;
           }
           //-----------------------------------------------------------------------
     160   void PagingLandScapeData2D::adjustDeformationRectangle(  const unsigned int x,   const unsigned int z )
           {
           if (  mIsRectModified )
           {
           if (  mRect.left > x )
           mRect.left = x;
           if (  mRect.right < x )
           mRect.right = x;
          
           if (  mRect.top > z )
           mRect.top = z;
           if (  mRect.bottom < z )
           mRect.bottom = z;
           }
           else
           {
           // first modification :
           // deformation rectangle is the point
           mRect.left = x;
           mRect.right = x;
           mRect.top = z;
           mRect.bottom = z;
           mIsRectModified = true;
           mIsModified = true;
           }
           unsigned int tileposx = x;
           unsigned int tileposz = z;
           PagingLandScapeTile *t =
           mParent->getSceneManager(   )->getPageManager(   )->getTilePage(  tileposx,   tileposz,  
           mPageX,   mPageZ );
           if (  t && t->isLoaded (   ) )
           {
           // tells what tile portion needs to be updated.
           PagingLandScapeRenderable * const r = t->getRenderable (   );
           r->adjustDeformationRectangle (  tileposx,   tileposz );
           }
           }
           //-----------------------------------------------------------------------
     198   const bool PagingLandScapeData2D::deformHeight(  const Vector3 &deformationPoint,  
     199   Real &modificationHeight )
           {
           // adjust x and z to be local to page
           const int x = static_cast<int> (  deformationPoint.x - mShiftX );
           const int z = static_cast<int> (  deformationPoint.z - mShiftZ );
           // due to Real imprecision on Reals,   we have to use boundaries here
           // otherwise we'll hit asserts.
           const int size = static_cast<int> (  mSize-1 );
           const unsigned int ux = static_cast<unsigned int> (  std::max(  std::min (  x,   size ),   0 ) );
           const unsigned int uz = static_cast<unsigned int> (  std::max(  std::min (  z,   size ),   0 ) );
           return deformHeight(  ux,   uz,   modificationHeight );
           }
           //-----------------------------------------------------------------------
     212   const bool PagingLandScapeData2D::deformHeight(  const unsigned int x,  
           const unsigned int z,  
     214   Real &modificationHeight )
           {
           const unsigned int arraypos = static_cast <unsigned int> (  z * mSize + x );
           assert (  mHeightData && arraypos < mMaxArrayPos );
          
           const Real maxH = mParent->getMaxHeight(   );
           const Real newH = mHeightData[arraypos] - modificationHeight;
          
           bool did_modif = false;
           if (  newH <= 0.0f )
           {
           if (  mHeightData[arraypos] != 0.0f )
           did_modif = setHeight(  x,   z,   arraypos,   0.0f );
           modificationHeight = 0.0f;
           }
           else if (  newH >= maxH )
           {
           if (  mHeightData[arraypos] != maxH )
           did_modif = setHeight(  x,   z,   arraypos,   maxH );
           modificationHeight = maxH;
           }
           else
           {
           did_modif = setHeight(  x,   z,   arraypos,   newH );
           modificationHeight = newH;
           }
           return did_modif;
          
           }
           //-----------------------------------------------------------------------
     244   bool PagingLandScapeData2D::setHeight(  const unsigned int x,   const unsigned int z,  
     245   const unsigned int Pos,   const Real h )
           {
           if (  mHeightData[Pos] != h )
           {
           mHeightData[ Pos ] = h;
          
           unsigned int tileposx = x;
           unsigned int tileposz = z;
           // Make position local to tiles.
           // and return a Tile.
           PagingLandScapeTile *t =
           mParent->getSceneManager(   )->getPageManager(   )->getTilePage (  tileposx,   tileposz,  
           mPageX,   mPageZ );
           if (  t && t->isLoaded (   ) )
           {
           // tells what tile portion needs to be updated.
           PagingLandScapeRenderable * const r = t->getRenderable (   );
           r->adjustDeformationRectangle (  tileposx,   tileposz );
          
           const unsigned int tSize = mParent->getOptions(   )->TileSize - 1;
           const unsigned int NumTiles = mParent->getOptions(   )->NumTiles;
          
           const PagingLandScapeTileInfo * const info = t->getInfo(   );
           const unsigned int tX = info->mTileX;
           const unsigned int tZ = info->mTileZ;
          
           // If we're on a page edge,   we must duplicate the change on the
           // neighbour tile (  if it has one... )
           // could be a direct neighbour or a diagonal one (  in a corner. )
           const bool left = (  tileposx == 0 && tX != 0 );
           const bool right = (  tileposx == tSize && tX != NumTiles - 1 );
           const bool down = (  tileposz == 0 && tZ != 0 );
           const bool up = (  tileposz == tSize && tZ != NumTiles - 1 );
          
          
           if (  left )
           {
           PagingLandScapeRenderable * const rn = r->_getNeighbor(  WEST );
           if (  rn )
           {
           if (  down )
           {
           PagingLandScapeRenderable * const rnUp = rn->_getNeighbor(  NORTH );
           if (  rnUp && rnUp->isLoaded (   ) )
           {
           rnUp->adjustDeformationRectangle (  tSize,   tSize );
           }
           }
           else if (  up )
           {
           PagingLandScapeRenderable * const rnDown = rn->_getNeighbor(  SOUTH );
           if (  rnDown && rnDown->isLoaded (   ) )
           {
           rnDown->adjustDeformationRectangle (  tSize,   0 );
           }
           }
           if (  rn->isLoaded (   ) )
           {
           rn->adjustDeformationRectangle (  tSize,   tileposz );
           }
           }
           }
           else if (  right )
           {
           PagingLandScapeRenderable * const rn = r->_getNeighbor(  EAST );
           if (  rn )
           {
           if (  down )
           {
           PagingLandScapeRenderable * const rnUp = rn->_getNeighbor(  NORTH );
           if (  rnUp && rnUp->isLoaded (   ) )
           {
           rnUp->adjustDeformationRectangle (  0,   tSize );
           }
           }
           else if (  up )
           {
           PagingLandScapeRenderable * const rnDown = rn->_getNeighbor(  SOUTH );
           if (  rnDown && rnDown->isLoaded (   ) )
           {
           rnDown->adjustDeformationRectangle (  0,   0 );
           }
           }
           if (  rn )
           {
           rn->adjustDeformationRectangle (  0,   tileposz );
           }
           }
           }
           if (  down )
           {
           PagingLandScapeRenderable * const rn = r->_getNeighbor(  NORTH );
           if (  rn && rn->isLoaded (   ) )
           {
           rn->adjustDeformationRectangle (  tileposx,   tSize );
           }
           }
           else if (  up )
           {
           PagingLandScapeRenderable * const rn = r->_getNeighbor(  SOUTH );
           if (  rn && rn->isLoaded (   ) )
           {
           rn->adjustDeformationRectangle (  tileposx,   0 );
           }
           }
           }
          
           adjustDeformationRectangle (  x,   z );
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
     358   bool PagingLandScapeData2D::setHeight(  const unsigned int x,   const unsigned int z,  
     359   const Real h )
           {
           const unsigned int Pos = static_cast <unsigned int> (  (  z * mSize )+ x );
           assert (  mHeightData && mMaxArrayPos > Pos );
           return setHeight(  x,   z,   Pos,   h );
           }
          #endif //_MAPSPLITTER
           //-----------------------------------------------------------------------
     367   const Vector3 PagingLandScapeData2D::getNormal (  const Real mX,   const Real mZ )
           {
           // First General method : (  9 adds and 6 muls + a normalization )
           // *---v3--*
           // | | |
           // | | |
           // v1--X--v2
           // | | |
           // | | |
           // *---v4--*
           //
           // U = v2 - v1;
           // V = v4 - v3;
           // N = Cross(  U,   V );
           // N.normalise;
           //
           // BUT IN CASE OF A HEIGHTMAP :
           //
           // if you do some math by hand before you code,  
           // you can see that N is immediately given by
           // Approximation (  2 adds and a normalization )
           //
           // N = Vector3(  z[x-1][y] - z[x+1][y],   z[x][y-1] - z[x][y+1],   2 );
           // N.normalise(   );
           //
           // or even using SOBEL operator VERY accurate!
           // (  14 adds and a normalization )
           //
           // N = Vector3 (  z[x-1][y-1] + z[x-1][y] + z[x-1][y] + z[x-1][y+1] - z[x+1][y-1] - z[x+1][y] - z[x+1][y] - z[x+1][y+1],  
           // z[x-1][y-1] + z[x][y-1] + z[x][y-1] + z[x+1][y-1] - z[x-1][y+1] - z[x][y+1] - z[x][y+1] - z[x+1][y+1],  
           // 8 );
           // N.normalize(   );
          
          
           // Fast SOBEL filter
          
           const size_t pageSize = mSize - 1;
          
           // the divider make sure we do respect proportion (  height and width proportional to y )
           const Real Divider = static_cast <Real> (  pageSize ) / mParent->getOptions(   )->scale.y;
          
           assert (  mHeightData );
          
           #define getisIn(  a,   b ) (  mHeightData[static_cast<unsigned int> (  a ) + static_cast<unsigned int> (  b ) * mSize] )
          
           if (  mX > 0 && mZ > 0 &&
           mX < pageSize && mZ < pageSize )
           {
          
           // Vector3 result (  getisIn(  x-1,  z-1 ) + getisIn (  x-1,   z ) + getisIn (  x-1,   z ) + getisIn (  x-1,   z+1 ) - getisIn (  x+1,   z-1 ) - getisIn (  x+1,   z ) - getisIn (  x+1,   z ) - getisIn (  x+1,   z+1 ),  
           // 8.0f,  
           // getisIn (  x-1,   z-1 ) + getisIn (  x,   z-1 ) + getisIn (  x,   z-1 ) + getisIn (  x+1,   z-1 ) - getisIn (  x-1,   z+1 ) - getisIn (  x,   z+1 ) - getisIn (  x,   z+1 ) - getisIn (  x+1,   z+1 ) );
          
           Vector3 result(  (  getisIn (  mX - 1 ,   mZ ) - getisIn (  mX + 1 ,   mZ ) ) * Divider,  
           2.0f,  
           (  getisIn (  mX,   mZ - 1 ) - getisIn (  mX ,   mZ + 1 ) ) * Divider );
          
           result.normalise (   );
          
           return result;
           }
           else
           {
           unsigned int x = static_cast <unsigned int> (  mX );
           unsigned int z = static_cast <unsigned int> (  mZ );
           Real a,  b,  c,  d;
          
           if (  x == 0 )
           {
           a = getisIn (  x ,   z );
           b = getisIn (  x + 1,   z );
           }
           else if (  x == pageSize )
           {
           a = getisIn (  x - 1 ,   z );
           b = getisIn (  x ,   z );
           }
           else
           {
           a = getisIn (  x - 1 ,   z );
           b = getisIn (  x + 1,   z );
           }
          
           if (  z == 0 )
           {
           c = getisIn (  x ,   z );
           d = getisIn (  x ,   z + 1 );
           }
           else if (  z == pageSize )
           {
           c = getisIn (  x ,   z - 1 );
           d = getisIn (  x ,   z );
           }
           else
           {
           c = getisIn (  x ,   z - 1 );
           d = getisIn (  x ,   z + 1 );
           }
          
          
           Vector3 result(  (  a - b ) * Divider,  
           2.0f,  
           (  c - d ) * Divider );
           result.normalise (   );
           return result;
          
          #ifdef _NOWAY
          #ifndef _MAPSPLITTER
           #define getisOut(  a,   b ) (  PagingLandScapeData2DManager::getSingleton (   ).getHeightAtPage (  mPageX,   mPageZ,   static_cast<int> (  a ),   static_cast<int> (  b ) ) )
          
          // Vector3 result (  getisOut(  x-1,  z-1 ) + getisOut (  x-1,   z ) + getisOut (  x-1,   z ) + getisOut (  x-1,   z+1 ) - getisOut (  x+1,   z-1 ) - getisOut (  x+1,   z ) - getisOut (  x+1,   z ) - getisOut (  x+1,   z+1 ),  
          // 8.0f,  
          // getisOut (  x-1,   z-1 ) + getisOut (  x,   z-1 ) + getisOut (  x,   z-1 ) + getisOut (  x+1,   z-1 ) - getisOut (  x-1,   z+1 ) - getisOut (  x,   z+1 ) - getisOut (  x,   z+1 ) - getisOut (  x+1,   z+1 ) );
          
           Vector3 result(  (  getisOut (  mX - 1 ,   mZ ) - getisOut (  mX + 1 ,   mZ ) ) * Divider,  
           2.0f,  
           (  getisOut (  mX,   mZ - 1 ) - getisOut (  mX ,   mZ + 1 ) ) * Divider );
          
           result.normalise (   );
          
          
           return result;
          #endif //_MAPSPLITTER
          #endif //
          
           }
           }
          } //namespace
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          
          

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2DManager.cpp

       1  /***************************************************************************
           OgrePagingLandScapeData2DManager.cpp - description
           -------------------
           begin : Mon Jun 16 2003
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreMath.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreMovableObject.h"
          #include "OgreAxisAlignedBox.h"
          
          #include "OgrePlane.h"
          
          #include "OgreCamera.h"
          
          #include "OgreSimpleRenderable.h"
          #include "OgreException.h"
          
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeCamera.h"
          
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeData2D.h"
          
          // Data loaders implementations
          // #include "OgrePagingLandScapeData2D_HeightField.h"
          // #include "OgrePagingLandScapeData2D_HeightFieldTC.h"
          //
          // #include "OgrePagingLandScapeData2D_HeightFieldN.h"
          // #include "OgrePagingLandScapeData2D_HeightFieldNTC.h"
          //
          // #include "OgrePagingLandScapeData2D_HeightFieldRaw.h"
          // #include "OgrePagingLandScapeData2D_HeightFieldRawTC.h"
          //
          // #include "OgrePagingLandScapeData2D_Spline.h"
          //
          // // load heights from texture.
          // #include "OgrePagingLandScapeData2D_HeightFieldBlendNeighbor.h"
          
          // needed to get RenderLevel for RealHeight
          #include "OgrePagingLandScapeRenderable.h"
          #include "OgrePagingLandScapeTile.h"
          #include "OgrePagingLandScapeTileInfo.h"
          #include "OgrePagingLandScapePage.h"
          #include "OgrePagingLandScapePageManager.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      69   PagingLandScapeData2DManager::PagingLandScapeData2DManager(  PagingLandScapeSceneManager * scnMgr,  
      70   PagingLandScapeOptions * opt  ) :
           mScnMgr(  scnMgr ),  
           mOptions (  opt ),  
           mData2DType (  0 ),  
           mData2DFormat (  "" ),  
           mWidth (  0 ),  
           mHeight (  0 ),  
           mMaxHeight (  0 ),  
           mPageManager (  0 )
           {
          // // Add default texture Types.
          // registerDataType (  new PagingLandScapeData2D_HeightField (  this ) );
          // registerDataType (  new PagingLandScapeData2D_HeightFieldRaw(  this ) );
          // registerDataType (  new PagingLandScapeData2D_HeightFieldTC(  this ) );
          // #ifndef _MAPSPLITTER
          // registerDataType (  new PagingLandScapeData2D_HeightFieldN(  this ) );
          // registerDataType (  new PagingLandScapeData2D_HeightFieldRawTC(  this ) );
          // registerDataType (  new PagingLandScapeData2D_HeightFieldNTC(  this ) );
          // registerDataType (  new PagingLandScapeData2D_HeightFieldBlendNeighbor(  this ) );
          // #endif //_MAPSPLITTER
          // registerDataType (  new PagingLandScapeData2D_Spline(  this ) );
           }
           //-----------------------------------------------------------------------
      93   PagingLandScapeData2D *PagingLandScapeData2DManager::allocateData2D(   ) const
           {
           assert (  !mData2DTypeMap.empty(   ) && mData2DTypeMap[mData2DType] );
           return mData2DTypeMap[mData2DType]->newPage(   );
           }
           //-----------------------------------------------------------------------
      99   PagingLandScapeData2DManager::~PagingLandScapeData2DManager(   )
           {
           reset(   );
           // for all in map delete.
           PagingLandScapeData2DMap::iterator i = mData2DTypeMap.begin(   );
           while (  i != mData2DTypeMap.end(   ) )
           {
           delete (  *i );
           ++i;
           }
           }
           //-----------------------------------------------------------------------
     111   void PagingLandScapeData2DManager::reset(   )
           {
           if (  !mActiveData2Ds.empty(   ) )
           {
           std::for_each(  mActiveData2Ds.begin(   ),   mActiveData2Ds.end(   ),  
           std::mem_fun(  &PagingLandScapeData2D::unload ) );
          
           // Insert actives into free list
           mFreeData2Ds.insert(  mFreeData2Ds.end(   ),   mActiveData2Ds.begin(   ),   mActiveData2Ds.end(   ) );
           // Remove all active instances
           mActiveData2Ds.clear(   );
           }
          
           // could save a delete if data type is the same... ?
           if (  !mData2DPool.empty(   ) )
           {
           std::for_each(  mData2DPool.begin(   ),   mData2DPool.end(   ),   delete_object(   ) );
           mData2DPool.clear(   );
           mFreeData2Ds.clear(   );
           }
          
           mWidth = 0;
           mHeight = 0;
           }
           //-----------------------------------------------------------------------
     136   void PagingLandScapeData2DManager::load (   )
           {
           if (  mOptions->data2DFormat != mData2DFormat )
           {
           reset (   );
           mData2DFormat = mOptions->data2DFormat;
           unsigned int i = 0;
           for (  ; i != mData2DTypeMap.size(   ); ++i )
           {
           if (  StringUtil::endsWith (  mData2DTypeMap[i]->getName (   ),   mData2DFormat,   false ) )
           {
           mData2DType = i;
           break;
           }
           }
           if (  i == mData2DTypeMap.size(   ) )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,  
           "PageData2D not supplied or wrong (  check case ) !",  
           " PagingLandScapeData2DManager::load" );
           }
           }
           WorldDimensionChange(   );
           mMaxHeight = mData2DTypeMap[mData2DType]->getMaxAbsoluteHeight (   );
           }
           //-----------------------------------------------------------------------
     162   bool PagingLandScapeData2DManager::reload(  const unsigned int dataX,   const unsigned int dataZ )
           {
          #ifndef _MAPSPLITTER
           PagingLandScapeData2D* data = getData2D (  dataX,   dataZ );
          
           data->unload(   );
           const bool ret = data->load(  dataX,   dataZ );
           const unsigned int tsize = mOptions->TileSize;
           const unsigned int psize = mOptions->PageSize;
           for (  unsigned int z = 0; z <= psize ; z += tsize )
           {
           for (  unsigned int x = 0; x <= psize ; x += tsize )
           {
           data->adjustDeformationRectangle (  x,   z );
           }
           }
           return ret;
          #else //_MAPSPLITTER
           return true;
          #endif //_MAPSPLITTER
           }
           //-----------------------------------------------------------------------
     184   PagingLandScapeData2D *PagingLandScapeData2DManager::getNewData2D(  const unsigned int x,   const unsigned int z )
           {
           PagingLandScapeData2D *newData2D;
           if (  mFreeData2Ds.empty(   ) )
           {
           const size_t pool_size = mData2DPool.size (   );
           const size_t new_pool_size = (  pool_size == 0 ) ? 9 : pool_size * 2;
           mData2DPool.reserve(  new_pool_size );
           mData2DPool.resize(  new_pool_size );
          
           // Create new pages
           for (  size_t i = pool_size; i < new_pool_size; ++i )
           {
           newData2D = allocateData2D(   );
           mData2DPool[i] = newData2D;
           mFreeData2Ds.push_back (  newData2D );
           }
           }
          
           newData2D = mFreeData2Ds.front (   );
           mFreeData2Ds.pop_front (   );
           mActiveData2Ds.push_back (  newData2D );
          
           newData2D->load (  x,   z );
          
           return newData2D;
           }
           //-----------------------------------------------------------------------
     212   void PagingLandScapeData2DManager::releaseData2D(  PagingLandScapeData2D *p )
           {
           mActiveData2Ds.remove(  p );
           mFreeData2Ds.push_back(  p );
           }
           //-----------------------------------------------------------------------
     218   PagingLandScapeData2D *PagingLandScapeData2DManager::getData2D(  const unsigned int x,   const unsigned int z,  
     219   const bool alwaysReturn )
           {
           if (  x < mWidth && z < mHeight )
           {
           PagingLandScapeData2DList::iterator l,   lend = mActiveData2Ds.end(   );
           for (  l = mActiveData2Ds.begin(   ); l != lend; ++l )
           {
           if (  (  *l )->isCoord(  x,   z ) )
           return (  *l );
           }
           if (  alwaysReturn )
           return getNewData2D(  x,   z );
           }
           assert (  !alwaysReturn );
           return 0;
           }
           //-----------------------------------------------------------------------
     236   void PagingLandScapeData2DManager::clear (   )
           {
           }
           //-----------------------------------------------------------------------
     240   void PagingLandScapeData2DManager::WorldDimensionChange(   )
           {
           const unsigned int newWidth = mOptions->world_width;
           const unsigned int newHeight = mOptions->world_height;
          
           reset(   );
          
           mWidth = newWidth;
           mHeight = newHeight;
           }
           //-----------------------------------------------------------------------
     251   void PagingLandScapeData2DManager::setPageManager (  PagingLandScapeSceneManager *scnMgr )
           {
           mPageManager = scnMgr->getPageManager(   );
           }
           //-----------------------------------------------------------------------
     256   bool PagingLandScapeData2DManager::load(  const unsigned int dataX,   const unsigned int dataZ )
           {
           PagingLandScapeData2D* data = getData2D (   dataX ,   dataZ  );
           if (  !data->isLoaded (   ) )
           {
           return data->load (  dataX,   dataZ );
           }
           return true;
           }
           //-----------------------------------------------------------------------
     266   void PagingLandScapeData2DManager::unload(  const unsigned int dataX,   const unsigned int dataZ )
           {
           PagingLandScapeData2D* data = getData2D (   dataX ,   dataZ,   false  );
           if (  data && data->isLoaded (   ) )
           {
           data->unload (   );
           releaseData2D (  data );
           }
           }
          
           //-----------------------------------------------------------------------
     277   bool PagingLandScapeData2DManager::isLoaded(  const unsigned int dataX,   const unsigned int dataZ )
           {
           PagingLandScapeData2D * const data = getData2D (  dataX ,   dataZ,   false );
           return data && data->isLoaded(   );
           }
           //-----------------------------------------------------------------------
     283   const ColourValue PagingLandScapeData2DManager::getCoverageAt(  const unsigned int dataX,  
           const unsigned int dataZ,  
     285   const Real x,  
     286   const Real z )
           {
           PagingLandScapeData2D* data = getData2D (  dataX ,   dataZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           // TODO check it the terrain height is modified
           return data->getCoverage(  x,   z );
           }
           return ColourValue::White;
           }
           //-----------------------------------------------------------------------
     297   const ColourValue PagingLandScapeData2DManager::getBaseAt(  const unsigned int dataX,  
           const unsigned int dataZ,  
     299   const Real x,  
     300   const Real z )
           {
           PagingLandScapeData2D* data = getData2D (  dataX ,   dataZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           // TODO check it the terrain height is modified
           return data->getBase(  x,   z );
           }
           return ColourValue::White;
           }
           //-----------------------------------------------------------------------
     311   const Real PagingLandScapeData2DManager::getShadowAt(  const unsigned int dataX,  
           const unsigned int dataZ,  
           const unsigned int x,  
           const unsigned int z,  
     315   const bool &positive )
           {
           PagingLandScapeData2D* data = getData2D (  dataX ,   dataZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           // TODO check it the terrain height is modified
           return data->getShadow(  x,   z,   positive );
           }
           return 0.0f;
           }
           //-----------------------------------------------------------------------
     326   const Real PagingLandScapeData2DManager::getHeight(  const unsigned int dataX,  
           const unsigned int dataZ,  
     328   const Real x,  
     329   const Real z )
           {
          
           PagingLandScapeData2D* data = getData2D (  dataX ,   dataZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           // TODO check it the terrain height is modified
           return data->getHeight(  x,   z );
           }
           return 0.0f;
           }
           //-----------------------------------------------------------------------
     341   const Real PagingLandScapeData2DManager::getHeight(  const unsigned int dataX,  
           const unsigned int dataZ,  
           const unsigned int x,  
           const unsigned int z )
           {
          
           PagingLandScapeData2D* data = getData2D (  dataX ,   dataZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           return data->getHeight(  x,   z );
           }
           return 0.0f;
           }
          
           //-----------------------------------------------------------------------
          // bool PagingLandScapeData2DManager::addNewHeight(  const Sphere newSphere )
          // {
          // unsigned int x,   z;
          //
          // Vector3 s = newSphere.getCenter(   );
          // // Calculate where is going to be placed the new height
          // PagingLandScapePageManager::getSingleton (   ).getPageIndices(  s.x,   s.z,   x,   z,   true );
          // // TODO: DeScale and add the sphere to all the necessary pages
          //
          // //place it there
          // return mData2D[ x ][ z ]->addNewHeight(  newSphere );
          // }
          
           //-----------------------------------------------------------------------
          // bool PagingLandScapeData2DManager::removeNewHeight(  const Sphere oldSphere )
          // {
          // unsigned int x,   z;
          // Vector3 s = oldSphere.getCenter(   );
          // // Calculate where is going to be placed the new height
          // PagingLandScapePageManager::getSingleton (   ).getPageIndices(  s.x,   s.z,   x,   z,   true );
          // // TODO: DeScale and add the sphere to all the necessary pages
          //
          // //remove it
          // return mData2D[ x ][ z ]->removeNewHeight(  oldSphere );
          // }
           //-----------------------------------------------------------------------
     382   const Real PagingLandScapeData2DManager::getMaxHeight(  const unsigned int x,  
           const unsigned int z )
           {
           PagingLandScapeData2D* data = getData2D (  x,   z,   false );
           if (  data && data->isLoaded(   ) )
           {
           return data->getMaxHeight(   );
           }
           return mMaxHeight;
           }
           //-----------------------------------------------------------------------
     393   const Real PagingLandScapeData2DManager::getMaxHeight(   ) const
           {
           return mMaxHeight;
           }
           //-----------------------------------------------------------------------
     398   bool PagingLandScapeData2DManager::setHeight(  const Vector3 &deformationPoint,  
     399   const Real modificationHeight,  
     400   const PagingLandScapeTileInfo* info )
           {
          #ifndef _MAPSPLITTER
           const unsigned int pX = info->mPageX;
           const unsigned int pZ = info->mPageZ;
           const unsigned int pSize = mOptions->PageSize - 1;
           // adjust x and z to be local to page
           const unsigned int x = static_cast<unsigned int> (  deformationPoint.x
           - pX * pSize
           + mOptions->maxUnScaledX );
           const unsigned int z = static_cast<unsigned int> (  deformationPoint.z
           - pZ * pSize
           + mOptions->maxUnScaledZ );
          
           PagingLandScapeData2D* data = getData2D (  pX ,   pZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           Real heightResult = modificationHeight;
           if (  data->setHeight (  x,   z,   heightResult ) )
           {
           const unsigned int wL = mOptions->world_width;
           const unsigned int hL = mOptions->world_height;
          
           // If we're on a page edge,   we must duplicate the change on the
           // neighbour page (  if it has one... )
           const bool left = (  x == 0 && pX != 0 );
           const bool right = (  x == pSize && pX < wL - 1 );
           const bool down = (  z == 0 && pZ != 0 );
           const bool up = (  z == pSize && pZ < hL - 1 );
          
           assert (  z <= pSize && x <= pSize );
          
           if (  left )
           {
           if (  down )
           {
           // lower left corner
           data = getData2D (  pX - 1,   pZ - 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  pSize,   pSize,   heightResult );
           }
           }
           else if (  up )
           {
           // upper left corner
           data = getData2D (  pX - 1,   pZ + 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  pSize,   0,   heightResult );
           }
           }
          
           // left
           data = getData2D (  pX - 1,   pZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  pSize,   z,   heightResult );
           }
           }
           else if (  right )
           {
           if (  up )
           {
           // upper right corner
           data = getData2D (  pX + 1,   pZ + 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  0,   0,   heightResult );
           }
           }
           else if (  down )
           {
           // lower right corner
           data = getData2D (  pX + 1,   pZ - 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  0,   pSize,   heightResult );
           }
           }
           // right
           data = getData2D (  pX + 1,   pZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  0,   z,   heightResult );
           }
           }
           if (  down )
           {
           // lower (  down only )
           data = getData2D (  pX,   pZ - 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  x,   pSize,   heightResult );
           }
           }
           else if (  up )
           {
           // upper (  up only )
           data = getData2D (  pX,   pZ + 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  x,   0,   heightResult );
           }
           }
           return true;
           } // if (  data->deformHeight (  x,   z,   heightResult ) )
           } // if (  data->isLoaded(   ) )
          #endif
           return false;
           }
           //-----------------------------------------------------------------------
     512   bool PagingLandScapeData2DManager::deformHeight(  const Vector3 &deformationPoint,  
     513   const Real modificationHeight,  
     514   const PagingLandScapeTileInfo* info )
           {
          #ifndef _MAPSPLITTER
           const unsigned int pX = info->mPageX;
           const unsigned int pZ = info->mPageZ;
           const unsigned int pSize = mOptions->PageSize - 1;
           // adjust x and z to be local to page
           const unsigned int x = static_cast<unsigned int> (  deformationPoint.x
           - pX * pSize
           + mOptions->maxUnScaledX );
           const unsigned int z = static_cast<unsigned int> (  deformationPoint.z
           - pZ * pSize
           + mOptions->maxUnScaledZ );
          
           PagingLandScapeData2D* data = getData2D (  pX ,   pZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           Real heightResult = modificationHeight;
           if (  data->deformHeight (  x,   z,   heightResult ) )
           {
           const unsigned int wL = mOptions->world_width;
           const unsigned int hL = mOptions->world_height;
          
           // If we're on a page edge,   we must duplicate the change on the
           // neighbour page (  if it has one... )
           const bool left = (  x == 0 && pX != 0 );
           const bool right = (  x == pSize && pX < wL - 1 );
           const bool down = (  z == 0 && pZ != 0 );
           const bool up = (  z == pSize && pZ < hL - 1 );
          
           assert (  z <= pSize && x <= pSize );
          
           if (  left )
           {
           if (  down )
           {
           // lower left corner
           data = getData2D (  pX - 1,   pZ - 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  pSize,   pSize,   heightResult );
           }
           }
           else if (  up )
           {
           // upper left corner
           data = getData2D (  pX - 1,   pZ + 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  pSize,   0,   heightResult );
           }
           }
          
           // left
           data = getData2D (  pX - 1,   pZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  pSize,   z,   heightResult );
           }
           }
           else if (  right )
           {
           if (  up )
           {
           // upper right corner
           data = getData2D (  pX + 1,   pZ + 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  0,   0,   heightResult );
           }
           }
           else if (  down )
           {
           // lower right corner
           data = getData2D (  pX + 1,   pZ - 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  0,   pSize,   heightResult );
           }
           }
           // right
           data = getData2D (  pX + 1,   pZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  0,   z,   heightResult );
           }
           }
           if (  down )
           {
           // lower (  down only )
           data = getData2D (  pX,   pZ - 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  x,   pSize,   heightResult );
           }
           }
           else if (  up )
           {
           // upper (  up only )
           data = getData2D (  pX,   pZ + 1 ,   false );
           if (  data && data->isLoaded(   ) )
           {
           data->setHeight (  x,   0,   heightResult );
           }
           }
           return true;
           } // if (  data->deformHeight (  x,   z,   heightResult ) )
           } // if (  data->isLoaded(   ) )
           return false;
          #else //_MAPSPLITTER
           return true;
          #endif //_MAPSPLITTER
           }
          
           //-----------------------------------------------------------------------
     629   const Real PagingLandScapeData2DManager::getInterpolatedWorldHeight (  const Real x,   const Real z,   Real *getSlopeAt )
           {
          
          #ifndef _MAPSPLITTER
           Real heightValue;
          
           //#define _DEBUGPOS
           //#define _DEBUGPOSHEIGHTSTICH
          
           // scale position from world to page scale
           const Real unscaledX = (  x * mOptions->invScale.x ) + mOptions->maxUnScaledX;
           const Real unscaledZ = (  z * mOptions->invScale.z ) + mOptions->maxUnScaledZ;
          
           const Real pSize = mOptions->PageSize - 1;
           const Real inv_pSize = 1.0f / pSize;
          
           //get Page
           int value = static_cast< int > (  unscaledX * inv_pSize );
           const int maxPageX = static_cast< int > (  mOptions->world_width );
           const int pageNumberX = (  value < 0  ) ? 0 : (  value >= maxPageX ? maxPageX - 1: value );
           const int maxPageZ = static_cast< int > (  mOptions->world_height );
           value = static_cast< int > (  unscaledZ * inv_pSize );
           const int pageNumberZ = (  value < 0  ) ? 0 : (  value >= maxPageZ ? maxPageZ - 1: value );
          
          
           const PagingLandScapePage * const page = mScnMgr->getPageManager(   )->getPage (  pageNumberX,   pageNumberZ,   false );
           if (  ! (  page && page->isPreLoaded(   ) ) )
           return 0.0f;
          
           // adjust x and z to be local to page
           const Real localPageX = unscaledX - (  pageNumberX*pSize );
           const Real localPageZ = unscaledZ - (  pageNumberZ*pSize );
          
          
           const unsigned int tSize = mOptions->TileSize - 1;
           const Real inv_tSize = 1.0f / tSize;
          
           //get Tile
           value = static_cast< int > (  localPageX * inv_tSize );
           const int maxNumTiles = static_cast< int > (  mOptions->NumTiles );
           const int tileNumberX = (  value < 0  ) ? 0 : (  value >= maxNumTiles? maxNumTiles - 1: value );
           value = static_cast< int > (  localPageZ * inv_tSize );
           const int tileNumberZ = (  value < 0  ) ? 0 : (  value >= maxNumTiles? maxNumTiles - 1: value );
          
           // adjust x and z to be local to tile
           const int localTileX = Math::ICeil (  localPageX - tileNumberX * tSize );
           const int localTileZ = Math::ICeil (  localPageZ - tileNumberZ * tSize );
          
          
           #ifdef _DEBUGPOSHEIGHT
           {
           RenderTarget *t = mOptions->primaryCamera->getViewport(   )->getTarget (   );
           const String debugPos (  " px: " + StringConverter::toString(  pageNumberX ) +
           " pz: " + StringConverter::toString(  pageNumberZ ) +
           " lpx: " + StringConverter::toString(  localPageX ) +
           " lpz: " + StringConverter::toString(  localPageZ ) +
          
           " tx: " + StringConverter::toString(  tileNumberX ) +
           " tz: " + StringConverter::toString(  tileNumberZ ) +
           " ltx: " + StringConverter::toString(  localTileX ) +
           " ltz: " + StringConverter::toString(  localTileZ )
          
            );
           t->setDebugText(  debugPos );
           }
           #endif // _DEBUG
          
          
           PagingLandScapeTile * const tile = page->getTile (  tileNumberX,   tileNumberZ );
           bool tileLoaded = tile && tile->isLoaded(   ) && tile->getRenderable(   );
           const int currentRenderLevel = (  tileLoaded ) ?
           tile->getRenderable(   )->getRenderLevel(   )
           :
           0;
          
          
          
          
           #ifdef _DEBUGPOSHEIGHTSTICH
           String debugStich (   "(  " + StringConverter::toString(  pageNumberX ) +
           ",   " + StringConverter::toString(  pageNumberZ ) +
           " )(  " + StringConverter::toString(  tileNumberX ) +
           ",   " + StringConverter::toString(  tileNumberZ ) +
          
           " )(  " + StringConverter::toString(  localPageX ) +
           ",   " + StringConverter::toString(  localPageZ ) +
          
           " )(  " + StringConverter::toString(  localTileX ) +
           ",   " + StringConverter::toString(  localTileZ ) +
          
           " ) rdl:" + StringConverter::toString(  currentRenderLevel )
          
            );
           #endif // _DEBUGPOSHEIGHTSTICH
          
          
           // find the 4 vertices that surround the point
           // use LOD info to determine vertex data spacing - this is passed into the method
           // determine vertices on left and right of point and top and bottom
           // don't access VBO since a big performance hit when only 4 vertices are needed
          
           // Step from one vertex to another in the level detail algorithm
           const int currentLodStep = 1 << currentRenderLevel;
           //const int currentLodStep = 1;
           const Real inv_currentLodStep = 1.0f / currentLodStep;
          
           // check if can be on a stitched part of tile
           const int tileSizeMinuscurrentLodStep = tSize + 1 - currentLodStep;
           if (  tileLoaded &&
           (  localTileX <= currentLodStep ||
           localTileX >= tileSizeMinuscurrentLodStep ||
           localTileZ <= currentLodStep ||
           localTileZ >= tileSizeMinuscurrentLodStep ) )
           {
          
           // get stitching configuration
           PagingLandScapeRenderable * const r = tile->getRenderable(   );
           PagingLandScapeRenderable * neighbour;
          
           // get each tile LOD and if stitching occurs in this direction.
           neighbour = r->_getNeighbor(  NORTH );
           const bool north = (  neighbour && neighbour->isLoaded(   )
           && neighbour->getRenderLevel(   ) > currentRenderLevel
           && localTileZ <= currentLodStep );//z-1
          
           neighbour = r->_getNeighbor(  SOUTH );
           const bool south = (  neighbour && neighbour->isLoaded(   )
           && neighbour->getRenderLevel(   ) > currentRenderLevel
           && localTileZ >= tileSizeMinuscurrentLodStep );//z+1
           assert (  north != south || (  south == false && north == false ) );
          
           neighbour = r->_getNeighbor(  EAST );
           const bool east = (  neighbour && neighbour->isLoaded(   )
           && neighbour->getRenderLevel(   ) > currentRenderLevel
           && localTileX >= tileSizeMinuscurrentLodStep );//x+1
          
           neighbour = r->_getNeighbor(  WEST );
           const bool west = (  neighbour && neighbour->isLoaded(   )
           && neighbour->getRenderLevel(   ) > currentRenderLevel
           && localTileX <= currentLodStep );//x-1
           assert (  east != west || (  east == false && west == false ) );
          
           if (  north || south || east || west )
           {
          
           // Interpolate at LOD that uses stitching between tiles if needed.
           //
           // lower LOD
           // *-----------*
           // |\ \ 3 / /|
           // |1\2 \ / 4/5|
           // *--*--*--*--*
           // higher LOD
           //
           // we iterate over triangle to find which contains the points.
           // then we launch a ray to triangle intersection query.
           //
           // any simpler suggestion welcome. (  gladly,   this is hell long full of repetition code. )
           //
          
           const Vector2 pos (  localPageX,   localPageZ );
           int bottom_right_x,   bottom_right_z;
           Vector2 a2d,   b2d ,  c2d;
          
           if (  north )
           {
           bool not_found = true;
           if (  east )//northeast
           {
           #ifdef _DEBUGPOSHEIGHTSTICH
           debugStich += " north: " + StringConverter::toString(  r->_getNeighbor(  NORTH )->getRenderLevel(   ) ) +
           " east: " + StringConverter::toString(  r->_getNeighbor(  EAST )->getRenderLevel(   ) );
           #endif //_DEBUGPOSHEIGHTSTICH
          
           // neighbour lod spread
           const int neighbour_currentLodStep = 1 << r->_getNeighbor(  EAST )->getRenderLevel(   );
           // Step half way between low detail steps
           const int halfsuperstep = neighbour_currentLodStep >> 1;
           const unsigned long neighbour_lod_mask = ~(  neighbour_currentLodStep - 1 );
           bottom_right_z = static_cast<int>(  localPageZ ) & neighbour_lod_mask;
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
           bottom_right_x = static_cast<int>(  localPageX ) & lod_mask;
          
           a2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x,   bottom_right_z + halfsuperstep );
           c2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + neighbour_currentLodStep );
          
           // biggest Middle tri
           if (  !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           // all other smalls tri up to middle
           // but omit first triangle
          
           // omit first tri
           a2d = Vector2 (  bottom_right_x,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x,   bottom_right_z + currentLodStep );
           c2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
          
           int step = 1;
           while (  step < halfsuperstep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.y += currentLodStep;
           b2d.y += currentLodStep;
           }
           // stops here,   not looking after middle of higher lod.
           // middle point
           if (  step < halfsuperstep )
           not_found = false;
           }
           else
           {
           not_found = false;
           }
          
           }
           else if (  west )//northwest
           {
           #ifdef _DEBUGPOSHEIGHTSTICH
           debugStich += " north: " + StringConverter::toString(  r->_getNeighbor(  NORTH )->getRenderLevel(   ) ) +
           " west: " + StringConverter::toString(  r->_getNeighbor(  WEST )->getRenderLevel(   ) );
           #endif //_DEBUGPOSHEIGHTSTICH
          
           // neighbour lod spread
           const int neighbour_currentLodStep = 1 << r->_getNeighbor(  WEST )->getRenderLevel(   );
           // Step half way between low detail steps
           const int halfsuperstep = neighbour_currentLodStep >> 1;
           const unsigned long neighbour_lod_mask = ~(  neighbour_currentLodStep - 1 );
           bottom_right_z = static_cast<int>(  localPageZ ) & neighbour_lod_mask;
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
           bottom_right_x = static_cast<int>(  localPageX ) & lod_mask;
          
           a2d = Vector2 (  bottom_right_x,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + halfsuperstep );
           c2d = Vector2 (  bottom_right_x,   bottom_right_z + neighbour_currentLodStep );
          
           // biggest Middle tri
           if (  !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           //all other small tri
          
          
           a2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + currentLodStep );
           c2d = Vector2 (  bottom_right_x,   bottom_right_z );
          
           int step = halfsuperstep;
          
           // begins at middle point
           a2d.y += halfsuperstep;
           b2d.y += halfsuperstep;
           c2d.y += neighbour_currentLodStep;
          
           while (  step < neighbour_currentLodStep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.y += currentLodStep;
           b2d.y += currentLodStep;
           }
           // stops here
           if (  step < neighbour_currentLodStep )
           not_found = false;
           }
           else
           {
           not_found = false;
           }
           }
           if (  not_found )
           {
           // in north stitching
           #ifdef _DEBUGPOSHEIGHTSTICH
           debugStich += " north: " + StringConverter::toString(  r->_getNeighbor(  NORTH )->getRenderLevel(   ) );
           #endif //_DEBUGPOSHEIGHTSTICH
          
           // neighbour lod spread
           const int neighbour_currentLodStep = 1 << r->_getNeighbor(  NORTH )->getRenderLevel(   );
           // Step half way between low detail steps
           const int halfsuperstep = neighbour_currentLodStep >> 1;
           const unsigned long neighbour_lod_mask = ~(  neighbour_currentLodStep - 1 );
           bottom_right_x = static_cast<int>(  localPageX ) & neighbour_lod_mask;
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
           bottom_right_z = static_cast<int>(  localPageZ ) & lod_mask;
          
           a2d = Vector2 (  bottom_right_x,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x + halfsuperstep,   bottom_right_z + currentLodStep );
           c2d = Vector2 (  bottom_right_x + neighbour_currentLodStep,   bottom_right_z );
          
           // biggest Middle tri
           if (  !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           //all other small tri
          
           // could omit first and last tri ?
           int step = 0;
          
           a2d = Vector2 (  bottom_right_x,   bottom_right_z + currentLodStep );
           b2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + currentLodStep );
           c2d = Vector2 (  bottom_right_x,   bottom_right_z );
           while (  step < halfsuperstep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.x += currentLodStep;
           b2d.x += currentLodStep;
           }
           // middle point
           if (  step >= halfsuperstep )
           {
           c2d.x += neighbour_currentLodStep;
          
           while (  step < neighbour_currentLodStep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.x += currentLodStep;
           b2d.x += currentLodStep;
           }
           }
           }
           }
           }
           else if (  south )
           {
           bool not_found = true;
           if (  east )//northeast
           {
           #ifdef _DEBUGPOSHEIGHTSTICH
           debugStich += " south: " + StringConverter::toString(  r->_getNeighbor(  SOUTH )->getRenderLevel(   ) ) +
           " east: " + StringConverter::toString(  r->_getNeighbor(  EAST )->getRenderLevel(   ) );
           #endif //_DEBUGPOSHEIGHTSTICH
          
           // neighbour lod spread
           const int neighbour_currentLodStep = 1 << r->_getNeighbor(  EAST )->getRenderLevel(   );
           // Step half way between low detail steps
           const int halfsuperstep = neighbour_currentLodStep >> 1;
           const unsigned long neighbour_lod_mask = ~(  neighbour_currentLodStep - 1 );
           bottom_right_z = static_cast<int>(  localPageZ ) & neighbour_lod_mask;
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
           bottom_right_x = static_cast<int>(  localPageX ) & lod_mask;
          
           a2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x,   bottom_right_z + halfsuperstep );
           c2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + neighbour_currentLodStep );
          
           // biggest Middle tri
           if (  !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           // all other smalls tri up to middle
           // but omit first triangle
          
           // omit first tri
           a2d = Vector2 (  bottom_right_x,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x,   bottom_right_z + currentLodStep );
           c2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
          
           int step = 1;
           while (  step < halfsuperstep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.y += currentLodStep;
           b2d.y += currentLodStep;
           }
           // stops here,   not looking after middle of higher lod.
           // middle point
           if (  step < halfsuperstep )
           not_found = false;
           }
           else
           {
           not_found = false;
           }
          
           }
           else if (  west )//northwest
           {
           #ifdef _DEBUGPOSHEIGHTSTICH
           debugStich += " south: " + StringConverter::toString(  r->_getNeighbor(  SOUTH )->getRenderLevel(   ) ) +
           " west: " + StringConverter::toString(  r->_getNeighbor(  WEST )->getRenderLevel(   ) );
           #endif //_DEBUGPOSHEIGHTSTICH
          
           // neighbour lod spread
           const int neighbour_currentLodStep = 1 << r->_getNeighbor(  WEST )->getRenderLevel(   );
           // Step half way between low detail steps
           const int halfsuperstep = neighbour_currentLodStep >> 1;
           const unsigned long neighbour_lod_mask = ~(  neighbour_currentLodStep - 1 );
           bottom_right_z = static_cast<int>(  localPageZ ) & neighbour_lod_mask;
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
           bottom_right_x = static_cast<int>(  localPageX ) & lod_mask;
          
           a2d = Vector2 (  bottom_right_x,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + halfsuperstep );
           c2d = Vector2 (  bottom_right_x,   bottom_right_z + neighbour_currentLodStep );
          
           // biggest Middle tri
           if (  !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           //all other small tri
          
          
           a2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + currentLodStep );
           c2d = Vector2 (  bottom_right_x,   bottom_right_z );
          
           int step = halfsuperstep;
          
           // begins at middle point
           a2d.y += halfsuperstep;
           b2d.y += halfsuperstep;
           c2d.y += neighbour_currentLodStep;
          
           while (  step < neighbour_currentLodStep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.y += currentLodStep;
           b2d.y += currentLodStep;
           }
           // stops here
           if (  step < neighbour_currentLodStep )
           not_found = false;
           }
           else
           {
           not_found = false;
           }
           }
           if (  not_found )
           {
           // south
           #ifdef _DEBUGPOSHEIGHTSTICH
           debugStich += " south: " + StringConverter::toString(  r->_getNeighbor(  SOUTH )->getRenderLevel(   ) );
           #endif //_DEBUGPOSHEIGHTSTICH
          
           // neighbour lod spread
           const int neighbour_currentLodStep = 1 << r->_getNeighbor(  SOUTH )->getRenderLevel(   );
           // Step half way between low detail steps
           const int halfsuperstep = neighbour_currentLodStep >> 1;
           const unsigned long neighbour_lod_mask = ~(  neighbour_currentLodStep - 1 );
           bottom_right_x = static_cast<int>(  localPageX ) & neighbour_lod_mask;
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
           bottom_right_z = static_cast<int>(  localPageZ ) & lod_mask;
          
           a2d = Vector2 (  bottom_right_x,   bottom_right_z + currentLodStep );
           b2d = Vector2 (  bottom_right_x + halfsuperstep,   bottom_right_z );
           c2d = Vector2 (  bottom_right_x + neighbour_currentLodStep,   bottom_right_z + currentLodStep );
          
           // biggest Middle tri
           if (  !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           //all other small tri
          
           // could omit first and last tri ?
           int step = 0;
          
           a2d = Vector2 (  bottom_right_x,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
           c2d = Vector2 (  bottom_right_x,   bottom_right_z + currentLodStep );
          
           while (  step < halfsuperstep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.x += currentLodStep;
           b2d.x += currentLodStep;
           }
           // middle point
           if (  step >= halfsuperstep )
           {
           c2d.x += neighbour_currentLodStep;
          
           while (  step < neighbour_currentLodStep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.x += currentLodStep;
           b2d.x += currentLodStep;
           }
           }
           }
           }
           }
           else if (  east ) // just east
           {
           #ifdef _DEBUGPOSHEIGHTSTICH
           debugStich += " east: " + StringConverter::toString(  r->_getNeighbor(  EAST )->getRenderLevel(   ) );
           #endif //_DEBUGPOSHEIGHTSTICH
          
           // neighbour lod spread
           const int neighbour_currentLodStep = 1 << r->_getNeighbor(  EAST )->getRenderLevel(   );
           // Step half way between low detail steps
           const int halfsuperstep = neighbour_currentLodStep >> 1;
           const unsigned long neighbour_lod_mask = ~(  neighbour_currentLodStep - 1 );
           bottom_right_z = static_cast<int>(  localPageZ ) & neighbour_lod_mask;
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
           bottom_right_x = static_cast<int>(  localPageX ) & lod_mask;
          
           a2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x,   bottom_right_z + halfsuperstep );
           c2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + neighbour_currentLodStep );
          
           // biggest Middle tri
           if (  !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           //all other small tri
           a2d = Vector2 (  bottom_right_x,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x,   bottom_right_z + currentLodStep );
           c2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
          
           int step = 0;
           while (  step < halfsuperstep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.y += currentLodStep;
           b2d.y += currentLodStep;
           }
           // middle point
           if (  step >= halfsuperstep )
           {
           c2d.y += neighbour_currentLodStep;
          
           while (  step < neighbour_currentLodStep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.y += currentLodStep;
           b2d.y += currentLodStep;
           }
           }
           }
           }
           else if (  west ) // just west
           {
           #ifdef _DEBUGPOSHEIGHTSTICH
           debugStich += " west: " + StringConverter::toString(  r->_getNeighbor(  WEST )->getRenderLevel(   ) );
           #endif //_DEBUGPOSHEIGHTSTICH
          
           // neighbour lod spread
           const int neighbour_currentLodStep = 1 << r->_getNeighbor(  WEST )->getRenderLevel(   );
           // Step half way between low detail steps
           const int halfsuperstep = neighbour_currentLodStep >> 1;
           const unsigned long neighbour_lod_mask = ~(  neighbour_currentLodStep - 1 );
           bottom_right_z = static_cast<int>(  localPageZ ) & neighbour_lod_mask;
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
           bottom_right_x = static_cast<int>(  localPageX ) & lod_mask;
          
           a2d = Vector2 (  bottom_right_x,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + halfsuperstep );
           c2d = Vector2 (  bottom_right_x,   bottom_right_z + neighbour_currentLodStep );
          
           // biggest Middle tri
           if (  !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           //all other small tri
          
          
           a2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z );
           b2d = Vector2 (  bottom_right_x + currentLodStep,   bottom_right_z + currentLodStep );
           c2d = Vector2 (  bottom_right_x,   bottom_right_z );
          
           int step = 0;
           while (  step < halfsuperstep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.y += currentLodStep;
           b2d.y += currentLodStep;
           }
           // middle point
           if (  step >= halfsuperstep )
           {
           c2d.y += neighbour_currentLodStep;
          
           while (  step < neighbour_currentLodStep &&
           !Math::pointInTri2D (  pos,   a2d,   b2d,   c2d ) )
           {
           step += currentLodStep;
          
           a2d.y += currentLodStep;
           b2d.y += currentLodStep;
           }
           }
           }
           }
          
           const Vector3 a (  a2d.x,   getHeightAtPage (  pageNumberX,   pageNumberZ,   a2d.x,   a2d.y ),   a2d.y );
           const Vector3 b (  b2d.x,   getHeightAtPage (  pageNumberX,   pageNumberZ,   b2d.x,   b2d.y ),   b2d.y );
           const Vector3 c (  c2d.x,   getHeightAtPage (  pageNumberX,   pageNumberZ,   c2d.x,   c2d.y ),   c2d.y );
          
          
           #ifdef _DEBUGPOSHEIGHTSTICH
           const Real shiftx = pageNumberX*pSize - mOptions->maxUnScaledX;
           const Real shiftz = pageNumberZ*pSize - mOptions->maxUnScaledZ;
          
           const Vector3 A (  (  a.x + shiftx ) * mOptions->scale.x,  
           a.y,  
           (  a.z + shiftz ) * mOptions->scale.z );
           const Vector3 B (  (  b.x + shiftx ) * mOptions->scale.x,  
           b.y,  
           (  b.z + shiftz ) * mOptions->scale.z );
           const Vector3 C (  (  c.x + shiftx ) * mOptions->scale.x,  
           c.y,  
           (  c.z + shiftz ) * mOptions->scale.z );
          
           static bool debugged_stitch_none = true;
          
           static SceneNode* Anode = 0;
           static SceneNode* Bnode = 0;
           static SceneNode* Cnode = 0;
          
           if (  debugged_stitch_none )
           {
           const String name(  "TriDebugSphere" );
           Entity* entity = PagingLandScapeSceneManager::getSingleton(   ).createEntity(  name,   "sphere.mesh" );
           SceneNode* Rootnode = PagingLandScapeSceneManager::getSingleton(   ).getRootSceneNode(   );
          
           Entity *e;
           Anode = Rootnode->createChildSceneNode(  name + "A" );
           e = entity->clone(  name + "A" );
           Anode->attachObject(  e );
           Anode->setScale(  0.1f,   0.1f,   0.1f );
           Anode->showBoundingBox(  true );
           e->getMesh(   )->getSubMesh(  0 )->setMaterialName(  "BaseRedNoLightNoDepthCheck" );
          
           Bnode = Rootnode->createChildSceneNode(  name + "B" );
           e = entity->clone(  name + "B" );
           Bnode->attachObject(  e );
           Bnode->setScale(  0.1f,   0.1f,   0.1f );
           Bnode->showBoundingBox(  true );
           e->getMesh(   )->getSubMesh(  0 )->setMaterialName (  "BaseRedNoLightNoDepthCheck" );
          
          
           Cnode = Rootnode->createChildSceneNode(  name + "C" );
           e = entity->clone(  name + "C" );
           Cnode->attachObject(  e );
           Cnode->setScale(  0.1f,   0.1f,   0.1f );
           Cnode->showBoundingBox(  true );
           e->getMesh(   )->getSubMesh(  0 )->setMaterialName (  "BaseRedNoLightNoDepthCheck" );
          
           debugged_stitch_none = false;
           }
          
           Anode->setPosition(  A );
           Bnode->setPosition(  B );
           Cnode->setPosition(  C );
          
           #endif //_DEBUGPOSHEIGHTSTICH
          
          
          
           const Ray triIntersect (  Vector3(  localPageX,   getMaxHeight(   ),   localPageZ ),   Vector3::NEGATIVE_UNIT_Y );
           std::pair<bool,   Real> res = Math::intersects(  triIntersect,   a,   b,   c,   true,   true );
           if (  res.first )
           heightValue = getMaxHeight(   ) - res.second;
           else
           heightValue = 0.0f;
          
           if (  getSlopeAt )
           {
           Vector3 result;
           Vector3 vector1;
           Vector3 vector2;
          
           vector1 = a - b;
           vector2 = b - c;
           result.x = (  vector1.y * vector2.z ) - (  vector1.z * vector2.y );
           result.y = (  vector1.z * vector2.x ) - (  vector1.x * vector2.z );
           result.z = (  vector1.x * vector2.y ) - (  vector1.y * vector2.x );
          
          // result.x = (  (  top_right_y - top_left_y ) * (  -mOptions->scale.z ) );
          // result.y = mOptions->scale.x * (  -mOptions->scale.z );
          // result.z = -mOptions->scale.x * (  bottom_left_y - top_left_y );
          
           result.normalise(   );
           *getSlopeAt = 1.0 + result.y;
           if (  fabs(  *getSlopeAt ) < 0.001f )
           *getSlopeAt = 0.0f;
           }
          
           return heightValue;
           }
           }
          
           // no stitching,   easy life...
           //
           // TL-----TR 1.0
           // | / |
           // | / | .
           // | / | .
           // | / | . ^
           // | / | |
           // BL-----BR 0.0 z
           // 1.0 ... 0.0
           //
           // < - x
           //
           // Where 1.0 is currentLodStep
           //
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
          
           const int bottom_right_x = static_cast<int>(  localPageX ) & lod_mask;
           const int bottom_right_z = static_cast<int>(  localPageZ ) & lod_mask;
           const int top_right_x = bottom_right_x + currentLodStep;
           const int top_right_z = bottom_right_z + currentLodStep;
          
          
           #ifdef _DEBUGPOSHEIGHTSTICH
           if (  1 )
           {
           RenderTarget *t = mOptions->primaryCamera->getViewport(   )->getTarget (   );
           const String Debugtext (  debugStich );
           t->setDebugText (  debugStich );
           }
           #endif //_DEBUGPOSHEIGHTSTICH
          
          
           // find the 4 heights around the point
           const Real bottom_right_y = getHeightAtPage (  pageNumberX,   pageNumberZ,   bottom_right_x ,   bottom_right_z );
           const Real bottom_left_y = getHeightAtPage (  pageNumberX,   pageNumberZ,   top_right_x,   bottom_right_z );
           const Real top_right_y = getHeightAtPage (  pageNumberX,   pageNumberZ,   bottom_right_x,   top_right_z );
           const Real top_left_y = getHeightAtPage (  pageNumberX,   pageNumberZ,   top_right_x,   top_right_z );
          
          
           #ifdef _DEBUGPOSHEIGHTSTICH
           const Real shiftx = pageNumberX*pSize - mOptions->maxUnScaledX;
           const Real shiftz = pageNumberZ*pSize - mOptions->maxUnScaledZ;
          
           const Vector3 BR(  (  bottom_right_x + shiftx ) * mOptions->scale.x,  
           bottom_right_y,  
           (  bottom_right_z + shiftz ) * mOptions->scale.z );
           const Vector3 BL(  (  top_right_x + shiftx ) * mOptions->scale.x,  
           bottom_left_y,  
           (  bottom_right_z + shiftz ) * mOptions->scale.z );
           const Vector3 TR(  (  bottom_right_x + shiftx ) * mOptions->scale.x,  
           top_right_y,  
           (  top_right_z + shiftz ) * mOptions->scale.z );
           const Vector3 TL(  (  top_right_x + shiftx ) * mOptions->scale.x,  
           top_left_y,  
           (  top_right_z + shiftz ) * mOptions->scale.z );
          
           static bool debugged_none = true;
          
           static SceneNode* BRnode = 0;
           static SceneNode* BLnode = 0;
           static SceneNode* TRnode = 0;
           static SceneNode* TLnode = 0;
          
           if (  debugged_none )
           {
           const String name(  "DebugSphere" );
           Entity* entity = PagingLandScapeSceneManager::getSingleton(   ).createEntity(  name,   "sphere.mesh" );
           SceneNode* Rootnode = PagingLandScapeSceneManager::getSingleton(   ).getRootSceneNode(   );
          
           BRnode = Rootnode->createChildSceneNode(  name + "BR" );
           BRnode->attachObject(  entity->clone(  name + "BR" ) );
           BRnode->setScale(  0.1f,   0.1f,   0.1f );
           BRnode->showBoundingBox(  true );
          
           BLnode = Rootnode->createChildSceneNode(  name + "BL" );
           BLnode->attachObject(  entity->clone(  name + "BL" ) );
           BLnode->setScale(  0.1f,   0.1f,   0.1f );
           BLnode->showBoundingBox(  true );
          
          
           TRnode = Rootnode->createChildSceneNode(  name + "TR" );
           TRnode->attachObject(  entity->clone(  name + "TR" ) );
           TRnode->setScale(  0.1f,   0.1f,   0.1f );
           TRnode->showBoundingBox(  true );
          
           TLnode = Rootnode->createChildSceneNode(  name + "TL" );
           TLnode->attachObject(  entity->clone(  name + "TL" ) );
           TLnode->setScale(  0.1f,   0.1f,   0.1f );
           TLnode->showBoundingBox(  true );
          
           debugged_none = false;
           }
          
           BRnode->setPosition(  BR );
           BLnode->setPosition(  BL );
           TRnode->setPosition(  TR );
           TLnode->setPosition(  TL );
          
           if (  0 )
           {
           RenderTarget *t = mOptions->primaryCamera->getViewport(   )->getTarget (   );
           const String Debugtext (  "(  X= " + StringConverter::toString(  localPageX ) + " Z=" +
           StringConverter::toString(  localPageZ ) + " ),   (  br_x=" +
           StringConverter::toString(  bottom_right_x ) + ",   br_z=" +
           StringConverter::toString(  bottom_right_z ) + " ) & spread=" +
           StringConverter::toString(  currentLodStep )+ " ) & lod=" +
           StringConverter::toString(  currentRenderLevel ) );
           t->setDebugText(  Debugtext );
           }
           #endif //_DEBUGPOSHEIGHTSTICH
          
           const Real z_pct = (  localPageZ - bottom_right_z ) * inv_currentLodStep;
           Real x_pct = (  localPageX - bottom_right_x ) * inv_currentLodStep;
          
           if (  x_pct > 1 - z_pct )
           {
           // This point is on the upper-left tri
           const Real y1 = bottom_left_y * (  1-z_pct ) + top_left_y * z_pct;
           const Real y2 = bottom_left_y * (  1-z_pct ) + top_right_y * z_pct;
           if (  z_pct > 0.0f )
           x_pct = (  x_pct - (  1-z_pct ) ) / z_pct;
          
           if (  getSlopeAt )
           {
           Vector3 result(  (  (  top_right_y - top_left_y ) * (  -mOptions->scale.z ) ),  
           mOptions->scale.x * (  -mOptions->scale.z ),  
           -mOptions->scale.x * (  bottom_left_y - top_left_y ) );
           result.normalise(   );
           *getSlopeAt = 1.0 + result.y;
           if (  fabs(  *getSlopeAt ) < 0.001f )
           *getSlopeAt = 0.0f;
           }
          
           return y1 * x_pct + y2 * (  1-x_pct );
           } // if (  x_pct > 1 - z_pct )
           else
           {
           // This point is on the lower-right tri
           const Real y1 = bottom_left_y * (  1-z_pct ) + top_right_y * z_pct;
           const Real y2 = bottom_right_y * (  1-z_pct ) + top_right_y * z_pct;
          
           if (  z_pct < 1.0f )
           x_pct = x_pct / (  1-z_pct );
          
           if (  getSlopeAt )
           {
           Vector3 result(  (  bottom_left_y - bottom_right_y ) * mOptions->scale.z,  
           -mOptions->scale.x * mOptions->scale.z,  
           mOptions->scale.x * (  top_right_y - bottom_right_y ) );
           result.normalise(   );
           *getSlopeAt = 1.0 + result.y;
           if (  fabs(  *getSlopeAt ) < 0.001f )
           *getSlopeAt = 0.0f;
           }
          
           return y1 * x_pct + y2 * (  1-x_pct );
           }
          
          #else //_MAPSPLITTER
           return 0.0f;
          #endif //_MAPSPLITTER
           }
           //-----------------------------------------------------------------------
    1491   const Real PagingLandScapeData2DManager::getWorldHeight(  const Real x,   const Real z )
           {
          #ifndef _MAPSPLITTER
           // figure out which page the point is on
           unsigned int pageX,   pageZ;
           if (  mPageManager->getPageIndices(  x,   z,   pageX,   pageZ,   false ) )
           {
           PagingLandScapeData2D * const data = getData2D (  pageX,   pageZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           // scale position from world to page scale
           Real localX = x * mOptions->invScale.x;
           Real localZ = z * mOptions->invScale.z;
          
           // adjust x and z to be local to page
           const Real pSize = mOptions->PageSize - 1;
          
           localX -= pageX*pSize - mOptions->maxUnScaledX;
           localZ -= pageZ*pSize - mOptions->maxUnScaledZ;
          
           return getHeightAtPage (  pageX,   pageZ,   static_cast<int> (  localX ),   static_cast<int> (  localZ ) );
           }
           }
          
          #endif //_MAPSPLITTER
           return 0.0f;
           }
           //-----------------------------------------------------------------------
    1519   const Real PagingLandScapeData2DManager::getHeightAtPage(  const unsigned int dataX,   const unsigned int dataZ,  
    1520   const Real x,   const Real z )
           {
           PagingLandScapeData2D* data = getData2D (  dataX,   dataZ,   false  );
           if (  data && data->isLoaded(   ) )
           {
           Real lX = x;
           Real lZ = z;
           const Real pSize = mOptions->PageSize - 1;
           PagingLandScapeData2D* srcdata = data;
           //check if we have to change current page
           if (  lX < 0.0f )
           {
           if (  dataX == 0 )
           lX = 0.0f;
           else
           {
           data = getData2D (  dataX - 1 ,   dataZ,   false  );
           if (  data && data->isLoaded(   ) )
           {
           lX = static_cast<Real> (  pSize );
           }
           else
           {
           lX = 0.0f;
           data = srcdata;
           }
           }
          
           }
           else if (  lX > pSize )
           {
           if (  dataX == mOptions->world_width - 1 )
           lX = static_cast<Real> (  pSize );
           else
           {
           data = getData2D (  dataX + 1 ,   dataZ,   false  );
           if (  data && data->isLoaded(   ) )
           {
           lX = 0.0f;
           }
           else
           {
           lX = static_cast<Real> (  pSize );
           data = srcdata;
           }
           }
           }
          
           if (  lZ < 0.0f )
           {
           if (  dataZ == 0 )
           lZ = 0.0f;
           else
           {
           data = getData2D (  dataX,   dataZ - 1,   false  );
           if (  data && data->isLoaded(   ) )
           {
           lZ = static_cast<Real> (  pSize );
           }
           else
           {
           lZ = 0.0f;
           data = srcdata;
           }
           }
           }
           else if (  lZ > pSize )
           {
           if (  dataZ == mOptions->world_height - 1 )
           lZ = static_cast<Real> (  pSize );
           else
           {
           data = getData2D (  dataX,   dataZ + 1,   false  );
           if (  data && data->isLoaded(   ) )
           {
           lZ = 0.0f;
           }
           else
           {
           lZ = static_cast<Real> (  pSize );
           data = srcdata;
           }
           }
           }
           assert (  data );
           return data->getHeight (  lX,   lZ );
           }
           return 0.0f;
           }
           //-----------------------------------------------------------------------
    1610   const Real PagingLandScapeData2DManager::getHeightAtPage(  const unsigned int dataX,   const unsigned int dataZ,  
           const int x,   const int z )
           {
           PagingLandScapeData2D * data = getData2D (  dataX,   dataZ,   false  );
           if (  data && data->isLoaded(   ) )
           {
           int lX = x;
           int lZ = z;
           const int pSize = mOptions->PageSize - 1;
           PagingLandScapeData2D* srcdata = data;
           //check if we have to change current page
           if (  lX < 0 )
           {
           if (  dataX == 0 )
           lX = 0;
           else
           {
           data = getData2D (  dataX - 1,   dataZ,   false  );
           if (  data && data->isLoaded(   ) )
           {
           lX = pSize;
           }
           else
           {
           lX = 0;
           data = srcdata;
           }
           }
          
           }
           else if (  lX > pSize )
           {
           if (  dataX == mOptions->world_width - 1 )
           lX = pSize;
           else
           {
           data = getData2D (  dataX + 1,   dataZ,   false  );
           if (  data && data->isLoaded(   ) )
           {
           lX = 0;
           }
           else
           {
           lX = pSize;
           data = srcdata;
           }
           }
           }
          
           if (  lZ < 0 )
           {
           if (  dataZ == 0 )
           lZ = 0;
           else
           {
           data = getData2D (  dataX,   dataZ - 1,   false  );
           if (  data && data->isLoaded(   ) )
           {
           lZ = pSize;
           }
           else
           {
           lZ = 0;
           data = srcdata;
           }
           }
           }
           else if (  lZ > pSize )
           {
           if (  dataZ == mOptions->world_height - 1 )
           lZ = pSize;
           else
           {
           data = getData2D (  dataX,   dataZ + 1,   false  );
           if (  data && data->isLoaded(   ) )
           {
           lZ = 0;
           }
           else
           {
           lZ = pSize;
           data = srcdata;
           }
           }
           }
           assert (  data );
           return data->getHeight (  lX,   lZ );
           }
           else
           {
           // not a border demand and we do not have the data.
           return 0.0f;
           }
           }
          
          
           //-----------------------------------------------------------------------
    1707   const Vector3 PagingLandScapeData2DManager::getNormalAt(  const unsigned int dataX,   const unsigned int dataZ,  
           const unsigned int x,   const unsigned int z )
           {
           PagingLandScapeData2D* data = getData2D (  dataX,   dataZ,   false  );
           if (  data && data->isLoaded(   ) )
           {
           #ifdef _LOADEDNORM
           // not as precise (  rgb normals gives 8 bits precision Real )
           // and finally nearly as fast.
           return data->getNormalAt (  x,   z );
           #else /*_LOADEDNORM*/
           {
           // First General method : (  9 adds and 6 muls + a normalization )
           // *---v3--*
           // | | |
           // | | |
           // v1--X--v2
           // | | |
           // | | |
           // *---v4--*
           //
           // U = v2 - v1;
           // V = v4 - v3;
           // N = Cross(  U,   V );
           // N.normalise;
           //
           // BUT IN CASE OF A HEIGHTMAP :
           //
           // if you do some math by hand before you code,  
           // you can see that N is immediately given by
           // Approximation (  2 adds and a normalization )
           //
           // N = Vector3(  z[x-1][y] - z[x+1][y],   z[x][y-1] - z[x][y+1],   2 );
           // N.normalise(   );
           //
           // or even using SOBEL operator VERY accurate!
           // (  14 adds and a normalization )
           //
           // N = Vector3 (  z[x-1][y-1] + z[x-1][y] + z[x-1][y] + z[x-1][y+1] - z[x+1][y-1] - z[x+1][y] - z[x+1][y] - z[x+1][y+1],  
           // z[x-1][y-1] + z[x][y-1] + z[x][y-1] + z[x+1][y-1] - z[x-1][y+1] - z[x][y+1] - z[x][y+1] - z[x+1][y+1],  
           // 8 );
           // N.normalize(   );
          
          
           // Fast SOBEL filter
          
           // the divider make sure we do respect proportion (  height and width proportional to y )
           const Real Divider = static_cast <Real> (  mOptions->PageSize - 1 ) / mOptions->scale.y;
          
           #define gH(  a,   b ) (  getHeightAtPage(  dataX,   dataZ,   static_cast<int> (  a ),   static_cast<int> (  b ) ) )
          
          // Vector3 result (  (  gH(  x-1,  z-1 ) + gH (  x-1,   z ) + gH (  x-1,   z ) + gH (  x-1,   z+1 ) - gH (  x+1,   z-1 ) - gH (  x+1,   z ) - gH (  x+1,   z ) - gH (  x+1,   z+1 ) ) * Divider,  
          // 8.0f,  
          // (  gH (  x-1,   z-1 ) + gH (  x,   z-1 ) + gH (  x,   z-1 ) + gH (  x+1,   z-1 ) - gH (  x-1,   z+1 ) - gH (  x,   z+1 ) - gH (  x,   z+1 ) - gH (  x+1,   z+1 ) ) * Divider );
          
           Vector3 result(  (  gH (  x - 1 ,   z ) - gH (  x + 1 ,   z ) ) * Divider,  
           2.0f,  
           (  gH (  x,   z - 1 ) - gH (  x ,   z + 1 ) ) * Divider );
          
           result.normalise (   );
          
           return result;
           }
           #endif //_NOLOAD
           }
           return Vector3::UNIT_Y;
           }
           //----------------------------------------------------------------------------
    1775   const Real PagingLandScapeData2DManager::getRealWorldSlope(  const Real x,   const Real z )
           {
          #ifndef _MAPSPLITTER
           // figure out which page the point is on
           const Vector3 pos(  x,   0,   z );
           unsigned int pageX,   pageZ;
           if (  mPageManager->getPageIndices(  pos.x,   pos.z,   pageX,   pageZ,   false ) )
           {
          
           PagingLandScapeData2D* data = getData2D (  pageX,   pageZ,   false );
           if (  data && data->isLoaded(   ) )
           {
           // figure out which tile the point is on
           PagingLandScapeTile *t = mPageManager->getTile(  pos.x,   pos.z,  
           pageX,   pageZ,  
           false );
           unsigned int Lod = 0;
           if (  t && t->isLoaded(   ) )
           Lod = t->getRenderable(   )->getRenderLevel(   );
           const Vector3 normalVector = getNormalAt(  pageX,   pageZ,   static_cast<unsigned int>(  x ),   static_cast<unsigned int>(  z ),   Lod );
           const Real slope = 1.0f + normalVector.y;
           if (  slope < 0.001f )
           return 0.0f;
           else
           return slope;
           }
           }
          #endif //_MAPSPLITTER
           return 0.0f;
           }
          
           //-----------------------------------------------------------------------
    1807   const Vector3 PagingLandScapeData2DManager::getNormalAt(  const unsigned int pageX,   const unsigned int pageZ,   const unsigned int x,   const unsigned int z,   const unsigned int Lod )
           {
           Vector3 result;
          
           // scale position from world to page scale
           Real localX = x * mOptions->invScale.x;
           Real localZ = z * mOptions->invScale.z;
          
           // adjust x and z to be local to page
           const Real pSize = mOptions->PageSize - 1;
          
           localX -= pageX * pSize - mOptions->maxUnScaledX;
           localZ -= pageZ * pSize - mOptions->maxUnScaledZ;
          
           // make sure x and z do not go outside the world boundaries
           if (  localX < 0 )
           localX = 0;
           else if (  localX >= pSize )
           localX = pSize - 1;
          
           if (  localZ < 0 )
           localZ = 0;
           else if (  localZ >= pSize )
           localZ = pSize - 1;
          
           // find the 4 vertices that surround the point
           // use LOD info to determine vertex data spacing - this is passed into the method
           // determine vertices on left and right of point and top and bottom
           // don't access VBO since a big performance hit when only 4 vertices are needed
           const int currentLodStep = 1 << Lod;
           const Real inv_currentLodStep = 1.0f / currentLodStep;
          
           // find the vertex to the 'bottom right' of the point
           const unsigned long lod_mask = ~(  currentLodStep - 1 );
           const int bottom_right_x = static_cast<int>(  localX ) & lod_mask;
           const int bottom_right_z = static_cast<int>(  localZ ) & lod_mask;
          
           // find the 4 heights around the point
           const Real bottom_right_y = getHeightAtPage(  pageX,   pageZ,   bottom_right_x ,   bottom_right_z );
           const Real bottom_left_y = getHeightAtPage(  pageX,   pageZ,   bottom_right_x + currentLodStep,   bottom_right_z );
           const Real top_right_y = getHeightAtPage(  pageX,   pageZ,   bottom_right_x,   bottom_right_z + currentLodStep );
           const Real top_left_y = getHeightAtPage(  pageX,   pageZ,   bottom_right_x + currentLodStep,   bottom_right_z + currentLodStep );
          
           const Real z_pct = (  localZ - bottom_right_z ) * inv_currentLodStep;
           Real x_pct = (  localX - bottom_right_x ) * inv_currentLodStep;
           // TL-----TR 1.0
           // | / |
           // | / | .
           // | / | .
           // | / | . ^
           // | / | |
           // BL-----BR 0.0 z
           // 1.0 ... 0.0
           //
           // < - x
          
           if (  x_pct > 1 - z_pct )
           {
           // This point is on the upper-left tri
           /*
           Vector3 vector1;
           Vector3 vector2;
          
           vector1.x = -mOptions->scale.x;
           vector1.y = top_right_y - top_left_y;
           vector1.z = 0;
           vector2.x = 0;
           vector2.y = bottom_left_y - top_left_y;
           vector2.z = -mOptions->scale.z;
          
           result.x = (  vector1.y * vector2.z ) - (  vector1.z * vector2.y );
           result.y = (  vector1.z * vector2.x ) - (  vector1.x * vector2.z );
           result.z = (  vector1.x * vector2.y ) - (  vector1.y * vector2.x );
           */
           // The formulas for calculating result are simplified from the above
           // commented-out code for computing the cross product.
           result.x = (  (  top_right_y - top_left_y ) * (  -mOptions->scale.z ) );
           result.y = mOptions->scale.x * (  -mOptions->scale.z );
           result.z = -mOptions->scale.x * (  bottom_left_y - top_left_y );
           }
           else
           {
           // This point is on the lower-right tri
           /*
           Vector3 vector1;
           Vector3 vector2;
          
           vector1.x = mOptions->scale.x;
           vector1.y = bottom_left_y - bottom_right_y;
           vector1.z = 0;
           vector2.x = 0;
           vector2.y = top_right_y - bottom_right_y;
           vector2.z = mOptions->scale.z;
          
           result.x = (  vector1.y * vector2.z ) - (  vector1.z * vector2.y );
           result.y = (  vector1.z * vector2.x ) - (  vector1.x * vector2.z );
           result.z = (  vector1.x * vector2.y ) - (  vector1.y * vector2.x );
           */
           // The formulas for calculating result are simplified from the above
           // commented-out code for computing the cross product.
           result.x = (  bottom_left_y - bottom_right_y ) * mOptions->scale.z;
           result.y = -mOptions->scale.x * mOptions->scale.z;
           result.z = mOptions->scale.x * (  top_right_y - bottom_right_y );
           }
          
           result.normalise(   );
           return result;
           }
           //-----------------------------------------------------------------------
    1916   Real PagingLandScapeData2DManager::getMaxSlope(  Vector3 location1,   Vector3 location2,   Real maxSlopeIn )
           {
           int testCount;
           int testIndex;
           Real maxSlope;
           Real nextSlope;
           Vector3 unitVector;
           Vector3 iterationOffset;
           Vector3 nextLocation;
           Real halfWorldSizeX;
           Real halfWorldSizeZ;
           Real distBetweenPoints;
          
           // worldSizeX = (  float )mOptions->world_width * mOptions->scale.x;
           // worldSizeZ = (  float )mOptions->world_height * mOptions->scale.z;
           halfWorldSizeX = mOptions->maxScaledX;
           halfWorldSizeZ = mOptions->maxScaledZ;
          
           if (  (  location1[0] > halfWorldSizeX ) || (  location1[2] > halfWorldSizeZ ) ||
           (  location2[0] > halfWorldSizeX ) || (  location2[2] > halfWorldSizeZ ) ||
           (  location1[0] < -halfWorldSizeX ) || (  location1[2] < -halfWorldSizeZ ) ||
           (  location2[0] < -halfWorldSizeX ) || (  location2[2] < -halfWorldSizeZ ) )
           {
           // One or both endpoints is off the edge of the world. Return max slope.
           return 1.0f;
           }
          
           getInterpolatedWorldHeight(  location2.x,   location2.z,   &maxSlope );
          // maxSlope = getRealWorldSlope(  location2.x,   location2.z );
           if (  maxSlope > maxSlopeIn )
           return maxSlope;
          
           unitVector.x = location2.x - location1.x;
           unitVector.y = 0.0f;
           unitVector.z = location2.z - location1.z;
          
           // before normalizing our unitVector,   calculate the distance between the endpoints
           distBetweenPoints = (  Real )sqrt(  (  unitVector.x * unitVector.x ) + (  unitVector.z * unitVector.z ) );
          // testCount = (  int )(  distSquared / (  mOptions->scale.x * mOptions->scale.x ) / 16.0f );
           testCount = (  int )(  (  distBetweenPoints / mOptions->scale.x ) * 4.0f );
          
           unitVector.normalise(   );
           iterationOffset.x = unitVector.x * (  mOptions->scale.x / 4.0f );
           iterationOffset.z = unitVector.z * (  mOptions->scale.z / 4.0f );
          
           nextLocation.x = location1.x;
           nextLocation.y = location1.y;
           nextLocation.z = location1.z;
          
           for (  testIndex = 0; testIndex < testCount; testIndex++ )
           {
           getInterpolatedWorldHeight(  nextLocation.x,   nextLocation.z,   &nextSlope );
          // nextSlope = getRealWorldSlope(  nextLocation.x,   nextLocation.z );
           if (  nextSlope > maxSlopeIn )
           return nextSlope;
          
           if (  nextSlope > maxSlope )
           maxSlope = nextSlope;
          
           nextLocation.x += iterationOffset.x;
           nextLocation.z += iterationOffset.z;
           }
          
           return maxSlope;
           }
          
          
          
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2D_HeightField.cpp

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightField.cpp - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreLogManager.h"
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreImage.h"
          #include "OgreImageCodec.h"
          
          #include "OgreArchiveManager.h"
          
          #include "OgreStringConverter.h"
          
          #include "OgreException.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeOptions.h"
          
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeData2D_HeightField.h"
          
          #include "fileutils.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      45   PagingLandScapeData2D* PagingLandScapeData2D_HeightField::newPage(   )
           {
           return new PagingLandScapeData2D_HeightField(  mParent );
           }
           //-----------------------------------------------------------------------
      50   PagingLandScapeData2D_HeightField::PagingLandScapeData2D_HeightField(  PagingLandScapeData2DManager *dataMgr ):
           PagingLandScapeData2D(  dataMgr )
           {
           mImage = 0;
           mCoverage = 0;
           mBase = 0;
           mShadow = 0;
           mMaxheight = mParent->getOptions(   )->scale.y;
           }
           //-------------------------------------------------------------------
      60   const Real PagingLandScapeData2D_HeightField::getMaxAbsoluteHeight(  void ) const
           {
           return mParent->getOptions(   )->scale.y;
           }
           //-----------------------------------------------------------------------
      65   PagingLandScapeData2D_HeightField::~PagingLandScapeData2D_HeightField(   )
           {
           }
           //-----------------------------------------------------------------------
      69   const ColourValue PagingLandScapeData2D_HeightField::getBase (  const Real mX,   const Real mZ )
           {
           if (  mBase != 0 )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  mZ * mBase->getWidth(   ) + mX ) * 4 );//4 bytes (  mImage is RGBA )
           if (  mBase->getSize (   ) > Pos )
           {
           const Real divider = 1.0f / 255;
           return ColourValue(  (  Real ) mBase->getData(   )[ Pos + 0] * divider,  
           (  Real ) mBase->getData(   )[ Pos + 1] * divider,  
           (  Real ) mBase->getData(   )[ Pos + 2] * divider,  
           (  Real ) mBase->getData(   )[ Pos + 3] * divider );
           }
           else
           {
           return ColourValue::White;
           }
           }
           else
           {
           return ColourValue::White;
           }
           }
          
           //-----------------------------------------------------------------------
      94   const ColourValue PagingLandScapeData2D_HeightField::getCoverage (  const Real mX,   const Real mZ )
           {
           if (  mCoverage != 0 )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  mZ * mCoverage->getWidth(   ) + mX ) * 4 );//4 bytes (  mImage is RGBA )
           if (  mCoverage->getSize (   ) > Pos )
           {
           const Real divider = 1.0f / 255;
           return ColourValue(  (  Real ) mCoverage->getData(   )[ Pos + 0] * divider,  
           (  Real ) mCoverage->getData(   )[ Pos + 1] * divider,  
           (  Real ) mCoverage->getData(   )[ Pos + 2] * divider,  
           (  Real ) mCoverage->getData(   )[ Pos + 3] * divider );
           }
           else
           {
           return ColourValue::White;
           }
           }
           else
           {
           return ColourValue::White;
           }
           }
          
           //-----------------------------------------------------------------------
     119   const Real PagingLandScapeData2D_HeightField::getShadow (  const Real mX,   const Real mZ,  
     120   const bool &positive )
           {
           if (  mShadow != 0 )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  mZ * mShadow->getWidth(   ) + mX ) * 3 );//3 bytes (  mImage is RGBA )
           if (  mShadow->getSize (   ) > Pos )
           {
           if (  positive )
           return static_cast<Real> (  mShadow->getData(   )[ Pos + 0] ) / 255;
           else
           return static_cast<Real> (  mShadow->getData(   )[ Pos + 1] ) / 255;
           }
           else
           {
           return 0.0f;
           }
           }
           else
           {
           return 0.0f;
           }
           }
          
           //-----------------------------------------------------------------------
     144   const Vector3 PagingLandScapeData2D_HeightField::getNormal (  const Real x,   const Real z )
           {
           #ifndef _LOADEDNORM
           return PagingLandScapeData2D::getNormal(  x,  z );
           #else
           if (  mImage )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  z * mSize + x ) * mBpp );//4 bytes (  mImage is RGBA )
          
           if (  mMax > Pos )
           {
           const Real normalscale = 1.0f / 127.0f;
           return Vector3 (  (  (  Real )(  mImage->getData(   )[Pos + 0] ) - 128.0f ) * normalscale,  
           (  (  Real )(  mImage->getData(   )[Pos + 1] ) - 128.0f ) * normalscale,  
           (  (  Real )(  mImage->getData(   )[Pos + 2] ) - 128.0f ) * normalscale );
           }
           else
           {
           return Vector3::UNIT_Y;
           }
           }
           else
           {
           return Vector3::UNIT_Y;
           }
           #endif //_NOLOAD
           }
           //-----------------------------------------------------------------------
     172   Real PagingLandScapeData2D_HeightField::getScale(   ) const
           {
           Real prescale;
           switch (  mBpp )
           {
           case 1:
           prescale = mParent->getOptions(   )->scale.y / 255;
           break;
           case 2:
           prescale = mParent->getOptions(   )->scale.y / 65535;
           break;
           case 3:
           prescale = mParent->getOptions(   )->scale.y / 16777215;
           break;
           case 4:
           prescale = mParent->getOptions(   )->scale.y / 16777215;
           break;
           default:
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,  
           "unrecongnized number of bpp for data src image.",  
           "PagingLandScapeData2D_HeightField::getScale" );
           break;
           }
           return prescale;
           }
           //-----------------------------------------------------------------------
     198   Real PagingLandScapeData2D_HeightField::getInvScale(   ) const
           {
           Real prescale;
           switch (  mBpp )
           {
           case 1:
           prescale = 255.0 / mParent->getOptions(   )->scale.y;
           break;
           case 2:
           prescale = 65535.0 / mParent->getOptions(   )->scale.y;
           break;
           case 3:
           prescale = 16777215.0 / mParent->getOptions(   )->scale.y;
           break;
           case 4:
           prescale = 16777215.0 / mParent->getOptions(   )->scale.y;
           break;
           default:
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,  
           "unrecongnized number of bpp for data src image.",  
           "PagingLandScapeData2D_HeightField::getScale" );
           break;
           }
           return prescale;
           }
           //-----------------------------------------------------------------------
     224   void PagingLandScapeData2D_HeightField::_save(   )
           {
           const Real scale = getInvScale(   );
           const size_t bpp = mBpp;
          
           size_t j = 0;
           uchar * ogre_restrict data = mImage->getData(   );
           for (  unsigned int i = 0; i < mMaxArrayPos; i++ )
           {
           switch (  bpp )
           {
           case 1:
           data[j] = uchar (  mHeightData[i] * scale );
           break;
           case 2:
           case 3:
           case 4:
           {
           const ushort syn = ushort (  mHeightData[i] * scale );
           #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
           data[j] = uchar (  (  syn >> 8 ) & 0xff );
           data[j+ 1] = uchar (  syn & 0xff );
           #else
           data[j] = uchar (  syn & 0xff );
           data[j+ 1] = uchar (  (  syn >> 8 ) & 0xff );
           #endif
           }
           break;
           default:
           assert(  0 );
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,  
           "unrecognized bpp image.",  
           "PagingLandScapeData2D_HeightField::_save" );
           break;
           }
           j += bpp;
           }
          
           const String fname = mParent->getOptions(   )->LandScape_filename + "." +
           StringConverter::toString(  mPageZ ) + "." +
           StringConverter::toString(  mPageX ) + ".";
           const String extname = mParent->getOptions(   )->LandScape_extension;
          
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           mParent->getOptions(   )->groupName,  
           fname + extname );
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           //FileInfo *inf = &(  *it );
           char *olddir = ChangeToDir (  const_cast< char * > (  (  (  it )->archive->getName(   ) ).c_str(   ) ) );
           //FileSystemArchive::pushDirectory(   )
           mImage->save (  fname + "modif." + extname );
           //FileSystemArchive::pushDirectory(   );
           RetablishDir (  olddir );
           }
           }
           //-----------------------------------------------------------------------
     283   bool PagingLandScapeData2D_HeightField::_load(  const unsigned int mX,   const unsigned int mZ )
           {
           const PagingLandScapeOptions * const opt = mParent->getOptions(   );
           const String pageName = "." + StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + ".";
           const String &fileExt = opt->LandScape_extension;
           const String &groupName = opt->groupName;
           const String strFileName = opt->LandScape_filename + pageName;
          
           mImage = new Image(   );
           if (  !(  opt->Deformable &&
           ResourceGroupManager::getSingleton(   ).resourceExists(  groupName,   strFileName + "modif." + fileExt ) ) )
           {
           if (  !ResourceGroupManager::getSingleton(   ).resourceExists(  groupName,   strFileName + fileExt ) )
           {
           LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,  
           String(  "PLSM2 : Cannot find map named " ) + strFileName + fileExt );
           return false;
           }
           mImage->load (  strFileName + fileExt,   groupName );
           }
           else
           {
           mImage->load (  strFileName + "modif." + fileExt,   groupName );
           }
          
           //check to make sure it's 2^n + 1 size.
           if (  mImage->getWidth(   ) != mImage->getHeight(   ) ||
           !_checkSize(  mImage->getWidth(   ) ) )
           {
           String err = "Error: Invalid height map size : " +
           StringConverter::toString(  static_cast <unsigned int> (  mImage->getWidth(   ) ) ) +
           ",  " + StringConverter::toString(  static_cast <unsigned int> (  mImage->getHeight(   ) ) ) +
           ". Should be 2^n+1,   2^n+1";
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   err,  
           "PagingLandScapeData2D_HeightField::_load" );
           }
          
           mBpp = PixelUtil::getNumElemBytes (  mImage->getFormat (   ) );
           const unsigned int bpp = static_cast <unsigned int> (  mBpp );
           if (  mSize != mImage->getWidth(   ) )
           {
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,  
           "Error: Declared World size <> Height Map Size.",  
           "PagingLandScapeData2D_HeightField::_load" );
           }
          
           if (  opt->coverage_vertex_color )
           {
           mCoverage = new Image(   );
           mCoverage->load (  opt->LandScape_filename + ".Coverage" + pageName + fileExt,  
           groupName );
          
           }
           if (  opt->base_vertex_color )
           {
           mBase = new Image(   );
           mBase->load(  opt->LandScape_filename + ".Base" + pageName + fileExt,  
           groupName );
           }
          
           if (  opt->vertex_shadowed )
           {
           mShadow = new Image(   );
           mShadow->load(  opt->LandScape_filename + ".HS" + pageName + fileExt,  
           groupName );
           }
          
           mXDimension = mImage->getWidth(   ) * bpp;
           mZDimension = mImage->getHeight(   ) * bpp;
           mMax = static_cast <unsigned int> (  mSize * mSize * bpp );
           mMaxArrayPos = static_cast <unsigned int> (  mSize * mSize );
           mHeightData = new Real[mMaxArrayPos];
          
           const Real scale = getScale(   );
          
           mMaxheight = 0.0f;
           const uchar * const ogre_restrict imagedata = mImage->getData(   );
           const unsigned int maxminusone = mMax;
          
           Real h;
           unsigned int j = 0;
           Real * const ogre_restrict heightField = mHeightData;
           for (  unsigned int src_pos = 0; src_pos < maxminusone; src_pos += bpp )
           {
           switch (  bpp )
           {
           case 1:
           h = imagedata[src_pos] * scale;
           break;
           case 2:
           case 3:
           case 4:
           {
           #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
           ushort val = imagedata[src_pos] << 8;
           val += imagedata[src_pos + 1];
           #else
           ushort val = imagedata[src_pos];
           val += imagedata[src_pos + 1] << 8;
           #endif
           h = val * scale;
           }
           break;
           default:
           assert(  0 );
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,  
           "unrecongnized bpp image.",  
           "PagingLandScapeData2D_HeightField::_load" );
           break;
           }
           mMaxheight = std::max (  h,   mMaxheight );
           heightField[j++] = h;
           }
           return true;
           }
          
           //-----------------------------------------------------------------------
     401   void PagingLandScapeData2D_HeightField::_load(   )
           {
           mImage = new Image(   );
           mImage->load (  mParent->getOptions(   )->LandScape_filename +
           "." + mParent->getOptions(   )->LandScape_extension,   mParent->getOptions(   )->groupName );
           mBpp = PixelUtil::getNumElemBytes (  mImage->getFormat (   ) );
          
           mXDimension = mImage->getWidth(   );
           mZDimension = mImage->getHeight(   );
          
           const size_t sourceHeight = mZDimension;
           const size_t sourceWidth = mXDimension;
          
           computePowerof2PlusOneSize (   );
          
           mSize = mXDimension;
           mMaxArrayPos = static_cast <unsigned int> (  mXDimension * mZDimension );
           mMax = static_cast <unsigned int> (  mMaxArrayPos * mBpp );
           mHeightData = new Real[mMaxArrayPos];
          
          
           const unsigned int bpp = static_cast <unsigned int> (  mBpp );
           const Real scale = getScale(   );
          
           mMaxheight = 0.0f;
           const uchar * ogre_restrict imagedata = mImage->getData(   );
           const unsigned int maxminusone = mMax;
           const unsigned int shift_fill = static_cast <unsigned int> (  mXDimension - sourceWidth );
          
           Real h;
           unsigned int dest_pos = 0;
           unsigned int src_pos = 0;
           Real * const ogre_restrict heightField = mHeightData;
           for (  unsigned int i = 0; i < sourceHeight; ++i )
           {
           for (  unsigned int j = 0; j < sourceWidth; ++j )
           {
           switch (  bpp )
           {
           case 1:
           h = imagedata[src_pos] * scale;
           break;
           case 2:
           case 3:
           case 4:
           {
           #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
           ushort val = imagedata[src_pos] << 8;
           val += imagedata[src_pos + 1];
           #else
           ushort val = imagedata[src_pos];
           val += imagedata[src_pos + 1] << 8;
           #endif
           h = val * scale;
           }
           break;
           default:
           assert(  0 );
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,  
           "unrecongnized bpp image.",  
           "PagingLandScapeData2D_HeightField::_load" );
           break;
           }
           //DEBUG_OUTPUT (   " Bpp " << StringConverter::toString (  h ) << "\n";
           mMaxheight = std::max (  h,   mMaxheight );
           heightField[dest_pos++] = h;
           src_pos += bpp;
           }
           memset (  &heightField[dest_pos],   0,   shift_fill );
           dest_pos += shift_fill;
           }
           }
           //-----------------------------------------------------------------------
     474   void PagingLandScapeData2D_HeightField::_unload(   )
           {
           delete mImage;
           mImage = 0;
           delete mCoverage;
           mCoverage = 0;
           delete mBase;
           mBase = 0;
           delete mShadow;
           mShadow = 0;
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2D_HeightFieldBlendNeighbor.cpp

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldBlendNeighbor.cpp - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreLogManager.h"
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreImage.h"
          #include "OgreStringConverter.h"
          
          #include "OgreResourceManager.h"
          
          
          #include "OgreException.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeOptions.h"
          
          #include "OgrePagingLandScapeData2D_HeightFieldBlendNeighbor.h"
          
          #include "fileutils.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      44   PagingLandScapeData2D* PagingLandScapeData2D_HeightFieldBlendNeighbor::newPage(   )
           {
           return new PagingLandScapeData2D_HeightFieldBlendNeighbor(  mParent );
           }
           //-----------------------------------------------------------------------
      49   PagingLandScapeData2D_HeightFieldBlendNeighbor::PagingLandScapeData2D_HeightFieldBlendNeighbor(  PagingLandScapeData2DManager *dataMgr )
           : PagingLandScapeData2D(  dataMgr )
           {
           mShadow = 0;
           mMaxheight = mParent->getOptions(   )->scale.y;
           }
          
           //-------------------------------------------------------------------
      57   const Real PagingLandScapeData2D_HeightFieldBlendNeighbor::getMaxAbsoluteHeight(  void ) const
           {
           return mParent->getOptions(   )->scale.y;
           }
           //-----------------------------------------------------------------------
      62   PagingLandScapeData2D_HeightFieldBlendNeighbor::~PagingLandScapeData2D_HeightFieldBlendNeighbor(   )
           {
           PagingLandScapeData2D::unload (   );
           }
          
           //-----------------------------------------------------------------------
      68   const Real PagingLandScapeData2D_HeightFieldBlendNeighbor::getShadow (  const Real mX,   const Real mZ,  
      69   const bool &positive )
           {
           if (  mShadow )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  mZ * mShadow->getWidth(   ) + mX ) * 3 );//3 bytes (  mImage is RGBA )
           if (  mShadow->getSize (   ) > Pos )
           {
           if (  positive )
           return static_cast<Real> (  mShadow->getData(   )[ Pos + 0] ) / 255;
           else
           return static_cast<Real> (  mShadow->getData(   )[ Pos + 1] ) / 255;
           }
           else
           {
           return 0.0f;
           }
           }
           else
           {
           return 0.0f;
           }
           }
           //-----------------------------------------------------------------------
      92   void PagingLandScapeData2D_HeightFieldBlendNeighbor::_save(   )
           {
           // Disabled for now
           return;
           uchar *data = new uchar[ mXDimension * mZDimension * 2 ];
          
           const double divider = 65535.0 / mParent->getOptions(   )->scale.y;
          
           unsigned int j = 0;
           for (  unsigned int i = 0; i < mMaxArrayPos; i++ )
           {
           const ushort syn = ushort (  mHeightData[i] * divider );
           #if OGRE_ENDIAN == ENDIAN_BIG
           data[j] = uchar (  (  syn >> 8 ) & 0xff );
           data[j+ 1] = uchar (  syn & 0xff );
           #else
           data[j] = uchar (  syn & 0xff );
           data[j+ 1] = uchar (  (  syn >> 8 ) & 0xff );
           #endif
           j += 2;
           }
          
           const String fname = mParent->getOptions(   )->LandScape_filename + "." +
           StringConverter::toString(  mPageZ ) + "." +
           StringConverter::toString(  mPageX ) + ".";
           const String extname = mParent->getOptions(   )->LandScape_extension;
          
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           mParent->getOptions(   )->groupName,  
           fname + extname );
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           //FileInfo *inf = &(  *it );
           char *olddir = ChangeToDir (  const_cast< char * > (  (  (  it )->archive->getName(   ) ).c_str(   ) ) );
           //FileSystemArchive::pushDirectory(   )
          
           std::ofstream outfile;
           String FileNameRaw;
          
           DataStreamPtr image_chunk(  new MemoryDataStream (  (  void* )data,  
           mXDimension * mZDimension * 2 * sizeof (  uchar ),  
           true ) );
          
           outfile.open (  const_cast< char * > (  (  fname + "modif." + extname ).c_str(   ) ),  
           std::ios::binary );
           // Write out
           outfile << image_chunk->getAsString (   );
           outfile.close (   );
          
          
           //FileSystemArchive::pushDirectory(   );
           RetablishDir (  olddir );
           }
           }
           //-----------------------------------------------------------------------
     149   bool PagingLandScapeData2D_HeightFieldBlendNeighbor::_load(  const unsigned int mX,   const unsigned int mZ )
           {
           const PagingLandScapeOptions *Options = mParent->getOptions(   );
           const String fileName = Options->LandScape_filename;
           const String ext = Options->LandScape_extension;
           const String extModif = "modif." + ext;
          
           const String pageExtZ = "." + StringConverter::toString(  mZ ) + ".";
           const String pageExtX = StringConverter::toString(  mX ) + ".";
           const String pageExtZone = "." + StringConverter::toString(  mZ + 1 ) + ".";
           const String pageExtXone = StringConverter::toString(  mX + 1 ) + ".";
          
           // Load data
           const String strFileName = fileName + pageExtZ + pageExtX;
           const String strRightName = fileName + pageExtZ + pageExtXone;
           const String strBottomName = fileName + pageExtZone + pageExtX;
           const String strBRName = fileName + pageExtZone + pageExtXone;
          
          
           Image *tex = new Image(   );
           Image *t_right = new Image(   );
           Image *t_bottom = new Image(   );
           Image *t_br = new Image(   );
          
           if (  Options->Deformable &&
           ResourceGroupManager::getSingleton(   ).resourceExists(  Options->groupName,   strFileName + extModif ) )
           {
          
           tex->load (  strFileName + extModif,   Options->groupName );
          
          
           if (  tex->getData(   ) == 0 )
           {
           LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,   String(  "PLSM2 : Cannot find map named " ) + strFileName + extModif );
          
           delete tex;
           delete t_right;
           delete t_bottom;
           delete t_br;
          
           return false;
           }
           if (  ResourceGroupManager::getSingleton(   ).resourceExists(  Options->groupName,   strRightName + extModif ) )
           t_right->load (  strRightName + extModif,   Options->groupName );
          
           if (  ResourceGroupManager::getSingleton(   ).resourceExists(  Options->groupName,   strBottomName + extModif ) )
           t_bottom ->load (  strBottomName + extModif,   Options->groupName );
          
           if (  ResourceGroupManager::getSingleton(   ).resourceExists(  Options->groupName,   strBRName + extModif ) )
           t_br->load (  strBRName + extModif,   Options->groupName );
          
          
           }
           else
           {
           tex->load (  strFileName + ext,   Options->groupName );
          
          
           if (  tex->getData(   ) == 0 )
           {
           LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,   String(  "PLSM2 : Cannot find map named " ) + strFileName + ext );
          
           delete tex;
           delete t_right;
           delete t_bottom;
           delete t_br;
          
           return false;
           }
           if (  ResourceGroupManager::getSingleton(   ).resourceExists(  Options->groupName,   strRightName + extModif ) )
           t_right->load (  strRightName + ext,   Options->groupName );
          
           if (  ResourceGroupManager::getSingleton(   ).resourceExists(  Options->groupName,   strBottomName + extModif ) )
           t_bottom ->load (  strBottomName + ext,   Options->groupName );
          
           if (  ResourceGroupManager::getSingleton(   ).resourceExists(  Options->groupName,   strBRName + extModif ) )
           t_br->load (  strBRName + ext,   Options->groupName );
           }
           //DataStreamPtr RawData;
           //RawData = ResourceGroupManager::getSingleton(   ).openResource(  finalName,  
           //mParent->getOptions(   )->groupName );
          
           // Validate size
           // Image size comes from setting (  since RAW is not self-describing )
           // here 16 bits Raw file
           mXDimension = mSize;
           mZDimension = mXDimension;
           mBpp = (  unsigned int )PixelUtil::getNumElemBytes (  tex->getFormat (   ) );;
           mMaxArrayPos = static_cast <unsigned int> (  mSize * mSize );
           const size_t numBytes = mMaxArrayPos * mBpp;
          
           if (  tex->getWidth(   ) != tex->getHeight(   ) ||
           tex->getWidth(   ) != mSize - 1 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,  
           "Texture size (  " + StringConverter::toString(  static_cast<unsigned int> (  tex->getSize(   ) ) ) +
           " ) does not agree with configuration settings.",  
           "PagingLandScapeData2D_HeightFieldBlendNeighbor::_load" );
           }
          
           uchar *pSrc = tex->getData(   );
           uchar *pRight = t_right->getData(   );
           uchar *pBottom = t_bottom->getData(   );
           uchar *pBr = t_br->getData(   );
          
           mMax = static_cast<unsigned int> (  numBytes ) + 1;
           mHeightData = new Real[mMaxArrayPos];
           const double scale = (  1.0 / 255 ) * Options->scale.y;
           mMaxheight = 0.0f;
          
           unsigned int j = 0;
          
          
           for (  unsigned int y = 0; y < tex->getHeight(   ); y++ )
           {
           for (  unsigned int x = 0; x < tex->getWidth(   ); x++ )
           {
           const uchar val = pSrc[ y * (  mSize-1 ) + x];
          
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
          
           // grab the Right Column
           if (  t_right->getData(   ) == 0 )
           {
           // Copy the pixel if we have no right border
           const uchar val = pSrc[ y * (  mSize-1 ) + (  mSize-2 )];
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
           else
           {
           // Copy the right border
           const uchar val = pRight[ y * (  mSize-1 )];
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
           }
           // Generate the bottom row
           for (  unsigned int x = 0; x < tex->getWidth(   ); x++ )
           {
           if (  t_bottom->getData(   ) == 0 )
           {
           const uchar val = pSrc[ (  mSize-2 ) * (  mSize-1 ) + x];
          
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           } else
           {
           const uchar val = pBottom[ x];
          
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
           }
           // Corner Pixel
           if (  t_br->getData(   ) == 0 )
           {
           const uchar val = pSrc[ (  mSize-2 ) * (  mSize-1 ) + (  mSize-2 )];
          
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
           else
           {
           const uchar val = pBr[0];
          
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
          
           delete tex;
           delete t_right;
           delete t_bottom;
           delete t_br;
          
           if (  Options->vertex_shadowed )
           {
           mShadow = new Image(   );
           mShadow->load(  fileName + ".HS" + pageExtZ + pageExtX + "png",  
           Options->groupName );
           //mParent->getOptions(   )->LandScape_extension );
           }
           return true;
           }
          
           //-----------------------------------------------------------------------
     344   void PagingLandScapeData2D_HeightFieldBlendNeighbor::_load(   )
           {
           // Load data
           DataStreamPtr RawData = ResourceGroupManager::getSingleton(   ).openResource(  mParent->getOptions(   )->LandScape_filename +
           "." +
           mParent->getOptions(   )->LandScape_extension,  
           mParent->getOptions(   )->groupName );
          
           // Validate size
           // Image size comes from setting (  since RAW is not self-describing )
           // here 16 bits Raw file
          
           mXDimension = mParent->getOptions(   )->RawWidth;
           mZDimension = mParent->getOptions(   )->RawHeight;
          
           mBpp = 2;
          
           const size_t sourceHeight = mZDimension;
           const size_t sourceWidth = mXDimension;
          
           computePowerof2PlusOneSize (   );
           mSize = mXDimension;
          
           if (  RawData->size(   ) != sourceHeight*sourceWidth*2 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,  
           "RAW size (  " + StringConverter::toString(  static_cast<unsigned int> (  RawData->size(   ) ) ) +
           " ) does not agree with configuration settings.",  
           "PagingLandScapeData2D_HeightFieldBlendNeighbor::_load" );
           }
          
           mMaxArrayPos = static_cast <unsigned int> (  mXDimension * mZDimension );
           const size_t numBytes = mMaxArrayPos * mBpp;
           mMax = static_cast<unsigned int> (  numBytes ) + 1;
          
           mHeightData = new Real[mMaxArrayPos];
           const double scale = (  1.0f / 65535.0f ) * mParent->getOptions(   )->scale.y;
           mMaxheight = 0.0f;
          
          
           MemoryDataStream dc(  RawData,  
           true );
           const uchar *pSrc = dc.getPtr (   );
          
           const unsigned int shift_fill = static_cast <unsigned int> (  mXDimension - sourceWidth );
           unsigned int dest_pos = 0;
           //for some reason water is 65035 in SRTM files...
           const bool srtm_water = mParent->getOptions(   )->SRTM_water;
           for (  unsigned int i = 0; i < sourceHeight; ++i )
           {
           for (  unsigned int j = 0; j < sourceWidth; ++j )
           {
           #if OGRE_ENDIAN == ENDIAN_BIG
           ushort val = *pSrc++ <<8;
           val += *pSrc++;
           #else
           ushort val = *pSrc++;
           val += *pSrc++ <<8;
           #endif
          
           if (  srtm_water && (  val - 65035 ) > 0 )
           val = 0;
          
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[dest_pos++] = h;
           }
           memset (  &mHeightData[dest_pos],   0,   shift_fill );
           dest_pos+= shift_fill;
           }
           }
           //-----------------------------------------------------------------------
     416   void PagingLandScapeData2D_HeightFieldBlendNeighbor::_unload(   )
           {
           delete mShadow;
           mShadow = 0;
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2D_HeightFieldN.cpp

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldN.cpp - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreLogManager.h"
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreImage.h"
          #include "OgreImageCodec.h"
          
          #include "OgreArchiveManager.h"
          
          #include "OgreStringConverter.h"
          
          #include "OgreException.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeOptions.h"
          
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeData2D_HeightFieldN.h"
          
          #include "fileutils.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      45   PagingLandScapeData2D* PagingLandScapeData2D_HeightFieldN::newPage(   )
           {
           return new PagingLandScapeData2D_HeightFieldN(  mParent );
           }
           //-----------------------------------------------------------------------
      50   PagingLandScapeData2D_HeightFieldN::PagingLandScapeData2D_HeightFieldN(  PagingLandScapeData2DManager *dataMgr )
           : PagingLandScapeData2D(  dataMgr )
           {
           mImage = 0;
           mCoverage = 0;
           mBase = 0;
           mShadow = 0;
           mMaxheight = mParent->getOptions(   )->scale.y;
           }
          
           //-----------------------------------------------------------------------
      61   PagingLandScapeData2D_HeightFieldN::~PagingLandScapeData2D_HeightFieldN(   )
           {
           PagingLandScapeData2D::unload (   );
           }
          
           //-------------------------------------------------------------------
      67   const Real PagingLandScapeData2D_HeightFieldN::getMaxAbsoluteHeight(  void ) const
           {
           return mParent->getOptions(   )->scale.y;
           }
           //-----------------------------------------------------------------------
      72   const ColourValue PagingLandScapeData2D_HeightFieldN::getBase (  const Real mX,   const Real mZ )
           {
           if (  mBase != 0 )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  mZ * mBase->getWidth(   ) + mX ) * 4 );//4 bytes (  mImage is RGBA )
           if (  mBase->getSize (   ) > Pos )
           {
           const Real divider = 1.0f / 255;
           return ColourValue(  (  Real ) mBase->getData(   )[ Pos + 0] * divider,  
           (  Real ) mBase->getData(   )[ Pos + 1] * divider,  
           (  Real ) mBase->getData(   )[ Pos + 2] * divider,  
           (  Real ) mBase->getData(   )[ Pos + 3] * divider );
           }
           else
           {
           return ColourValue::White;
           }
           }
           else
           {
           return ColourValue::White;
           }
           }
          
           //-----------------------------------------------------------------------
      97   const ColourValue PagingLandScapeData2D_HeightFieldN::getCoverage (  const Real mX,   const Real mZ )
           {
           if (  mCoverage != 0 )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  mZ * mCoverage->getWidth(   ) + mX ) * 4 );//4 bytes (  mImage is RGBA )
           if (  mCoverage->getSize (   ) > Pos )
           {
           const Real divider = 1.0f / 255;
           return ColourValue(  (  Real ) mCoverage->getData(   )[ Pos + 0] * divider,  
           (  Real ) mCoverage->getData(   )[ Pos + 1] * divider,  
           (  Real ) mCoverage->getData(   )[ Pos + 2] * divider,  
           (  Real ) mCoverage->getData(   )[ Pos + 3] * divider );
           }
           else
           {
           return ColourValue::White;
           }
           }
           else
           {
           return ColourValue::White;
           }
           }
          
           //-----------------------------------------------------------------------
     122   const Real PagingLandScapeData2D_HeightFieldN::getShadow (  const Real mX,   const Real mZ,  
     123   const bool &positive )
           {
           if (  mShadow != 0 )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  mZ * mShadow->getWidth(   ) + mX ) * 3 );//3 bytes (  mImage is RGBA )
           if (  mShadow->getSize (   ) > Pos )
           {
           if (  positive )
           return static_cast<Real> (  mShadow->getData(   )[ Pos + 0] ) / 255;
           else
           return static_cast<Real> (  mShadow->getData(   )[ Pos + 1] ) / 255;
           }
           else
           {
           return 0.0f;
           }
           }
           else
           {
           return 0.0f;
           }
           }
          
           //-----------------------------------------------------------------------
     147   const Vector3 PagingLandScapeData2D_HeightFieldN::getNormal (  const Real x,   const Real z )
           {
           #ifndef _LOADEDNORM
           return PagingLandScapeData2D::getNormal(  x,  z );
           #else
           if (  mImage )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  z * mSize + x ) * mBpp );//4 bytes (  mImage is RGBA )
          
           if (  mMax > Pos )
           {
           const Real normalscale = 1.0f / 127.0f;
           return Vector3 (  (  (  Real )(  mImage->getData(   )[Pos + 0] ) - 128.0f ) * normalscale,  
           (  (  Real )(  mImage->getData(   )[Pos + 1] ) - 128.0f ) * normalscale,  
           (  (  Real )(  mImage->getData(   )[Pos + 2] ) - 128.0f ) * normalscale );
           }
           else
           {
           return Vector3::UNIT_Y;
           }
           }
           else
           {
           return Vector3::UNIT_Y;
           }
           #endif //_NOLOAD
           }
           //-----------------------------------------------------------------------
     175   void PagingLandScapeData2D_HeightFieldN::_save(   )
           {
           const Real scale = 256.0 / mParent->getOptions(   )->scale.y;
          
           uchar *img = mImage->getData(   );
           unsigned int j = 0;
           const unsigned int bpp = static_cast <unsigned int> (  mBpp );
           for (  unsigned int i = 0; i < mMax - 1; i += bpp )
           {
           img[ i + (  mBpp - 1 )] = uchar (  mHeightData[j++] * scale );
           }
           const String fname = mParent->getOptions(   )->LandScape_filename + ".HN." +
           StringConverter::toString(  mPageZ ) + "." +
           StringConverter::toString(  mPageX ) + ".";
           const String extname = mParent->getOptions(   )->LandScape_extension;
          
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           mParent->getOptions(   )->groupName,  
           fname + extname );
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           //FileInfo *inf = &(  *it );
           char *olddir = ChangeToDir (  const_cast< char * > (  (  (  it )->archive->getName(   ) ).c_str(   ) ) );
           //FileSystemArchive::pushDirectory(   )
           mImage->save (  fname + "modif." + extname );
           //FileSystemArchive::pushDirectory(   );
           RetablishDir (  olddir );
           }
           }
           //-----------------------------------------------------------------------
     207   bool PagingLandScapeData2D_HeightFieldN::_load(  const unsigned int mX,   const unsigned int mZ )
           {
           const String strFileName = mParent->getOptions(   )->LandScape_filename + ".HN." +
           StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + ".";
          
           String finalName = strFileName +
           "modif." +
           mParent->getOptions(   )->LandScape_extension;
           if (  !(  mParent->getOptions(   )->Deformable &&
           ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  
           finalName ) ) )
           {
           finalName = strFileName +
           mParent->getOptions(   )->LandScape_extension;
           if (  !ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  
           finalName ) )
           {
           LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,   String(  "PLSM2 : Cannot find map named " ) + finalName );
           return false;
           }
           }
           mImage = new Image(   );
           mImage->load (  finalName,   mParent->getOptions(   )->groupName );
          
          
           //check to make sure it's 2^n + 1 size.
           if (  mImage->getWidth(   ) != mImage->getHeight(   ) || !_checkSize(  mImage->getWidth(   ) ) )
           {
           String err = "Error: Invalid heightmap size : " +
           StringConverter::toString(  static_cast <unsigned int> (  mImage->getWidth(   ) ) ) +
           ",  " + StringConverter::toString(  static_cast <unsigned int> (  mImage->getHeight(   ) ) ) +
           ". Should be 2^n+1,   2^n+1";
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   err,   "PagingLandScapeData2D_HeightFieldN::_load" );
           }
          
           mBpp = PixelUtil::getNumElemBytes (  mImage->getFormat (   ) );
           if (  mBpp != 4 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   "Error: Image is not a RGBA image.(  4 bytes,   32 bits )",  
           "PagingLandScapeData2D_HeightFieldN::_load" );
           }
          
          
           if (  mSize != mImage->getWidth(   ) )
           {
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,   "Error: Declared World size <> Height Map Size.",   "PagingLandScapeData2D_HeightFieldN::_load" );
           }
           mMax = static_cast <unsigned int> (  mSize * mImage->getHeight(   ) * mBpp + 1 );
          
           if (  mParent->getOptions(   )->coverage_vertex_color )
           {
           mCoverage = new Image(   );
           mCoverage->load(  mParent->getOptions(   )->LandScape_filename +
           ".Coverage." +
           StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + "." +
           mParent->getOptions(   )->LandScape_extension,   mParent->getOptions(   )->groupName );
          
           }
           if (  mParent->getOptions(   )->base_vertex_color )
           {
           mBase = new Image(   );
           mBase->load(  mParent->getOptions(   )->LandScape_filename +
           ".Base." +
           StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + "." +
           mParent->getOptions(   )->LandScape_extension,   mParent->getOptions(   )->groupName );
           }
          
           if (  mParent->getOptions(   )->vertex_shadowed )
           {
           mShadow = new Image(   );
           mShadow->load(  mParent->getOptions(   )->LandScape_filename +
           ".HS." +
           StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + "." +
           mParent->getOptions(   )->LandScape_extension,   mParent->getOptions(   )->groupName );
           }
          
           mXDimension = mImage->getWidth(   );
           mZDimension = mImage->getHeight(   );
           mMaxArrayPos = static_cast <unsigned int> (  mSize * mImage->getHeight(   ) );
           mHeightData = new Real[mMaxArrayPos];
           unsigned int j = 0;
           const double scale = mParent->getOptions(   )->scale.y / 256;
           mMaxheight = 0.0f;
           uchar *imagedata = mImage->getData(   );
           const unsigned int bpp = static_cast <unsigned int> (  mBpp );
           for (  unsigned int i = 0; i < mMax - 1; i += bpp )
           {
           const Real h = imagedata[ i + (  bpp - 1 )] * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
           return true;
           }
          
           //-----------------------------------------------------------------------
     306   void PagingLandScapeData2D_HeightFieldN::_load(   )
           {
          
           mImage = new Image(   );
          
          
           mImage->load (  mParent->getOptions(   )->LandScape_filename +
           "." + mParent->getOptions(   )->LandScape_extension,   mParent->getOptions(   )->groupName );
          
          
           //check to make sure it's 2^n size.
           if (  !_checkSize(  mImage->getHeight(   ) ) || !_checkSize(  mImage->getWidth(   ) ) )
           {
           String err = "Error: Invalid heightmap size : " +
           StringConverter::toString(  static_cast <unsigned int> (  mImage->getWidth(   ) ) ) +
           ",  " + StringConverter::toString(  static_cast <unsigned int> (  mImage->getHeight(   ) ) ) +
           ". Should be 2^n";
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   err,   "PagingLandScapeData2D_HeightFieldN::_load" );
           }
          
           mBpp = static_cast <unsigned int> (  PixelUtil::getNumElemBytes (  mImage->getFormat (   ) ) );
           if (  mBpp != 1 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   "Error: Image is not a greyscale image.(  1 byte,   8 bits )",  
           "PagingLandScapeData2D_HeightFieldN::_load" );
           }
          
           mXDimension = mImage->getWidth(   );
           mZDimension = mImage->getHeight(   );
           mSize = mImage->getWidth(   );
           mMax = static_cast <unsigned int> (  mSize * mImage->getHeight(   ) * mBpp );
          
           mMaxArrayPos = static_cast <unsigned int> (  mSize * mImage->getHeight(   ) );
           mHeightData = new Real[mMaxArrayPos];
          
           const double scale = mParent->getOptions(   )->scale.y / 256;
           mMaxheight = 0.0f;
           uchar *imagedata = mImage->getData(   );
           for (  unsigned int i = 0; i < mMax; i ++ )
           {
           const Real h = imagedata[i] * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[i] = h;
           }
          
           }
           //-----------------------------------------------------------------------
     353   void PagingLandScapeData2D_HeightFieldN::_unload(   )
           {
           delete mImage;
           mImage = 0;
           delete mCoverage;
           mCoverage = 0;
           delete mBase;
           mBase = 0;
           delete mShadow;
           mShadow = 0;
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2D_HeightFieldNTC.cpp

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldNTC.cpp - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreLogManager.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreImage.h"
          #include "OgreStringConverter.h"
          
          #include "OgreException.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeOptions.h"
          
          #include "OgrePagingLandScapeData2D_HeightFieldNTC.h"
          
          
          #include "fileutils.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      43   PagingLandScapeData2D* PagingLandScapeData2D_HeightFieldNTC::newPage(   )
           {
           return new PagingLandScapeData2D_HeightFieldNTC(  mParent );
           }
           //-----------------------------------------------------------------------
      48   PagingLandScapeData2D_HeightFieldNTC::PagingLandScapeData2D_HeightFieldNTC(  PagingLandScapeData2DManager *dataMgr )
           : PagingLandScapeData2D(  dataMgr )
           {
           mImage = 0;
           input_max = 3000.0f;
           input_min = 0.0f;
           mMaxheight = _decodeTC (  1.0f ) * mParent->getOptions(   )->scale.y;
           }
          
           //-------------------------------------------------------------------
      58   const Real PagingLandScapeData2D_HeightFieldNTC::getMaxAbsoluteHeight(  void ) const
           {
           return _decodeTC (  1.0f ) * mParent->getOptions(   )->scale.y;
           }
           //-----------------------------------------------------------------------
      63   PagingLandScapeData2D_HeightFieldNTC::~PagingLandScapeData2D_HeightFieldNTC(   )
           {
           }
           //-----------------------------------------------------------------------
      67   const ColourValue PagingLandScapeData2D_HeightFieldNTC::getBase (  const Real mX,   const Real mZ )
           {
           return ColourValue::White;
           }
          
           //-----------------------------------------------------------------------
      73   const ColourValue PagingLandScapeData2D_HeightFieldNTC::getCoverage (  const Real mX,   const Real mZ )
           {
           return ColourValue::White;
           }
           //-----------------------------------------------------------------------
      78   const Vector3 PagingLandScapeData2D_HeightFieldNTC::getNormalAt (  const Real x,   const Real z )
           {
           #ifndef _LOADEDNORM
           return PagingLandScapeData2D::getNormal(  x,  z );
           #else
           if (  mImage )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  z * mSize + x ) * mBpp );//4 bytes (  mImage is RGBA )
          
           if (  mMax > Pos )
           {
           const Real normalscale = 1.0f / 127.0f;
           return Vector3 (  (  (  Real )(  mImage->getData(   )[Pos + 0] ) - 128.0f ) * normalscale,  
           (  (  Real )(  mImage->getData(   )[Pos + 1] ) - 128.0f ) * normalscale,  
           (  (  Real )(  mImage->getData(   )[Pos + 2] ) - 128.0f ) * normalscale );
           }
           else
           {
           return Vector3::UNIT_Y;
           }
           }
           else
           {
           return Vector3::UNIT_Y;
           }
           #endif //_NOLOAD
          
           }
           //-----------------------------------------------------------------------
     107   void PagingLandScapeData2D_HeightFieldNTC::_save(   )
           {
          
           const Real scale = 1.0f / mParent->getOptions(   )->scale.y;
          
           uchar *img = mImage->getData(   );
           unsigned int j = 0;
           const unsigned int bpp = static_cast <unsigned int> (  mBpp );
           for (  unsigned int i = 0; i < mMax - 1; i += bpp )
           {
           img[ i + (  mBpp - 1 )] = uchar (  _encodeTC(  mHeightData[j++] ) * scale );
           }
           const String fname = mParent->getOptions(   )->LandScape_filename + ".HN." +
           StringConverter::toString(  mPageZ ) + "." +
           StringConverter::toString(  mPageX ) + ".";
           const String extname = mParent->getOptions(   )->LandScape_extension;
          
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           mParent->getOptions(   )->groupName,  
           fname + extname );
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           //FileInfo *inf = &(  *it );
           char *olddir = ChangeToDir (  const_cast< char * > (  (  (  it )->archive->getName(   ) ).c_str(   ) ) );
           //FileSystemArchive::pushDirectory(   )
           mImage->save (  fname + "modif." + extname );
           //FileSystemArchive::pushDirectory(   );
           RetablishDir (  olddir );
           }
          
           }
           //-----------------------------------------------------------------------
     141   bool PagingLandScapeData2D_HeightFieldNTC::_load(  const unsigned int mX,   const unsigned int mZ )
           {
           const String strFileName = mParent->getOptions(   )->LandScape_filename + ".HN." +
           StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + ".";
          
           String finalName = strFileName +
           "modif." +
           mParent->getOptions(   )->LandScape_extension;
           if (  !(  mParent->getOptions(   )->Deformable &&
           ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  
           finalName ) ) )
           {
           finalName = strFileName +
           mParent->getOptions(   )->LandScape_extension;
           if (  !ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  
           finalName ) )
           {
           LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,   String(  "PLSM2 : Cannot find map named " ) + finalName );
           return false;
           }
           }
           mImage = new Image(   );
           mImage->load (  finalName,   mParent->getOptions(   )->groupName );
          
           //check to make sure it's 2^n + 1 size.
           if (  mImage->getWidth(   ) != mImage->getHeight(   ) || !_checkSize(  mImage->getWidth(   ) ) )
           {
           String err = "Error: Invalid heightmap size : " +
           StringConverter::toString(  static_cast <unsigned int> (  mImage->getWidth(   ) ) ) +
           ",  " + StringConverter::toString(  static_cast <unsigned int> (  mImage->getHeight(   ) ) ) +
           ". Should be 2^n+1,   2^n+1";
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   err,   "PagingLandScapeData2D_HeightField::_load" );
           }
          
           mBpp = PixelUtil::getNumElemBytes (  mImage->getFormat (   ) );
           if (  mBpp != 4 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   "Error: Image is not a RGBA image.(  4 bytes,   32 bits )",  
           "PagingLandScapeData2D_HeightField::_load" );
           }
          
           if (  mSize != mImage->getWidth(   ) )
           {
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,   "Error: Declared World size <> Height Map Size.",   "PagingLandScapeData2D_HeightField::_load" );
           }
          
           mXDimension = mImage->getWidth(   );
           mZDimension = mImage->getHeight(   );
           mMax = static_cast <unsigned int> (  mSize * mImage->getHeight(   ) * mBpp + 1 );
          
           mMaxArrayPos = static_cast <unsigned int> (  mSize * mImage->getHeight(   ) );
           mHeightData = new Real[mMaxArrayPos];
           unsigned int j = 0;
           const double divider = 1.0 / 255;
           const Real scale = mParent->getOptions(   )->scale.y;
           uchar *data = mImage->getData(   );
           mMaxheight = 0.0f;
           const unsigned int bpp = static_cast <unsigned int> (  mBpp );
           for (  unsigned int i = 0; i < mMax - 1; i += bpp )
           {
           const Real h = _decodeTC(  data[ i + (  mBpp - 1 )] * divider )* scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
           return true;
           }
           //-----------------------------------------------------------------------
     209   void PagingLandScapeData2D_HeightFieldNTC::_load(   )
           {
          
           mImage = new Image(   );
          
           mImage->load(  mParent->getOptions(   )->LandScape_filename +
           "." + mParent->getOptions(   )->LandScape_extension,  
           mParent->getOptions(   )->groupName );
          
           //check to make sure it's 2^n size.
           if (  !_checkSize(  mImage->getHeight(   ) ) || !_checkSize(  mImage->getWidth(   ) ) )
           {
           String err = "Error: Invalid heightmap size : " +
           StringConverter::toString(  static_cast <unsigned int> (  mImage->getWidth(   ) ) ) +
           ",  " + StringConverter::toString(  static_cast <unsigned int> (  mImage->getHeight(   ) ) ) +
           ". Should be 2^n,   2^n";
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   err,   "PagingLandScapeData2D_HeightFieldNTC::_load" );
           }
          
           mBpp = PixelUtil::getNumElemBytes (  mImage->getFormat (   ) );
           if (  mBpp != 1 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   "Error: Image is not a grayscale image.(  1 byte,   8 bits )",  
           "PagingLandScapeData2D_HeightFieldNTC::_load" );
           }
          
           mSize = static_cast <unsigned int> (  mImage->getWidth(   ) );
           mMax = static_cast <unsigned int> (  mSize * mImage->getHeight(   ) * mBpp + 1 );
          
           mMaxArrayPos = static_cast <unsigned int> (  mSize * mImage->getHeight(   ) );
           mHeightData = new Real[mMaxArrayPos];
           unsigned int j = 0;
           const double divider = 1.0 / 255;
           const Real scale = mParent->getOptions(   )->scale.y;
           uchar *data = mImage->getData(   );
           mMaxheight = 0.0f;
           const unsigned int bpp = static_cast <unsigned int> (  mBpp );
           for (  unsigned int i = 0; i < mMax - 1; i += bpp )
           {
           const Real h = _decodeTC(  data[ i + (  mBpp - 1 )] * divider )* scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
          
           }
          
          
           //-----------------------------------------------------------------------
     257   void PagingLandScapeData2D_HeightFieldNTC::_unload(   )
           {
           delete mImage;
           mImage = 0;
           }
          
           //-----------------------------------------------------------------------
     264   inline Real PagingLandScapeData2D_HeightFieldNTC::_decodeTC(  const Real encoded ) const
           {
           return (  (  Real ) (  encoded + 0.5f ) ) * (  input_max - input_min ) + input_min;
           }
          
           //-----------------------------------------------------------------------
     270   inline uchar PagingLandScapeData2D_HeightFieldNTC::_encodeTC(  const Real decoded ) const
           {
           return static_cast<uchar> (  (  decoded - input_min ) / (  input_max - input_min ) - 0.5f );
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2D_HeightFieldRaw.cpp

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldRaw.cpp - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreLogManager.h"
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreImage.h"
          #include "OgreStringConverter.h"
          
          #include "OgreResourceManager.h"
          
          
          #include "OgreException.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeOptions.h"
          
          #include "OgrePagingLandScapeData2D_HeightFieldRaw.h"
          
          #include "fileutils.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      44   PagingLandScapeData2D* PagingLandScapeData2D_HeightFieldRaw::newPage(   )
           {
           return new PagingLandScapeData2D_HeightFieldRaw(  mParent );
           }
           //-----------------------------------------------------------------------
      49   PagingLandScapeData2D_HeightFieldRaw::PagingLandScapeData2D_HeightFieldRaw(  PagingLandScapeData2DManager *dataMgr )
           : PagingLandScapeData2D(  dataMgr )
           {
           mShadow = 0;
           mMaxheight = mParent->getOptions(   )->scale.y;
           }
           //-------------------------------------------------------------------
      56   const Real PagingLandScapeData2D_HeightFieldRaw::getMaxAbsoluteHeight(  void ) const
           {
           return mParent->getOptions(   )->scale.y;
           }
           //-----------------------------------------------------------------------
      61   PagingLandScapeData2D_HeightFieldRaw::~PagingLandScapeData2D_HeightFieldRaw(   )
           {
           }
          
           //-----------------------------------------------------------------------
      66   const Real PagingLandScapeData2D_HeightFieldRaw::getShadow (  const Real mX,   const Real mZ,  
      67   const bool &positive )
           {
           if (  mShadow )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  mZ * mShadow->getWidth(   ) + mX ) * 3 );//3 bytes (  mImage is RGBA )
           if (  mShadow->getSize (   ) > Pos )
           {
           if (  positive )
           return static_cast<Real> (  mShadow->getData(   )[ Pos + 0] ) / 255;
           else
           return static_cast<Real> (  mShadow->getData(   )[ Pos + 1] ) / 255;
           }
           else
           {
           return 0.0f;
           }
           }
           else
           {
           return 0.0f;
           }
           }
           //-----------------------------------------------------------------------
      90   void PagingLandScapeData2D_HeightFieldRaw::_save(   )
           {
           uchar *data = new uchar[ mXDimension * mZDimension * 2 ];
          
           const double divider = 65535.0 / mParent->getOptions(   )->scale.y;
          
           unsigned int j = 0;
           for (  unsigned int i = 0; i < mMaxArrayPos; i++ )
           {
           const ushort syn = ushort (  mHeightData[i] * divider );
           #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
           data[j] = uchar (  (  syn >> 8 ) & 0xff );
           data[j+ 1] = uchar (  syn & 0xff );
           #else
           data[j] = uchar (  syn & 0xff );
           data[j+ 1] = uchar (  (  syn >> 8 ) & 0xff );
           #endif
           j += 2;
           }
          
           const String fname = mParent->getOptions(   )->LandScape_filename + "." +
           StringConverter::toString(  mPageZ ) + "." +
           StringConverter::toString(  mPageX ) + ".";
           const String extname = mParent->getOptions(   )->LandScape_extension;
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           mParent->getOptions(   )->groupName,  
           fname + extname );
           //ResourceGroupManager::getSingleton(   ).openResource (   )
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           //FileInfo *inf = &(  *it );
           char *olddir = ChangeToDir (  const_cast< char * > (  (  (  it )->archive->getName(   ) ).c_str(   ) ) );
           //FileSystemArchive::pushDirectory(   )
          
           std::ofstream outfile;
           String FileNameRaw;
          
           DataStreamPtr image_chunk(  new MemoryDataStream (  (  void* )data,  
           mXDimension * mZDimension * 2 * sizeof (  uchar ),  
           true ) );
           outfile.open (  const_cast< char * > (  (  fname + "modif." + extname ).c_str(   ) ),  
           std::ios::binary );
           // Write out
           outfile << image_chunk->getAsString (   );
           outfile.close (   );
          
          
           //FileSystemArchive::pushDirectory(   );
           RetablishDir (  olddir );
           }
           }
           //-----------------------------------------------------------------------
     144   bool PagingLandScapeData2D_HeightFieldRaw::_load(  const unsigned int mX,   const unsigned int mZ )
           {
           // Load data
           const String strFileName = mParent->getOptions(   )->LandScape_filename + "." +
           StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + ".";
          
           String finalName = strFileName +
           "modif." +
           mParent->getOptions(   )->LandScape_extension;
          
           if (  !(  mParent->getOptions(   )->Deformable &&
           ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  finalName ) ) )
           {
           finalName = strFileName + mParent->getOptions(   )->LandScape_extension;
           if (  !ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  finalName ) )
           {
           LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,   String(  "PLSM2 : Cannot find map named " ) + finalName );
           return false;
           }
           }
          
           DataStreamPtr RawData;
           RawData = ResourceGroupManager::getSingleton(   ).openResource(  finalName,  
           mParent->getOptions(   )->groupName );
          
          
           // Validate size
           // Image size comes from setting (  since RAW is not self-describing )
           // here 16 bits Raw file
           mXDimension = mSize;
           mZDimension = mXDimension;
           mBpp = 2;
           mMaxArrayPos = static_cast <unsigned int> (  mSize * mSize );
           const size_t numBytes = mMaxArrayPos * mBpp;
           if (  RawData->size(   ) != numBytes )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,  
           "RAW size (  " + StringConverter::toString(  static_cast<unsigned int> (  RawData->size(   ) ) ) +
           " ) does not agree with configuration settings.",  
           "PagingLandScapeData2D_HeightFieldRaw::_load" );
           }
           mMax = static_cast<unsigned int> (  numBytes ) + 1;
          
           mHeightData = new Real[mMaxArrayPos];
           const double scale = (  double ) mParent->getOptions(   )->scale.y / 65535;
           mMaxheight = 0.0f;
          
           MemoryDataStream dc (  RawData,  
           true );
           const uchar *pSrc = dc.getPtr (   );
          
           unsigned int j = 0;
           for (  unsigned int i = 0; i < mMax - 1; i += mBpp )
           {
           #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
           ushort val = *pSrc++ <<8;
           val += *pSrc++;
           #else
           ushort val = *pSrc++;
           val += *pSrc++ <<8;
           #endif
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
          
          
           if (  mParent->getOptions(   )->vertex_shadowed )
           {
           mShadow = new Image(   );
           mShadow->load(  mParent->getOptions(   )->LandScape_filename +
           ".HS." +
           StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + "." +
           "png",  
           mParent->getOptions(   )->groupName );
           //mParent->getOptions(   )->LandScape_extension );
           }
           return true;
           }
          
           //-----------------------------------------------------------------------
     227   void PagingLandScapeData2D_HeightFieldRaw::_load(   )
           {
           // Load data
           const PagingLandScapeOptions * const opt = mParent->getOptions(   );
           const String mName(  opt->LandScape_filename + "." + opt->LandScape_extension );
           const String gName (  opt->groupName );
           ResourceGroupManager *rsm = ResourceGroupManager::getSingletonPtr(   );
           DataStreamPtr RawData = rsm->openResource(  mName,   gName );
          
           // Validate size
           // Image size comes from setting (  since RAW is not self-describing )
           // here 16 bits Raw file
          
           mXDimension = opt->RawWidth;
           mZDimension = opt->RawHeight;
          
           mBpp = 2;
          
           const size_t sourceHeight = mZDimension;
           const size_t sourceWidth = mXDimension;
          
           computePowerof2PlusOneSize (   );
           mSize = mXDimension;
          
           if (  RawData->size(   ) != sourceHeight*sourceWidth*2 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,  
           "RAW size (  " + StringConverter::toString(  static_cast<unsigned int> (  RawData->size(   ) ) ) +
           " ) does not agree with configuration settings.",  
           "PagingLandScapeData2D_HeightFieldRaw::_load" );
           }
          
           mMaxArrayPos = static_cast <unsigned int> (  mXDimension * mZDimension );
           const size_t numBytes = mMaxArrayPos * mBpp;
           mMax = static_cast<unsigned int> (  numBytes ) + 1;
          
           mHeightData = new Real[mMaxArrayPos];
           const Real scale = opt->ScaledHeightY;
           mMaxheight = 0.0f;
          
          
           MemoryDataStream dc(  RawData,  
           true );
           const uchar *pSrc = dc.getPtr (   );
          
           const unsigned int shift_fill = static_cast <unsigned int> (  mXDimension - sourceWidth );
           unsigned int dest_pos = 0;
           //for some reason water is 65035 in SRTM files...
           const bool srtm_water = opt->SRTM_water;
           for (  unsigned int i = 0; i < sourceHeight; ++i )
           {
           for (  unsigned int j = 0; j < sourceWidth; ++j )
           {
           #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
           ushort val = *pSrc++ << 8;
           val += *pSrc++;
           #else
           ushort val = *pSrc++;
           val += *pSrc++ << 8;
           #endif
          
           if (  srtm_water && (  val - 65035 ) > 0 )
           val = 0;
          
           const Real h = val * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[dest_pos++] = h;
           }
           memset (  &mHeightData[dest_pos],   0,   shift_fill );
           dest_pos+= shift_fill;
           }
           }
           //-----------------------------------------------------------------------
     300   void PagingLandScapeData2D_HeightFieldRaw::_unload(   )
           {
           delete mShadow;
           mShadow = 0;
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2D_HeightFieldRawTC.cpp

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldRawTC.cpp - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreLogManager.h"
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreImage.h"
          #include "OgreStringConverter.h"
          
          #include "OgreResourceManager.h"
          
          #include "OgreException.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeOptions.h"
          
          #include "OgrePagingLandScapeData2D_HeightFieldRawTC.h"
          
          #include "fileutils.h"
          
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      44   PagingLandScapeData2D* PagingLandScapeData2D_HeightFieldRawTC::newPage(   )
           {
           return new PagingLandScapeData2D_HeightFieldRawTC(  mParent );
           }
           //-----------------------------------------------------------------------
      49   PagingLandScapeData2D_HeightFieldRawTC::PagingLandScapeData2D_HeightFieldRawTC(  PagingLandScapeData2DManager *dataMgr )
           : PagingLandScapeData2D(  dataMgr )
           {
           mImage = 0;
           input_max = 3000.0f;
           input_min = 0.0f;
           mMaxheight = _decodeRawTC (  1.0f ) * mParent->getOptions(   )->scale.y;
           }
           //-------------------------------------------------------------------
      58   const Real PagingLandScapeData2D_HeightFieldRawTC::getMaxAbsoluteHeight(  void ) const
           {
           return _decodeRawTC (  1.0f ) * mParent->getOptions(   )->scale.y;
           }
          
           //-----------------------------------------------------------------------
      64   PagingLandScapeData2D_HeightFieldRawTC::~PagingLandScapeData2D_HeightFieldRawTC(   )
           {
           }
           //-----------------------------------------------------------------------
      68   const ColourValue PagingLandScapeData2D_HeightFieldRawTC::getBase (  const Real mX,   const Real mZ )
           {
           return ColourValue::White;
           }
          
           //-----------------------------------------------------------------------
      74   const ColourValue PagingLandScapeData2D_HeightFieldRawTC::getCoverage (  const Real mX,   const Real mZ )
           {
           return ColourValue::White;
           }
           //-----------------------------------------------------------------------
      79   const Vector3 PagingLandScapeData2D_HeightFieldRawTC::getNormalAt (  const Real x,   const Real z )
           {
           #ifndef _LOADEDNORM
           return PagingLandScapeData2D::getNormal(  x,  z );
           #else
           if (  mImage )
           {
           unsigned int Pos = static_cast<unsigned int> (  (  z * mSize + x ) * mBpp );//4 bytes (  mImage is RGBA )
          
           if (  mMax > Pos )
           {
           const Real normalscale = 1.0f / 127.0f;
           return Vector3 (  (  (  Real )(  mImage->getData(   )[Pos + 0] ) - 128.0f ) * normalscale,  
           (  (  Real )(  mImage->getData(   )[Pos + 1] ) - 128.0f ) * normalscale,  
           (  (  Real )(  mImage->getData(   )[Pos + 2] ) - 128.0f ) * normalscale );
           }
           else
           {
           return Vector3::UNIT_Y;
           }
           }
           else
           {
           return Vector3::UNIT_Y;
           }
           #endif //_NOLOAD
           }
           //-----------------------------------------------------------------------
     107   void PagingLandScapeData2D_HeightFieldRawTC::_save(   )
           {
           uchar *data = new uchar[ mXDimension * mZDimension * 2 ];
          
           const double divider = 65535.0 / mParent->getOptions(   )->scale.y;
          
           unsigned int j = 0;
           for (  unsigned int i = 0; i < mXDimension*mZDimension; i++ )
           {
           ushort syn = static_cast <ushort> (  _encodeRawTC (  mHeightData[i] ) * divider );
           #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
           data[j] = uchar (  (  syn >> 8 ) & 0xff );
           data[j+ 1] = uchar (  syn & 0xff );
           #else
           data[j] = uchar (  syn & 0xff );
           data[j+ 1] = uchar (  (  syn >> 8 ) & 0xff );
           #endif
           j += 2;
           }
           const String fname = mParent->getOptions(   )->LandScape_filename + "." +
           StringConverter::toString(  mPageZ ) + "." +
           StringConverter::toString(  mPageX ) + ".";
           const String extname = mParent->getOptions(   )->LandScape_extension;
          
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           mParent->getOptions(   )->groupName,  
           fname + extname );
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           //FileInfo *inf = &(  *it );
           char *olddir = ChangeToDir (  const_cast< char * > (  (  (  it )->archive->getName(   ) ).c_str(   ) ) );
           //FileSystemArchive::pushDirectory(   )
          
           std::ofstream outfile;
           String FileNameRaw;
          
           DataStreamPtr image_chunk(  new MemoryDataStream (  (  void* )data,  
           mXDimension * mZDimension * 2 * sizeof (  uchar ),  
           true ) );
          
           outfile.open (  const_cast< char * > (  (  fname + "modif." + extname ).c_str(   ) ),  
           std::ios::binary );
           // Write out
           outfile << image_chunk->getAsString (   );
           outfile.close (   );
          
          
           //FileSystemArchive::pushDirectory(   );
           RetablishDir (  olddir );
           }
           }
           //-----------------------------------------------------------------------
     161   bool PagingLandScapeData2D_HeightFieldRawTC::_load(  const unsigned int mX,   const unsigned int mZ )
           {
           // Load data
           //mRawData.clear(   );
          
           const String strFileName = mParent->getOptions(   )->LandScape_filename + "." +
           StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + ".";
          
          
           String finalName = strFileName +
           "modif." +
           mParent->getOptions(   )->LandScape_extension;
           if (  !(  mParent->getOptions(   )->Deformable &&
           ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  finalName ) ) )
           {
           finalName = strFileName +
           mParent->getOptions(   )->LandScape_extension;
           if (  !ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  finalName ) )
           {
           LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,   String(  "PLSM2 : Cannot find map named " ) + finalName );
           return false;
           }
           }
           DataStreamPtr RawData;
           RawData = ResourceGroupManager::getSingleton(   ).openResource(  finalName,  
           mParent->getOptions(   )->groupName );
          
           // Validate size
           // Image size comes from setting (  since RAW is not self-describing )
           // here 16 bits Raw file
           mXDimension = mSize;
           mZDimension = mXDimension;
           mBpp = 2;
          
           size_t numBytes = mSize * mSize * mBpp;
           if (  RawData->size(   ) != numBytes )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,  
           " ) does not agree with configuration settings.",  
           "PagingLandScapeData2D_HeightFieldRaw::_load" );
           }
           mMax = static_cast<unsigned int> (  numBytes ) + 1;
          
           mMaxArrayPos = static_cast <unsigned int> (  mSize * mSize );
           mHeightData = new Real[mMaxArrayPos];
          
           const Real divider = 1.0f / 65535.0f;
           const Real scale = mParent->getOptions(   )->scale.y;
          
           MemoryDataStream dc (  RawData,  
           true );
           const uchar *pSrc = dc.getPtr (   );
          
           mMaxheight = 0.0f;
           unsigned int j = 0;
           for (  unsigned int i = 0; i < mMax - 1; i += mBpp )
           {
           #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
           ushort val = *pSrc++ <<8;
           val += *pSrc++;
           #else
           ushort val = *pSrc++;
           val += *pSrc++ <<8;
           #endif
           const Real h = _decodeRawTC (  val * divider )* scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
          
          // if (  mParent->getOptions(   )->vertex_shadowed )
          // {
          // mShadow = new Image(   );
          // mShadow->load(  mParent->getOptions(   )->LandScape_filename +
          // ".HS." +
          // StringConverter::toString(  mZ ) + "." +
          // StringConverter::toString(  mX ) + "." +
          // "png" );
          // //mParent->getOptions(   )->LandScape_extension );
          // }
           return true;
           }
           //-----------------------------------------------------------------------
     244   void PagingLandScapeData2D_HeightFieldRawTC::_load(   )
           {
           // Load data
           DataStreamPtr RawData = ResourceGroupManager::getSingleton(   ).openResource(  mParent->getOptions(   )->LandScape_filename +
           "." +
           mParent->getOptions(   )->LandScape_extension,  
           mParent->getOptions(   )->groupName );
          
           // Validate size
           // Image size comes from setting (  since RAW is not self-describing )
           // here 16 bits Raw file
          
           mXDimension = mParent->getOptions(   )->RawWidth;
           mZDimension = mParent->getOptions(   )->RawHeight;
          
           mBpp = 2;
          
           const size_t sourceHeight = mZDimension;
           const size_t sourceWidth = mXDimension;
          
           computePowerof2PlusOneSize (   );
           mSize = mXDimension;
          
           if (  RawData->size(   ) != sourceHeight*sourceWidth*2 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,  
           "RAW size (  " + StringConverter::toString(  static_cast<unsigned int> (  RawData->size(   ) ) ) +
           " ) does not agree with configuration settings.",  
           "PagingLandScapeData2D_HeightFieldRaw::_load" );
           }
          
           mMaxArrayPos = static_cast <unsigned int> (  mXDimension * mZDimension );
           const size_t numBytes = mMaxArrayPos * mBpp;
           mMax = static_cast<unsigned int> (  numBytes ) + 1;
          
           mHeightData = new Real[mMaxArrayPos];
          
           mMaxheight = 0.0f;
          
          
           MemoryDataStream dc(  RawData,  
           true );
           const uchar *pSrc = dc.getPtr (   );
          
           const Real divider = 1.0f / 65535.0f;
           const Real scale = mParent->getOptions(   )->scale.y;
           const unsigned int shift_fill = static_cast <unsigned int> (  mXDimension - sourceWidth );
           unsigned int dest_pos = 0;
           //for some reason water is 65035 in SRTM files...
           const bool srtm_water = mParent->getOptions(   )->SRTM_water;
           for (  unsigned int i = 0; i < sourceHeight; ++i )
           {
           for (  unsigned int j = 0; j < sourceWidth; ++j )
           {
           #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
           ushort val = *pSrc++ <<8;
           val += *pSrc++;
           #else
           ushort val = *pSrc++;
           val += *pSrc++ <<8;
           #endif
          
           if (  srtm_water && (  val - 65035 ) > 0 )
           val = 0;
          
           const Real h = _decodeRawTC (  val * divider ) * scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[dest_pos++] = h;
           }
           memset (  &mHeightData[dest_pos],   0,   shift_fill );
           dest_pos+= shift_fill;
           }
           }
          
          
           //-----------------------------------------------------------------------
     320   void PagingLandScapeData2D_HeightFieldRawTC::_unload(   )
           {
           delete mImage;
           mImage = 0;
           }
          
           //-----------------------------------------------------------------------
     327   inline Real PagingLandScapeData2D_HeightFieldRawTC::_decodeRawTC(  const Real encoded ) const
           {
           return (  (  Real ) (  encoded + 0.5f ) ) * (  input_max - input_min ) + input_min;
           }
           //-----------------------------------------------------------------------
     332   inline ushort PagingLandScapeData2D_HeightFieldRawTC::_encodeRawTC(  const Real decoded ) const
           {
           return static_cast <short> (  (  decoded - input_min ) / (  input_max - input_min ) - 0.5f );
           }
          
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2D_HeightFieldTC.cpp

       1  /***************************************************************************
           OgrePagingLandScapeData2D_HeightFieldTC.cpp - description
           -------------------
           begin : Mon Oct 13 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          
          #include "OgreLogManager.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreImage.h"
          #include "OgreStringConverter.h"
          
          #include "OgreException.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeOptions.h"
          
          #include "OgrePagingLandScapeData2D_HeightFieldTC.h"
          
          
          #include "fileutils.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      44   PagingLandScapeData2D* PagingLandScapeData2D_HeightFieldTC::newPage(   )
           {
           return new PagingLandScapeData2D_HeightFieldTC(  mParent );
           }
           //-----------------------------------------------------------------------
      49   PagingLandScapeData2D_HeightFieldTC::PagingLandScapeData2D_HeightFieldTC(  PagingLandScapeData2DManager *dataMgr )
           : PagingLandScapeData2D(  dataMgr )
           {
           mImage = 0;
           input_max = 3000.0f;
           input_min = 0.0f;
           mMaxheight = _decodeTC (  1.0f ) * mParent->getOptions(   )->scale.y;
           }
           //-------------------------------------------------------------------
      58   const Real PagingLandScapeData2D_HeightFieldTC::getMaxAbsoluteHeight(  void ) const
           {
           return _decodeTC (  1.0f ) * mParent->getOptions(   )->scale.y;
           }
          
           //-----------------------------------------------------------------------
      64   PagingLandScapeData2D_HeightFieldTC::~PagingLandScapeData2D_HeightFieldTC(   )
           {
           }
           //-----------------------------------------------------------------------
      68   const ColourValue PagingLandScapeData2D_HeightFieldTC::getBase (  const Real mX,   const Real mZ )
           {
           return ColourValue::White;
           }
          
           //-----------------------------------------------------------------------
      74   const ColourValue PagingLandScapeData2D_HeightFieldTC::getCoverage (  const Real mX,   const Real mZ )
           {
           return ColourValue::White;
           }
           //-----------------------------------------------------------------------
      79   void PagingLandScapeData2D_HeightFieldTC::_save(   )
           {
          
           const Real scale = 1.0f / mParent->getOptions(   )->scale.y;
          
           uchar *img = mImage->getData(   );
           unsigned int j = 0;
           for (  unsigned int i = 0; i < mMax - 1; i ++ )
           {
           img[ i ] = uchar (  _encodeTC(  mHeightData[j++] ) * scale );
           }
           const String fname = mParent->getOptions(   )->LandScape_filename + "." +
           StringConverter::toString(  mPageZ ) + "." +
           StringConverter::toString(  mPageX ) + ".";
           const String extname = mParent->getOptions(   )->LandScape_extension;
          
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           mParent->getOptions(   )->groupName,  
           fname + extname );
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           //FileInfo *inf = &(  *it );
           char *olddir = ChangeToDir (  const_cast< char * > (  (  (  it )->archive->getName(   ) ).c_str(   ) ) );
           //FileSystemArchive::pushDirectory(   )
           mImage->save (  fname + "modif." + extname );
           //FileSystemArchive::pushDirectory(   );
           RetablishDir (  olddir );
           }
          
           }
           //-----------------------------------------------------------------------
     112   bool PagingLandScapeData2D_HeightFieldTC::_load(  const unsigned int mX,   const unsigned int mZ )
           {
           const String strFileName = mParent->getOptions(   )->LandScape_filename + "." +
           StringConverter::toString(  mZ ) + "." +
           StringConverter::toString(  mX ) + ".";
          
           String finalName = strFileName +
           "modif." +
           mParent->getOptions(   )->LandScape_extension;
           if (  !(  mParent->getOptions(   )->Deformable &&
           ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  
           finalName ) ) )
           {
           finalName = strFileName +
           mParent->getOptions(   )->LandScape_extension;
           if (  !ResourceGroupManager::getSingleton(   ).resourceExists(  mParent->getOptions(   )->groupName,  
           finalName ) )
           {
          
           LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,   String(  "PLSM2 : Cannot find map named " ) + finalName );
           return false;
           }
           }
           mImage = new Image(   );
           mImage->load (  finalName,   mParent->getOptions(   )->groupName );
          
           //check to make sure it's 2^n + 1 size.
           if (  mImage->getWidth(   ) != mImage->getHeight(   ) ||
           !_checkSize(  mImage->getWidth(   ) ) )
           {
           String err = "Error: Invalid heightmap size : " +
           StringConverter::toString(  static_cast<int>(  mImage->getWidth(   ) ) ) +
           ",  " + StringConverter::toString(  static_cast<int>(  mImage->getHeight(   ) ) ) +
           ". Should be 2^n+1,   2^n+1";
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   err,   "PagingLandScapeData2D_HeightField::_load" );
           }
          
           mBpp = PixelUtil::getNumElemBytes (  mImage->getFormat (   ) );
           if (  mBpp != 1 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   "Error: Image is not a gray image.(  1 bytes,   8 bits )",  
           "PagingLandScapeData2D_HeightField::_load" );
           }
          
           if (  mSize != mImage->getWidth(   ) )
           {
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,   "Error: Declared World size <> Height Map Size.",   "PagingLandScapeData2D_HeightField::_load" );
           }
          
           mXDimension = mImage->getWidth(   );
           mZDimension = mImage->getHeight(   );
           mMax = static_cast <unsigned int> (  mSize * mImage->getHeight(   ) + 1 );
          
           mMaxArrayPos = mMax - 1;
           mHeightData = new Real[mMaxArrayPos];
           unsigned int j = 0;
           const double divider = 1.0 / 255;
           const Real scale = mParent->getOptions(   )->scale.y;
           uchar *data = mImage->getData(   );
           mMaxheight = 0.0f;
           for (  unsigned int i = 0; i < mMax - 1; i++ )
           {
           const Real h = _decodeTC(  data[ i ] * divider )* scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[j++] = h;
           }
           return true;
           }
           //-----------------------------------------------------------------------
     181   void PagingLandScapeData2D_HeightFieldTC::_load(   )
           {
           mImage = new Image(   );
           mImage->load (  mParent->getOptions(   )->LandScape_filename +
           "." + mParent->getOptions(   )->LandScape_extension,   mParent->getOptions(   )->groupName );
           mBpp = PixelUtil::getNumElemBytes (  mImage->getFormat (   ) );
           if (  mBpp != 1 )
           {
           OGRE_EXCEPT(  Exception::ERR_INVALIDPARAMS,   "Error: Image is not a greyscale image.(  1 byte,   8 bits )",  
           "PagingLandScapeData2D_HeightField::_load" );
           }
          
           mXDimension = mImage->getWidth(   );
           mZDimension = mImage->getHeight(   );
          
           const size_t sourceHeight = mZDimension;
           const size_t sourceWidth = mXDimension;
          
           computePowerof2PlusOneSize (   );
          
           mSize = mXDimension;
           mMaxArrayPos = static_cast <unsigned int> (  mXDimension * mZDimension );
           mMax = static_cast <unsigned int> (  mMaxArrayPos * mBpp );
           mHeightData = new Real[mMaxArrayPos];
          
           const Real divider = 1.0f / 65535.0f;
           const Real scale = mParent->getOptions(   )->scale.y;
           mMaxheight = 0.0f;
           const unsigned int shift_fill = static_cast <unsigned int> (  mXDimension - sourceWidth );
           uchar *imagedata = mImage->getData(   );
           unsigned int dest_pos = 0;
           for (  unsigned int i = 0; i < sourceHeight; ++i )
           {
           for (  unsigned int j = 0; j < sourceWidth; ++j )
           {
           const Real h = _decodeTC(  *imagedata++ * divider )* scale;
           mMaxheight = std::max (  h,   mMaxheight );
           mHeightData[dest_pos++] = h;
           }
           memset (  &mHeightData[dest_pos],   0,   shift_fill );
           dest_pos += shift_fill;
           }
          
          
           }
          
          
           //-----------------------------------------------------------------------
     229   void PagingLandScapeData2D_HeightFieldTC::_unload(   )
           {
           delete mImage;
           mImage = 0;
           }
          
           //-----------------------------------------------------------------------
     236   inline Real PagingLandScapeData2D_HeightFieldTC::_decodeTC(  const Real encoded ) const
           {
           return (  (  Real ) (  encoded + 0.5f ) ) * (  input_max - input_min ) + input_min;
           }
          
           //-----------------------------------------------------------------------
     242   inline uchar PagingLandScapeData2D_HeightFieldTC::_encodeTC(  const Real decoded ) const
           {
           return static_cast<uchar> (  (  decoded - input_min ) / (  input_max - input_min ) - 0.5f );
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeData2D_Spline.cpp

       1  /********************************************************************************
           OgrePagingLandScapeData2D_Spline.cpp
           *****************************************************************************
           A NURBS-based heightfield generator for use with the pagingLandScapeplugin
          
           Note that it could easily be adapted for use as a general NURBS surface
           generator.
           *****************************************************************************
           begin : Sat Nov 9 2003
           copyright : (  C ) 2003 Chris "Antiarc" Heald
           email : antiarc@captionthis.com
          ********************************************************************************/
          
          /********************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ********************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeOptions.h"
          
          #include "OgrePagingLandScapeData2D_Spline.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      39   PagingLandScapeData2D* PagingLandScapeData2D_Spline::newPage(   )
           {
           return new PagingLandScapeData2D_Spline(  mParent );
           }
           //-----------------------------------------------------------------------
      44   PagingLandScapeData2D_Spline::PagingLandScapeData2D_Spline(  PagingLandScapeData2DManager *dataMgr )
           : PagingLandScapeData2D(  dataMgr ),  
           mSurface (  0 ),  
           mPoints (  0 )
           {
           mMaxheight = 256.0f * mParent->getOptions(   )->scale.y;
           }
          
           //-----------------------------------------------------------------------
      53   PagingLandScapeData2D_Spline::~PagingLandScapeData2D_Spline(   )
           {
           delete mSurface;
           delete[] mPoints;
           }
           //-------------------------------------------------------------------
      59   void PagingLandScapeData2D_Spline::_save(   )
           {
          
           }
           //-------------------------------------------------------------------
      64   const Real PagingLandScapeData2D_Spline::getMaxAbsoluteHeight(  void ) const
           {
           return mParent->getOptions(   )->scale.y;
           }
           //-----------------------------------------------------------------------
      69   bool PagingLandScapeData2D_Spline::_load(  const unsigned int mX,   const unsigned int mZ )
           {
           int resolution = mParent->getOptions(   )->PageSize;
           mSize = resolution;
           mMax = static_cast <unsigned int> (  mSize * mSize );
           int pCount = 50;
           int mDegree = 3;
           Real MAX = 500;
           int tessLevel = static_cast <unsigned int> (  mSize );
          
           srand (  time(  NULL ) );
          
           mPoints = new Point4D[pCount * pCount];
           const int knotVecSize = pCount + mDegree + 1;
           float *knots = new float[knotVecSize];
           int i;
           for (  i = 0; i < knotVecSize; i++ )
           {
           if (  i < mDegree )
           {
           knots[i] = 0;
           }
           else if (  i > knotVecSize - mDegree )
           {
           knots[i] = knotVecSize - (  2 * mDegree ) + 1;
           }
           else
           {
           knots[i] = i - mDegree + 1;
           }
           }
           int dataSize = pCount * pCount;
           for (  i = 0; i < dataSize; i++ )
           {
           mPoints[i].x = (  int ) (  i/pCount );
           mPoints[i].y = double (  rand(   ) ) / MAX;
           mPoints[i].w = 1;
           mPoints[i].z = 0;//i % pCount;
           }
           mSurface = new CDRGNURBSSurface(   );
           mSurface->Init(  mDegree,   mDegree,  
           pCount,   pCount,  
           mPoints,  
           knots,   knots,  
           tessLevel,   tessLevel );
           mSurface->TessellateSurface(   );
           delete[] knots;
           delete[] mPoints;
          
           mXDimension = mSize;
           mZDimension = mSize;
           mMaxArrayPos = resolution * resolution;
           mHeightData = new Real[mMaxArrayPos];
           Real scale = mParent->getOptions(   )->scale.y;
           mMaxheight = 0.0f;
           unsigned int k;
           for (  k = 0; k < mMaxArrayPos; k ++ )
           {
           Real h = static_cast<Real> (  mSurface->getData(  k ).y * scale );
           mHeightData[k] = h;
           mMaxheight = std::max (  h,   mMaxheight );
           }
           mIsLoaded = true;
           return true;
           }
           //-----------------------------------------------------------------------
     135   void PagingLandScapeData2D_Spline::_load(   )
           {
          
           }
           //-----------------------------------------------------------------------
     140   void PagingLandScapeData2D_Spline::_unload(   )
           {
           delete mSurface;
           mSurface = 0;
           mIsLoaded = false;
           }
          
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeHorizon.cpp

       1  /***************************************************************************
           OgrePagingLandScapeHorizon.cpp - description
           -------------------
           begin : Sat Mar 08 2003
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreMovableObject.h"
          #include "OgreAxisAlignedBox.h"
          
          #include "OgreCamera.h"
          
          #include "OgreMaterialManager.h"
          #include "OgreTextureManager.h"
          #include "OgreTechnique.h"
          #include "OgrePass.h"
          #include "OgreTextureUnitState.h"
          
          #include "OgrePagingLandScapeTileInfo.h"
          
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeHorizon.h"
          #include "OgrePagingLandScapeCamera.h"
          
          
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      47   PagingLandScapeHorizon::PagingLandScapeHorizon(  const PagingLandScapeOptions * const options ):
           mOptions(  options )
           {
           mPageWidth = options->world_width;
           mPageHeight = options->world_height;
          
           mNumTilesPage = options->NumTiles;
          
           mTileWidth = mPageWidth * mNumTilesPage;
           mTileHeight = mPageHeight * mNumTilesPage;
          
           size_t p_memssize = mPageWidth*mPageHeight;
          
           mMinPageHeights = new Real[p_memssize];
           memset (  mMinPageHeights,   0,   p_memssize * sizeof(  Real ) );
          
           mMaxPageHeights = new Real[p_memssize];
           memset (  mMaxPageHeights,   0,   p_memssize * sizeof(  Real ) );
          
           size_t t_memssize = mTileWidth*mTileHeight;
          
           mMinTileHeights = new Real[t_memssize];
           memset (  mMinTileHeights,   0,   t_memssize * sizeof(  Real ) );
          
           mMaxTileHeights = new Real[t_memssize];
           memset (  mMaxTileHeights,   0,   t_memssize * sizeof(  Real ) );
          
           material_enabled = false;
           mVisData = 0;
           }
           //-----------------------------------------------------------------------
      78   PagingLandScapeHorizon::~PagingLandScapeHorizon(   )
           {
           delete [] mMinPageHeights;
           delete [] mMaxPageHeights;
          
           delete [] mMinTileHeights;
           delete [] mMaxTileHeights;
          
           mVisibilityMaterial.setNull(   );
           }
           //-----------------------------------------------------------------------
      89   void PagingLandScapeHorizon::prepare(  const PagingLandScapeCamera* cam )
           {
           if (  material_enabled )
           {
           //reset.
           memset (  mVisData,   0,   mTileWidth * mTileHeight * 4 );
          
           //add camera point
           const Real tileX = cam->mCurrentCameraPageX * mNumTilesPage + cam->mCurrentCameraTileX;
           const Real tileZ = cam->mCurrentCameraPageZ * mNumTilesPage + cam->mCurrentCameraTileZ;
           const unsigned int tilePos = static_cast <unsigned int> (  (  tileX + tileZ * mTileWidth ) * 4 );
           mVisData [ tilePos ] = 0;
           mVisData [ tilePos + 1] = 0;
           mVisData [ tilePos + 2] = 255;
           mVisData [ tilePos + 3] = 255;
           }
           }
           //-----------------------------------------------------------------------
     107   void PagingLandScapeHorizon::update(   )
           {
           if (  material_enabled )
           {
           const PixelBox srcBox = mVisImage.getPixelBox(   );
          
           HardwarePixelBufferSharedPtr Texbuffer = mVisTex->getBuffer (  0,   0 );
           const PixelBox lock = Texbuffer->lock (  srcBox,   HardwareBuffer::HBL_DISCARD );
           // lock.data can now be freely accessed
           PixelUtil::bulkPixelConversion(  srcBox,   lock );
          
           Texbuffer->unlock(   );
           }
           }
           //-----------------------------------------------------------------------
     122   MaterialPtr PagingLandScapeHorizon::getVisibilityMaterial(   )
           {
           if (  mVisibilityMaterial.isNull(   ) )
           {
           const PagingLandScapeOptions * const opt = mOptions;
           const String filename = opt->LandScape_filename;
           const String name = filename +
           "Visibility";
           mVisibilityMaterial = MaterialManager::getSingleton(   ).getByName (  name );
           if (  mVisibilityMaterial.isNull(   ) )
           {
           mVisibilityMaterial = MaterialManager::getSingleton(   ).create (  name,  
           opt->groupName );
          
           TextureUnitState *tu0 = mVisibilityMaterial->getTechnique (  0 )->
           getPass (  0 )->createTextureUnitState (   );
          
           tu0->setTextureName (  filename + ".Small." +
           opt->TextureExtension );
          
          
           tu0->setAlphaOperation (  LBX_BLEND_MANUAL,   LBS_MANUAL,   LBS_CURRENT,   0.7,   1,   1 );
           //tu0->setTextureAddressingMode (  TextureUnitState::TextureAddressingMode::TAM_CLAMP );
           tu0->setTextureAddressingMode (  TextureUnitState::TAM_CLAMP );
           mVisibilityMaterial->setSceneBlending (  SBT_TRANSPARENT_ALPHA );
           //mVisibilityMaterial->setDepthCheckEnabled (  false );
           //mVisibilityMaterial->setDepthWriteEnabled (  false );
          
           const size_t s = mTileWidth * mTileHeight * 4;
           uchar *TexData = new uchar [s];
           memset (  TexData,   0,   s * sizeof(  uchar ) );
           // Assign the texture to the alpha map
           mVisImage.loadDynamicImage(  TexData,   mTileWidth,   mTileHeight,   1,   PF_R8G8B8A8,   true );
           mVisData = mVisImage.getData(   );
           const String texname = filename + ".Visibility";
           mVisTex = TextureManager::getSingleton(   ).loadImage(  texname,  
           opt->groupName,  
           mVisImage,  
           TEX_TYPE_2D,   0,   1.0f );
           TextureUnitState *tu1 = mVisibilityMaterial->getTechnique (  0 )->
           getPass (  0 )->createTextureUnitState(  texname );
           tu1->setTextureAddressingMode (  TextureUnitState::TAM_CLAMP );
           }
           else
           {
           const size_t s = mTileWidth * mTileHeight * 4;
           uchar *TexData = new uchar [s];
           memset (  TexData,   0,   s * sizeof(  uchar ) );
           // Assign the texture to the alpha map
           mVisImage.loadDynamicImage(  TexData,   mTileWidth,   mTileHeight,   1,   PF_R8G8B8A8,   true );
           mVisData = mVisImage.getData(   );
           mVisTex = TextureManager::getSingleton(   ).getByName (  filename + ".Visibility" );
           }
           }
           mVisibilityMaterial->load(   );
           material_enabled = true;
           return mVisibilityMaterial;
           }
           //-----------------------------------------------------------------------
     181   void PagingLandScapeHorizon::AddVisibleTile (  const unsigned int Tilex,   const unsigned int Tilez,  
     182   const bool visible )
           {
           if (  material_enabled )
           {
           const unsigned int tilePos = (  Tilex + Tilez * mTileWidth ) * 4;
           if (  visible )
           {
           mVisData [ tilePos ] = 0;
           mVisData [ tilePos + 1] = 255;
           mVisData [ tilePos + 2] = 0;
           mVisData [ tilePos + 3] = 255;
           }
           else
           {
           mVisData [ tilePos ] = 255;
           mVisData [ tilePos + 1] = 0;
           mVisData [ tilePos + 2] = 0;
           mVisData [ tilePos + 3] = 255;
           }
           }
           }
           //-----------------------------------------------------------------------
     204   void PagingLandScapeHorizon::AddVisibleTile (  const PagingLandScapeTileInfo *info,  
     205   const bool visible )
           {
           if (  material_enabled )
           {
           const unsigned int TileX = info->mPageX*mNumTilesPage + info->mTileX;
           const unsigned int TileZ = info->mPageZ*mNumTilesPage + info->mTileZ;
          
           AddVisibleTile (  TileX,   TileZ,   visible );
           }
           }
           //-----------------------------------------------------------------------
     216   void PagingLandScapeHorizon::registerMinMaxHeightPage (  const unsigned int pageX,   const unsigned int pageZ,  
     217   const Real minHeight,   const Real maxHeight )
           {
           const size_t pos = mPageWidth*mPageHeight;
           mMinPageHeights[pos] = minHeight;
           mMaxPageHeights[pos] = maxHeight;
           }
           //-----------------------------------------------------------------------
     224   void PagingLandScapeHorizon::registerMinMaxHeightTile (  const PagingLandScapeTileInfo *info,  
     225   const Real minHeight,   const Real maxHeight )
           {
           const size_t tilePos = (  info->mPageX*mNumTilesPage + info->mTileX
           + (  (  info->mPageZ*mNumTilesPage ) + info->mTileZ ) * mTileWidth );
          
           assert (  tilePos < mTileWidth*mTileHeight );
          
           mMinTileHeights[tilePos] = minHeight;
           mMaxTileHeights[tilePos] = maxHeight;
          
           const size_t pagePos = info->mPageX + info->mPageZ * mPageWidth;
          
           assert (  pagePos < mPageWidth*mPageHeight );
          
           // if tile height is maximum or minimum height page
           if (  mMaxPageHeights[pagePos] < maxHeight )
           mMaxPageHeights[pagePos] = maxHeight;
           if (  mMinPageHeights[pagePos] > minHeight )
           mMinPageHeights[pagePos] = minHeight;
           }
           //-----------------------------------------------------------------------
     246   bool PagingLandScapeHorizon::IsPageVisible(  const PagingLandScapeCamera* cam,  
           const unsigned int destpageX,   const unsigned int destpageZ )
           {
           const Real PageX = cam->mCurrentCameraPageX;
           const Real PageZ = cam->mCurrentCameraPageZ;
          
           // test if there is potential occluders
           if (  fabs (  PageX - destpageX ) < 2 && fabs (  PageZ - destpageZ ) < 2 )
           return true;
          
           assert (  destpageX + destpageZ*mPageWidth < mPageWidth*mPageHeight );
          
           return calcVis(  Vector3 (  PageX,   cam->getDerivedPosition (   ).y,   PageZ ),  
           Vector3 (  destpageX,   mMaxPageHeights[destpageX + destpageZ*mPageWidth],   destpageZ ),  
           mMinPageHeights,   mPageWidth,   mPageHeight );
           }
           //-----------------------------------------------------------------------
     263   bool PagingLandScapeHorizon::IsTileVisible(  const PagingLandScapeCamera* cam,  
     264   const PagingLandScapeTileInfo *destinfo )
           {
          
          
           const Real RsrcTileX = cam->mCurrentCameraPageX * mNumTilesPage + cam->mCurrentCameraTileX;
           const Real RsrcTileZ = cam->mCurrentCameraPageZ * mNumTilesPage + cam->mCurrentCameraTileZ;
          
           const Real RdestTileX = destinfo->mPageX*mNumTilesPage + destinfo->mTileX;
           const Real RdestTileZ = destinfo->mPageZ*mNumTilesPage + destinfo->mTileZ;
          
           // test if there is potential occluders
           if (  fabs (  RsrcTileX - RdestTileX ) < 2.0f && fabs (  RsrcTileZ - RdestTileZ ) < 2.0f )
           return true;
          
           const size_t pos = static_cast <size_t> (  RdestTileX + RdestTileZ*mTileWidth );
          
           assert (  pos < mTileWidth*mTileHeight );
          
           return calcVis(  Vector3 (  RsrcTileX,   cam->getDerivedPosition (   ).y,   RsrcTileZ ),  
           Vector3 (  RdestTileX,   mMaxTileHeights[pos],   RdestTileZ ),  
           mMinTileHeights,   mTileWidth,   mTileHeight );
           }
           //-----------------------------------------------------------------------
     287   bool PagingLandScapeHorizon::calcVis(  const Vector3 &src,   const Vector3 &dest,  
           const Real * const heightMap,  
           const unsigned int mapWidth,   const unsigned int mapHeight )
           {
           /* Make sure the ray is normalised */
           const Real x = dest.x - src.x;
           const Real z = dest.z - src.z;
           /*normalise only on x and z*/
           const Real fLength = Math::Sqrt(  x * x + z * z );
           // Will also work for zero-sized vectors,   but will change nothing
           if (  fLength < 1e-08 )
           return true;
          
           const Real fInvLength = 1.0 / fLength;
           const Vector3 direction (  x * fInvLength,  
           (  dest.y - src.y ) * fInvLength,  
           z * fInvLength );
          
          
           Real lasty = src.y;
          
           Vector3 currpos (  src + direction ); // fetch new tile
          
           /* For each heightmap location in the ray */
           while (  currpos.x >= 0 &&
           currpos.z >= 0 &&
           currpos.x < mapWidth &&
           currpos.z < mapHeight )
           {
           const size_t posx = static_cast <size_t> (  currpos.x + 0.5f );
           const size_t posz = static_cast <size_t> (  currpos.z + 0.5f );
           if (  posx == dest.x && posz == dest.z )
           break;
          
           const Real curry = currpos.y;
           currpos = currpos + direction; // fetch new tile
           const Real nexty = currpos.y; // fetch next tile height
          
           const Real h = heightMap[posx + posz*mapWidth];
           if (  h > nexty && h > lasty )
           {
           AddVisibleTile (  static_cast <unsigned int> (  dest.x ),  
           static_cast <unsigned int> (  dest.z ),  
           false );
           return false; // line of sight is occluded
           }
           lasty = curry;
           }
           AddVisibleTile (  static_cast <unsigned int> (  dest.x ),  
           static_cast <unsigned int> (  dest.z ),  
           true );
           return true;
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeIndexBuffer.cpp

       1  /***************************************************************************
           OgrePagingLandScapeIndexBufferManager.cpp - description
           -------------------
           begin : Fri Feb 28 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreHardwareBufferManager.h"
          #include "OgreVertexIndexData.h"
          
          #include "OgreVector3.h"
          
          #include "OgreSimpleRenderable.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeRenderable.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeIndexBuffer.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      35   PagingLandScapeIndexBufferManager::PagingLandScapeIndexBufferManager(  PagingLandScapeSceneManager * scnMgr ):
           mScnMgr(  scnMgr ),  
           mTileSize (  0 ),  
           mNumIndexes (  0 )
           {
          
           }
           //-----------------------------------------------------------------------
      43   PagingLandScapeIndexBufferManager::~PagingLandScapeIndexBufferManager(   )
           {
           clear(   );
           }
           //-----------------------------------------------------------------------
      48   void PagingLandScapeIndexBufferManager::load(   )
           {
           const unsigned int tileSize = mScnMgr->getOptions(   )->TileSize;
           const unsigned int numIndexes = mScnMgr->getOptions(   )->maxRenderLevel + 1;
          
           if (  tileSize != mTileSize || numIndexes != mNumIndexes )
           {
           // Clear
           mLevelIndex.reserve (  numIndexes );
           mLevelIndex.resize (  numIndexes );
           for (  unsigned int k = 0; k < numIndexes; k++ )
           {
           mLevelIndex[k] = new IndexMap(   );
           }
          
           mNumIndexes = numIndexes;
           mTileSize = tileSize;
           }
           }
           //-----------------------------------------------------------------------
      68   void PagingLandScapeIndexBufferManager::clear(   )
           {
           if (  !mLevelIndex.empty(   ) )
           {
           for (  unsigned int i = 0; i < mNumIndexes; i++ )
           {
           delete mLevelIndex[i];
           }
           mLevelIndex.clear(   );
           }
           if (  !mCache.empty(   ) )
           {
           const size_t cachesize = mCache.size (   );
           for(  size_t j = 0; j < cachesize; j++ )
           {
           delete mCache[j];
           }
           mCache.clear(   );
           }
           }
           //-----------------------------------------------------------------------
      89   IndexData *PagingLandScapeIndexBufferManager::getIndexData(  const int renderLevel,  
      90   PagingLandScapeRenderable **Neighbors )
           {
           assert (  renderLevel < static_cast <int> (  mNumIndexes ) );
           assert (  renderLevel >= 0 ) ;
          
           unsigned int stitchFlags = 0;
          
           bool eastStitch;
           if (  Neighbors[ EAST ] &&
           Neighbors[ EAST ]->isLoaded (   ) && Neighbors[ EAST ]->isVisible (   ) &&
           Neighbors[ EAST ]->mRenderLevel > renderLevel )
           {
           assert (  Neighbors[ EAST ]->mRenderLevel < static_cast <int> (  mNumIndexes ) );
           stitchFlags |= STITCH_EAST;
           stitchFlags |=
           (  Neighbors[ EAST ]->mRenderLevel - renderLevel ) << STITCH_EAST_SHIFT;
           eastStitch = true;
           }
           else
           {
           eastStitch = false;
           }
          
           bool westStitch;
           if (  Neighbors[ WEST ] &&
           Neighbors[ WEST ]->isLoaded (   ) && Neighbors[ WEST ]->isVisible (   ) &&
           Neighbors[ WEST ]->mRenderLevel > renderLevel )
           {
           assert (  Neighbors[ WEST ]->mRenderLevel < static_cast <int> (  mNumIndexes ) );
           stitchFlags |= STITCH_WEST;
           stitchFlags |=
           (  Neighbors[ WEST ]->mRenderLevel - renderLevel ) << STITCH_WEST_SHIFT;
           westStitch = true;
           }
           else
           {
           westStitch = false;
           }
          
           bool northStitch;
           if (  Neighbors[ NORTH ] &&
           Neighbors[ NORTH ]->isLoaded (   ) && Neighbors[ NORTH ]->isVisible (   ) &&
           Neighbors[ NORTH ]->mRenderLevel > renderLevel )
           {
           assert (  Neighbors[ NORTH ]->mRenderLevel < static_cast <int> (  mNumIndexes ) );
           stitchFlags |= STITCH_NORTH;
           stitchFlags |=
           (  Neighbors[ NORTH ]->mRenderLevel - renderLevel ) << STITCH_NORTH_SHIFT;
           northStitch = true;
           }
           else
           {
           northStitch = false;
           }
          
           bool southStitch;
           if (  Neighbors[ SOUTH ] &&
           Neighbors[ SOUTH ]->isLoaded (   ) && Neighbors[ SOUTH ]->isVisible (   ) &&
           Neighbors[ SOUTH ]->mRenderLevel > renderLevel )
           {
           assert (  Neighbors[ SOUTH ]->mRenderLevel < static_cast <int> (  mNumIndexes ) );
           stitchFlags |= STITCH_SOUTH;
           stitchFlags |=
           (  Neighbors[ SOUTH ]->mRenderLevel - renderLevel ) << STITCH_SOUTH_SHIFT;
           southStitch = true;
           }
           else
           {
           southStitch = false;
           }
          
          
           // Check preexisting
           assert (  mLevelIndex.size(   ) > (  unsigned int )renderLevel );
           IndexMap::iterator ii = mLevelIndex[ renderLevel ]->find(  stitchFlags );
           if (  ii == mLevelIndex[ renderLevel ]->end(   ) )
           {
           // Create
           IndexData* indexData = generateTriListIndexes(  northStitch,  
           southStitch,  
           eastStitch,  
           westStitch,  
           renderLevel,  
           Neighbors );
          
           mCache.push_back(  indexData );
           mLevelIndex[ renderLevel ]->insert(  
           IndexMap::value_type(  stitchFlags,   indexData ) );
          
           indexData->optimiseVertexCacheTriList(   );
          
           return indexData;
           }
           else
           {
           return ii->second;
           }
          
           }
          
           //-----------------------------------------------------------------------
     191   IndexData* PagingLandScapeIndexBufferManager::generateTriListIndexes(  const bool northStitch,  
     192   const bool southStitch,  
     193   const bool eastStitch,  
     194   const bool westStitch,  
           const int RenderLevel,  
     196   PagingLandScapeRenderable **Neighbors ) const
           {
           const int step = 1 << RenderLevel;
           assert (  step > 0 );
          
          
           const unsigned int tileSize = mTileSize;
           const unsigned int new_length = (  tileSize / step ) * (  tileSize / step ) * 2 * 2 * 2;
          
           IndexData* indexData = new IndexData(   );
           assert (  indexData );
          
           const bool is32bits = new_length > 65535 ? true : false;
           indexData->indexBuffer =
           HardwareBufferManager::getSingleton(   ).createIndexBuffer(  
           (  is32bits ) ? HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT,  
           new_length,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY );
          
          
          
           const unsigned int north = northStitch ? step : 0;
           const unsigned int south = southStitch ? step : 0;
           const unsigned int east = eastStitch ? step : 0;
           const unsigned int west = westStitch ? step : 0;
          
          
           unsigned int numIndexes = 0;
           const unsigned int step_offset = step * tileSize;
           unsigned int height_count = north * tileSize;
           void *idx;
           if (  is32bits )
           {
           /** Returns the index into the height array for the given coordinates. */
           unsigned int * ogre_restrict pIdx = static_cast<unsigned int*>(  indexData->indexBuffer->lock(  0,  
           indexData->indexBuffer->getSizeInBytes(   ),  
           HardwareBuffer::HBL_DISCARD ) );
           assert (  pIdx );
           for (  unsigned int j = north; j < tileSize - 1 - south; j += step )
           {
           for (  unsigned int i = west; i < tileSize - 1 - east; i += step )
           {
           //triangles
           assert (  (  i + step + height_count + step_offset ) < (  tileSize * tileSize ) );
          
          
           *pIdx++ = static_cast<unsigned int> (  i + height_count ); numIndexes++;
           *pIdx++ = static_cast<unsigned int> (  i + height_count + step_offset ); numIndexes++;
           *pIdx++ = static_cast<unsigned int> (  i + step + height_count ); numIndexes++;
          
           *pIdx++ = static_cast<unsigned int> (  i + height_count + step_offset ); numIndexes++;
           *pIdx++ = static_cast<unsigned int> (  i + step + height_count + step_offset ); numIndexes++;
           *pIdx++ = static_cast<unsigned int> (  i + step + height_count ); numIndexes++;
           }
           height_count += step_offset;
           }
           idx = pIdx;
           }
           else
           {
           /** Returns the index into the height array for the given coordinates. */
           ushort * ogre_restrict pIdx = static_cast<ushort*>(  indexData->indexBuffer->lock(  0,  
           indexData->indexBuffer->getSizeInBytes(   ),  
           HardwareBuffer::HBL_DISCARD ) );
           assert (  pIdx );
           for (  unsigned int j = north; j < tileSize - 1 - south; j += step )
           {
           for (  unsigned int i = west; i < tileSize - 1 - east; i += step )
           {
           //triangles
           assert (  (  i + step + height_count + step_offset ) < (  (  tileSize ) * (  tileSize ) ) );
          
          
           *pIdx++ = static_cast<ushort> (  i + height_count ); numIndexes++;
           *pIdx++ = static_cast<ushort> (  i + height_count + step_offset ); numIndexes++;
           *pIdx++ = static_cast<ushort> (  i + step + height_count ); numIndexes++;
          
           *pIdx++ = static_cast<ushort> (  i + height_count + step_offset ); numIndexes++;
           *pIdx++ = static_cast<ushort> (  i + step + height_count + step_offset ); numIndexes++;
           *pIdx++ = static_cast<ushort> (  i + step + height_count ); numIndexes++;
           }
           height_count += step_offset;
           }
           idx = pIdx;
           }
           assert (  numIndexes < new_length );
          
           // North stitching
           assert (  RenderLevel < static_cast <int> (  mNumIndexes ) );
           if (  northStitch )
           {
           assert (  Neighbors[ NORTH ] );
           assert (  Neighbors[ NORTH ]->isLoaded (   ) );
           assert (  Neighbors[ NORTH ]->isVisible (   ) );
           assert (  Neighbors[ NORTH ]->mRenderLevel > RenderLevel );
           assert (  Neighbors[ NORTH ]->mRenderLevel < static_cast <int> (  mNumIndexes ) );
           numIndexes += stitchEdge(  NORTH,   RenderLevel,   Neighbors[NORTH]->mRenderLevel,  
           westStitch ,   eastStitch ,   &idx,   is32bits );
           }
           // East stitching
           if (  eastStitch )
           {
           assert (  Neighbors[ EAST ] );
           assert (  Neighbors[ EAST ]->isLoaded (   ) );
           assert (  Neighbors[ EAST ]->isVisible (   ) );
           assert (  Neighbors[ EAST ]->mRenderLevel > RenderLevel );
           assert (  Neighbors[ EAST ]->mRenderLevel < static_cast <int> (  mNumIndexes ) );
           numIndexes += stitchEdge(  EAST,   RenderLevel,   Neighbors[EAST]->mRenderLevel,  
           northStitch,   southStitch,   &idx,   is32bits );
           }
           // South stitching
           if (  southStitch )
           {
           assert (  Neighbors[ SOUTH ] );
           assert (  Neighbors[ SOUTH ]->isLoaded (   ) );
           assert (  Neighbors[ SOUTH ]->isVisible (   ) );
           assert (  Neighbors[ SOUTH ]->mRenderLevel > RenderLevel );
           assert (  Neighbors[ SOUTH ]->mRenderLevel < static_cast <int> (  mNumIndexes ) );
           numIndexes += stitchEdge(  SOUTH,   RenderLevel,   Neighbors[SOUTH]->mRenderLevel,  
           eastStitch ,   westStitch,   &idx,   is32bits );
           }
           // West stitching
           if (  westStitch )
           {
           assert (  Neighbors[ WEST ] );
           assert (  Neighbors[ WEST ]->isLoaded (   ) );
           assert (  Neighbors[ WEST ]->isVisible (   ) );
           assert (  Neighbors[ WEST ]->mRenderLevel > RenderLevel );
           assert (  Neighbors[ WEST ]->mRenderLevel < static_cast <int> (  mNumIndexes ) );
           numIndexes += stitchEdge(  WEST,   RenderLevel,   Neighbors[WEST]->mRenderLevel,  
           southStitch ,   northStitch,   &idx,   is32bits );
           }
          
           assert (  numIndexes < new_length );
          
           indexData->indexBuffer->unlock(   );
           indexData->indexCount = numIndexes;
           indexData->indexStart = 0;
          
           return indexData;
           }
           //-----------------------------------------------------------------------
     338   unsigned int PagingLandScapeIndexBufferManager::stitchEdge(  const Neighbor neighbor,  
           const int hiLOD,   const int loLOD,  
     340   const bool omitFirstTri,   const bool omitLastTri,  
           void** ppIdx,  
     342   const bool is32bits ) const
           {
           assert(  loLOD > hiLOD );
           /*
           Now do the stitching; we can stitch from any level to any level.
           The stitch pattern is like this for each pair of vertices in the lower LOD
           (  excuse the poor ascii art ):
          
           lower LOD
           *-----------*
           |\ \ 3 / /|
           |1\2 \ / 4/5|
           *--*--*--*--*
           higher LOD
          
           The algorithm is,   for each pair of lower LOD vertices:
           1. Iterate over the higher LOD vertices,   generating tris connected to the
           first lower LOD vertex,   up to and including 1/2 the span of the lower LOD
           over the higher LOD (  tris 1-2 ). Skip the first tri if it is on the edge
           of the tile and that edge is to be stitched itself.
           2. Generate a single tri for the middle using the 2 lower LOD vertices and
           the middle vertex of the higher LOD (  tri 3 ).
           3. Iterate over the higher LOD vertices from 1/2 the span of the lower LOD
           to the end,   generating tris connected to the second lower LOD vertex
           (  tris 4-5 ). Skip the last tri if it is on the edge of a tile and that
           edge is to be stitched itself.
          
           The same algorithm works for all edges of the patch; stitching is done
           clockwise so that the origin and steps used change,   but the general
           approach does not.
           */
          
          
           // Work out the steps ie how to increment indexes
           // Step from one vertex to another in the high detail version
           int step = 1 << hiLOD;
           // Step from one vertex to another in the low detail version
           int superstep = 1 << loLOD;
           // Step half way between low detail steps
           int halfsuperstep = superstep >> 1;
          
           // Work out the starting points and sign of increments
           // We always work the strip clockwise
           int startx,   starty,   endx,   rowstep;
           bool horizontal;
          
           const int tileSize = static_cast <int> (  mTileSize - 1 );
           switch (  neighbor )
           {
           case NORTH:
           startx = starty = 0;
           endx = tileSize;
           rowstep = step;
           horizontal = true;
           break;
           case SOUTH:
           // invert x AND y direction,   helps to keep same winding
           startx = starty = tileSize;
           endx = 0;
           rowstep = -step;
           step = -step;
           superstep = -superstep;
           halfsuperstep = -halfsuperstep;
           horizontal = true;
           break;
           case EAST:
           startx = 0;
           endx = tileSize;
           starty = tileSize;
           rowstep = -step;
           horizontal = false;
           break;
           case WEST:
           startx = tileSize;
           endx = 0;
           starty = 0;
           rowstep = step;
           step = -step;
           superstep = -superstep;
           halfsuperstep = -halfsuperstep;
           horizontal = false;
           break;
           default:
           startx = 0;
           endx = 0;
           starty = 0;
           rowstep = 0;
           step = 0;
           superstep = 0;
           halfsuperstep = 0;
           horizontal = false;
           assert (  0 );
           break;
           };
           assert (  *ppIdx );
           unsigned int numIndexes = 0;
           const bool isHorizontal = horizontal;
           if (  is32bits )
           {
           // Get pointer to be updated
           unsigned int* ogre_restrict pIdx = static_cast <unsigned int*> (  *ppIdx );
           for (  int j = startx; j != endx; j += superstep )
           {
           int k;
           for (  k = 0; k != halfsuperstep; k += step )
           {
           int jk = j + k;
           //skip the first bit of the corner?
           if (  j != startx || k != 0 || !omitFirstTri )
           {
           if (  isHorizontal )
           {
           *pIdx++ = _index32(  j ,   starty ); numIndexes++;
           *pIdx++ = _index32(  jk,   starty + rowstep ); numIndexes++;
           *pIdx++ = _index32(  jk + step,   starty + rowstep ); numIndexes++;
           }
           else
           {
           *pIdx++ = _index32(  starty,   j ); numIndexes++;
           *pIdx++ = _index32(  starty + rowstep,   jk ); numIndexes++;
           *pIdx++ = _index32(  starty + rowstep,   jk + step ); numIndexes++;
           }
           }
           }
          
           // Middle tri
           if (  isHorizontal )
           {
           *pIdx++ = _index32(  j,   starty ); numIndexes++;
           *pIdx++ = _index32(  j + halfsuperstep,   starty + rowstep ); numIndexes++;
           *pIdx++ = _index32(  j + superstep,   starty ); numIndexes++;
           }
           else
           {
           *pIdx++ = _index32(  starty,   j ); numIndexes++;
           *pIdx++ = _index32(  starty + rowstep,   j + halfsuperstep ); numIndexes++;
           *pIdx++ = _index32(  starty,   j + superstep ); numIndexes++;
           }
          
           for (  k = halfsuperstep; k != superstep; k += step )
           {
           int jk = j + k;
           if (  j != endx - superstep || k != superstep - step || !omitLastTri )
           {
           if (  isHorizontal )
           {
           *pIdx++ = _index32(  j + superstep,   starty ); numIndexes++;
           *pIdx++ = _index32(  jk,   starty + rowstep ); numIndexes++;
           *pIdx++ = _index32(  jk + step,   starty + rowstep ); numIndexes++;
           }
           else
           {
           *pIdx++ = _index32(  starty,   j + superstep ); numIndexes++;
           *pIdx++ = _index32(  starty + rowstep,   jk ); numIndexes++;
           *pIdx++ = _index32(  starty + rowstep,   jk + step ); numIndexes++;
           }
           }
           }
           }
           *ppIdx = pIdx;
           }
           else
           {
           // Get pointer to be updated
           ushort* ogre_restrict pIdx = static_cast <ushort*> (  *ppIdx );
           for (  int j = startx; j != endx; j += superstep )
           {
           int k;
           for (  k = 0; k != halfsuperstep; k += step )
           {
           int jk = j + k;
           //skip the first bit of the corner?
           if (  j != startx || k != 0 || !omitFirstTri )
           {
           if (  isHorizontal )
           {
           *pIdx++ = _index16(  j ,   starty ); numIndexes++;
           *pIdx++ = _index16(  jk,   starty + rowstep ); numIndexes++;
           *pIdx++ = _index16(  jk + step,   starty + rowstep ); numIndexes++;
           }
           else
           {
           *pIdx++ = _index16(  starty,   j ); numIndexes++;
           *pIdx++ = _index16(  starty + rowstep,   jk ); numIndexes++;
           *pIdx++ = _index16(  starty + rowstep,   jk + step ); numIndexes++;
           }
           }
           }
          
           // Middle tri
           if (  isHorizontal )
           {
           *pIdx++ = _index16(  j,   starty ); numIndexes++;
           *pIdx++ = _index16(  j + halfsuperstep,   starty + rowstep ); numIndexes++;
           *pIdx++ = _index16(  j + superstep,   starty ); numIndexes++;
           }
           else
           {
           *pIdx++ = _index16(  starty,   j ); numIndexes++;
           *pIdx++ = _index16(  starty + rowstep,   j + halfsuperstep ); numIndexes++;
           *pIdx++ = _index16(  starty,   j + superstep ); numIndexes++;
           }
          
           for (  k = halfsuperstep; k != superstep; k += step )
           {
           int jk = j + k;
           if (  j != endx - superstep || k != superstep - step || !omitLastTri )
           {
           if (  isHorizontal )
           {
           *pIdx++ = _index16(  j + superstep,   starty ); numIndexes++;
           *pIdx++ = _index16(  jk,   starty + rowstep ); numIndexes++;
           *pIdx++ = _index16(  jk + step,   starty + rowstep ); numIndexes++;
           }
           else
           {
           *pIdx++ = _index16(  starty,   j + superstep ); numIndexes++;
           *pIdx++ = _index16(  starty + rowstep,   jk ); numIndexes++;
           *pIdx++ = _index16(  starty + rowstep,   jk + step ); numIndexes++;
           }
           }
           }
           }
           *ppIdx = pIdx;
           }
           return numIndexes;
           }
          
           //*******************
           //Added by Fiesch adapted from a post by tonyhnz
     572   IndexData *PagingLandScapeIndexBufferManager::getRawIndexes(  int renderLevel )
           {
           // no stitching is done
           // used to expose terrain vertex data
          
           if (  renderLevel >= static_cast <int> (  mNumIndexes ) )
           renderLevel = static_cast <int> (  mNumIndexes )-1;
          
           if (  renderLevel < 0 )
           renderLevel =0 ;
          
           const unsigned int stitchFlags = 0;
          
           assert (  mLevelIndex.size(   ) > (  unsigned int )renderLevel );
          
           IndexMap::iterator ii = mLevelIndex[ renderLevel ]->find(   stitchFlags  );
           if (   ii == mLevelIndex[ renderLevel ]->end(   ) )
           {
           // Create
           IndexData* indexData = generateTriListIndexes(   false,  
           false,  
           false,  
           false,  
           renderLevel,  
           0 );
           mLevelIndex[ renderLevel ]->insert(  
           IndexMap::value_type(  stitchFlags,   indexData ) );
          
           return indexData;
           }
           else
           {
           return ii->second;
           }
           }
          } //namespace
          

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeIntersectionSceneQuery.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeIntersectionSceneQuery.cpp - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004by Jon Anderson
          email : janders@users.sf.net
          
          
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeIntersectionSceneQuery.h"
          
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgrePagingLandScapeOctreeIntersectionSceneQuery.h"
          
          #include "OgreEntity.h"
          #include "OgreRoot.h"
          
          namespace Ogre
          {
          
          //---------------------------------------------------------------------
      51  PagingLandScapeIntersectionSceneQuery::PagingLandScapeIntersectionSceneQuery(  SceneManager* creator )
           : PagingLandScapeOctreeIntersectionSceneQuery(  creator )
          {
           // Add bounds fragment type
           mSupportedWorldFragments.insert(  SceneQuery::WFT_SINGLE_INTERSECTION );
           mSupportedWorldFragments.insert(  SceneQuery::WFT_PLANE_BOUNDED_REGION );
          }
          
          //---------------------------------------------------------------------
      60  PagingLandScapeIntersectionSceneQuery::~PagingLandScapeIntersectionSceneQuery(  void )
          {
          }
          
          //---------------------------------------------------------------------
      65  void PagingLandScapeIntersectionSceneQuery::execute(  IntersectionSceneQueryListener* listener )
          {
           if(  mWorldFragmentType == SceneQuery::WFT_SINGLE_INTERSECTION )
           {
           PagingLandScapeOctreeIntersectionSceneQuery::execute(  listener );
           }
           else if (  mWorldFragmentType == SceneQuery::WFT_PLANE_BOUNDED_REGION )
           {
           // We want the whole bounded volume
          // assert(  (  *bi )->fragment.fragmentType == SceneQuery::WFT_PLANE_BOUNDED_REGION );
          // if (  !listener->queryResult(  const_cast<WorldFragment*>(  &(  brush->fragment ) ),  
          // result.second + traceDistance ) )
          // return false;
          
           }
          }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeListenerManager.cpp

       1  /*-----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright � 2000-2004 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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 "OgrePagingLandScapePrecompiledHeaders.h"
          
          
          #include "OgrePagingLandScapeListenerManager.h"
          #include "OgrePagingLandScapeSceneManager.h"
          
          namespace Ogre
          {
           //-------------------------------------------------------------------------
      33   PagingLandScapeListenerManager::PagingLandScapeListenerManager(  PagingLandScapeSceneManager * scnMgr )
           {
           };
           //-------------------------------------------------------------------------
      37   PagingLandScapeListenerManager::~PagingLandScapeListenerManager(  void )
           {
           std::for_each(  mTerrainReadyListeners.begin(   ),   mTerrainReadyListeners.end(   ),   delete_object(   ) );
          
           std::for_each(  mShowPageListeners.begin(   ),   mShowPageListeners.end(   ),   delete_object(   ) );
           std::for_each(  mHidePageListeners.begin(   ),   mHidePageListeners.end(   ),   delete_object(   ) );
           std::for_each(  mPreloadPageListeners.begin(   ),   mPreloadPageListeners.end(   ),   delete_object(   ) );
           std::for_each(  mLoadPageListeners.begin(   ),   mLoadPageListeners.end(   ),   delete_object(   ) );
           std::for_each(  mUnloadPageListeners.begin(   ),   mUnloadPageListeners.end(   ),   delete_object(   ) );
           std::for_each(  mPostunloadPageListeners.begin(   ),   mPostunloadPageListeners.end(   ),   delete_object(   ) );
           std::for_each(  mModifyPageListeners.begin(   ),   mModifyPageListeners.end(   ),   delete_object(   ) );
          
          
           std::for_each(  mShowTileListeners.begin(   ),   mShowTileListeners.end(   ),   delete_object(   ) );
           std::for_each(  mHideTileListeners.begin(   ),   mHideTileListeners.end(   ),   delete_object(   ) );
           std::for_each(  mLoadTileListeners.begin(   ),   mLoadTileListeners.end(   ),   delete_object(   ) );
           std::for_each(  mUnloadTileListeners.begin(   ),   mUnloadTileListeners.end(   ),   delete_object(   ) );
           std::for_each(  mModifyTileListeners.begin(   ),   mModifyTileListeners.end(   ),   delete_object(   ) );
          
           };
           //-------------------------------------------------------------------------
      58   void PagingLandScapeListenerManager::firePagePreloaded(  const size_t pagex,  
      59   const size_t pagez,  
      60   const Real* heightData,  
      61   const AxisAlignedBox &Bbox )
           {
           if (  mPreloadPageListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   0,   0,   heightData,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mPreloadPageListeners.begin(   );
           it != mPreloadPageListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
      72   void PagingLandScapeListenerManager::firePageLoaded(  const size_t pagex,   const size_t pagez,  
      73   const Real* heightData,   const AxisAlignedBox &Bbox )
           {
           if (  mLoadPageListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   0,   0,   heightData,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mLoadPageListeners.begin(   );
           it != mLoadPageListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
      84   void PagingLandScapeListenerManager::firePageUnloaded(  const size_t pagex,   const size_t pagez,  
      85   const Real* heightData,   const AxisAlignedBox &Bbox )
           {
           if (  mUnloadPageListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   0,   0,   heightData,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mUnloadPageListeners.begin(   );
           it != mUnloadPageListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
          
           //-------------------------------------------------------------------------
      97   void PagingLandScapeListenerManager::firePagePostunloaded(  const size_t pagex,   const size_t pagez )
           {
           if (  mPostunloadPageListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   0,   0,   0,   AxisAlignedBox(   ) );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mPostunloadPageListeners.begin(   );
           it != mPostunloadPageListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
     108   void PagingLandScapeListenerManager::firePageShow(  const size_t pagex,   const size_t pagez,  
     109   const Real* heightData,   const AxisAlignedBox &Bbox )
           {
           if (  mShowPageListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   0,   0,   heightData,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mShowPageListeners.begin(   );
           it != mShowPageListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
     120   void PagingLandScapeListenerManager::firePageHide(  const size_t pagex,   const size_t pagez,  
     121   const Real* heightData,   const AxisAlignedBox &Bbox )
           {
           if (  mHidePageListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   0,   0,   heightData,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mHidePageListeners.begin(   );
           it != mHidePageListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
     132   void PagingLandScapeListenerManager::fireTileLoaded (  const size_t pagex,   const size_t pagez,  
     133   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox )
           {
           if (  mLoadTileListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   tilex,   tilez,   0,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mLoadTileListeners.begin(   );
           it != mLoadTileListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
     144   void PagingLandScapeListenerManager::fireTileUnloaded(  const size_t pagex,   const size_t pagez,  
     145   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox )
           {
           if (  mUnloadTileListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   tilex,   tilez,   0,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mUnloadTileListeners.begin(   );
           it != mUnloadTileListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
     156   void PagingLandScapeListenerManager::fireTileDeformed(  const size_t pagex,   const size_t pagez,  
     157   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox )
           {
           if (  mModifyTileListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   tilex,   tilez,   0,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mModifyTileListeners.begin(   );
           it != mModifyTileListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
     168   void PagingLandScapeListenerManager::fireTileShow(  const size_t pagex,   const size_t pagez,  
     169   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox )
           {
           if (  mShowTileListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   tilex,   tilez,   0,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mShowTileListeners.begin(   );
           it != mShowTileListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
     180   void PagingLandScapeListenerManager::fireTileHide(  const size_t pagex,   const size_t pagez,  
     181   const size_t tilex,   const size_t tilez,   const AxisAlignedBox &Bbox )
           {
           if (  mHideTileListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  pagex,   pagez,   tilex,   tilez,   0,   Bbox );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mHideTileListeners.begin(   );
           it != mHideTileListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
     192   void PagingLandScapeListenerManager::fireTerrainReady(   )
           {
           if (  mTerrainReadyListeners.empty(   ) )
           return;
          
           PagingLandscapeEvent e (  0,   0,   0,   0,   0,   AxisAlignedBox (   ) );
           for (  std::list<PagingLandscapeDelegate *>::iterator it = mTerrainReadyListeners.begin(   );
           it != mTerrainReadyListeners.end(   ); ++it )
           (  *(  *it ) )(  &e );
           }
           //-------------------------------------------------------------------------
     203   bool PagingLandScapeListenerManager::setOption(  const String& strKey,   const void* pValue )
           {
          
           PagingLandscapeDelegate *d = const_cast < PagingLandscapeDelegate * > (  static_cast < const PagingLandscapeDelegate * >(  pValue ) );
           if (  StringUtil::startsWith(  strKey,   "add",   true ) )
           {
           if (  strKey == "addTerrainListener" )
           {
           addTerrainListener (  d );
           return true;
           }
          
           if (  strKey == "addPreloadPageListener" )
           {
           addPreloadPageListener (  d );
           return true;
           }
           if (  strKey == "addShowPageListener" )
           {
           addShowPageListener (  d );
           return true;
           }
           if (  strKey == "addHidePageListener" )
           {
           addHidePageListener (  d );
           return true;
           }
           if (  strKey == "addLoadPageListener" )
           {
           addLoadPageListener (  d );
           return true;
           }
           if (  strKey == "addModifyPageListener" )
           {
           addModifyPageListener (  d );
           return true;
           }
           if (  strKey == "addPostunloadPageListener" )
           {
           addPostunloadPageListener (  d );
           return true;
           }
           if (  strKey == "addUnloadPageListener" )
           {
           addUnloadPageListener (  d );
           return true;
           }
          
           if (  strKey == "addShowTileListener" )
           {
           addShowTileListener (  d );
           return true;
           }
           if (  strKey == "addHideTileListener" )
           {
           addHideTileListener (  d );
           return true;
           }
           if (  strKey == "addLoadTileListener" )
           {
           addLoadTileListener (  d );
           return true;
           }
           if (  strKey == "addModifyTileListener" )
           {
           addModifyTileListener (  d );
           return true;
           }
           if (  strKey == "addUnloadTileListener" )
           {
           addUnloadTileListener (  d );
           return true;
           }
           }
          
           if (  StringUtil::startsWith(  strKey,   "remove",   true ) )
           {
          
           if (  strKey == "removeTerrainListener" )
           {
           removeTerrainListener (  d );
           return true;
           }
          
           if (  strKey == "removePreloadPageListener" )
           {
           removePreloadPageListener (  d );
           return true;
           }
           if (  strKey == "removeShowPageListener" )
           {
           removeShowPageListener (  d );
           return true;
           }
           if (  strKey == "removeHidePageListener" )
           {
           removeHidePageListener (  d );
           return true;
           }
           if (  strKey == "removeLoadPageListener" )
           {
           removeLoadPageListener (  d );
           return true;
           }
           if (  strKey == "removeModifyPageListener" )
           {
           removeModifyPageListener (  d );
           return true;
           }
           if (  strKey == "removePostunloadPageListener" )
           {
           removePostunloadPageListener (  d );
           return true;
           }
           if (  strKey == "removeUnloadPageListener" )
           {
           removeUnloadPageListener (  d );
           return true;
           }
          
           if (  strKey == "removeShowTileListener" )
           {
           removeShowTileListener (  d );
           return true;
           }
           if (  strKey == "removeHideTileListener" )
           {
           removeHideTileListener (  d );
           return true;
           }
           if (  strKey == "removeLoadTileListener" )
           {
           removeLoadTileListener (  d );
           return true;
           }
           if (  strKey == "removeModifyTileListener" )
           {
           removeModifyTileListener (  d );
           return true;
           }
           if (  strKey == "removeUnloadTileListener" )
           {
           removeUnloadTileListener (  d );
           return true;
           }
           }
           return false;
           }
           //-------------------------------------------------------------------------
     352   void PagingLandScapeListenerManager::addTerrainListener(  PagingLandscapeDelegate* pl )
           {
           mTerrainReadyListeners.push_back(  pl );
           }
           //-------------------------------------------------------------------------
     357   void PagingLandScapeListenerManager::removeTerrainListener(  PagingLandscapeDelegate* pl )
           {
           mTerrainReadyListeners.remove (  pl );
           }
           //-------------------------------------------------------------------------
     362   void PagingLandScapeListenerManager::addPreloadPageListener(  PagingLandscapeDelegate* pl )
           {
           mPreloadPageListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     367   void PagingLandScapeListenerManager::removePreloadPageListener(  PagingLandscapeDelegate* pl )
           {
           mPreloadPageListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     372   void PagingLandScapeListenerManager::addShowPageListener(  PagingLandscapeDelegate* pl )
           {
           mShowPageListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     377   void PagingLandScapeListenerManager::removeShowPageListener(  PagingLandscapeDelegate* pl )
           {
           mShowPageListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     382   void PagingLandScapeListenerManager::addHidePageListener(  PagingLandscapeDelegate* pl )
           {
           mHidePageListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     387   void PagingLandScapeListenerManager::removeHidePageListener(  PagingLandscapeDelegate* pl )
           {
           mHidePageListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     392   void PagingLandScapeListenerManager::addLoadPageListener(  PagingLandscapeDelegate* pl )
           {
           mLoadPageListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     397   void PagingLandScapeListenerManager::removeLoadPageListener(  PagingLandscapeDelegate* pl )
           {
           mLoadPageListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     402   void PagingLandScapeListenerManager::addModifyPageListener(  PagingLandscapeDelegate* pl )
           {
           mModifyPageListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     407   void PagingLandScapeListenerManager::removeModifyPageListener(  PagingLandscapeDelegate* pl )
           {
           mModifyPageListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     412   void PagingLandScapeListenerManager::addPostunloadPageListener(  PagingLandscapeDelegate* pl )
           {
           mPostunloadPageListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     417   void PagingLandScapeListenerManager::removePostunloadPageListener(  PagingLandscapeDelegate* pl )
           {
           mPostunloadPageListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     422   void PagingLandScapeListenerManager::addUnloadPageListener(  PagingLandscapeDelegate* pl )
           {
           mUnloadPageListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     427   void PagingLandScapeListenerManager::removeUnloadPageListener(  PagingLandscapeDelegate* pl )
           {
           mUnloadPageListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     432   void PagingLandScapeListenerManager::addShowTileListener(  PagingLandscapeDelegate* pl )
           {
           mShowTileListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     437   void PagingLandScapeListenerManager::removeShowTileListener(  PagingLandscapeDelegate* pl )
           {
           mShowTileListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     442   void PagingLandScapeListenerManager::addHideTileListener(  PagingLandscapeDelegate* pl )
           {
           mHideTileListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     447   void PagingLandScapeListenerManager::removeHideTileListener(  PagingLandscapeDelegate* pl )
           {
           mHideTileListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     452   void PagingLandScapeListenerManager::addLoadTileListener(  PagingLandscapeDelegate* pl )
           {
           mLoadTileListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     457   void PagingLandScapeListenerManager::removeLoadTileListener(  PagingLandscapeDelegate* pl )
           {
           mLoadTileListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     462   void PagingLandScapeListenerManager::addModifyTileListener(  PagingLandscapeDelegate* pl )
           {
           mModifyTileListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     467   void PagingLandScapeListenerManager::removeModifyTileListener(  PagingLandscapeDelegate* pl )
           {
           mModifyTileListeners.remove (  pl );
           };
           //-------------------------------------------------------------------------
     472   void PagingLandScapeListenerManager::addUnloadTileListener(  PagingLandscapeDelegate* pl )
           {
           mUnloadTileListeners.push_back(  pl );
           };
           //-------------------------------------------------------------------------
     477   void PagingLandScapeListenerManager::removeUnloadTileListener(  PagingLandscapeDelegate* pl )
           {
           mUnloadTileListeners.remove (  pl );
           };
          }//namespace
          

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeMeshDecal.cpp

       1  /*-----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright � 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------*/
          /***************************************************************************
          OgrePagingLandScapeMeshDecal.cpp - description
          -------------------
          begin : Sat Oct 15,   2006
          copyright : (  C ) 2006 by Steven Klug
          email : stevenklug@san.rr.com
          
          
          ***************************************************************************/
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "Ogre.h"
          
          #include "OgrePagingLandScapeMeshDecal.h"
          #include "OgrePagingLandScapeAxisAlignedBoxSceneQuery.h"
          
          #include <numeric>
          
          using namespace Ogre;
          using namespace std;
          
          namespace
          {
           typedef PagingLandScapeAxisAlignedBoxSceneQuery::CustomQueryResult CustomQueryResult;
          
           template<class T>
      49   class IndexCalculator
           {
           int width_;
           int offset_;
           public:
      54   IndexCalculator(   int width,   int offset  )
           : width_(   width  )
           ,   offset_(   offset  ) {}
          
      58   T GetIndex(   int x,   int z  ) const
           {
           return offset_ + x + (   z * width_  );
           }
           };
          }
          
      65  PagingLandScapeMeshDecal::PagingLandScapeMeshDecal(   const String& name,  
      66   const String& materialName,  
      67   const Vector2& size,  
      68   const String& sceneMgrInstanceName  )
           : MovableObject(   name  )
           ,   material_(   MaterialManager::getSingleton(   ).getByName(   materialName  )  )
           ,   size_(   size  )
           ,   sceneMgr_(   Root::getSingleton(   ).getSceneManager(   sceneMgrInstanceName  )  )
           ,   position_(   Vector3::ZERO  )
           ,   mDirty(  true )
          {
           if(   material_.isNull(   )  )
           {
           OGRE_EXCEPT(   Exception::ERR_INVALIDPARAMS,  
           "Invalid material name for mesh decal.",  
           "PagingLandScapeMeshDecal::PagingLandScapeMeshDecal" );
           }
          
           // Create a dummy rayQuery to avoid heap allocation every frame.
           rayQuery_ = sceneMgr_->createRayQuery(   Ray(   Vector3::ZERO,   Vector3::NEGATIVE_UNIT_Y  )  );
           rayQuery_->setQueryTypeMask(   SceneManager::WORLD_GEOMETRY_TYPE_MASK  );
           rayQuery_->setWorldFragmentType(   SceneQuery::WFT_SINGLE_INTERSECTION  );
          
           AABBquery_ = sceneMgr_->createAABBQuery(   AxisAlignedBox(   )  );
          
           // Allocate objects for render op.
           renderOp_.vertexData = new VertexData(   );
           renderOp_.indexData = new IndexData(   );
          
           // Create declaration (  memory format ) of vertex data
           VertexDeclaration* decl = renderOp_.vertexData->vertexDeclaration;
           decl->addElement(   0,   0,   VET_FLOAT3,   VES_POSITION  );
           declSize_ = sizeof(   Vector3  );
           decl->addElement(   0,   declSize_,   VET_FLOAT2,   VES_TEXTURE_COORDINATES,   0 );
           declSize_ += sizeof(   Vector2  );
          
           // Set bounding information
           AABB_.setMinimum(   Vector3(   -size_.x / 2,   1,   -size_.y / 2  )  );
           AABB_.setMaximum(   Vector3(   size_.x / 2,   1,   size_.y / 2  )  );
          
          // CreateGeometry(   );
          }
          
     108  PagingLandScapeMeshDecal::~PagingLandScapeMeshDecal(   )
          {
           sceneMgr_->destroyQuery(   rayQuery_  );
           sceneMgr_->destroyQuery(   AABBquery_  );
           delete renderOp_.vertexData;
           delete renderOp_.indexData;
          }
          
     116  void PagingLandScapeMeshDecal::_notifyAttached(  Node* parent,   bool isTagPoint )
          {
           MovableObject::_notifyAttached(  parent,   isTagPoint );
           CreateGeometry(   );
          }
          
          
     123  void PagingLandScapeMeshDecal::CreateGeometry(   )
          {
           Matrix4 xlate;
           if(   mParentNode  )
           getWorldTransforms(   &xlate  );
           else
           xlate = Matrix4::IDENTITY;
           Matrix4 invXlate = xlate.inverse(   );
          
           // Deterimine approximate size of vertex data from query.
           // Get the scale.
           Real scaleX;
           Real scaleZ;
           sceneMgr_->getOption(   "ScaleX",   &scaleX  );
           sceneMgr_->getOption(   "ScaleZ",   &scaleZ  );
          
           const AxisAlignedBox& box = getWorldBoundingBox(   true  );
           subSections_.clear(   );
           subExtents_.clear(   );
           height_ = 0;
           width_ = 0;
          
           AABBquery_->setBox(   box  );
           AABBquery_->execute(   this  );
          
           if(   !height_ || !width_  )
           return;
          
           //only continue if it's dirty
           if (  !mDirty ) {
           return;
           }
           //make a copy of the subextends for lookup
           mOldSubExtents = subExtents_;
           mDirty = false;
          
           Real xOffset = -size_.x / 2;
           Real zOffset = -size_.y / 2;
          
           // Create vertex data structure for 4 vertices shared between submeshes
           VertexData* vertexData = renderOp_.vertexData;
          
           // Allocate vertex buffer of the requested number of vertices (  vertexCount )
           // and bytes per vertex (  offset )
           HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton(   ).
           createVertexBuffer(   declSize_,  
           GetNumVertices(   ),  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY  );
          // HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE  );
          
           // Set vertex buffer binding so buffer 0 is bound to our vertex buffer
           vertexData->vertexBufferBinding->setBinding(   0,   vbuf  );
          
           Real minY = Math::POS_INFINITY;
           Real maxY = Math::NEG_INFINITY;
           float* buffer = (  float* )vbuf->lock(   HardwareBuffer::HBL_DISCARD  );
           int vertexCount = 0;
          
           SubSectionContainer::const_iterator it = subSections_.begin(   );
           SubSectionContainer::const_iterator itEnd = subSections_.end(   );
           for(   ; it != itEnd; ++it  )
           {
           VertexContainer::const_iterator vertIt = it->begin(   );
           VertexContainer::const_iterator vertItEnd = it->end(   );
           for(   ; vertIt != vertItEnd; ++vertIt  )
           {
           // Copy our vertices into the hardware buffer and calculate
           // texture coords.
           // TODO: Don't transform vertices that aren't included due to LoD.
           Vector3 localVertex = invXlate * vertIt->vertex_; // Convert back to local coordinates.
           *buffer++ = localVertex.x;
           *buffer++ = localVertex.y;
           *buffer++ = localVertex.z;
           // Keep track of height bounds for final AABB.
           if(   localVertex.y < minY  )
           minY = localVertex.y;
           if(   localVertex.y > maxY  )
           maxY = localVertex.y;
           // Calculate texture coordinates based on distances from the
           // edges of our rectangle.
           *buffer++ = (   localVertex.x - xOffset  ) / size_.x;
           *buffer++ = 1.0 - (   (   localVertex.z - zOffset  ) / size_.y  );
           ++vertexCount;
           }
           }
           vbuf->unlock(   );
          
           vertexData->vertexCount = vertexCount;
          
           // Create index data.
           IndexData* indexData = renderOp_.indexData;
           indexData->indexStart = 0;
           size_t maxNumIndices = GetNumIndices(   );
           bool is32bits = maxNumIndices >= 0x10000;
           // Allocate index buffer of the requested number of vertices (  ibufCount )
           HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(   ).
           createIndexBuffer(   (  is32bits ) ? HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT,  
           maxNumIndices,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY  );
           if(   is32bits  )
           indexData->indexCount = CreateIndices<uint>(   ibuf  );
           else
           indexData->indexCount = CreateIndices<ushort>(   ibuf  );
          
           // Put the hardware index buffer into our render operation object.
           indexData->indexBuffer = ibuf;
           indexData->optimiseVertexCacheTriList(   );
          
           subSections_.clear(   );
           subExtents_.clear(   );
          
           AABB_.setMinimum(   Vector3(   -size_.x / 2,   minY,   -size_.y / 2  )  );
           AABB_.setMaximum(   Vector3(   size_.x / 2,   maxY,   size_.y / 2 )  );
           radius_ = std::max(   size_.x / 2,   size_.y / 2 );
           radius_ = std::max(   radius_,   maxY  );
          }
          
     240  size_t PagingLandScapeMeshDecal::GetNumVertices(   ) const
          {
           size_t vertices = 0;
           SubSectionContainer::const_iterator it = subSections_.begin(   );
           for(   ; it != subSections_.end(   ); ++it  )
           vertices += it->size(   );
           return vertices;
          }
          
     249  size_t PagingLandScapeMeshDecal::GetNumIndices(   ) const
          {
           size_t indices = 0;
           SubExtentContainer::const_iterator it = subExtents_.begin(   );
           for(   ; it != subExtents_.end(   ); ++it  )
           {
           int step = 1 << it->renderLevel_;
           indices += (   it->width_ / step  ) * (   it->height_ / step  ) * 6;
           }
           return indices;
          }
          
          template<class T>
     262  int PagingLandScapeMeshDecal::CreateIndices(   Ogre::HardwareIndexBufferSharedPtr ibuf  )
          {
           T* indices = (  T* )ibuf->lock(   HardwareBuffer::HBL_DISCARD  );
           int indexCount = 0;
           int indexOffset = 0;
           for(   int z = 0; z < height_; ++z  )
           {
           for(   int x = 0; x < width_; ++x  )
           {
           indexCount += MeshSubSection<T>(   x,   z,   indices,   indexOffset  );
           }
           }
           ibuf->unlock(   );
           return indexCount;
          }
          
          template<class T>
     279  int PagingLandScapeMeshDecal::MeshSubSection(   int x,   int z,   T*& indices,   int& indexOffset  )
          {
           int indexCount = 0;
           int offset = indexOffset;
           const SubExtent& extents = subExtents_[z * width_ + x];
           int rl = extents.renderLevel_;
           // Get render levels of neighbors so we can stitch them properly.
           int northRL = z > 0 ? GetRenderLevel(   x,   z - 1  ) : rl;
           int westRL = x > 0 ? GetRenderLevel(   x - 1,   z  ) : rl;
           int southRL = z < height_ - 1 ? GetRenderLevel(   x,   z + 1  ) : rl;
           int eastRL = x < width_ - 1 ? GetRenderLevel(   x + 1,   z  ) : rl;
           // We only stitch if the neighbor's render level is greater than ours.
           bool northStitch = northRL > rl;
           bool westStitch = westRL > rl;
           bool southStitch = southRL > rl;
           bool eastStitch = eastRL > rl;
           // Get extents.
           int height = extents.height_;
           int width = extents.width_;
           int step = 1 << rl;
           int lineStepOffset = width * step;
           int iEnd = height - 1 - (   southStitch ? step : 0  );
           int i = 0;
           if(   northStitch  )
           {
           i = step;
           offset += lineStepOffset;
           }
           for(   ; i < iEnd; i += step  )
           {
           int nextLineOffset = offset + lineStepOffset;
           int jEnd = width - 1 - (   eastStitch ? step : 0  );
           for(   int j = westStitch ? step : 0; j < jEnd; j += step  )
           {
           *indices++ = j + offset; // up-left
           *indices++ = j + nextLineOffset; // low-left
           *indices++ = j + step + offset; // up-right
          
           *indices++ = j + step + offset; // up-right
           *indices++ = j + nextLineOffset; // low-left
           *indices++ = j + step + nextLineOffset; // low-right
          
           indexCount += 6;
           }
           offset = nextLineOffset;
           }
           // Stich any sides that need stiching.
           if(   northStitch  )
           indexCount += StitchEdge(   indices,   extents,   rl,   northRL,   true,   true,   westStitch,   eastStitch,   indexOffset  );
           if(   westStitch  )
           indexCount += StitchEdge(   indices,   extents,   rl,   westRL,   false,   false,   southStitch,   northStitch,   indexOffset  );
           if(   southStitch  )
           indexCount += StitchEdge(   indices,   extents,   rl,   southRL,   true,   false,   eastStitch,   westStitch,   indexOffset  );
           if(   eastStitch  )
           indexCount += StitchEdge(   indices,   extents,   rl,   eastRL,   false,   true,   northStitch,   southStitch,   indexOffset  );
          
           indexOffset += (   width * height  );
           return indexCount;
          }
          
          // Use the same stiching algorithm the landscape renderer does or
          // the decal won't look right. TODO: At some point it would be nice
          // to just use the actual code from the renderer,   but it's made to
          // work specifically with tiles,   not sub-sections of tiles.
          template<class T>
     344  int PagingLandScapeMeshDecal::StitchEdge(   T*& indices,  
           const SubExtent& extents,  
           const int hiLOD,  
           const int loLOD,  
     348   const bool horizontal,  
     349   const bool forward,  
     350   const bool omitFirstTri,  
     351   const bool omitLastTri,  
           const int indexOffset  )
          {
           // Work out the steps ie how to increment indexes
           // Step from one vertex to another in the high detail version
           int step = 1 << hiLOD;
           // Step from one vertex to another in the low detail version
           int superstep = 1 << loLOD;
           // Step half way between low detail steps
           int halfsuperstep = superstep >> 1;
          
           // Work out the starting points and sign of increments
           // We always work the strip clockwise
           int startx,   startz,   endx,   rowstep;
           if(   horizontal  )
           {
           if(   forward  )
           {
           startx = startz = 0;
           endx = extents.width_ - 1;
           rowstep = step;
           }
           else
           {
           startx = extents.width_ - 1;
           startz = extents.height_ - 1;
           endx = 0;
           rowstep = -step;
           step = -step;
           superstep = -superstep;
           halfsuperstep = -halfsuperstep;
           }
           }
           else
           {
           if(   forward  )
           {
           startx = 0;
           endx = extents.height_ - 1;
           startz = extents.width_ - 1;
           rowstep = -step;
           }
           else
           {
           startx = extents.height_ - 1;
           endx = 0;
           startz = 0;
           rowstep = step;
           step = -step;
           superstep = -superstep;
           halfsuperstep = -halfsuperstep;
           }
           }
          
           int indexCount = 0;
           IndexCalculator<T> calc(   extents.width_,   indexOffset  );
           for(   int j = startx; j != endx; j += superstep  )
           {
           int k;
           for(   k = 0; k != halfsuperstep; k += step  )
           {
           int jk = j + k;
           //skip the first bit of the corner?
           if(   j != startx || k != 0 || !omitFirstTri  )
           {
           if(   horizontal  )
           {
           *indices++ = calc.GetIndex(   j ,   startz  );
           *indices++ = calc.GetIndex(   jk,   startz + rowstep  );
           *indices++ = calc.GetIndex(   jk + step,   startz + rowstep  );
           }
           else
           {
           *indices++ = calc.GetIndex(   startz,   j  );
           *indices++ = calc.GetIndex(   startz + rowstep,   jk  );
           *indices++ = calc.GetIndex(   startz + rowstep,   jk + step  );
           }
           indexCount += 3;
           }
           }
          
           // Middle tri
           if(   horizontal  )
           {
           *indices++ = calc.GetIndex(   j,   startz  );
           *indices++ = calc.GetIndex(   j + halfsuperstep,   startz + rowstep  );
           *indices++ = calc.GetIndex(   j + superstep,   startz  );
           }
           else
           {
           *indices++ = calc.GetIndex(   startz,   j  );
           *indices++ = calc.GetIndex(   startz + rowstep,   j + halfsuperstep  );
           *indices++ = calc.GetIndex(   startz,   j + superstep  );
           }
           indexCount += 3;
          
           for(   k = halfsuperstep; k != superstep; k += step  )
           {
           int jk = j + k;
           if(   j != endx - superstep || k != superstep - step || !omitLastTri  )
           {
           if(   horizontal  )
           {
           *indices++ = calc.GetIndex(   j + superstep,   startz  );
           *indices++ = calc.GetIndex(   jk,   startz + rowstep  );
           *indices++ = calc.GetIndex(   jk + step,   startz + rowstep  );
           }
           else
           {
           *indices++ = calc.GetIndex(   startz,   j + superstep  );
           *indices++ = calc.GetIndex(   startz + rowstep,   jk  );
           *indices++ = calc.GetIndex(   startz + rowstep,   jk + step  );
           }
           indexCount += 3;
           }
           }
           }
           return indexCount;
          }
          
          // From Ogre::MovableObject
     472  void PagingLandScapeMeshDecal::_updateRenderQueue(   RenderQueue* queue  )
          {
           queue->addRenderable(   this,   mRenderQueueID,   OGRE_RENDERABLE_DEFAULT_PRIORITY + 1  );
          }
          
          // From Ogre::Renderable
     478  void PagingLandScapeMeshDecal::getRenderOperation(   Ogre::RenderOperation& op  )
          {
           // Update our RenderOperation if necessary.
           const Vector3& position = mParentNode->getWorldPosition(   );
           const Quaternion& orientation = mParentNode->getOrientation(   );
           if(   position != position_ ||
           orientation != orientation_  )
           {
           position_ = position;
           orientation_ = orientation;
           //force a full geometry rebuild
           mDirty = true;
           }
           //calling this every frame will only trigger a full rebuild when the LOD has changed
           CreateGeometry(   );
           op = renderOp_;
          }
          
     496  void PagingLandScapeMeshDecal::getWorldTransforms(   Ogre::Matrix4* xform  ) const
          {
           *xform = mParentNode->_getFullTransform(   );
          }
          
     501  const Quaternion& PagingLandScapeMeshDecal::getWorldOrientation(   ) const
          {
           return mParentNode->_getDerivedOrientation(   );
          }
          
     506  const Vector3& PagingLandScapeMeshDecal::getWorldPosition(   ) const
          {
           return mParentNode->getWorldPosition(   );
          }
          
     511  Real PagingLandScapeMeshDecal::getSquaredViewDepth(   const Camera* cam  ) const
          {
           return (   getWorldPosition(   ) - cam->getDerivedPosition(   )  ).squaredLength(   );
          }
          
          // Receive terrain vertices from our query.
     517  bool PagingLandScapeMeshDecal::queryResult(  SceneQuery::WorldFragment* fragment )
          {
           if(   fragment->fragmentType != SceneQuery::WFT_CUSTOM_GEOMETRY  )
           {
           OGRE_EXCEPT(   Exception::ERR_INTERNAL_ERROR,  
           "SceneQuery flags invalid.",  
           "PagingLandScapeMeshDecal::queryResult" );
           }
          
           CustomQueryResult* result = reinterpret_cast<CustomQueryResult*>(   fragment->geometry  );
           switch(   result->type_  )
           {
           case CustomQueryResult::QUERY_EXTENTS_TYPE:
           {
           // Reserve space for our sub-sections.
           width_ = result->data_.queryExtents_.width_;
           height_ = result->data_.queryExtents_.height_;
           subSections_.resize(   width_ * height_  );
           subExtents_.resize(   width_ * height_  );
           break;
           }
          
           case CustomQueryResult::SUBSECTION_EXTENTS_TYPE:
           {
           currentSubX_ = result->data_.subExtents_.subX_;
           currentSubZ_ = result->data_.subExtents_.subZ_;
           int offset = currentSubX_ + currentSubZ_ * width_;
           SubExtent& subExtent = subExtents_[offset];
           subExtent.width_ = result->data_.subExtents_.width_;
           subExtent.height_ = result->data_.subExtents_.height_;
           subExtent.renderLevel_ = result->data_.subExtents_.renderLevel_;
           // TODO: Optimize! We wouldn't need an intermediate array at all
           // if the scene query gave us all the sub-section extents up front
           // so we could allocate the correct size fo the vertex buffer. It's
           // a bit tricky in the scene query,   so leaving it this way for now.
           // Another option could be to overallocate the vertex buffer assuming
           // that each sub-section was the full tile size,   but that's also
           // pretty wasteful (  though possibly faster,   since no heap allocation ).
           subSections_[offset].reserve(   subExtent.width_ * subExtent.height_  );
          
           //compare with earlier result and see if any LOD has changed
           if (  !mDirty ) {
           if (  mOldSubExtents.size(   ) >= offset ) {
           SubExtent& oldSubExtent = mOldSubExtents[offset];
           if (  oldSubExtent.renderLevel_ != subExtent.renderLevel_ ) {
           mDirty = true;
           }
           } else {
           mDirty = true;
           }
           }
           break;
           }
          
           case CustomQueryResult::VERTEX_TYPE:
           {
           VertexContainer& subSection = subSections_[currentSubX_ + currentSubZ_ * width_];
           Vertex vertex(   result->data_.vertexData_.x_,  
           result->data_.vertexData_.y_,  
           result->data_.vertexData_.z_,  
           result->data_.vertexData_.included_  );
           subSection.push_back(   vertex  );
           break;
           }
          
           default:
           OGRE_EXCEPT(   Exception::ERR_INTERNAL_ERROR,  
           "Result type invalid.",  
           "PagingLandScapeMeshDecal::queryResult" );
           }
           return true;
          }
          
          //-----------------------------------------------------------------------
          String PagingLandScapeMeshDecalFactory::FACTORY_TYPE_NAME = "PagingLandScapeMeshDecal";
          
          #if 0
          //-----------------------------------------------------------------------
     595  PagingLandScapeMeshDecal* PagingLandScapeMeshDecalFactory::create(   SceneManager& sceneMgr,  
     596   const String& name,  
     597   const String& materialName,  
     598   const Vector2& size,  
     599   const String& sceneMgrInstance  )
          {
           NameValuePairList params;
           params["materialName"] = materialName;
           params["width"] = StringConverter::toString(   size.x  );
           params["height"] = StringConverter::toString(   size.y  );
           params["sceneMgrInstance"] = sceneMgrInstance;
          
           return static_cast<PagingLandScapeMeshDecal*>(  
           sceneMgr.createMovableObject(   name,  
           PagingLandScapeMeshDecalFactory::FACTORY_TYPE_NAME,  
           &params  )  );
          }
          #endif
          //-----------------------------------------------------------------------
     614  const String& PagingLandScapeMeshDecalFactory::getType(  void ) const
          {
           return FACTORY_TYPE_NAME;
          }
          //-----------------------------------------------------------------------
     619  MovableObject* PagingLandScapeMeshDecalFactory::createInstanceImpl
          (  
     621   const String& name,  
     622   const NameValuePairList* params
           )
          {
           String materialName;
           Real width = 0.0;
           Real height = 0.0;
           String sceneMgrInstance;
           if(   params != 0  )
           {
           NameValuePairList::const_iterator it = params->find(   "materialName"  );
           if(   it != params->end(   )  )
           {
           materialName = it->second;
           }
           it = params->find(   "width"  );
           if(   it != params->end(   )  )
           {
           width = StringConverter::parseReal(   it->second  );
           }
           it = params->find(   "height"  );
           if(   it != params->end(   )  )
           {
           height = StringConverter::parseReal(   it->second  );
           }
           it = params->find(   "sceneMgrInstance"  );
           if(   it != params->end(   )  )
           {
           sceneMgrInstance = it->second;
           }
           }
          
           return new PagingLandScapeMeshDecal(   name,   materialName,   Vector2(   width,   height  ),   sceneMgrInstance  );
          }
          //-----------------------------------------------------------------------
     656  void PagingLandScapeMeshDecalFactory::destroyInstance(   MovableObject* obj  )
          {
           delete obj;
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOcclusion.cpp

       1  
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "Ogre.h"
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          
          #include "OgrePagingLandScapeOcclusion.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          
          #include "OgrePagingLandScapeOcclusionSorter.h"
          #include "OgrePagingLandScapeOcclusionVisibilityData.h"
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          #include "OgrePagingLandScapeOcclusionCHCTraversal.h"
          #include "OgrePagingLandScapeOcclusionSWTraversal.h"
          #include "OgrePagingLandScapeOcclusionVFTraversal.h"
          #include "OgrePagingLandScapeOcclusionDebugTraversal.h"
          
          #include "OgrePagingLandScapeOcclusionQuerySet.h"
          
          #include "OgreOcclusionBoundingBox.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      31   Occlusion::Occlusion(  unsigned int visibilityThsd ):
           mCurrentCam(  0 ),  
           mVisibilityTreshold(  visibilityThsd ),  
           mIsQueryPoolNotInitiated(  true ),  
           mFrameConservativeVisibility (  300 )
           {
           };
           //-----------------------------------------------------------------------
      39   bool Occlusion::nextFrame(  PagingLandScapeOctreeCamera *cam,  
      40   MovableObjectList *camInProgressVisibles,  
      41   bool onlyshadowcaster,  
      42   RenderQueue *q )
           {
           bool newframe = true;
          
           mCurrentRenderQueue = q;
           mOnlyShadowCaster = onlyshadowcaster;
          
           if (  cam != mCurrentCam )
           {
           mCurrentCam = cam;
           }
           if (  mCurrentCam->nextFrame(  Root::getSingleton(   ).getCurrentFrameNumber (   ) ) )
           {
           // change frame Id counter
           //that identify current frame.
           mFrameId = mCurrentCam->getFrameId(   );
           newframe = true;
           }
          
           if (  newframe )
           {
           camInProgressVisibles->clear(   );
           #ifdef _VISIBILITYDEBUG
           // reset counters.
           triangle_cnt = 0;
           traversed_nodes_cnt = 0;
           frustum_culled_nodes_cnt = 0;
           query_cnt = 0;
           object_cnt = 0;
           #endif //_VISIBILITYDEBUG
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
      77   void Occlusion::queueDraw(  PagingLandScapeOctreeNode& n )
           {
           #ifdef _VISIBILITYDEBUG
           object_cnt++;
           #endif //_VISIBILITYDEBUG
          
           VisibilityData * const vis = n.getNodeData (  mCurrentCam );
           if (  !vis->notified )
           {
           // notify objects handled by this node
           n.notifyNodeObjects (  mCurrentCam,   mOnlyShadowCaster );
           }
           // as it's visible add its attached objects to render queue.
           // note that we know it already has been notified by camera,  
           // when we issued query.
           n._addAlreadyNotifiedToVisibles (   );
          
           // now it had been drawn,   notified should be false.
           vis->notified = false;
           vis->frameID = mFrameId;
           }
           //-----------------------------------------------------------------------
      99   bool Occlusion::issueDrawQuery(  PagingLandScapeOctreeNode& n )
           {
           VisibilityData * const vis = n.getNodeData (  mCurrentCam );
          
           #ifdef _VISIBILITYDEBUG
           query_cnt++;
           traversed_nodes_cnt++;
           assert (  vis->viewFrustumVisible );
           #endif //_VISIBILITYDEBUG
          
           assert (  vis->frameID != mFrameId ) ;
           assert (  vis->query == 0 );
           assert (  n.isOccluder(   ) );
          
           MovableObjectList *moToRender = n.getVisibleNotifiedNodeObjects(  mCurrentCam,   mOnlyShadowCaster );
          
           // Mark that Node already notified by this frame/cam combination
           vis->frameID = mFrameId;
           vis->notified = true;
          
           if (  !moToRender->empty(   ) )
           {
           HardwareOcclusionQuery *query = mQueryPool.getPoolable(   );
           vis->query = query;
          
           // create the render Queue.
           MovableObjectList::iterator it = moToRender->begin(   ),   itend = moToRender->end(   );
           while (  it != itend )
           {
           (  *it )->_updateRenderQueue(  &*mCurrentRenderQueue );
           ++it;
           }
          
           // draw and query.
           query->beginOcclusionQuery (   );
           mScnMngr->directRenderSingleQueue (  &*mCurrentRenderQueue );
           query->endOcclusionQuery (   );
          
           moToRender->clear(   );
          
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
     144   void Occlusion::issueBboxQuery(  OcclusionElement& n )
           {
           #ifdef _VISIBILITYDEBUG
           query_cnt++;
           #endif //_VISIBILITYDEBUG
          
           VisibilityData * const vis = n.getNodeData (  mCurrentCam );
           assert (  vis->query == 0 );
           HardwareOcclusionQuery *query = mQueryPool.getPoolable(   );
           vis->query = query;
          
           query->beginOcclusionQuery(   );
           // render bounding box for object
           mScnMngr->directRenderSingleObject(  n.getOcclusionBoundingBox(   ) );
           query->endOcclusionQuery(   );
          
           //mScnMngr->addVisible (  n.getOcclusionBoundingBox(   ) );
           }
           //-----------------------------------------------------------------------
     163   bool Occlusion::isQueryResultIsVisible(  OcclusionElement& node )
           {
           // check visibility result
           unsigned int visiblePixels = 0;
           //this one wait if result not available
           VisibilityData * const vis = node.getNodeData (  mCurrentCam );
           vis->query->pullOcclusionQuery (  &visiblePixels );
          
           mQueryPool.removePoolable (  vis->query );
           vis->query = 0;
          
           if (  visiblePixels > mVisibilityTreshold )
           {
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
     181   void Occlusion::pullUpVisibility(  OcclusionElement& node )
           {
           OcclusionElement* n = &node;
           VisibilityData *vis = n->getNodeData (  mCurrentCam );
          
           while (  !vis->queryVisible )
           {
           vis->queryVisible = true;
           n = n->getParent(   );
           if (  0 == n )
           return;
           vis = n->getNodeData (  mCurrentCam );
           }
           }
           //-----------------------------------------------------------------------
     196   bool Occlusion::insideViewFrustum(  OcclusionElement& n )
           {
           const bool result = mCurrentCam->isVisible (  n.getCullBoundingBox (   ) );
          
           #ifdef _VISIBILITYDEBUG
           if (  result )
           {
           n.getNodeData (  mCurrentCam )->viewFrustumVisible = true;
           }
           else
           {
           n.getNodeData (  mCurrentCam )->viewFrustumVisible = false;
           frustum_culled_nodes_cnt++;
           }
           #endif
          
           return result;
           }
           //-----------------------------------------------------------------------
           //this is the algorithm from the paper
     216   void Occlusion::CHCtraversal(  PagingLandScapeOctree *octree,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           if (  mIsQueryPoolNotInitiated )
           initQueryPool (   );
          
           const unsigned int visibilityTreshold = mVisibilityTreshold;
           const Vector3 &camPos = mCurrentCam->getDerivedPosition(   );
           FrontToBackNodeSorterPriorityQueue traversalStack = FrontToBackNodeSorterPriorityQueue(  FrontToBackNodeSorterOperator (  camPos ) );
          
           //draw leaves,   stack otherwise
           CHCTraversal toStackTraversal(  traversalStack,   *this );
           const unsigned int frameId = mFrameId;
           const unsigned int lastframeId = mFrameId - 1;
          
           // first Octree
           traversalStack.push (  octree );
           while (  !traversalStack.empty(   ) || !m_queryQueue.empty(   ) )
           {
           //first part
           // get previous frame occlusion results
           while (  traversalStack.empty(   ) &&
           !m_queryQueue.empty(   ) &&
           !m_queryQueue.front(   )->getNodeData (  mCurrentCam )->query->isStillOutstanding(   ) )
           {
           OcclusionElement& node = *(  m_queryQueue.front(   ) );
           m_queryQueue.pop(   );
          
           VisibilityData * const vis = node.getNodeData (  mCurrentCam );
           // should be already frustum culled and flagged as not visible
           assert (  vis->lastQueryFrameId == frameId );
           assert (  !vis->queryVisible );
           #ifdef _VISIBILITYDEBUG
           assert (  vis->viewFrustumVisible );
           #endif //_VISIBILITYDEBUG
          
           // check visibility result
           unsigned int visiblePixels = 0;
           //this one wait if result not available
           vis->query->pullOcclusionQuery(  &visiblePixels );
           mQueryPool.removePoolable(  vis->query );
           vis->query = 0;
           if(  visiblePixels > visibilityTreshold )
           {
           pullUpVisibility (  node );
          
           // Traverse for sure this visible node
           // And therefore check children
           node.traversal (  toStackTraversal,   visibleBounds );
           //node.traversal (  toStackTraversal,   0 );
           }
           }
           //2nd part
           // query visible objects
           while (  !traversalStack.empty(   ) )
           {
           OcclusionElement& node = *traversalStack.top (   );
           traversalStack.pop (   );
          
           // make sure there's no loop of some sort.
           // as we must query a node only once
           assert (  frameId != node.getNodeData (  mCurrentCam )->lastQueryFrameId );
           if (  insideViewFrustum (  node ) )
           {
           VisibilityData * const vis = node.getNodeData (  mCurrentCam );
           // identify visible in the last frame nodes
           const bool wasVisible = vis->queryVisible &&
           lastframeId == vis->lastQueryFrameId;
           if (  node.isLeaf(   ) )
           {
           if (  wasVisible && node.isOccluder(   ) )
           {
           // Draw & query at the same time previously visible nodes
           if (  issueDrawQuery (  static_cast <PagingLandScapeOctreeNode &> (  node ) ) )
           {
           m_queryQueue.push (  &node );
           }
           else
           {
           // skip testing previously visible node
           // that is not visible when notified.
           // make next frame get here again,  
           // saving a box query
           vis->queryVisible = true;
           vis->lastQueryFrameId = frameId;
           continue;
           }
           }
           else
           {
           issueBboxQuery (  node );
           m_queryQueue.push (  &node );
           }
           }
           else
           {
           if (  wasVisible )
           {
           // skip testing previously visible node
           // (  interior nodes in hierarchy )
           node.traversal (  toStackTraversal,   visibleBounds );
           //node.traversal (  toStackTraversal,   0 );
           }
           else
           {
           // only query node that wasn't visible last frame
           issueBboxQuery (  node );
           m_queryQueue.push (  &node );
           }
           }
          
           // reset this node's visibility to false
           // Will be updated by results queries that will pull up results.
           // by children that will be flagged visible and will transmit info
           // to their parent nodes (  pullUpVisibility(   ) )
           vis->queryVisible = false;
           // update node's visited flag to make sure we won't visit 2 times
           // and to "tick" the visible info.
           vis->lastQueryFrameId = frameId;
           }
           }
           }
           }
           //-----------------------------------------------------------------------
           //this is the algorithm from the paper,   conservative way.
     340   void Occlusion::CHCtraversalConservative(  PagingLandScapeOctree *octree,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
          
           const unsigned int frameConservativeVisibility = mFrameConservativeVisibility;
           const unsigned int visibilityTreshold = mVisibilityTreshold;
          
           if (  mIsQueryPoolNotInitiated )
           initQueryPool (   );
          
          
           const Vector3 &camPos = mCurrentCam->getDerivedPosition(   );
           FrontToBackNodeSorterPriorityQueue traversalStack = FrontToBackNodeSorterPriorityQueue(  FrontToBackNodeSorterOperator (  camPos ) );
          
           //draw leaves,   stack otherwise
           CHCTraversal toStackTraversal(  traversalStack,   *this );
           const unsigned int frameId = mFrameId;
           const unsigned int lastframeId = mFrameId - 1;
          
           // first Octree
           traversalStack.push (  octree );
           while (  !traversalStack.empty(   ) || !m_queryQueue.empty(   ) )
           {
           //first part
           // get previous frame occlusion results
           while (  traversalStack.empty(   ) &&
           !m_queryQueue.empty(   ) &&
           !m_queryQueue.front(   )->getNodeData (  mCurrentCam )->query->isStillOutstanding(   ) )
           {
           OcclusionElement& node = *(  m_queryQueue.front(   ) );
           m_queryQueue.pop(   );
          
           VisibilityData * const vis = node.getNodeData (  mCurrentCam );
           // should be already frustum culled and flagged as not visible
           assert (  vis->lastQueryFrameId == frameId );
           assert (  !vis->queryVisible );
           #ifdef _VISIBILITYDEBUG
           assert (  vis->viewFrustumVisible );
           #endif //_VISIBILITYDEBUG
          
           // check visibility result
           unsigned int visiblePixels = 0;
           //this one wait if result not available
           vis->query->pullOcclusionQuery(  &visiblePixels );
           mQueryPool.removePoolable(  vis->query );
           vis->query = 0;
           if(  visiblePixels > visibilityTreshold )
           {
           pullUpVisibility (  node );
          
           // Traverse for sure this visible node
           // And therefore check children
           node.traversal (  toStackTraversal,   visibleBounds );
           //node.traversal (  toStackTraversal,   0 );
           }
           }
           //2nd part
           // query visible objects
           while (  !traversalStack.empty(   ) )
           {
           OcclusionElement& node = *traversalStack.top (   );
           traversalStack.pop (   );
          
           // make sure there's no loop of some sort.
           // as we must query a node only once
           assert (  frameId != node.getNodeData (  mCurrentCam )->lastQueryFrameId );
           if (  insideViewFrustum (  node ) )
           {
           VisibilityData * const vis = node.getNodeData (  mCurrentCam );
          
           // identify visible in the last frame nodes
           const bool wasVisible = vis->queryVisible;
           const bool wasVisibleandQueriedBeforeLastNFrame = wasVisible
           && lastframeId - frameConservativeVisibility < vis->lastQueryFrameId;
           if (  wasVisibleandQueriedBeforeLastNFrame )
           {
           if (  node.isLeaf(   ) && node.isOccluder(   ) )
           {
           MovableObjectList *moToRender = static_cast <PagingLandScapeOctreeNode *> (  &node )->getVisibleNotifiedNodeObjects(  mCurrentCam,   mOnlyShadowCaster );
           // create the render Queue.
           if (  !moToRender->empty(   ) )
           {
           MovableObjectList::iterator it = moToRender->begin(   ),  
           itend = moToRender->end(   );
           while (  it != itend )
           {
           (  *it )->_updateRenderQueue (  &*mCurrentRenderQueue );
           ++it;
           }
           mScnMngr->directRenderSingleQueue (  &*mCurrentRenderQueue );
           }
           vis->notified = true;
           }
           pullUpVisibility (  node );
           node.traversal (  toStackTraversal,   visibleBounds );
           //node.traversal (  toStackTraversal,   0 );
           }
           else
           {
           const bool wasVisibleandQueriedExacltyLastNFrame = wasVisible &&
           lastframeId - frameConservativeVisibility == vis->lastQueryFrameId;
           if (  node.isLeaf(   ) )
           {
           if (  wasVisibleandQueriedExacltyLastNFrame && node.isOccluder(   ) )
           {
           // Draw & query at the same time previously visible nodes
           if (  issueDrawQuery (  static_cast <PagingLandScapeOctreeNode &> (  node ) ) )
           {
           m_queryQueue.push (  &node );
           }
           else
           {
           // skip testing previously visible node
           // that is not visible when notified.
           // make next frame get here again,  
           // saving a box query
           vis->queryVisible = true;
           vis->lastQueryFrameId = frameId;
           continue;
           }
           }
           else
           {
           issueBboxQuery (  node );
           m_queryQueue.push (  &node );
           }
           }
           else
           {
           if (  wasVisibleandQueriedExacltyLastNFrame )
           {
           // skip testing previously visible node
           // (  interior nodes in hierarchy )
           node.traversal (  toStackTraversal,   visibleBounds );
           //node.traversal (  toStackTraversal,   0 );
           }
           else
           {
           // only query node that wasn't visible last frame
           issueBboxQuery (  node );
           m_queryQueue.push (  &node );
           }
           }
           // reset this node's visibility to false
           // Will be updated by results queries that will pull up results.
           // by children that will be flagged visible and will transmit info
           // to their parent nodes (  pullUpVisibility(   ) )
           vis->queryVisible = false;
           // update node's visited flag to make sure we won't visit 2 times
           // and to "tick" the visible info.
           vis->lastQueryFrameId = frameId;
           }
           }
           }
           }
           }
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOcclusionCHCTraversal.cpp

       1  
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          #include "OgrePagingLandScapeOcclusion.h"
          
          #include "OgrePagingLandScapeOcclusionSorter.h"
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          #include "OgrePagingLandScapeOcclusionCHCTraversal.h"
          #include "OgrePagingLandScapeOcclusionVisibilityData.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      19   void CHCTraversal::onTree(  PagingLandScapeOctree& node,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           #ifdef _VISIBILITYDEBUG
           assert (  node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible );
           occlusion.traversed_nodes_cnt++;
           #endif //_VISIBILITYDEBUG
          
           if (  !node.mNodes.empty(   ) )
           {
           PagingLandScapeOctreeNodeList::iterator it = node.mNodes.begin(   );
           while (  it != node.mNodes.end(   ) )
           {
           stack.push (  *it );
           ++it;
           }
           }
          
           PagingLandScapeOctree *n =
           node.mChildren[ 0 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           stack.push(  n );
           n = node.mChildren[ 1 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           stack.push(  n );
           n = node.mChildren[ 0 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           stack.push(  n );
           n = node.mChildren[ 1 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           stack.push(  n );
           n = node.mChildren[ 0 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           stack.push(  n );
           n = node.mChildren[ 1 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           stack.push(  n );
           n = node.mChildren[ 0 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           stack.push(  n );
           n = node.mChildren[ 1 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           stack.push(  n );
           }
           //-----------------------------------------------------------------------
      63   void CHCTraversal::onLeaf(  PagingLandScapeOctreeNode& n,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           #ifdef _VISIBILITYDEBUG
           assert (  n.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible );
           assert (  n.getNodeData (  occlusion.mCurrentCam )->queryVisible );
           occlusion.traversed_nodes_cnt++;
           #endif //_VISIBILITYDEBUG
           if (  !n.isOccluder(   ) || mIsNotSolidScene )
           occlusion.queueDraw (  n );
           }
           //-----------------------------------------------------------------------
      74   CHCTraversal::CHCTraversal(  FrontToBackNodeSorterPriorityQueue& vStack,   Occlusion& o ):
           stack(  vStack ),  
           occlusion(  o ),  
           frameId(  o.getFrame(   ) ),  
           mIsNotSolidScene(  occlusion.isNotSolidScene(   ) )
           {
           }
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOcclusionCameraTraversal.cpp

       1  
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          #include "OgrePagingLandScapeOcclusion.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          #include "OgrePagingLandScapeOcclusionCameraTraversal.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      18   void RegisterCameraTraversal::onTree(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           n.addCamNodeData (  cam );
           traverseChildren (  n,   visibleBounds );
           }
           //-----------------------------------------------------------------------
      24   void RegisterCameraTraversal::onLeaf(  PagingLandScapeOctreeNode& n,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           n.addCamNodeData (  cam );
           }
           //-----------------------------------------------------------------------
      29   void UnregisterCameraTraversal::onTree(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           n.removeCamNodeData (  cam );
           traverseChildren (  n,   visibleBounds );
           }
           //-----------------------------------------------------------------------
      35   void UnregisterCameraTraversal::onLeaf(  PagingLandScapeOctreeNode& n,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           n.removeCamNodeData (  cam );
           }
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOcclusionDebugTraversal.cpp

       1  
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapePrerequisites.h"
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          #include "OgrePagingLandScapeOcclusion.h"
          
          #include "OgrePagingLandScapeOcclusionVisibilityData.h"
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          #include "OgrePagingLandScapeOcclusionDebugTraversal.h"
          
          #include "OgreDebugRectangle2D.h"
          
          #ifdef _VISIBILITYDEBUG
          namespace Ogre
          {
           // Debug Info
           //
           //-----------------------------------------------------------------------
      24   TreeOverlayDebug::TreeOverlayDebug(  Occlusion& o,   PagingLandScapeOctreeSceneManager *scnMgr ):
           occlusion(  o ),  
           mScnMrg (  scnMgr )
           {
           }
           //-----------------------------------------------------------------------
      30   void TreeOverlayDebug::onTree(  PagingLandScapeOctree& n,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           SimpleRenderable * const s = n.getRectangle2d(  mScnMrg );
           if (  n.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible )
           {
           if (  n.getNodeData (  occlusion.mCurrentCam )->queryVisible )
           {
           s->setMaterial (  "BaseWhiteNoLightNoDepthCheck" );
           occlusion.mCurrentRenderQueue->addRenderable (  s,   s->getRenderQueueGroup (   ) );
          
           traverseChildren (  n,   visibleBounds );
           }
           else
           {
           s->setMaterial (  "BaseRedNoLightNoDepthCheck" );
           occlusion.mCurrentRenderQueue->addRenderable (  s,   s->getRenderQueueGroup (   ) );
           }
           }
           else
           {
           s->setMaterial (  "BaseGreenNoLightNoDepthCheck" );
           occlusion.mCurrentRenderQueue->addRenderable (  s,   s->getRenderQueueGroup (   ) );
           }
           }
           //-----------------------------------------------------------------------
      55   void TreeOverlayDebug::onLeaf(  PagingLandScapeOctreeNode& n,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           SimpleRenderable * const s = n.getRectangle2d(  mScnMrg );
           if(  n.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible )
           {
           if(  n.getNodeData (  occlusion.mCurrentCam )->queryVisible )
           {
           s->setMaterial (  "BaseWhiteNoLightNoDepthCheck" );
           occlusion.mCurrentRenderQueue->addRenderable(  s,   s->getRenderQueueGroup (   ) );
           }
           else
           {
           s->setMaterial (  "BaseRedNoLightNoDepthCheck" );
           occlusion.mCurrentRenderQueue->addRenderable(  s,   s->getRenderQueueGroup (   ) );
           }
           }
           else
           {
           s->setMaterial (  "BaseGreenNoLightNoDepthCheck" );
           occlusion.mCurrentRenderQueue->addRenderable(  s,   s->getRenderQueueGroup (   ) );
           }
           }
          }
          #endif //_VISIBILITYDEBUG

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOcclusionElement.cpp

       1  
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include <stack>
          #include <queue>
          
          #include "OgrePagingLandScapeOcclusionElement.h"
          
          #include "OgrePagingLandScapePrerequisites.h"
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include "OgrePagingLandScapeOcclusionVisibilityData.h"
          #include "OgreDebugRectangle2D.h"
          
          
          namespace Ogre
          {
           //---------------------------------------------------------------------
      18   OcclusionElement::OcclusionElement(   ) :
           #ifdef _VISIBILITYDEBUG
           mDebugRectangle2d(  0 ),  
           #endif //_VISIBILITYDEBUG
           mIsRegisteredToCam (  false )
           {
           }
           //---------------------------------------------------------------------
      26   OcclusionElement::~OcclusionElement(   )
           {
           #ifdef _VISIBILITYDEBUG
           delete mDebugRectangle2d;
           #endif //_VISIBILITYDEBUG
          
           NodeDataPerCamMapiterator i = nodeDataPerCam.begin (   );
           while (  i != nodeDataPerCam.end(   ) )
           {
           delete i->second;
           ++i;
           }
           nodeDataPerCam.clear(   );
           }
           //---------------------------------------------------------------------
      41   VisibilityData *OcclusionElement::getNodeData(  PagingLandScapeOctreeCamera *cam )
           {
           if (  nodeDataPerCam.find(  cam->getId(   ) ) == nodeDataPerCam.end(   ) )
           nodeDataPerCam[cam->getId(   )] = new VisibilityData(   );
           //assert (  nodeDataPerCam.find(  cam->getId(   ) ) != nodeDataPerCam.end(   ) );
           return nodeDataPerCam[cam->getId(   )];
           }
           //---------------------------------------------------------------------
      49   void OcclusionElement::addCamNodeData (  PagingLandScapeOctreeCamera *cam )
           {
           if (  nodeDataPerCam.find(  cam->getId(   ) ) == nodeDataPerCam.end(   ) )
           nodeDataPerCam[cam->getId(   )] = new VisibilityData(   );
           }
           //---------------------------------------------------------------------
      55   void OcclusionElement::removeCamNodeData (  PagingLandScapeOctreeCamera *cam )
           {
           NodeDataPerCamMapiterator i = nodeDataPerCam.find (  cam->getId(   ) );
           if (  i != nodeDataPerCam.end(   ) )
           {
           delete i->second;
           nodeDataPerCam.erase (  i );
           }
           }
           #ifdef _VISIBILITYDEBUG
           //---------------------------------------------------------------------
      66   DebugRectangle2D *OcclusionElement::getRectangle2d(  SceneManager *scnMgr )
           {
           if (  !mDebugRectangle2d )
           {
           mDebugRectangle2d = new DebugRectangle2D(   );
           //scnMgr->getRootSceneNode (   )->createChildSceneNode (   )->attachObject (  mDebugRectangle2d );
           }
           return mDebugRectangle2d;
           }
           #endif //_VISIBILITYDEBUG
          }//namespace Ogre

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOcclusionQuerySet.cpp

       1  /*
          -----------------------------------------------------------------------------
          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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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 "Ogre.h"
          #include "OgrePagingLandScapeOcclusionQuerySet.h"
          #include "OgreHardwareOcclusionQuery.h"
          
          
          namespace Ogre
          {
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOcclusionSWTraversal.cpp

       1  
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          #include "OgrePagingLandScapeOcclusionSWTraversal.h"
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          
          #include "OgrePagingLandScapeOcclusionSorter.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          #include "OgrePagingLandScapeOcclusion.h"
          #include "OgrePagingLandScapeOcclusionVisibilityData.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      19   SWTraversal::SWTraversal (  Occlusion& o ):
           occlusion(  o ),  
           mCurrentVisibility (  PagingLandScapeOctreeCamera::NONE ),  
           camPos(  occlusion.mCurrentCam->getDerivedPosition (   ) )
           {
          
           }
           //-----------------------------------------------------------------------
      27   void SWTraversal::traverseChildren(  PagingLandScapeOctree & node,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           FrontToBackNodeSorterPriorityQueue myStack = FrontToBackNodeSorterPriorityQueue(  FrontToBackNodeSorterOperator (  camPos ) );
          
           //assert (  node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible );
           if (  !node.mNodes.empty(   ) )
           {
           PagingLandScapeOctreeNodeList::const_iterator it = node.mNodes.begin(   );
           while (  it != node.mNodes.end(   ) )
           {
           myStack.push(  *it );
           ++it;
           }
           }
          
           PagingLandScapeOctree *n =
           node.mChildren[ 0 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           myStack.push (  n );
           n = node.mChildren[ 1 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           myStack.push (  n );
           n = node.mChildren[ 0 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           myStack.push (  n );
           n = node.mChildren[ 1 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           myStack.push (  n );
           n = node.mChildren[ 0 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           myStack.push (  n );
           n = node.mChildren[ 1 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           myStack.push (  n );
           n = node.mChildren[ 0 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           myStack.push (  n );
           n = node.mChildren[ 1 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           myStack.push (  n );
          
           //traverse nearer child first
           while (  !myStack.empty (   ) )
           {
           OcclusionElement& nstacked = *myStack.top (   );
           myStack.pop (   );
           nstacked.traversal(  *this,   visibleBounds );
           }
           }
           //-----------------------------------------------------------------------
      77   bool SWTraversal::isVisible(  OcclusionElement & n )
           {
           // issue query
           if (  n.isLeaf (   ) && n.isOccluder(   )  )
           {
           if (  occlusion.issueDrawQuery (  static_cast <PagingLandScapeOctreeNode &> (  n ) ) )
           {
           // we just wait for result
           return occlusion.isQueryResultIsVisible (  n );
           }
           else
           {
           return false;
           }
           }
           else
           {
           occlusion.issueBboxQuery (  n );
           // we just wait for result
           return occlusion.isQueryResultIsVisible (  n );
           }
          
           }
           //-----------------------------------------------------------------------
     101   void SWTraversal::onLeaf(  PagingLandScapeOctreeNode &n,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           if(  occlusion.mCurrentCam->isVisible (  n.getCullBoundingBox (   ) ) )
           {
          
           #ifdef _VISIBILITYDEBUG
           occlusion.traversed_nodes_cnt++;
           n.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = true;
           #endif //_VISIBILITYDEBUG
          
           const bool isitVisible = isVisible (  n );
           if (  isitVisible )
           {
           #ifdef _VISIBILITYDEBUG
           occlusion.object_cnt++;
           #endif //_VISIBILITYDEBUG
           occlusion.queueDraw (  n );
           }
           #ifdef _VISIBILITYDEBUG
           n.getNodeData (  occlusion.mCurrentCam )->queryVisible = isitVisible;
           #endif //_VISIBILITYDEBUG
          
           }
          
           #ifdef _VISIBILITYDEBUG
           else
           {
           occlusion.traversed_nodes_cnt++;
           n.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = false;
           occlusion.frustum_culled_nodes_cnt++;
           }
           #endif //_VISIBILITYDEBUG
           }
           //-----------------------------------------------------------------------
     135   void SWTraversal::onTree(  PagingLandScapeOctree & n,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           if(  occlusion.mCurrentCam->isVisible(  n.getCullBoundingBox (   ) ) )
           {
          
           #ifdef _VISIBILITYDEBUG
           occlusion.traversed_nodes_cnt++;
           n.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = true;
           #endif //_VISIBILITYDEBUG
          
           const bool isitVisible = isVisible(  n );
          
           if (  isitVisible )
           {
           traverseChildren (  n,   visibleBounds );
           }
          
           #ifdef _VISIBILITYDEBUG
           n.getNodeData (  occlusion.mCurrentCam )->queryVisible = isitVisible;
           #endif //_VISIBILITYDEBUG
          
           }
          
           #ifdef _VISIBILITYDEBUG
           else
           {
           occlusion.traversed_nodes_cnt++;
           n.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = false;
           occlusion.frustum_culled_nodes_cnt++;
           }
           #endif //_VISIBILITYDEBUG
           }
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOcclusionTraversal.cpp

       1  
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          #include "OgrePagingLandScapeOcclusion.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      15   void ConstTraversalConst::traverseChildren(  const PagingLandScapeOctree& node,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           if (  !node.mNodes.empty(   ) )
           {
           //Add stuff to be rendered;
           PagingLandScapeOctreeNodeList::const_iterator it = node.mNodes.begin(   );
           PagingLandScapeOctreeNodeList::const_iterator itEnd = node.mNodes.end(   );
           while (  it != itEnd )
           {
           (  *it )->traversal (  *this,   visibleBounds );
           ++it;
           }
           }
          
           PagingLandScapeOctree *n =
           node.mChildren[ 0 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 1 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 0 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 1 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 0 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 1 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 0 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 1 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           }
           //-----------------------------------------------------------------------
      57   void TraversalConst::traverseChildren(  PagingLandScapeOctree& node,   VisibleObjectsBoundsInfo * const visibleBounds ) const
           {
           if (  !node.mNodes.empty(   ) )
           {
           //Add stuff to be rendered;
           PagingLandScapeOctreeNodeList::iterator it = node.mNodes.begin(   );
           PagingLandScapeOctreeNodeList::iterator itEnd = node.mNodes.end(   );
           while (  it != itEnd )
           {
           (  *it )->traversal(  *this,   visibleBounds );
           ++it;
           }
           }
          
           PagingLandScapeOctree *n =
           node.mChildren[ 0 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 1 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 0 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 1 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 0 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 1 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 0 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
           n = node.mChildren[ 1 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           }
           //-----------------------------------------------------------------------
      99   void Traversal::traverseChildren(  PagingLandScapeOctree& node,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           // hasLocalChildren
           if (  !node.mNodes.empty(   ) )
           {
           //Add stuff to be rendered;
           PagingLandScapeOctreeNodeList::iterator it = node.mNodes.begin(   );
           PagingLandScapeOctreeNodeList::iterator itEnd = node.mNodes.end(   );
           while (  it != itEnd )
           {
           (  *it )->traversal (  *this,   visibleBounds );
           ++it;
           }
           }
          
           PagingLandScapeOctree *n =
           node.mChildren[ 0 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           n = node.mChildren[ 1 ][ 0 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           n = node.mChildren[ 0 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           n = node.mChildren[ 1 ][ 1 ][ 0 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           n = node.mChildren[ 0 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           n = node.mChildren[ 1 ][ 0 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           n = node.mChildren[ 0 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           n = node.mChildren[ 1 ][ 1 ][ 1 ];
           if (  n && n->hasChildren(   ) )
           n->traversal (  *this,   visibleBounds );
          
           }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOcclusionVFTraversal.cpp

       1  
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          #include "OgrePagingLandScapeOcclusionVFTraversal.h"
          
          #include "OgrePagingLandScapeOcclusionVisibilityData.h"
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          #include "OgrePagingLandScapeOcclusionElement.h"
          #include "OgrePagingLandScapeOcclusion.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      18   ViewFrustumCullingTraversal::ViewFrustumCullingTraversal (  Occlusion& o ):
           occlusion(  o ),  
           mCurrentVisibility (  PagingLandScapeOctreeCamera::NONE )
           {
          
           }
           //-----------------------------------------------------------------------
      25   void ViewFrustumCullingTraversal::onTree(  PagingLandScapeOctree& node,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           PagingLandScapeOctreeCamera::Visibility newVis = mCurrentVisibility;
          
           if (  newVis != PagingLandScapeOctreeCamera::FULL )
           {
           // box is not hierarchically culled as inside frustum box
           // so we need to check it.
           newVis = occlusion.mCurrentCam->getVisibility(  node.getCullBoundingBox (   ) );
           // if the octant is invisible
           if (  newVis == PagingLandScapeOctreeCamera::NONE )
           {
           // Culled Octree.
           // outside frustum
          
           #ifdef _VISIBILITYDEBUG
           node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = false;
           node.getNodeData (  occlusion.mCurrentCam )->queryVisible = false;
           occlusion.frustum_culled_nodes_cnt++;
           occlusion.traversed_nodes_cnt++;
           #endif //_VISIBILITYDEBUG
          
           return;
           }
           }
          
           #ifdef _VISIBILITYDEBUG
           node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = true;
           node.getNodeData (  occlusion.mCurrentCam )->queryVisible = true;
           occlusion.traversed_nodes_cnt++;
           #endif //_VISIBILITYDEBUG
          
           // if we get there,   then it's at least partially visible.
           // Store parent Vis
           PagingLandScapeOctreeCamera::Visibility oldVis = mCurrentVisibility;
           mCurrentVisibility = newVis;
          
           traverseChildren (  node,   visibleBounds );
          
           // Restore Parent Vis so that bothers can be pre-culled.
           mCurrentVisibility = oldVis;
           }
           //-----------------------------------------------------------------------
      68   void ViewFrustumCullingTraversal::onLeaf(  PagingLandScapeOctreeNode &node,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           // if this PagingLandScapeOctree is partially visible,   manually cull all
           // scene nodes attached directly to this level.
           PagingLandScapeOctreeCamera::Visibility newVis = mCurrentVisibility;
           if (  newVis != PagingLandScapeOctreeCamera::FULL )
           {
           newVis = occlusion.mCurrentCam->getVisibility(  node.getCullBoundingBox (   ) );
           // if the node is invisible
           if (  newVis == PagingLandScapeOctreeCamera::NONE )
           {
           // Culled Node.
           // outside frustum
          
           #ifdef _VISIBILITYDEBUG
           node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = false;
           node.getNodeData (  occlusion.mCurrentCam )->queryVisible = false;
           occlusion.frustum_culled_nodes_cnt++;
           occlusion.traversed_nodes_cnt++;
           #endif //_VISIBILITYDEBUG
          
           return;
           }
           }
          
           #ifdef _VISIBILITYDEBUG
           node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = true;
           node.getNodeData (  occlusion.mCurrentCam )->queryVisible = true;
           occlusion.traversed_nodes_cnt++;
           occlusion.object_cnt++;
           #endif //_VISIBILITYDEBUG
          
           // if we get there,   then it's at least partially visible.
           // Store parent Vis
           PagingLandScapeOctreeCamera::Visibility oldVis = mCurrentVisibility;
           mCurrentVisibility = newVis;
          
           node._addToRenderQueue (  occlusion.mCurrentCam,  
           occlusion.mCurrentRenderQueue,  
           occlusion.mOnlyShadowCaster,   visibleBounds );
          
          
           // Restore Parent Vis so that bothers can be pre-culled.
           mCurrentVisibility = oldVis;
           }
          
          
           //-----------------------------------------------------------------------
     116   ViewFrustumCullingTraversalDirect::ViewFrustumCullingTraversalDirect (  Occlusion& o ):
           occlusion(  o )
           {
          
           }
           //-----------------------------------------------------------------------
     122   void ViewFrustumCullingTraversalDirect::onTree(  PagingLandScapeOctree& node,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           if (  occlusion.mCurrentCam->isVisible(  node.getCullBoundingBox (   ) ) )
           {
          
           #ifdef _VISIBILITYDEBUG
           occlusion.traversed_nodes_cnt++;
           node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = true;
           node.getNodeData (  occlusion.mCurrentCam )->queryVisible = true;
           #endif //_VISIBILITYDEBUG
          
           // if we get there,   then it's at least partially visible.
           traverseChildren (  node,   visibleBounds );
           }
           #ifdef _VISIBILITYDEBUG
           else
           {
           // Culled Octree.
           // outside frustum
           occlusion.traversed_nodes_cnt++;
           occlusion.frustum_culled_nodes_cnt++;
           node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = false;
           node.getNodeData (  occlusion.mCurrentCam )->queryVisible = false;
           }
           #endif //_VISIBILITYDEBUG
           }
           //-----------------------------------------------------------------------
     149   void ViewFrustumCullingTraversalDirect::onLeaf(  PagingLandScapeOctreeNode &node,   VisibleObjectsBoundsInfo * const visibleBounds )
           {
           // if this PagingLandScapeOctree is partially visible,   manually cull all
           // scene nodes attached directly to this level.
           if (  occlusion.mCurrentCam->isVisible(  node.getCullBoundingBox (   ) ) )
           {
           #ifdef _VISIBILITYDEBUG
           occlusion.traversed_nodes_cnt++;
           node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = true;
           node.getNodeData (  occlusion.mCurrentCam )->queryVisible = true;
           occlusion.object_cnt++;
           #endif //_VISIBILITYDEBUG
          
           // if we get there,   then it's at least partially visible.
           node._addToRenderQueue (  occlusion.mCurrentCam,  
           occlusion.mCurrentRenderQueue,  
           occlusion.mOnlyShadowCaster,   visibleBounds );
          
           }
           #ifdef _VISIBILITYDEBUG
           else
           {
           // Culled Octree.
           // outside frustum
           occlusion.traversed_nodes_cnt++;
           occlusion.frustum_culled_nodes_cnt++;
           node.getNodeData (  occlusion.mCurrentCam )->viewFrustumVisible = false;
           node.getNodeData (  occlusion.mCurrentCam )->queryVisible = false;
           }
           #endif //_VISIBILITYDEBUG
           }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctree.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 General Public License as published by the Free Software
          Foundation; either version 2 of the License,   or (  at your option ) any later__add
          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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          PagingLandScapeOctree.cpp - description
          -------------------
          begin : Mon Sep 30 2002
          copyright : (  C ) 2002 by Jon Anderson
          email : janders@users.sf.net
          
          Enhancements 2003 - 2004 (  C ) The OGRE Team
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreWireBoundingBox.h"
          #include "OgreOcclusionBoundingBox.h"
          
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          #include "OgreDebugRectangle2D.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      49   PagingLandScapeOctree::PagingLandScapeOctree(   ) :
           OcclusionElement(   ),  
          
           mWireBoundingBox(  0 ),  
           mHalfSize(  Vector3::ZERO ),  
           mNumNodes (  0 ),  
           mParent (  0 ),  
           mOcclusionBoundingBox(  0 )
           {
           //initialize all children to null.
           for (  unsigned int i = 0; i < 2; i++ )
           {
           for (  unsigned int j = 0; j < 2; j++ )
           {
           for (  unsigned int k = 0; k < 2; k++ )
           {
           mChildren[ i ][ j ][ k ] = 0;
           }
           }
           }
           }
           //-----------------------------------------------------------------------
      71   void PagingLandScapeOctree::reset(   )
           {
           //initialize all children to null.
           PagingLandScapeOctree *o;
           for (  unsigned int i = 0; i < 2; i++ )
           {
           for (  unsigned int j = 0; j < 2; j++ )
           {
           for (  unsigned int k = 0; k < 2; k++ )
           {
           o = mChildren[ i ][ j ][ k ];
           if (  o )
           {
           mSceneMgr->deleteOctree (  mChildren[ i ][ j ][ k ] );
           mChildren[ i ][ j ][ k ] = 0;
           }
           }
           }
           }
           mSceneMgr = 0;
           mParent = 0;
           mNumNodes = 0;
           }
           //-----------------------------------------------------------------------
      95   PagingLandScapeOctree::~PagingLandScapeOctree(   )
           {
           //initialize all children to null.
          #ifdef _DEBUG
           for (  unsigned int i = 0; i < 2; i++ )
           {
           for (  unsigned int j = 0; j < 2; j++ )
           {
           for (  unsigned int k = 0; k < 2; k++ )
           {
           assert (  mChildren[ i ][ j ][ k ] == 0 );
           }
           }
           }
          #endif //_DEBUG
          
           delete mWireBoundingBox;
           delete mOcclusionBoundingBox;
          
           mParent = 0;
           }
           //-----------------------------------------------------------------------
           /** Returns true is the box will fit in a child.
           */
     119   bool PagingLandScapeOctree::_isTwiceSize(  const AxisAlignedBox &box ) const
           {
           // infinite boxes never fit in a child - always root node
           if (  box.isInfinite(   ) )
           return false;
          
           const Vector3 &halfMBoxSize = mBox.getHalfSize(   );
           const Vector3 &boxSize = box.getSize(   );
           return (  (  boxSize.x <= halfMBoxSize.x ) &&
           (  boxSize.y <= halfMBoxSize.y ) &&
           (  boxSize.z <= halfMBoxSize.z ) );
           }
           //-----------------------------------------------------------------------
           /** Returns true is the box will fit in a child.
           */
     134   bool PagingLandScapeOctree::_isTwiceCullSize(  const AxisAlignedBox &box ) const
           {
           // infinite boxes never fit in a child - always root node
           if (  box.isInfinite(   ) )
           return false;
          
           const Vector3 &boxSize = box.getSize(   );
           return(  boxSize.x <= mCullHalfSize.x ) &&
           (  boxSize.y <= mCullHalfSize.y ) &&
           (  boxSize.z <= mCullHalfSize.z ) ;
          
           }
           //-----------------------------------------------------------------------
           /** Returns true is the box will fit in a child.
           */
     149   bool PagingLandScapeOctree::_isNotCrossingAxes(  const AxisAlignedBox &box ) const
           {
           const Vector3 &boxMin = box.getMinimum(   );
           const Vector3 &boxMax = box.getMaximum(   );
          
           const Vector3 octCullCenter = mCullBox.getMinimum(   ) + mCullHalfSize;
          
           return !(  (  boxMin.x <= octCullCenter.x && octCullCenter.x <= boxMax.x ) ||
           (  boxMin.y <= octCullCenter.y && octCullCenter.y <= boxMax.y ) ||
           (  boxMin.z <= octCullCenter.z && octCullCenter.z <= boxMax.z ) );
          
           }
           //-----------------------------------------------------------------------
     162   PagingLandScapeOctree *PagingLandScapeOctree::_getCullChildWhereBoxFits(  const AxisAlignedBox &box,  
     163   PagingLandScapeOctreeSceneManager *scn )
           {
           /** It's assumed the the given box has already been proven to fit into
           * a child. Since it's a loose PagingLandScapeOctree,   only the centers need to be
           * compared to find the appropriate node.
           */
           const Vector3 octCenter = mCullBox.getMinimum(   ) + mCullHalfSize;
           const Vector3 ncenter = box.getMaximum(   ).midPoint(  box.getMinimum(   ) );
          
           unsigned int x;
           if (  ncenter.x > octCenter.x )
           x = 1;
           else
           x = 0;
          
           unsigned int y;
           if (  ncenter.y > octCenter.y )
           y = 1;
           else
           y = 0;
          
           unsigned int z;
           if (  ncenter.z > octCenter.z )
           z = 1;
           else
           z = 0;
          
           if (  mChildren[ x ][ y ][ z ] == 0 )
           {
           const Vector3 &octantMax = mBox.getMaximum(   );
           const Vector3 &octantMin = mBox.getMinimum(   );
          
           Vector3 min,   max;
          
           if (  x == 0 )
           {
           min.x = octantMin.x;
           max.x = octCenter.x;
           }
           else
           {
           min.x = octCenter.x;
           max.x = octantMax.x;
           }
          
           if (  y == 0 )
           {
           min.y = octantMin.y;
           max.y = octCenter.y;
           }
           else
           {
           min.y = octCenter.y;
           max.y = octantMax.y;
           }
          
           if (  z == 0 )
           {
           min.z = octantMin.z;
           max.z = octCenter.z;
           }
           else
           {
           min.z = octCenter.z;
           max.z = octantMax.z;
           }
          
           PagingLandScapeOctree *newChild = scn->getNewOctree(   );
           newChild->setParent (  this );
           newChild->setSceneManager(  scn );
           newChild ->setBoundingBox(  min,   max );
           scn->registeredNodeInCamera (  newChild );
           #ifdef _VISIBILITYDEBUG
           newChild ->setDebugCorners(  scn );
           #endif //_VISIBILITYDEBUG
           mChildren[x][y][z] = newChild;
           }
           return mChildren[x][y][z];
          
           }
           //-----------------------------------------------------------------------
     244   PagingLandScapeOctree *PagingLandScapeOctree::_getChildWhereBoxFits(  const AxisAlignedBox &box,  
     245   PagingLandScapeOctreeSceneManager *scn )
           {
           /** It's assumed the the given box has already been proven to fit into
           * a child. Since it's a loose PagingLandScapeOctree,   only the centers need to be
           * compared to find the appropriate node.
           */
           const Vector3 &octantMax = mBox.getMaximum(   );
           const Vector3 &octantMin = mBox.getMinimum(   );
           const Vector3 octCenter = octantMin + mHalfSize;
          
           const Vector3 ncenter = box.getMaximum(   ).midPoint(  box.getMinimum(   ) );
          
           assert (  octantMax.x >= ncenter.x && octantMax.y >= ncenter.y && octantMax.z >= ncenter.z &&
           octantMin.x <= ncenter.x && octantMin.y <= ncenter.y && octantMin.z <= ncenter.z );
          
           unsigned int x;
           if (  ncenter.x > octCenter.x )
           x = 1;
           else
           x = 0;
          
           unsigned int y;
           if (  ncenter.y > octCenter.y )
           y = 1;
           else
           y = 0;
          
           unsigned int z;
           if (  ncenter.z > octCenter.z )
           z = 1;
           else
           z = 0;
          
           if (  mChildren[ x ][ y ][ z ] == 0 )
           {
           Vector3 min,   max;
          
           if (  x == 0 )
           {
           min.x = octantMin.x;
           max.x = octCenter.x;
           }
           else
           {
           min.x = octCenter.x;
           max.x = octantMax.x;
           }
          
           if (  y == 0 )
           {
           min.y = octantMin.y;
           max.y = octCenter.y;
           }
           else
           {
           min.y = octCenter.y;
           max.y = octantMax.y;
           }
          
           if (  z == 0 )
           {
           min.z = octantMin.z;
           max.z = octCenter.z;
           }
           else
           {
           min.z = octCenter.z;
           max.z = octantMax.z;
           }
          
          #ifdef _DEBUG
           std::cout << "new Child\n";
          #endif
          
           PagingLandScapeOctree *newChild = scn->getNewOctree(   );
           newChild->setParent (  this );
           newChild->setSceneManager(  scn );
           newChild->setBoundingBox(  min,   max );
          
           assert (  max.x >= ncenter.x && max.y >= ncenter.y && max.z >= ncenter.z &&
           min.x <= ncenter.x && min.y <= ncenter.y && min.z <= ncenter.z );
          
          
           scn->registeredNodeInCamera (  newChild );
           #ifdef _VISIBILITYDEBUG
           newChild ->setDebugCorners(  scn );
           #endif //_VISIBILITYDEBUG
           mChildren[x][y][z] = newChild;
           }
           return mChildren[x][y][z];
          
           }
           //-----------------------------------------------------------------------
     338   void PagingLandScapeOctree::setBoundingBox(  const Vector3 &min,  
     339   const Vector3 &max )
           {
           mBox.setExtents(  min,   max );
           mCullHalfSize = max - min;
           const Vector3 halfSize = mCullHalfSize * 0.5f;
           mHalfSize = halfSize;
           mCullBox.setExtents(  min - halfSize,   max + halfSize );
           if(  mWireBoundingBox != 0 )
           mWireBoundingBox->setupBoundingBox(  mBox );
           if(  mOcclusionBoundingBox != 0 )
           mOcclusionBoundingBox->setupBoundingBox(  mBox );
           }
           //-----------------------------------------------------------------------
     352   void PagingLandScapeOctree::_addNode(  PagingLandScapeOctreeNode * n )
           {
           if (  n->isStaticNode (   ) )
           mStaticNodes.push_back (  n );
           else
           mMovingNodes.push_back (  n );
           mNodes.push_back (  n );
           n->setOctant(  this );
           //update total counts.
           _ref(   );
           }
           //-----------------------------------------------------------------------
     364   void PagingLandScapeOctree::_removeNode(  PagingLandScapeOctreeNode * n )
           {
           assert (  !mNodes.empty(   ) );
          
           NodeList::iterator it;
          
           it = std::find (  mNodes.begin (   ),   mNodes.end (   ),   n );
           if (  it != mNodes.end (   ) )
           mNodes.erase (  it );
          
           if (  n->isStaticNode (   ) )
           {
           it = std::find(  mStaticNodes.begin (   ),   mStaticNodes.end (   ),   n );
           if (  it != mStaticNodes.end (   ) )
           mStaticNodes.erase (  it );
           }
           else
           {
           it = std::find(  mMovingNodes.begin (   ),   mMovingNodes.end (   ),   n );
           if (  it != mMovingNodes.end (   ) )
           mMovingNodes.erase (  it );
           }
           n->setOctant(  0 );
           //update total counts.
           _unref(  mNumNodes == 1 );
           }
           //-----------------------------------------------------------------------
     391   void PagingLandScapeOctree::_unref(  const bool removeChildren )
           {
           --mNumNodes;
           if (  removeChildren )
           {
           //remove null children
           PagingLandScapeOctree *child;
           for (  unsigned int i = 0; i < 2; i++ )
           {
           for (  unsigned int j = 0; j < 2; j++ )
           {
           for (  unsigned int k = 0; k < 2; k++ )
           {
           child = mChildren[ i ][ j ][ k ];
           if (  child && !child->hasChildren(   ) )
           {
           mSceneMgr->deleteOctree(  child );
           mChildren[ i ][ j ][ k ] = 0;
           }
           }
           }
           }
           }
           if (  mParent != 0 )
           {
           mParent->_unref(  mNumNodes == 0 );
           }
           };
           //-----------------------------------------------------------------------
     420   void PagingLandScapeOctree::_getCullBounds(  AxisAlignedBox *b ) const
           {
           // const Vector3 * const corners = mBox.getAllCorners(   );
           // b->setExtents(  corners[ 0 ] - mHalfSize,   corners[ 4 ] + mHalfSize );
           *b = mCullBox;
           }
           //-----------------------------------------------------------------------
     427   WireBoundingBox* PagingLandScapeOctree::getWireBoundingBox(   )
           {
           // Create a WireBoundingBox if needed
           if (  mWireBoundingBox == 0 )
           {
           mWireBoundingBox = new WireBoundingBox(   );
           //mWireBoundingBox->setRenderQueueGroup (  RENDER_QUEUE_WORLD_GEOMETRY_2 );
           mWireBoundingBox->setupBoundingBox(  mBox );
           }
          
           return mWireBoundingBox;
           }
           //-----------------------------------------------------------------------
     440   OcclusionBoundingBox* PagingLandScapeOctree::getOcclusionBoundingBox(   )
           {
           // Create an OcclusionBoundingBox only if needed
           if (  mOcclusionBoundingBox == 0 )
           {
           mOcclusionBoundingBox = new OcclusionBoundingBox(   );
           //mOcclusionBoundingBox->setRenderQueueGroup (  RENDER_QUEUE_WORLD_GEOMETRY_2 );
           mOcclusionBoundingBox->setupBoundingBox (  mBox );
           }
           return mOcclusionBoundingBox;
           }
           //-----------------------------------------------------------------------
     452   void PagingLandScapeOctree::setParent(  PagingLandScapeOctree * parent )
           {
           mParent = parent;
           }
           //-----------------------------------------------------------------------
     457   void PagingLandScapeOctree::setSceneManager(  PagingLandScapeOctreeSceneManager * scn )
           {
           mSceneMgr = scn;
           }
          #ifdef _VISIBILITYDEBUG
           //-----------------------------------------------------------------------
     463   void PagingLandScapeOctree::setDebugCorners(  PagingLandScapeOctreeSceneManager *scnMgr )
           {
           // use the ratio (  OCtreeAAB / thisAAB ) / 8
           const Vector3 &max = mBox.getMaximum (   );
           const Vector3 &min = mBox.getMinimum (   );
          
           const Vector3 &sceneMax = scnMgr->getBoundingBox (   ).getMaximum (   );
           const Vector3 &sceneMin = scnMgr->getBoundingBox (   ).getMinimum (   );
          
           const Real width = sceneMax.x - sceneMin.x;
           const Real height = sceneMax.z - sceneMin.z;
           if (  Math::Abs(  width ) > 1e-08 && Math::Abs(  height ) > 1e-08 )
           {
           Real left = 0.0f,   top = 0.0f,   right = 0.0f,   bottom = 0.0f;
          
           const Real toScreenDivider = 1.0f / 3;
          
           const Real xleft = min.x - sceneMin.x;
           if (  Math::Abs(  xleft ) > 1e-08 )
           left = (  xleft / width ) * toScreenDivider;
          
           const Real ztop = min.z - sceneMin.z;
           if (  Math::Abs(  ztop ) > 1e-08 )
           top = (  ztop / height ) * toScreenDivider;
          
           const Real xright = max.x - sceneMin.x;
           if (  Math::Abs(  xright ) > 1e-08 )
           right = (  xright / width ) * toScreenDivider;
          
           const Real zbottom = max.z - sceneMin.z;
           if (  Math::Abs(  zbottom ) > 1e-08 )
           bottom = (  zbottom / height ) * toScreenDivider;
          
           getRectangle2d (  scnMgr )->setCorners (  (  1.0f - toScreenDivider ) + left,  
           (  1.0f - toScreenDivider ) + top,  
           (  1.0f - toScreenDivider ) + right,  
           (  1.0f - toScreenDivider ) + bottom );
           }
           }
          #endif //_VISIBILITYDEBUG
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctreeAxisAlignedBoxSceneQuery.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreeAxisAlignedBoxSceneQuery.cpp - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004by Jon Anderson
          email : janders@users.sf.net
          
          
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOctreeAxisAlignedBoxSceneQuery.h"
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgreEntity.h"
          
          namespace Ogre
          {
          
          //---------------------------------------------------------------------
      46  PagingLandScapeOctreeAxisAlignedBoxSceneQuery::PagingLandScapeOctreeAxisAlignedBoxSceneQuery(  SceneManager* creator )
           : DefaultAxisAlignedBoxSceneQuery(  creator )
          {
          }
          
          //---------------------------------------------------------------------
      52  PagingLandScapeOctreeAxisAlignedBoxSceneQuery::~PagingLandScapeOctreeAxisAlignedBoxSceneQuery(  void )
          {
          }
          
          //---------------------------------------------------------------------
      57  void PagingLandScapeOctreeAxisAlignedBoxSceneQuery::execute(  SceneQueryListener* listener )
          {
           std::list < SceneNode* > list;
           //find the nodes that intersect the AAB
           static_cast< PagingLandScapeOctreeSceneManager* >(  mParentSceneMgr )->findNodesIn(  mAABB,   list,   0 );
          
           //grab all moveables from the node that intersect...
           std::list < SceneNode* >::iterator it = list.begin(   );
           while (  it != list.end(   ) )
           {
           SceneNode::ObjectIterator oit = (  *it )->getAttachedObjectIterator(   );
           while (  oit.hasMoreElements(   ) )
           {
           MovableObject* m = oit.getNext(   );
           if (  (  m->getQueryFlags(   ) & mQueryMask ) && m->isInScene(   ) && mAABB.intersects(  m->getWorldBoundingBox(   ) ) )
           {
           listener->queryResult(  m );
           }
           }
           ++it;
           }
          }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctreeCamera.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          PagingLandScapeOctreecamera.cpp - description
          -------------------
          begin : Fri Sep 27 2002
          copyright : (  C ) 2002 by Jon Anderson
          email : janders@users.sf.net
          
          Enhancements 2003 - 2004 (  C ) The OGRE Team
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreMath.h"
          #include "OgreAxisAlignedBox.h"
          #include "OgreRoot.h"
          #include "OgreViewport.h"
          #include "OgreRenderSystem.h"
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          
          namespace Ogre
          {
           unsigned int PagingLandScapeOctreeCamera::s_camId = 0;
           //-----------------------------------------------------------------------
      51   PagingLandScapeOctreeCamera::PagingLandScapeOctreeCamera(  const String& name,   SceneManager* sm ) :
           Camera(  name,   sm ),  
           mVisFacesLastCHCRender(  0 ),  
           isOcclusionSystemRegistered (  false ),  
           mOcclusionMode (  VIEW_FRUSTUM_DIRECT ),  
           mFrameId(  0 ),  
           mFrameSceneId(  0 )
           {
           mUniqueIdentification = s_camId++;
           updateRegistrationInOcclusionSystem (   );
           }
           //-----------------------------------------------------------------------
      63   PagingLandScapeOctreeCamera::~PagingLandScapeOctreeCamera(   )
           {
           }
           //-----------------------------------------------------------------------
      67   bool PagingLandScapeOctreeCamera::nextFrame(  const unsigned int framesSceneId )
           {
           if (  framesSceneId != mFrameSceneId )
           {
           // change frame Id counter
           //that identify current frame.
           mFrameSceneId = framesSceneId;
           mFrameId += 1;
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
      80   bool PagingLandScapeOctreeCamera::isRegisteredInOcclusionSystem(   ) const
           {
           return isOcclusionSystemRegistered;
           }
           //-----------------------------------------------------------------------
      85   void PagingLandScapeOctreeCamera::setRegisteredInOcclusionSystem(  const bool registered )
           {
           isOcclusionSystemRegistered = registered;
           }
           //-----------------------------------------------------------------------
      90   void PagingLandScapeOctreeCamera::changeOcclusionMode(  culling_modes nextOcclusionMode )
           {
           if (  nextOcclusionMode != mOcclusionMode )
           {
           if (  nextOcclusionMode == VIEW_FRUSTUM_DIRECT )
           {
           if (  mLastViewport )
           mLastViewport->setClearEveryFrame (  true );
           }
           else
           {
           if (  !getSceneManager (   )->getDestinationRenderSystem (   )->getCapabilities(   )->hasCapability(  RSC_HWOCCLUSION ) )
           {
           OGRE_EXCEPT(  1,  
           "Your card does not support HWOCCLUSION ",  
           "PagingLandScapeOctreeCamera::setNextOcclusionMode" );
           }
           if (  mLastViewport )
           mLastViewport->setClearEveryFrame (  false );
           }
          
           mOcclusionMode = nextOcclusionMode;
           updateRegistrationInOcclusionSystem(   );
           }
           }
           //-----------------------------------------------------------------------
     116   void PagingLandScapeOctreeCamera::updateRegistrationInOcclusionSystem(   )
           {
           if (  needRegistrationInOcclusionSystem(   ) && !isRegisteredInOcclusionSystem(   ) )
           {
           static_cast <PagingLandScapeOctreeSceneManager *> (  getSceneManager (   ) )->registerCamera(  this );
           setRegisteredInOcclusionSystem (  true );
           }
           else if (  !needRegistrationInOcclusionSystem(   ) && isRegisteredInOcclusionSystem(   ) )
           {
           static_cast <PagingLandScapeOctreeSceneManager *> (  getSceneManager (   ) )->unregisterCamera(  this );
           setRegisteredInOcclusionSystem (  false );
           }
           }
           //-----------------------------------------------------------------------
     130   void PagingLandScapeOctreeCamera::setNextOcclusionMode(   )
           {
           culling_modes nextOcclusionMode = static_cast <culling_modes> (  (  mOcclusionMode + 1 ) % NUM_CULLING_MODE );
          
           changeOcclusionMode (  nextOcclusionMode );
           }
           //-----------------------------------------------------------------------
     137   bool PagingLandScapeOctreeCamera::needRegistrationInOcclusionSystem(   ) const
           {
           #ifdef _VISIBILITYDEBUG
           return true;
           #endif //_VISIBILITYDEBUG
          
           if (  mOcclusionMode == CHC ||
           mOcclusionMode == CHC_CONSERVATIVE )
           return true;
           else
           return false;
           };
           //-----------------------------------------------------------------------
     150   void PagingLandScapeOctreeCamera::setOcclusionMode(  culling_modes occlusionMode )
           {
           changeOcclusionMode (  occlusionMode );
           };
           //-----------------------------------------------------------------------
     155   void PagingLandScapeOctreeCamera::setOcclusionModeAsString(  const String &cullingModeAsString )
           {
           culling_modes cullingmode (  VIEW_FRUSTUM_DIRECT );
           if (  cullingModeAsString == "VIEW_FRUSTUM_DIRECT" )
           cullingmode = VIEW_FRUSTUM_DIRECT;
           else if (  cullingModeAsString == "CHC" )
           cullingmode = CHC;
           else if (  cullingModeAsString == "CHC_CONSERVATIVE" )
           cullingmode = CHC_CONSERVATIVE;
           setOcclusionMode(  cullingmode );
           };
           //-----------------------------------------------------------------------
     167   String PagingLandScapeOctreeCamera::getOcclusionModeAsString(   ) const
           {
           switch (  getOcclusionMode(   ) )
           {
           case CHC: return String(  "CHC" );
           case CHC_CONSERVATIVE: return String(  "CHC_CONSERVATIVE" );
           case VIEW_FRUSTUM_DIRECT:
           default:
           return String(  "VIEW_FRUSTUM_DIRECT" );
           }
           }
           //-----------------------------------------------------------------------
     179   PagingLandScapeOctreeCamera::Visibility PagingLandScapeOctreeCamera::getVisibility(  const AxisAlignedBox &bound ) const
           {
           // Null boxes always invisible
           if (   bound.isNull(   )  )
           return NONE;
           // Infinite boxes always visible
           if (  bound.isInfinite(   ) )
           return FULL;
          
           // Get centre of the box
           const Vector3 &centre (  bound.getCenter(   ) );
           // Get the half-size of the box
           const Vector3 &halfSize (  bound.getHalfSize(   ) );
          
           bool all_inside = true;
          
           const bool infinite_far_clip = (  mFarDist == 0 );
           for (  unsigned int plane = 0; plane < 6; ++plane )
           {
          
           // Skip far plane if infinite view frustum
           if (  plane == FRUSTUM_PLANE_FAR && infinite_far_clip )
           continue;
          
           // This updates frustum planes and deals with cull frustum
           const Plane::Side side = getFrustumPlane(  plane ).getSide(  centre,   halfSize );
           if (  side == Plane::NEGATIVE_SIDE )
           return NONE;
           // We can't return now as the box could be later on the negative side of a plane.
           if (  side == Plane::BOTH_SIDE )
           all_inside = false;
           }
          
           if (   all_inside  )
           return FULL;
           else
           return PARTIAL;
          
           }
          
          }
          
          
          
          

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctreeIntersectionSceneQuery.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreeIntersectionSceneQuery.cpp - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004by Jon Anderson
          email : janders@users.sf.net
          
          
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOctreeIntersectionSceneQuery.h"
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgreEntity.h"
          #include "OgreRoot.h"
          
          namespace Ogre
          {
          
          //---------------------------------------------------------------------
      47  PagingLandScapeOctreeIntersectionSceneQuery::PagingLandScapeOctreeIntersectionSceneQuery(  SceneManager* creator )
           : DefaultIntersectionSceneQuery(  creator )
          {
          
          }
          
          //---------------------------------------------------------------------
      54  PagingLandScapeOctreeIntersectionSceneQuery::~PagingLandScapeOctreeIntersectionSceneQuery(  void )
          {
          }
          
          //---------------------------------------------------------------------
      59  void PagingLandScapeOctreeIntersectionSceneQuery::execute(  IntersectionSceneQueryListener* listener )
          {
           typedef std::pair<MovableObject *,   MovableObject *> MovablePair;
           typedef std::set
           < std::pair<MovableObject *,   MovableObject *> > MovableSet;
          
           MovableSet set;
          
           // Iterate over all movable types
           Root::MovableObjectFactoryIterator factIt =
           Root::getSingleton(   ).getMovableObjectFactoryIterator(   );
           while(  factIt.hasMoreElements(   ) )
           {
           SceneManager::MovableObjectIterator it =
           mParentSceneMgr->getMovableObjectIterator(  
           factIt.getNext(   )->getType(   ) );
           while(   it.hasMoreElements(   )  )
           {
          
           MovableObject * e = it.getNext(   );
          
           std::list < SceneNode * > list;
           //find the nodes that intersect the AAB
           static_cast<PagingLandScapeOctreeSceneManager*>(   mParentSceneMgr  ) -> findNodesIn(   e->getWorldBoundingBox(   ),   list,   0  );
           //grab all movables from the node that intersect...
           std::list < SceneNode * >::iterator itscn = list.begin(   );
           while(   itscn != list.end(   )  )
           {
           SceneNode::ObjectIterator oit = (  *itscn ) -> getAttachedObjectIterator(   );
           while(   oit.hasMoreElements(   )  )
           {
           MovableObject * m = oit.getNext(   );
          
           if(   m != e &&
           set.find(   MovablePair(  e,  m ) ) == set.end(   ) &&
           set.find(   MovablePair(  m,  e ) ) == set.end(   ) &&
           (  m->getQueryFlags(   ) & mQueryMask ) &&
           (  m->getTypeFlags(   ) & mQueryTypeMask ) &&
           m->isInScene(   ) &&
           e->getWorldBoundingBox(   ).intersects(   m->getWorldBoundingBox(   )  )  )
           {
           listener -> queryResult(   e,   m  );
           // deal with attached objects,   since they are not directly attached to nodes
           if (  m->getMovableType(   ) == "Entity" )
           {
           Entity* e2 = static_cast<Entity*>(  m );
           Entity::ChildObjectListIterator childIt = e2->getAttachedObjectIterator(   );
           while(  childIt.hasMoreElements(   ) )
           {
           MovableObject* c = childIt.getNext(   );
           if (  c->getQueryFlags(   ) & mQueryMask &&
           e->getWorldBoundingBox(   ).intersects(   c->getWorldBoundingBox(   )  ) )
           {
           listener->queryResult(  e,   c );
           }
           }
           }
           }
           set.insert(   MovablePair(  e,  m )  );
          
           }
           ++itscn;
           }
          
           }
           }
          }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctreeNode.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          PagingLandScapeOctreenode.cpp - description
          -------------------
          begin : Fri Sep 27 2002
          copyright : (  C ) 2002 by Jon Anderson
          email : janders@users.sf.net
          
          Enhancements 2003 - 2004 (  C ) The OGRE Team
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreRoot.h"
          
          #include "OgrePagingLandScapeOctreeNode.h"
          #include "OgreOcclusionBoundingBox.h"
          #include "OgreWireBoundingBox.h"
          #include "OgreRenderQueue.h"
          
          #include "OgreDebugRectangle2D.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      50   PagingLandScapeOctreeNode::PagingLandScapeOctreeNode(  SceneManager* creator ) :
           SceneNode(  creator ),  
           OcclusionElement(   ),  
          
           mOctant(  0 ),  
           mOcclusionBoundingBox(  0 ),  
           mIsStaticNode(  true ),  
           mIsOccluder(  true )
           {
          
           }
           //-----------------------------------------------------------------------
      62   PagingLandScapeOctreeNode::PagingLandScapeOctreeNode(  SceneManager* creator,   const String& name ) :
           SceneNode(  creator,   name ),  
           OcclusionElement(   ),  
          
           mOctant(  0 ),  
           mOcclusionBoundingBox(  0 ),  
           mIsStaticNode(  true ),  
           mIsOccluder(  true )
           {
          
           }
           //-----------------------------------------------------------------------
      74   PagingLandScapeOctreeNode::~PagingLandScapeOctreeNode(   )
           {
           removeAllChildren(   );
           if (  mParent )
           mParent->removeChild(  this );
           assert (  !mParent );
           delete mOcclusionBoundingBox;
           }
           //-----------------------------------------------------------------------
           //same as SceneNode,   only it doesn't care about children...
      84   void PagingLandScapeOctreeNode::_updateBounds(  void )
           {
           mWorldAABB.setNull(   );
           mLocalAABB.setNull(   );
          
           // Update bounds from own attached objects
           ObjectMap::const_iterator i = mObjectsByName.begin(   );
           while (  i != mObjectsByName.end(   ) )
           {
           const MovableObject * const mo = i->second;
           // Get local bounds of object
           mLocalAABB.merge(  mo->getBoundingBox(   ) );
           // Get World bounds of object
           mWorldAABB.merge(  mo->getWorldBoundingBox(  true ) );
          
           ++i;
           }
          
           //update the PagingLandScapeOctreeSceneManager that things might have moved.
           // if it hasn't been added to the PagingLandScapeOctree,   add it,   and if has moved
           // enough to leave it's current node,   we'll update it.
          
           if (  ! mWorldAABB.isNull(   ) )
           {
           assert (  mCreator );
           static_cast < PagingLandScapeOctreeSceneManager * > (  mCreator )->_updatePagingLandScapeOctreeNode(  this );
           }
           mHalfSize = (  mWorldAABB.getMaximum (   ) - mWorldAABB.getMinimum (   ) ) * 0.5;
           if (  mOcclusionBoundingBox )
           mOcclusionBoundingBox->setupBoundingBox(  mWorldAABB );
           if (  mWireBoundingBox )
           mWireBoundingBox->setupBoundingBox(  mWorldAABB );
           if (  !mIsRegisteredToCam )
           static_cast< PagingLandScapeOctreeSceneManager * > (  mCreator )->
           registeredNodeInCamera (  this );
           }
           //-----------------------------------------------------------------------
           /** Since we are loose,   only check the center.
           */
     123   bool PagingLandScapeOctreeNode::_isIn(  const AxisAlignedBox &box ) const
           {
           // Always fail if not in the scene graph or box is null
           if (  !mIsInSceneGraph || box.isNull(   ) )
           return false;
           // Always succeed if AABB is infinite
           if (  box.isInfinite(   ) )
           return true;
          
           // Object Bounding Box Center
           const Vector3 center = mWorldAABB.getMaximum(   ).midPoint(  mWorldAABB.getMinimum(   ) );
          
           // Min and Max of Octree BBox
           const Vector3 &bmin = box.getMinimum(   );
           const Vector3 &bmax = box.getMaximum(   );
          
           // Object Bbox center is IN Octree BBox ?
          
           const bool centre = bmax.x >= center.x && bmax.y >= center.y && bmax.z >= center.z &&
           bmin.x <= center.x && bmin.y <= center.y && bmin.z <= center.z;
           if (  !centre )
           return false;
          
           // Even if covering the centre line,   need to make sure this BB is not large
           // enough to require being moved up into parent. When added,   bboxes would
           // end up in parent due to cascade but when updating need to deal with
           // bbox growing too large for this child
           const Vector3 octreeSize (  bmax - bmin );
           const Vector3 nodeSize (  mWorldAABB.getMaximum(   ) - mWorldAABB.getMinimum(   ) );
          
           return (  nodeSize < octreeSize );
          
           }
           //-----------------------------------------------------------------------
           /** Adds the attached objects of this PagingLandScapeOctreeScene node into the queue. */
     158   void PagingLandScapeOctreeNode::_addToRenderQueue(  Camera* cam,  
           RenderQueue * const queue,  
           const bool onlyShadowCasters,  
           VisibleObjectsBoundsInfo* visibleBounds )
           {
           ObjectMap::iterator mit = mObjectsByName.begin(   );
          
           while (  mit != mObjectsByName.end(   ) )
           {
           MovableObject * const mo = mit->second;
          
           mo->_notifyCurrentCamera(  cam );
          
           if (  mo->isVisible(   ) &&
           (  !onlyShadowCasters || mo->getCastShadows(   ) ) )
           {
           mo->_updateRenderQueue(  queue );
          
           if (  visibleBounds )
           {
           visibleBounds->merge(  mo->getWorldBoundingBox(  true ),  
           mo->getWorldBoundingSphere(  true ),   cam );
           }
           }
           ++mit;
           }
          
           // check if the scene manager or this node wants the bounding box shown.
           if (  getShowBoundingBox(   ) || mCreator->getShowBoundingBoxes(   ) )
           _addBoundingBoxToQueue(  queue );
          
           if (   mCreator->getDisplaySceneNodes(   ) )
           queue -> addRenderable(   this  );
          
           }
           //-----------------------------------------------------------------------
     194   void PagingLandScapeOctreeNode::attachObject(  MovableObject* obj )
           {
           if (  mIsStaticNode )
           {
           const String movableType = obj->getMovableType(   );
           if (  movableType == "Entity" || movableType == "StaticGeometry" )
           {
           if (  StringUtil::startsWith(  obj->getName(   ),   "Static",   false ) )
           {
           if (  mIsOccluder && !StringUtil::startsWith(  obj->getName(   ),   "StaticOccluder",   false ) )
           {
           mIsOccluder = false;
           }
           }
           else
           {
           mIsStaticNode = false;
           mIsOccluder = false;
           }
           }
           else if (  movableType != "PagingLandScapeRenderable"
           && movableType != "TerrainMipMap" )
           {
           mIsStaticNode = false;
           mIsOccluder = false;
           }
           }
           SceneNode::attachObject (  obj );
           }
           //-----------------------------------------------------------------------
     224   MovableObject* PagingLandScapeOctreeNode::detachObject(  unsigned short index )
           {
           // if we detach 1 object,   after the return,  
           // there's none left so we reset the thing.
           if (  !mObjectsByName.empty(   ) && 1 == mObjectsByName.size(   ) )
           {
           mIsStaticNode = true;
           mIsOccluder = true;
           }
           return SceneNode::detachObject (  index );
          
           }
           //-----------------------------------------------------------------------
     237   MovableObject* PagingLandScapeOctreeNode::detachObject(  const String& name )
           {
           if (  !mObjectsByName.empty(   ) && 1 == mObjectsByName.size(   ) )
           {
           mIsStaticNode = true;
           mIsOccluder = true;
           }
           return SceneNode::detachObject (  name );
           }
           //-----------------------------------------------------------------------
     247   void PagingLandScapeOctreeNode::detachObject(  MovableObject* obj )
           {
           if (  !mObjectsByName.empty(   ) && 1 == mObjectsByName.size(   ) )
           {
           mIsStaticNode = true;
           mIsOccluder = true;
           }
           SceneNode::detachObject (  obj );
           }
           //-----------------------------------------------------------------------
     257   void PagingLandScapeOctreeNode::detachAllObjects(  void )
           {
           SceneNode::detachAllObjects (   );
           mIsStaticNode = true;
           mIsOccluder = true;
           }
           //-----------------------------------------------------------------------
     264   void PagingLandScapeOctreeNode::_addAlreadyNotifiedToVisibles(   )
           {
           if (  !mNotifiedVisibles.empty(   ) )
           {
           PagingLandScapeOctreeSceneManager * const osm = static_cast < PagingLandScapeOctreeSceneManager * > (  mCreator );
          
           // create the render Queue.
           MovableObjectList::iterator it = mNotifiedVisibles.begin(   ),  
           itend = mNotifiedVisibles.end(   );
           while (  it != itend )
           {
           assert (  (  *it )->isVisible (   ) );
           osm->addVisible (  *it );
           ++it;
           }
           mNotifiedVisibles.clear(   );
           }
           }
           //-----------------------------------------------------------------------
     283   void PagingLandScapeOctreeNode::_addToVisibles(  Camera* cam,  
     284   const bool onlyShadowCasters )
           {
           if (  !mNotifiedVisibles.empty(   ) )
           {
           PagingLandScapeOctreeSceneManager * const osm = static_cast < PagingLandScapeOctreeSceneManager * > (  mCreator );
          
           // create the render Queue.
           ObjectMap::iterator mit = mObjectsByName.begin (   );
           while (  mit != mObjectsByName.end (   ) )
           {
           MovableObject * const mo = mit->second;
           mo->_notifyCurrentCamera (  cam );
           if (  mo->isVisible (   ) &&
           (  !onlyShadowCasters || mo->getCastShadows (   ) ) )
           {
           osm->addVisible (  mo );
           }
           ++mit;
           }
           mNotifiedVisibles.clear (   );
           }
           }
           //-----------------------------------------------------------------------
     307   bool PagingLandScapeOctreeNode::notifyNodeObjects(  Camera* cam,  
     308   const bool onlyShadowCasters )
           {
           // if at least one is visible.
           bool isVisible = false;
           mNotifiedVisibles.clear(   );
           ObjectMap::iterator mit = mObjectsByName.begin (   );
           while (  mit != mObjectsByName.end (   ) )
           {
           MovableObject * const mo = mit->second;
           mo->_notifyCurrentCamera (  cam );
           if (  mo->isVisible (   ) &&
           (  !onlyShadowCasters || mo->getCastShadows (   ) ) )
           {
           mNotifiedVisibles.push_back (  mo );
           isVisible = true;
           }
           ++mit;
           }
           return isVisible;
           }
           //-----------------------------------------------------------------------
     329   MovableObjectList *PagingLandScapeOctreeNode::getVisibleNotifiedNodeObjects(  Camera* cam,  
     330   const bool onlyShadowCasters )
           {
           notifyNodeObjects(  cam,   onlyShadowCasters );
           return &mNotifiedVisibles;
           }
           //-----------------------------------------------------------------------
     336   OcclusionBoundingBox* PagingLandScapeOctreeNode::getOcclusionBoundingBox(   )
           {
           // Create an OcclusionBoundingBox if needed
           if(  mOcclusionBoundingBox == 0 )
           {
           mOcclusionBoundingBox = new OcclusionBoundingBox(   );
           //mOcclusionBoundingBox->setRenderQueueGroup (  RENDER_QUEUE_WORLD_GEOMETRY_2 );
           mOcclusionBoundingBox->setupBoundingBox(  mWorldAABB );
           }
           return mOcclusionBoundingBox;
           }
           //-----------------------------------------------------------------------
     348   void PagingLandScapeOctreeNode::addChild(  Node* child )
           {
           mIsRegisteredToCam = false;
           static_cast< PagingLandScapeOctreeSceneManager * > (  mCreator )->registeredNodeInCamera(  this );
           // call superclass method
           Node::addChild (  child );
           }
           //-----------------------------------------------------------------------
     356   void PagingLandScapeOctreeNode::_removeNodeAndChildren(   )
           {
           assert (  mCreator );
           static_cast< PagingLandScapeOctreeSceneManager * > (  mCreator )->unregisteredNodeInCamera (  this );
           mIsRegisteredToCam = false;
          
           PagingLandScapeOctree * oct = getOctant(   );
           if (  oct )
           oct->_removeNode(  this );
           setOctant (  0 );
          
           //remove all the children nodes as well from the PagingLandScapeOctree.
           ChildNodeMap::iterator it = mChildren.begin(   );
           while(  it != mChildren.end(   ) )
           {
           static_cast<PagingLandScapeOctreeNode *>(  it->second )->_removeNodeAndChildren(   );
           ++it;
           }
           }
           //-----------------------------------------------------------------------
     376   void PagingLandScapeOctreeNode::removeAllChildren(  void )
           {
           ChildNodeMap::iterator i,   iend = mChildren.end(   );
           for (  i = mChildren.begin(   ); i != iend; ++i )
           {
           static_cast <PagingLandScapeOctreeNode* > (  i->second )->_removeNodeAndChildren(   );
           }
           Node::removeAllChildren(   );
           }
           //-----------------------------------------------------------------------
     386   Node * PagingLandScapeOctreeNode::removeChild(  unsigned short index )
           {
           PagingLandScapeOctreeNode *on = static_cast<PagingLandScapeOctreeNode* >(  SceneNode::removeChild(  index ) );
           on->_removeNodeAndChildren(   );
           return on;
           }
           //-----------------------------------------------------------------------
     393   Node * PagingLandScapeOctreeNode::removeChild(  Node* child )
           {
           PagingLandScapeOctreeNode *on = static_cast<PagingLandScapeOctreeNode* >(  SceneNode::removeChild(  child ) );
           on->_removeNodeAndChildren(   );
           return on;
           }
           //-----------------------------------------------------------------------
     400   Node * PagingLandScapeOctreeNode::removeChild(  const String & name )
           {
           PagingLandScapeOctreeNode *on = static_cast< PagingLandScapeOctreeNode * >(  SceneNode::removeChild(  name ) );
           on->_removeNodeAndChildren(   );
           return on;
           }
           #ifdef _VISIBILITYDEBUG
           //-----------------------------------------------------------------------
     408   void PagingLandScapeOctreeNode::setDebugCorners(  PagingLandScapeOctreeSceneManager *scnMgr )
           {
           // use the ratio (  OCtreeAAB / thisAAB ) / 8
           const Vector3 &max = mWorldAABB.getMaximum (   );
           const Vector3 &min = mWorldAABB.getMinimum (   );
          
           Real left = 0,   top = 0,   right = 0,   bottom = 0;
          
          
           const Vector3 &sceneMax = scnMgr->getBoundingBox (   ).getMaximum (   );
           const Vector3 &sceneMin = scnMgr->getBoundingBox (   ).getMinimum (   );
          
           const Real width = sceneMax.x - sceneMin.x;
           const Real height = sceneMax.z - sceneMin.z;
           if (  Math::Abs(  width ) > 1e-08 && Math::Abs(  height ) > 1e-08 )
           {
           const Real toScreenDivider = 1.0f / 3;
          
           const Real xleft = min.x - sceneMin.x;
           if (  Math::Abs(  xleft ) > 1e-08 )
           left = (  xleft / width ) * toScreenDivider;
          
           const Real ztop = min.z - sceneMin.z;
           if (  Math::Abs(  ztop ) > 1e-08 )
           top = (  ztop / height ) * toScreenDivider;
          
           const Real xright = max.x - sceneMin.x;
           if (  Math::Abs(  xright ) > 1e-08 )
           right = (  xright / width ) * toScreenDivider;
          
           const Real zbottom = max.z - sceneMin.z;
           if (  Math::Abs(  zbottom ) > 1e-08 )
           bottom = (  zbottom / height ) * toScreenDivider;
          
           getRectangle2d (  scnMgr )->setCorners (  (  1.0f - toScreenDivider ) + left,  
           (  1.0f - toScreenDivider ) + top,  
           (  1.0f - toScreenDivider ) + right,  
           (  1.0f - toScreenDivider ) + bottom );
           }
           }
           #endif //_VISIBILITYDEBUG
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctreePlaneBoundedVolumeListSceneQuery.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreePlaneBoundedVolumeListSceneQuery.cpp - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004by Jon Anderson
          email : janders@users.sf.net
          
          
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOctreePlaneBoundedVolumeListSceneQuery.h"
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgreEntity.h"
          
          namespace Ogre
          {
          
          //---------------------------------------------------------------------
      46  PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery::PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery(  SceneManager* creator )
           : DefaultPlaneBoundedVolumeListSceneQuery(  creator )
          {
          }
          
          //---------------------------------------------------------------------
      52  PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery::~PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery(  void )
          {
          }
          
          //---------------------------------------------------------------------
      57  void PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery::execute(  SceneQueryListener* listener )
          {
           PlaneBoundedVolumeList::iterator pi,   piend;
           piend = mVolumes.end(   );
           for (  pi = mVolumes.begin(   ); pi != piend; ++pi )
           {
           std::list < SceneNode* > list;
           //find the nodes that intersect the AAB
           static_cast< PagingLandScapeOctreeSceneManager* >(  mParentSceneMgr )->findNodesIn(  *pi,   list,   0 );
          
           //grab all moveables from the node that intersect...
           std::list < SceneNode* >::iterator it = list.begin(   );
           while (  it != list.end(   ) )
           {
           SceneNode::ObjectIterator oit = (  *it )->getAttachedObjectIterator(   );
           while (  oit.hasMoreElements(   ) )
           {
           MovableObject* m = oit.getNext(   );
           if (  (  m->getQueryFlags(   ) & mQueryMask ) && m->isInScene(   ) && (  *pi ).intersects(  m->getWorldBoundingBox(   ) ) )
           {
           listener->queryResult(  m );
           }
           }
           ++it;
           }
           }
          }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctreeRaySceneQuery.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreeRaySceneQuery.cpp - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004by Jon Anderson
          email : janders@users.sf.net
          
          
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOctreeRaySceneQuery.h"
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgreEntity.h"
          
          namespace Ogre
          {
          
          //---------------------------------------------------------------------
      46  PagingLandScapeOctreeRaySceneQuery::PagingLandScapeOctreeRaySceneQuery(  SceneManager* creator )
           : DefaultRaySceneQuery(  creator )
          {
          }
          
          //---------------------------------------------------------------------
      52  PagingLandScapeOctreeRaySceneQuery::~PagingLandScapeOctreeRaySceneQuery(  void )
          {
          }
          
          //---------------------------------------------------------------------
      57  void PagingLandScapeOctreeRaySceneQuery::execute(  RaySceneQueryListener* listener )
          {
           // if anything else is queried,   ask Octree Scene Manager.
           if (  getQueryTypeMask(   ) != SceneManager::WORLD_GEOMETRY_TYPE_MASK )
           {
           std::list < SceneNode* > list;
           //find the nodes that intersect the AAB
           static_cast< PagingLandScapeOctreeSceneManager* >(  mParentSceneMgr )->findNodesIn(  mRay,   list,   0 );
          
           //grab all movables from the node that intersect...
           std::list < SceneNode* >::iterator it = list.begin(   );
           while (  it != list.end(   ) )
           {
           SceneNode::ObjectIterator oit = (  *it )->getAttachedObjectIterator(   );
           while (  oit.hasMoreElements(   ) )
           {
           MovableObject* m = oit.getNext(   );
           if (  (  m->getQueryFlags(   ) & mQueryMask ) && m->isInScene(   ) )
           {
           std::pair< bool,   Real > result = mRay.intersects(  m->getWorldBoundingBox(   ) );
          
           if (  result.first )
           {
           listener->queryResult(  m,   result.second );
           }
           }
           }
           ++it;
           }
           }
           //else
           // { //if we want to handle static scene geometry inside the scene manager ?
           //
           // }
          }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctreeSceneManager.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright (  c ) 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          PagingLandScapeOctreescenemanager.cpp - description
          -------------------
          begin : Fri Sep 27 2002
          copyright : (  C ) 2002 by Jon Anderson
          email : janders@users.sf.net
          
          Enhancements 2003 - 2004 (  C ) The OGRE Team
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          
          #include "OgrePagingLandScapeOctreeAxisAlignedBoxSceneQuery.h"
          #include "OgrePagingLandScapeOctreeIntersectionSceneQuery.h"
          #include "OgrePagingLandScapeOctreePlaneBoundedVolumeListSceneQuery.h"
          #include "OgrePagingLandScapeOctreeRaySceneQuery.h"
          #include "OgrePagingLandScapeOctreeSphereSceneQuery.h"
          #include "OgreRenderSystem.h"
          #include "OgreWireBoundingBox.h"
          #include "OgreRenderOperation.h"
          #include "OgreStringConverter.h"
          
          #include "OgreOverlayManager.h"
          #include "OgreOverlayElement.h"
          
          #include "OgrePagingLandScapeOctreeCamera.h"
          #include "OgrePagingLandScapeOctree.h"
          #include "OgrePagingLandScapeOctreeNode.h"
          
          #include "OgreOcclusionBoundingBox.h"
          #include "OgrePagingLandScapeOcclusionSorter.h"
          #include "OgrePagingLandScapeOcclusionVisibilityData.h"
          #include "OgrePagingLandScapeOcclusionTraversal.h"
          #include "OgrePagingLandScapeOcclusionCameraTraversal.h"
          #include "OgrePagingLandScapeOcclusionVFTraversal.h"
          #include "OgrePagingLandScapeOcclusionSWTraversal.h"
          #include "OgrePagingLandScapeOcclusionDebugTraversal.h"
          
          
          
          extern "C"
          {
      70   void findNodesInBox(  Ogre::SceneManager *sm,  
           const Ogre::AxisAlignedBox &box,  
           std::list < Ogre::SceneNode * > &list,  
           const Ogre::SceneNode * const exclude )
           {
           static_cast<Ogre::PagingLandScapeOctreeSceneManager*>(  sm )->findNodesIn(  box,   list,   exclude );
           }
      77   void findNodesInSphere(  Ogre::SceneManager *sm,  
           const Ogre::Sphere &sphere,  
           std::list < Ogre::SceneNode * > &list,  
           const Ogre::SceneNode * const exclude )
           {
           static_cast<Ogre::PagingLandScapeOctreeSceneManager*>(  sm )->findNodesIn(  sphere,   list,   exclude );
           }
          }
          
          namespace Ogre
          {
           //---------------------------------------------------------------------
           enum Intersection
           {
           OUTSIDE=0,  
           INSIDE=1,  
           INTERSECT=2
           };
           int PagingLandScapeOctreeSceneManager::intersect_call = 0;
           //---------------------------------------------------------------------
      97   Intersection intersect(  const Ray &ray,   const AxisAlignedBox &box )
           {
           // Null box?
           if (  box.isNull(   ) )
           return OUTSIDE;
           // Infinite box?
           if (  box.isInfinite(   ) )
           return INTERSECT;
          
           const Vector3& min = box.getMinimum(   );
           const Vector3& max = box.getMaximum(   );
           const Vector3& rayorig = ray.getOrigin(   );
          
           // Check origin inside first
           if (   rayorig > min && rayorig < max  )
           return INSIDE;
          
           const Vector3& raydir = ray.getDirection(   );
          
           Real lowt = 0.0f;
           Real t;
           bool hit = false;
           Vector3 hitpoint;
          
           // Check each face in turn,   only check closest 3
           // Min x
           if (  rayorig.x < min.x && raydir.x > 0 )
           {
           t = (  min.x - rayorig.x ) / raydir.x;
           if (  t > 0 )
           {
           // Substitute t back into ray and check bounds and dist
           hitpoint = rayorig + raydir * t;
           if (  hitpoint.y >= min.y && hitpoint.y <= max.y &&
           hitpoint.z >= min.z && hitpoint.z <= max.z &&
           (  !hit || t < lowt ) )
           {
           return INTERSECT;
           }
           }
           }
           // Max x
           if (  rayorig.x > max.x && raydir.x < 0 )
           {
           t = (  max.x - rayorig.x ) / raydir.x;
           if (  t > 0 )
           {
           // Substitute t back into ray and check bounds and dist
           hitpoint = rayorig + raydir * t;
           if (  hitpoint.y >= min.y && hitpoint.y <= max.y &&
           hitpoint.z >= min.z && hitpoint.z <= max.z &&
           (  !hit || t < lowt ) )
           {
           return INTERSECT;
           }
           }
           }
           // Min y
           if (  rayorig.y < min.y && raydir.y > 0 )
           {
           t = (  min.y - rayorig.y ) / raydir.y;
           if (  t > 0 )
           {
           // Substitute t back into ray and check bounds and dist
           hitpoint = rayorig + raydir * t;
           if (  hitpoint.x >= min.x && hitpoint.x <= max.x &&
           hitpoint.z >= min.z && hitpoint.z <= max.z &&
           (  !hit || t < lowt ) )
           {
           return INTERSECT;
           }
           }
           }
           // Max y
           if (  rayorig.y > max.y && raydir.y < 0 )
           {
           t = (  max.y - rayorig.y ) / raydir.y;
           if (  t > 0 )
           {
           // Substitute t back into ray and check bounds and dist
           hitpoint = rayorig + raydir * t;
           if (  hitpoint.x >= min.x && hitpoint.x <= max.x &&
           hitpoint.z >= min.z && hitpoint.z <= max.z &&
           (  !hit || t < lowt ) )
           {
           return INTERSECT;
           }
           }
           }
           // Min z
           if (  rayorig.z < min.z && raydir.z > 0 )
           {
           t = (  min.z - rayorig.z ) / raydir.z;
           if (  t > 0 )
           {
           // Substitute t back into ray and check bounds and dist
           hitpoint = rayorig + raydir * t;
           if (  hitpoint.x >= min.x && hitpoint.x <= max.x &&
           hitpoint.y >= min.y && hitpoint.y <= max.y &&
           (  !hit || t < lowt ) )
           {
           return INTERSECT;
           }
           }
           }
           // Max z
           if (  rayorig.z > max.z && raydir.z < 0 )
           {
           t = (  max.z - rayorig.z ) / raydir.z;
           if (  t > 0 )
           {
           // Substitute t back into ray and check bounds and dist
           hitpoint = rayorig + raydir * t;
           if (  hitpoint.x >= min.x && hitpoint.x <= max.x &&
           hitpoint.y >= min.y && hitpoint.y <= max.y &&
           (  !hit || t < lowt ) )
           {
           return INTERSECT;
           }
           }
           }
           return OUTSIDE;
           }
          
           //---------------------------------------------------------------------
     222   Intersection intersect2(  const Ray &one,   const AxisAlignedBox &two )
           {
           PagingLandScapeOctreeSceneManager::intersect_call++;
          
           // Null box?
           if (  two.isNull(   ) )
           return OUTSIDE;
           // Infinite box?
           if (  two.isInfinite(   ) )
           return INTERSECT;
          
           const Vector3* const pCorners = two.getAllCorners(   );
           const Vector3 origin = one.getOrigin(   );
           const Vector3 dir = one.getDirection(   );
          
           Vector3 maxT (  -1.0f,   -1.0f,   -1.0f );
          
           unsigned int i = 0;
           bool inside = true;
           for (  i = 0; i < 3; i++ )
           {
           if (  origin[i] < pCorners[0][i] )
           {
           inside = false;
           if(  dir[i] > 0 )
           maxT[i] = (  pCorners[0][i] - origin[i] ) / dir[i];
           }
           else if (  origin[i] > pCorners[4][i] )
           {
           inside = false;
           if(  dir[i] < 0 )
           maxT[i] = (  pCorners[4][i] - origin[i] ) / dir[i];
           }
           }
          
           if(  inside )
           {
           return INTERSECT;
           }
           int whichPlane = 0;
           if(  maxT[1] > maxT[whichPlane] )
           whichPlane = 1;
           if(  maxT[2] > maxT[whichPlane] )
           whichPlane = 2;
          
           if(  (  (  int )maxT[whichPlane] ) & 0x80000000 )
           {
           return OUTSIDE;
           }
           const Real maxTThisPlane = maxT[whichPlane];
           for(  i = 0; i < 3; i++ )
           {
           if(  i != whichPlane )
           {
           const Real f = origin[i] + maxTThisPlane * dir[i];
           if (  f < (  pCorners[0][i] - 0.00001f ) ||
           f > (  pCorners[4][i] + 0.00001f ) )
           {
           return OUTSIDE;
           }
           }
           }
          
           return INTERSECT;
          
           }
           //---------------------------------------------------------------------
           /** Checks how the second box intersects with the first.
           */
     291   Intersection intersect(  const PlaneBoundedVolume &one,   const AxisAlignedBox &two )
           {
           PagingLandScapeOctreeSceneManager::intersect_call++;
           // Null box?
           if (  two.isNull(   ) )
           return OUTSIDE;
           if (  two.isInfinite(   ) )
           return INTERSECT;
          
           // Get corners of the box
           const Vector3 * const pCorners = two.getAllCorners(   );
          
           // For each plane,   see if all points are on the negative side
           // If so,   object is not visible.
           // If one or more are,   it's partial.
           // If all aren't,   full
           static const int corners[ 8 ] = {0,   4,   3,   5,   2,   6,   1,   7};
          
           bool all_inside = true;
           PlaneList::const_iterator i,   iend = one.planes.end(   );
           for (  i = one.planes.begin(   ); i != iend; ++i )
           {
           const Plane& plane = *i;
           bool all_outside = true;
           for (  unsigned int corner = 0; corner < 8; ++corner )
           {
           const Real distance = plane.getDistance(  pCorners[ corners[ corner ] ] );
           all_outside = all_outside && (  distance < 0 );
           all_inside = all_inside && (  distance >= 0 );
          
           if (  !all_outside && !all_inside )
           break;
           }
          
           if (  all_outside )
           return OUTSIDE;
           }
          
           if (  all_inside )
           return INSIDE;
           else
           return INTERSECT;
          
           }
           //---------------------------------------------------------------------
           /** Checks how the second box intersects with the first.
           */
     338   Intersection intersect(  const AxisAlignedBox &one,   const AxisAlignedBox &two )
           {
           PagingLandScapeOctreeSceneManager::intersect_call++;
          
           // Null box?
           if (  one.isNull(   ) || two.isNull(   ) )
           return OUTSIDE;
           if (  one.isInfinite(   ) )
           return INSIDE;
           if (  two.isInfinite(   ) )
           return INTERSECT;
          
           const Vector3 * outside = one.getAllCorners(   );
           const Vector3 *inside = two.getAllCorners(   );
          
           if (  inside[ 4 ].x < outside[ 0 ].x ||
           inside[ 4 ].y < outside[ 0 ].y ||
           inside[ 4 ].z < outside[ 0 ].z ||
           inside[ 0 ].x > outside[ 4 ].x ||
           inside[ 0 ].y > outside[ 4 ].y ||
           inside[ 0 ].z > outside[ 4 ].z )
           {
           return OUTSIDE;
           }
          
           const bool full = (  inside[ 0 ].x > outside[ 0 ].x &&
           inside[ 0 ].y > outside[ 0 ].y &&
           inside[ 0 ].z > outside[ 0 ].z &&
           inside[ 4 ].x < outside[ 4 ].x &&
           inside[ 4 ].y < outside[ 4 ].y &&
           inside[ 4 ].z < outside[ 4 ].z );
          
           if (  full )
           return INSIDE;
           else
           return INTERSECT;
          
           }
           //---------------------------------------------------------------------
           /** Checks how the box intersects with the sphere.
           */
     379   Intersection intersect(  const Sphere &one,   const AxisAlignedBox &two )
           {
           PagingLandScapeOctreeSceneManager::intersect_call++;
          
           // Null box?
           if (  two.isNull(   ) )
           return OUTSIDE;
           if (  two.isInfinite(   ) )
           return INTERSECT;
          
          
           const Real sradius = Math::Sqr (  one.getRadius(   ) );
           const Vector3 scenter = one.getCenter(   );
           const Vector3 * const corners = two.getAllCorners(   );
          
           const Vector3 mndistance = (  corners[ 0 ] - scenter );
           const Vector3 mxdistance = (  corners[ 4 ] - scenter );
          
          
           if (  mndistance.squaredLength(   ) < sradius &&
           mxdistance.squaredLength(   ) < sradius )
           {
           return INSIDE;
           }
          
           //find the square of the distance
           //from the sphere to the box
           Real d = 0;
           for (  unsigned int i = 0 ; i < 3 ; i++ )
           {
           const Real sCenteri = scenter[ i ];
           if (  sCenteri < corners[ 0 ][ i ] )
           {
           const Real s = sCenteri - corners[ 0 ][ i ];
           d += s * s;
           }
           else if (  sCenteri > corners[ 4 ][ i ] )
           {
           const Real s = sCenteri - corners[ 4 ][ i ];
           d += s * s;
           }
          
           }
          
           const bool partial = (  d <= sradius );
          
           if (  !partial )
           {
           return OUTSIDE;
           }
          
           else
           {
           return INTERSECT;
           }
          
          
           }
           //-----------------------------------------------------------------------
           //-----------------------------------------------------------------------
           //-----------------------------------------------------------------------
           const String PagingLandScapeOctreeSceneManagerFactory::FACTORY_TYPE_NAME = "PagingLandScapeOctreeSceneManager";
           //-----------------------------------------------------------------------
     442   void PagingLandScapeOctreeSceneManagerFactory::initMetaData(  void ) const
           {
           mMetaData.typeName = FACTORY_TYPE_NAME;
           mMetaData.description = "Scene manager organising the scene on the basis of an octree,   possibly using occlusion culling.";
           mMetaData.sceneTypeMask = ST_EXTERIOR_REAL_FAR; // support all types
           mMetaData.worldGeometrySupported = false;
           }
           //-----------------------------------------------------------------------
     450   SceneManager* PagingLandScapeOctreeSceneManagerFactory::createInstance(  
     451   const String& instanceName )
           {
           return new PagingLandScapeOctreeSceneManager(  instanceName );
           }
           //-----------------------------------------------------------------------
     456   void PagingLandScapeOctreeSceneManagerFactory::destroyInstance(  SceneManager* instance )
           {
           delete instance;
           }
           //---------------------------------------------------------------------
     461   PagingLandScapeOctreeSceneManager::PagingLandScapeOctreeSceneManager(  const String& name ):
           SceneManager(  name ),  
           mPagingLandScapeOctree(  0 ),  
           mCurrentOptionCamera(  0 )
           {
           mOctreeSet.setPoolSize (  64 );
           AxisAlignedBox b(  -10000,   -10000,   -10000,   10000,   10000,   10000 );
           int depth = 8;
           init(  b,   depth );
           }
           //---------------------------------------------------------------------
     472   PagingLandScapeOctreeSceneManager::PagingLandScapeOctreeSceneManager(  const String& name,   AxisAlignedBox &box,   int max_depth ) :
           SceneManager(  name ),  
           mPagingLandScapeOctree(  0 )
           {
           init(  box,   max_depth );
           }
           //---------------------------------------------------------------------
     479   const String& PagingLandScapeOctreeSceneManager::getTypeName(  void ) const
           {
           return PagingLandScapeOctreeSceneManagerFactory::FACTORY_TYPE_NAME;
           }
           //---------------------------------------------------------------------
     484   void PagingLandScapeOctreeSceneManager::init(  const AxisAlignedBox &box,   int depth )
           {
           delete mSceneRoot; //get rid of old root.
          
           // -- Changes by Steve
           // Don't do it this way,   it will add it to the mSceneNodes which we don't want
           //mSceneRoot = createSceneNode(  "SceneRoot" );
           mSceneRoot = new PagingLandScapeOctreeNode(  this,   "SceneRoot" );
           mSceneRoot->_notifyRootNode(   );
           // -- End changes by Steve
          
          
           if (  mPagingLandScapeOctree )
           deleteOctree (  mPagingLandScapeOctree );
           mPagingLandScapeOctree = mOctreeSet.getPoolable(   );
           assert (  mPagingLandScapeOctree );
           mPagingLandScapeOctree->setSceneManager (  this );
          
           mMaxDepth = depth;
           mBox = box;
          
           //mSceneRoot isn't put into the PagingLandScapeOctree since it has no volume.
           mPagingLandScapeOctree->setBoundingBox (  box.getMinimum(   ),   box.getMaximum(   ) );
          
           #ifdef _VISIBILITYDEBUG
           mShowBoxes = false;
           mCullCamera = false;
           // setDisplaySceneNodes(  true );
           #endif //_VISIBILITYDEBUG
          
          
           mOcclusion.init (  this );
           mOcclusionDepth = 0;
          
           }
           //---------------------------------------------------------------------
     520   PagingLandScapeOctreeSceneManager::~PagingLandScapeOctreeSceneManager(   )
           {
           // -- Changed by Steve
           // Don't do this here,   SceneManager will do it
           /*
           if(  mSceneRoot )
           delete mSceneRoot;
           */
           // --End Changes by Steve
          
           if (  mPagingLandScapeOctree )
           {
           deleteOctree (  mPagingLandScapeOctree );
           mPagingLandScapeOctree = 0;
           }
           VisiblesPerCam::iterator i = mVisibles.begin (   );
           while (  i != mVisibles.end(   ) )
           {
           delete (  i->second );
           ++i;
           }
           mVisibles.clear(   );
           mOctreeSet.deletePool (   );
           }
           //---------------------------------------------------------------------
     545   Camera * PagingLandScapeOctreeSceneManager::createCamera(  const String &name )
           {
           if (  mCameras.find(  name ) != mCameras.end(   ) )
           {
           OGRE_EXCEPT(  
           Exception::ERR_DUPLICATE_ITEM,  
           "A camera with the name " + name + " already exists",  
           "PagingLandScapeSceneManager::createCamera" );
           }
           Camera * c = new PagingLandScapeOctreeCamera(  name,   this );
           mCameras.insert(  CameraList::value_type(  name,   c ) );
           addCamera (  c );
           return c;
           }
           //-----------------------------------------------------------------------
     560   void PagingLandScapeOctreeSceneManager::addCamera(  Camera *cam )
           {
           PagingLandScapeOctreeCamera *c = static_cast <PagingLandScapeOctreeCamera *> (  cam );
           mVisibles[c->getId (   )] = new MovableObjectList(   );
           if (  !c->isRegisteredInOcclusionSystem(   )
           && c->needRegistrationInOcclusionSystem(   ) )
           {
           mPagingLandScapeOctree->traversal(  RegisterCameraTraversal(  c ),   0 );
           c->setRegisteredInOcclusionSystem(  true );
           }
           if (  !mCurrentOptionCamera )
           mCurrentOptionCamera = c;
           }
           //-----------------------------------------------------------------------
     574   void PagingLandScapeOctreeSceneManager::unregisterCamera(  PagingLandScapeOctreeCamera *c )
           {
           VisiblesPerCam::iterator i = mVisibles.find (  c->getId (   ) );
           if (  i != mVisibles.end(   ) )
           {
           delete (  i->second );
           mVisibles.erase(  i );
           }
           if (  c->isRegisteredInOcclusionSystem (   ) )
           {
           mPagingLandScapeOctree->traversal (  UnregisterCameraTraversal(  c ),   0 );
           c->setRegisteredInOcclusionSystem (  false );
           }
           if (  mCurrentOptionCamera == c )
           c = 0;
           }
           //-----------------------------------------------------------------------
     591   void PagingLandScapeOctreeSceneManager::destroyCamera(  Camera *cam )
           {
           SceneManager::destroyCamera(  cam );
           }
           //-----------------------------------------------------------------------
     596   void PagingLandScapeOctreeSceneManager::destroyCamera(  const String& name )
           {
           // Find in list
           CameraList::iterator i = mCameras.find(  name );
           if (  i != mCameras.end(   ) )
           {
           unregisterCamera (  static_cast <PagingLandScapeOctreeCamera *> (  i->second ) );
           SceneManager::destroyCamera (  name );
           }
           }
           //-----------------------------------------------------------------------
     607   void PagingLandScapeOctreeSceneManager::destroyAllCameras(  void )
           {
           CameraList::iterator i = mCameras.begin(   );
           for (  ; i != mCameras.end(   ); ++i )
           {
           unregisterCamera (  static_cast <PagingLandScapeOctreeCamera *> (  i->second ) );
           // Notify render system
           mDestRenderSystem->_notifyCameraRemoved(  i->second );
           delete i->second;
           }
           mCameras.clear (   );
           }
           //---------------------------------------------------------------------
     620   void PagingLandScapeOctreeSceneManager::destroySceneNode(  const String &name )
           {
           PagingLandScapeOctreeNode * on = static_cast < PagingLandScapeOctreeNode* > (  SceneManager::getSceneNode(  name ) );
          
           if (  on != 0 )
           _removePagingLandScapeOctreeNode(  on );
          
           SceneManager::destroySceneNode(  name );
           }
           //---------------------------------------------------------------------
     630   bool PagingLandScapeOctreeSceneManager::getOptionValues(  const String & key,   StringVector &refValueList )
           {
           return SceneManager::getOptionValues(  key,   refValueList );
           }
           //---------------------------------------------------------------------
     635   bool PagingLandScapeOctreeSceneManager::getOptionKeys(  StringVector & refKeys )
           {
           SceneManager::getOptionKeys(  refKeys );
          
           refKeys.push_back(  "CullCamera" );
           refKeys.push_back(  "Size" );
           refKeys.push_back(  "ShowPagingLandScapeOctree" );
           refKeys.push_back(  "Depth" );
          
           return true;
           }
           //---------------------------------------------------------------------
     647   void PagingLandScapeOctreeSceneManager::_updatePagingLandScapeOctreeNode(  PagingLandScapeOctreeNode * onode )
           {
           const AxisAlignedBox box = onode->_getWorldAABB(   );
          
           if (  box.isNull(   ) )
           return ;
          
           // Skip if octree has been destroyed (  shutdown conditions )
           if (  !mPagingLandScapeOctree )
           return;
          
           if (  onode->getOctant(   ) == 0 )
           {
           //if outside the PagingLandScapeOctree,   force into the root node.
           if (  ! onode->_isIn(  mPagingLandScapeOctree->getBoundingBox(   ) ) )
           mPagingLandScapeOctree->_addNode(  onode );
           else
           _addPagingLandScapeOctreeNode(  onode,   mPagingLandScapeOctree );
           return ;
           }
          
           if (  ! onode->_isIn(  onode->getOctant(   )->getBoundingBox(   ) ) )
           {
           _removePagingLandScapeOctreeNode(  onode );
          
           //if outside the PagingLandScapeOctree,   force into the root node.
           if (  ! onode->_isIn(  mPagingLandScapeOctree->getBoundingBox(   ) ) )
           mPagingLandScapeOctree->_addNode(  onode );
           else
           _addPagingLandScapeOctreeNode(  onode,   mPagingLandScapeOctree );
           }
           }
           //---------------------------------------------------------------------
           /** Only removes the node from the PagingLandScapeOctree. It leaves the PagingLandScapeOctree,   even if it's empty.
           */
     682   void PagingLandScapeOctreeSceneManager::_removePagingLandScapeOctreeNode(  PagingLandScapeOctreeNode * n )
           {
           assert (  n );
          
           // Skip if octree has been destroyed (  shutdown conditions )
           if (  !mPagingLandScapeOctree )
           return;
          
           PagingLandScapeOctree * oct = n->getOctant(   );
           if (  oct )
           oct->_removeNode (  n );
           n->setOctant (  0 );
           unregisteredNodeInCamera (  n );
           }
           //---------------------------------------------------------------------
     697   void PagingLandScapeOctreeSceneManager::_addPagingLandScapeOctreeMovableNode(  PagingLandScapeOctreeNode * n,  
     698   PagingLandScapeOctree *octant,  
           int depth )
           {
           const AxisAlignedBox bx = n->_getWorldAABB(   );
          
           //if the PagingLandScapeOctree is twice as big as the scene node,  
           //we will add it to a child.
           if (  (  depth < mMaxDepth ) && octant->_isTwiceSize (  bx ) )
           {
           _addPagingLandScapeOctreeMovableNode(  n,  
           octant->_getChildWhereBoxFits(  bx,   this ),  
           ++depth );
           }
           else
           {
           #ifdef _VISIBILITYDEBUG
           n ->setDebugCorners(  this );
           #endif //_VISIBILITYDEBUG
          
           #ifdef _DEBUG
           std::cout << "Depth Placement "
           << StringConverter::toString (  depth )
           << " \n";
           #endif //_DEBUG
          
           octant->_addNode(  n );
           }
           }
           //---------------------------------------------------------------------
     727   void PagingLandScapeOctreeSceneManager::_addPagingLandScapeOctreeStaticNode(  PagingLandScapeOctreeNode * n,  
     728   PagingLandScapeOctree *octant,  
           int depth )
           {
           const AxisAlignedBox bx = n->_getWorldAABB(   );
          
           //if the PagingLandScapeOctree is twice as big as the scene node,  
           //we will add it to a child.
           if (  (  depth < mMaxDepth ) && octant->_isTwiceCullSize (  bx ) )
           {
           if (  octant->_isNotCrossingAxes(  bx ) )
           {
           _addPagingLandScapeOctreeStaticNode(  n,  
           octant->_getCullChildWhereBoxFits(  bx,   this ),  
           ++depth );
           }
           else
           {
           // re-insert it as a moving node,   therefore avoiding crossing problem.
           n->setStaticCulling (  false );
           _addPagingLandScapeOctreeMovableNode(  n,  
           mPagingLandScapeOctree,  
           0 );
           }
           }
           else
           {
           #ifdef _VISIBILITYDEBUG
           n ->setDebugCorners(  this );
           #endif //_VISIBILITYDEBUG
           octant->_addNode(  n );
           }
           }
           //---------------------------------------------------------------------
     761   void PagingLandScapeOctreeSceneManager::_addPagingLandScapeOctreeNode(  PagingLandScapeOctreeNode * n,   PagingLandScapeOctree *octant,   int depth )
           {
           assert (  n && octant );
           if (  n->isStaticNode (   ) )
           _addPagingLandScapeOctreeStaticNode(  n,   octant,   depth );
           else
           _addPagingLandScapeOctreeMovableNode(  n,   octant,   depth );
           registeredNodeInCamera (  n );
           }
           //---------------------------------------------------------------------
     771   SceneNode * PagingLandScapeOctreeSceneManager::createSceneNode(  void )
           {
           PagingLandScapeOctreeNode * on = new PagingLandScapeOctreeNode(  this );
           mSceneNodes[ on->getName(   ) ] = on;
           return on;
           }
           //---------------------------------------------------------------------
     778   SceneNode * PagingLandScapeOctreeSceneManager::createSceneNode(  const String &name )
           {
           // Check name not used
           if (  mSceneNodes.find(  name ) != mSceneNodes.end(   ) )
           {
           OGRE_EXCEPT(  
           Exception::ERR_DUPLICATE_ITEM,  
           "A scene node with the name " + name + " already exists",  
           "PagingLandScapeOctreeSceneManager::createSceneNode"  );
           }
           PagingLandScapeOctreeNode * on = new PagingLandScapeOctreeNode(  this,   name );
           mSceneNodes[ on->getName(   ) ] = on;
           return on;
           }
           //---------------------------------------------------------------------
     793   void PagingLandScapeOctreeSceneManager::registeredNodeInCamera(  OcclusionElement *on )
           {
           // register existing camera in nodes
           bool isRegistered = false;
           for (  CameraList::iterator it = mCameras.begin(   ); it != mCameras.end(   ); ++it )
           {
           // Notify occlusion system
           PagingLandScapeOctreeCamera *c = static_cast <PagingLandScapeOctreeCamera *> (  it->second );
           assert (  c );
           if (  c->isRegisteredInOcclusionSystem (   ) )
           {
           on->traversal (  RegisterCameraTraversal(  c ),   0 );
           isRegistered = true;
           }
           }
           on->setRegisteredtoCam (  isRegistered );
           }
           //---------------------------------------------------------------------
     811   void PagingLandScapeOctreeSceneManager::unregisteredNodeInCamera(  OcclusionElement *on )
           {
           // register existing camera in nodes
           for (  CameraList::iterator it = mCameras.begin(   );it != mCameras.end(   ); ++it )
           {
           // Notify occlusion system
           PagingLandScapeOctreeCamera *c = static_cast <PagingLandScapeOctreeCamera *> (  it->second );
           assert (  c );
           if (  c->isRegisteredInOcclusionSystem (   ) )
           on->traversal (  UnregisterCameraTraversal(  c ),   0 );
           }
           on->setRegisteredtoCam (  false );
           }
           //---------------------------------------------------------------------
     825   void PagingLandScapeOctreeSceneManager::_updateSceneGraph(  Camera * cam )
           {
           SceneManager::_updateSceneGraph(  cam );
           }
           //---------------------------------------------------------------------
     830   void PagingLandScapeOctreeSceneManager::enableHardwareOcclusionTests(   )
           {
           Camera * const c_cam = mCameraInProgress;
          
           // make sure we always occlude in SOLID MODE
           mCamDetail = c_cam->getPolygonMode (   );
           if (  mCamDetail != PM_SOLID )
           {
           mOcclusion.setIfNotSolidScene (  true );
           c_cam->setPolygonMode (  PM_SOLID );
           }
           else
           {
           mOcclusion.setIfNotSolidScene (  false );
           }
          
           //#define HWOCCLUSIONRTT
           #ifdef HWOCCLUSIONRTT
          
           const Viewport * const c_camViewPort = c_cam->getViewport(   );
           assert (  c_camViewPort );
           if (  mOcclusionDepth == 0 )
           {
           mOcclusionDepth = mDestRenderSystem->
           createRenderTexture(  
           "OcclusionDepthTexture",  
           c_camViewPort->getActualWidth(   ) / 8,  
           c_camViewPort->getActualHeight(   ) / 8,  
           TEX_TYPE_2D,  
           PF_DEPTH );
          
          
           mOcclusionDepth->setAutoUpdated (  false );
           mOcclusionDepth->setActive (  false );
          
           mOcclusionCamera = createCamera (  "OcclusionDepthTextureCamera" );
           Viewport * const v = mOcclusionDepth->addViewport(  mOcclusionCamera );
           assert (  v );
           v->setOverlaysEnabled (  false );
           v->setClearEveryFrame(  false );
           v->setBackgroundColour(  ColourValue::Black );
          
          #define RENDERCOLOR
          #ifdef RENDERCOLOR
           MaterialPtr mat = MaterialManager::getSingleton(   ).create (  
           "OcclusionDepthTextureMat",  
           ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
           mat->getTechnique(  0 )->getPass(  0 )->createTextureUnitState(  "OcclusionDepthTexture" );
          
           Overlay *OcclusionDepthOverlay = OverlayManager::getSingleton (   ).create(  "OcclusionDepthOverlay" );
           OverlayElement *OcclusionDepthPanel =
           OverlayManager::getSingleton (   ).createOverlayElement (  "Panel",  
           "OcclusionDepthPanel",  
           false );
           OcclusionDepthPanel->setMaterialName (  "OcclusionDepthTextureMat" );
           OcclusionDepthOverlay->add2D (  (  OverlayContainer * )OcclusionDepthPanel );
           OcclusionDepthOverlay->show (   );
          
           //OcclusionDepthOverlay->setScale (  0.5f,   0.5f );
           OcclusionDepthPanel->setPosition (  0.8,   0.8 );
          #endif //RENDERCOLOR
          
           mOcclusionCamera->setNearClipDistance(  c_cam->getNearClipDistance(   ) );
           mOcclusionCamera->setFarClipDistance(  c_cam->getFarClipDistance(   ) );
           mOcclusionCamera->setAspectRatio(  
           (  Real )c_camViewPort->getActualWidth(   ) / c_camViewPort->getActualHeight(   ) );
           }
          
           // copy camera characteristics to occlusion camera.
           mOcclusionCamera->setPosition (  c_cam->getWorldPosition (   ) );
           mOcclusionCamera->setOrientation (  c_cam->getWorldOrientation (   ) );
           mOcclusionCamera->setNearClipDistance(  c_cam->getNearClipDistance(   ) );
           mOcclusionCamera->setFarClipDistance(  c_cam->getFarClipDistance(   ) );
          
          
           mDestRenderSystem->_setViewport(  mOcclusionCamera->getViewport (   ) );
           mDestRenderSystem->_setWorldMatrix(  Matrix4::IDENTITY );
           mDestRenderSystem->_setViewMatrix(  c_cam->getViewMatrix(   ) );
           mDestRenderSystem->_setProjectionMatrix(  c_cam->getProjectionMatrix(   ) );
          
           mDestRenderSystem->_beginFrame(   );
          
           mDestRenderSystem->clearFrameBuffer (  FBT_DEPTH | FBT_COLOUR,  
           mOcclusionCamera->getViewport (   )->getBackgroundColour (   ) );
          
           #else //HWOCCLUSIONRTT
          
           assert (  c_cam->getViewport(   ) );
           mDestRenderSystem->_setViewport(  c_cam->getViewport(   ) );
           mDestRenderSystem->clearFrameBuffer (  FBT_DEPTH | FBT_COLOUR,  
           c_cam->getViewport (   )->getBackgroundColour (   ),  //color
           1.0f,  //depth
           0 );//stencil
           mDestRenderSystem->_beginFrame(   );
           assert (  c_cam->getViewport(   )->getClearEveryFrame (   ) == false );
           #endif //HWOCCLUSIONRTT
          
           mDestRenderSystem->_beginGeometryCount(   );
          
           }
           //---------------------------------------------------------------------
     931   void PagingLandScapeOctreeSceneManager::disableHardwareOcclusionTests(   )
           {
           PagingLandScapeOctreeCamera * const octreeCam = static_cast <PagingLandScapeOctreeCamera *> (  mCameraInProgress );
          
           assert (  octreeCam->getViewport (   ) );
           #ifdef HWOCCLUSIONRTT
          
           mDestRenderSystem->_endFrame(   );
           mDestRenderSystem->_setViewport(  octreeCam->getViewport (   ) );
          
           #else //HWOCCLUSIONRTT
           mDestRenderSystem->_endFrame(   );
           #endif //HWOCCLUSIONRTT
          
           if (  mCamDetail != PM_SOLID )
           {
           mDestRenderSystem->clearFrameBuffer (  FBT_DEPTH | FBT_COLOUR,  
           octreeCam->getViewport (   )->getBackgroundColour (   ),  //color
           1.0f,  //depth
           0 );//stencil
           }
          
           // make sure we restore previous detail level.
           octreeCam->setPolygonMode (  mCamDetail );
          
           // Notify camera or vis faces
           octreeCam->_addCHCRenderedFaces(  mDestRenderSystem->_getFaceCount(   ) );
           }
           //---------------------------------------------------------------------
          #ifdef PLSM2_EIHORT
     961   void PagingLandScapeOctreeSceneManager::_findVisibleObjects(  Camera* cam,   VisibleObjectsBoundsInfo * visibleBounds,   bool onlyShadowCasters )
          #else
           void PagingLandScapeOctreeSceneManager::_findVisibleObjects(  Camera * cam,   bool onlyShadowCasters )
          #endif
           {
           RenderQueue *q = SceneManager::getRenderQueue(   );
          
          
           PagingLandScapeOctreeCamera * const octreeCam = static_cast <PagingLandScapeOctreeCamera *> (  cam );
          
           assert (  mVisibles.find(  octreeCam->getId(   ) ) != mVisibles.end(   ) );
           mCamInProgressVisibles = mVisibles[octreeCam->getId(   )];
           assert (  mCamInProgressVisibles );
          
           #ifdef _VISIBILITYDEBUG
           /*
           if (  !octreeCam->isRegisteredInOcclusionSystem(   ) )
           {
           mPagingLandScapeOctree->traversal(  RegisterCameraTraversal(  octreeCam ) );
           octreeCam->setRegisteredInOcclusionSystem(  true );
           }
           */
           mBoxes.clear(   );
           if (  mCullCamera )
           {
           if (  getCamera(  "CullCamera" ) )
           cam = getCamera(  "CullCamera" );
           }
           #endif // _VISIBILITYDEBUG
          
           if (  mPagingLandScapeOctree->hasChildren (   ) )
           {
           mNumObjects = 0;
          
           // should find a way to be sure that
           // it's a new frame,   and not just a camera change or something.
           if (  mOcclusion.nextFrame (  static_cast < PagingLandScapeOctreeCamera * > (  cam ),  
           mCamInProgressVisibles,  
           onlyShadowCasters,  
           q ) )
           {
           switch (  octreeCam->getOcclusionMode(   ) )
           {
           case CHC:
           {
           enableHardwareOcclusionTests(   );
           mOcclusion.CHCtraversal (  mPagingLandScapeOctree,   visibleBounds );
           disableHardwareOcclusionTests(   );
           q->clear(   );
           #ifdef _VISIBILITYDEBUG
           if (  mCullDebug && cam->getViewport (   ) )
           {
           mDebugText =(  
           "CHC = " + StringConverter::toString(  mOcclusion.object_cnt ) + ",   t=" +
           StringConverter::toString(  mOcclusion.traversed_nodes_cnt ) + ",   f=" +
           StringConverter::toString(  mOcclusion.frustum_culled_nodes_cnt ) + ",   q=" +
           StringConverter::toString(  mOcclusion.query_cnt )
            );
           }
           #endif //_VISIBILITYDEBUG
           }
           break;
           case CHC_CONSERVATIVE:
           {
           enableHardwareOcclusionTests(   );
           mOcclusion.CHCtraversalConservative (  mPagingLandScapeOctree,   visibleBounds );
           disableHardwareOcclusionTests(   );
           q->clear(   );
          
           #ifdef _VISIBILITYDEBUG
           if (  mCullDebug && cam->getViewport (   ) )
           {
           mDebugText =(  
           "CHC Conservative = " + StringConverter::toString(  mOcclusion.object_cnt ) + ",   t=" +
           StringConverter::toString(  mOcclusion.traversed_nodes_cnt ) + ",   f=" +
           StringConverter::toString(  mOcclusion.frustum_culled_nodes_cnt ) + ",   q=" +
           StringConverter::toString(  mOcclusion.query_cnt )
            );
           }
           #endif //_VISIBILITYDEBUG
           }
           break;
          // case STOP_AND_WAIT:
          // {
          // enableHardwareOcclusionTests(   );
          // mOcclusion.initQueryPool (   );
          // mPagingLandScapeOctree->traversal (  SWTraversal (  mOcclusion ),   visibleBounds );
          // disableHardwareOcclusionTests(   ); q->clear(   );
          //
          // #ifdef _VISIBILITYDEBUG
          // if (  mCullDebug && cam->getViewport (   ) ) {cam->getViewport (   )->getTarget (   )->setDebugText(  
          // "SnW = " + StringConverter::toString(  mOcclusion.object_cnt ) + ",   t=" +
          // StringConverter::toString(  mOcclusion.traversed_nodes_cnt ) + ",   f=" +
          // StringConverter::toString(  mOcclusion.frustum_culled_nodes_cnt ) + ",   q=" +
          // StringConverter::toString(  mOcclusion.query_cnt )
          //  );}
          //
          // #endif //_VISIBILITYDEBUG
          //
          // }
          // break;
          // case VIEW_FRUSTUM:
          // {
          // mPagingLandScapeOctree->traversal (  ViewFrustumCullingTraversal (  mOcclusion ),   visibleBounds );
          // q->clear(   );
          // #ifdef _VISIBILITYDEBUG
          // if (  mCullDebug && cam->getViewport (   ) )
          // { cam->getViewport (   )->getTarget (   )->setDebugText(  
          // "VF = " + StringConverter::toString(  mOcclusion.object_cnt ) + ",   t=" +
          // StringConverter::toString(  mOcclusion.traversed_nodes_cnt ) + ",   f=" +
          // StringConverter::toString(  mOcclusion.frustum_culled_nodes_cnt ) + ",   q=" +
          // StringConverter::toString(  mOcclusion.query_cnt )
          //  );}
          //
          // #endif //_VISIBILITYDEBUG
          // }
          // break;
           case VIEW_FRUSTUM_DIRECT:
           {
           ViewFrustumCullingTraversalDirect temp (  mOcclusion );
           mPagingLandScapeOctree->traversal (  temp,   visibleBounds );
          
           #ifdef _VISIBILITYDEBUG
           if (  mCullDebug && cam->getViewport (   ) )
           {
           mDebugText =(  
           "VFD = " + StringConverter::toString(  mOcclusion.object_cnt ) + ",   t=" +
           StringConverter::toString(  mOcclusion.traversed_nodes_cnt ) + ",   f=" +
           StringConverter::toString(  mOcclusion.frustum_culled_nodes_cnt ) + ",   q=" +
           StringConverter::toString(  mOcclusion.query_cnt )
            );
           }
           #endif // _VISIBILITYDEBUG
           }
           break;
          
           default:
           assert (  0 );
           break;
           }
           }
          
           if (  !mCamInProgressVisibles->empty(   ) )
           {
           MovableObjectList::iterator movableIt = mCamInProgressVisibles->begin(   );
           MovableObjectList::iterator mitend = mCamInProgressVisibles->end(   );
           while (  movableIt != mitend )
           {
           (  *movableIt )->_updateRenderQueue (  q );
           ++movableIt;
           }
           }
          
           #ifdef _VISIBILITYDEBUG
           if (  mCullDebug )
           {
           mPagingLandScapeOctree->traversal (  TreeOverlayDebug (  mOcclusion,   this ),   visibleBounds );
           }
           #endif // _VISIBILITYDEBUG
           }
           }
           //---------------------------------------------------------------------
    1123   void PagingLandScapeOctreeSceneManager::addVisible(  MovableObject *mo )
           {
           mCamInProgressVisibles->push_back (  mo );
           }
           //---------------------------------------------------------------------
    1128   void PagingLandScapeOctreeSceneManager::directRenderSingleQueue(  RenderQueue *queue )
           {
           RenderQueue *oldQueue = mRenderQueue;
           mRenderQueue = queue;
          
           SceneManager::_renderVisibleObjects (   );
          
           queue->clear (   );
           mRenderQueue = oldQueue;
           }
           //---------------------------------------------------------------------
    1139   void PagingLandScapeOctreeSceneManager::directRenderSingleObject(  Renderable *r )
           {
           const Camera * const c_cam = mCameraInProgress;
           mDestRenderSystem->_setWorldMatrix(  Matrix4::IDENTITY );
          // mDestRenderSystem->_setViewMatrix(  c_cam->getViewMatrix(   ) );
          // mDestRenderSystem->_setProjectionMatrix(  c_cam->getProjectionMatrix(   ) );
          
           mDestRenderSystem->setCurrentPassIterationCount(  1 );
           _setPass(  r->getMaterial(   )->getBestTechnique(   )->getPass(  0 ) );
           useRenderableViewProjMode (  r );
          
           RenderOperation ro;
           r->getRenderOperation (  ro );
           mDestRenderSystem->_render(  ro );
          
           }
           //---------------------------------------------------------------------
    1156   void PagingLandScapeOctreeSceneManager::registerCamera (  PagingLandScapeOctreeCamera *c )
           {
           mPagingLandScapeOctree->traversal(  RegisterCameraTraversal(  c ),   0 );
           }
           //---------------------------------------------------------------------
           // --- non template versions
    1162   void _findNodes(  const AxisAlignedBox &t,   std::list < SceneNode * > &list,  
           const Ogre::SceneNode * const exclude,   const bool full,   PagingLandScapeOctree *octant )
           {
          
           bool isFull = full;
           if (  !full )
           {
           AxisAlignedBox obox;
           octant->_getCullBounds(  &obox );
          
           const Intersection isect = intersect(  t,   obox );
          
           if (  isect == OUTSIDE )
           return ;
          
           isFull = (  isect == INSIDE );
           }
          
          
           const bool b_full = isFull;
           NodeList::iterator it = octant->mNodes.begin(   );
          
           while (  it != octant->mNodes.end(   ) )
           {
           PagingLandScapeOctreeNode * const on = (  *it );
          
           if (  on != exclude )
           {
           if (  b_full )
           {
           list.push_back(  on );
           }
          
           else
           {
           const Intersection nsect = intersect(  t,   on->_getWorldAABB(   ) );
          
           if (  nsect != OUTSIDE )
           {
           list.push_back(  on );
           }
           }
          
           }
          
           ++it;
           }
          
          
          
           if (  octant->mChildren[ 0 ][ 0 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 0 ][ 0 ] );
          
           if (  octant->mChildren[ 1 ][ 0 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 0 ][ 0 ] );
          
           if (  octant->mChildren[ 0 ][ 1 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 1 ][ 0 ] );
          
           if (  octant->mChildren[ 1 ][ 1 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 1 ][ 0 ] );
          
           if (  octant->mChildren[ 0 ][ 0 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 0 ][ 1 ] );
          
           if (  octant->mChildren[ 1 ][ 0 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 0 ][ 1 ] );
          
           if (  octant->mChildren[ 0 ][ 1 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 1 ][ 1 ] );
          
           if (  octant->mChildren[ 1 ][ 1 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 1 ][ 1 ] );
          
           }
           //---------------------------------------------------------------------
    1238   void _findNodes(  const Sphere &t,   std::list < SceneNode * > &list,  
           const SceneNode * const exclude,  
           const bool full,   PagingLandScapeOctree *octant )
           {
           bool isFull = full;
           if (  !full )
           {
           AxisAlignedBox obox;
           octant->_getCullBounds(  &obox );
          
           const Intersection isect = intersect(  t,   obox );
          
           if (  isect == OUTSIDE )
           return ;
          
           isFull = (  isect == INSIDE );
           }
          
           const bool b_full = isFull;
           NodeList::iterator it = octant->mNodes.begin(   );
          
           while (  it != octant->mNodes.end(   ) )
           {
           PagingLandScapeOctreeNode * const on = (  *it );
          
           if (  on != exclude )
           {
           if (  b_full )
           {
           list.push_back(  on );
           }
          
           else
           {
           const Intersection nsect = intersect(  t,   on->_getWorldAABB(   ) );
          
           if (  nsect != OUTSIDE )
           {
           list.push_back(  on );
           }
           }
          
           }
          
           ++it;
           }
          
          
          
           if (  octant->mChildren[ 0 ][ 0 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 0 ][ 0 ] );
          
           if (  octant->mChildren[ 1 ][ 0 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 0 ][ 0 ] );
          
           if (  octant->mChildren[ 0 ][ 1 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 1 ][ 0 ] );
          
           if (  octant->mChildren[ 1 ][ 1 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 1 ][ 0 ] );
          
           if (  octant->mChildren[ 0 ][ 0 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 0 ][ 1 ] );
          
           if (  octant->mChildren[ 1 ][ 0 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 0 ][ 1 ] );
          
           if (  octant->mChildren[ 0 ][ 1 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 1 ][ 1 ] );
          
           if (  octant->mChildren[ 1 ][ 1 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 1 ][ 1 ] );
          
           }
           //---------------------------------------------------------------------
    1313   void _findNodes(  const PlaneBoundedVolume &t,   std::list < SceneNode * > &list,  
           const Ogre::SceneNode * const exclude,   const bool full,   PagingLandScapeOctree *octant )
           {
          
           bool isFull = full;
           if (  !full )
           {
           AxisAlignedBox obox;
           octant->_getCullBounds(  &obox );
          
           const Intersection isect = intersect(  t,   obox );
          
           if (  isect == OUTSIDE )
           return ;
          
           isFull = (  isect == INSIDE );
           }
          
          
           const bool b_full = isFull;
           NodeList::iterator it = octant->mNodes.begin(   );
          
           while (  it != octant->mNodes.end(   ) )
           {
           PagingLandScapeOctreeNode * const on = (  *it );
           if (  on != exclude )
           {
           if (  b_full )
           {
           list.push_back(  on );
           }
           else
           {
           const Intersection nsect = intersect(  t,   on->_getWorldAABB(   ) );
          
           if (  nsect != OUTSIDE )
           {
           list.push_back(  on );
           }
           }
           }
           ++it;
           }
          
           if (  octant->mChildren[ 0 ][ 0 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 0 ][ 0 ] );
          
           if (  octant->mChildren[ 1 ][ 0 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 0 ][ 0 ] );
          
           if (  octant->mChildren[ 0 ][ 1 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 1 ][ 0 ] );
          
           if (  octant->mChildren[ 1 ][ 1 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 1 ][ 0 ] );
          
           if (  octant->mChildren[ 0 ][ 0 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 0 ][ 1 ] );
          
           if (  octant->mChildren[ 1 ][ 0 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 0 ][ 1 ] );
          
           if (  octant->mChildren[ 0 ][ 1 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 1 ][ 1 ] );
          
           if (  octant->mChildren[ 1 ][ 1 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 1 ][ 1 ] );
          
           }
           //---------------------------------------------------------------------
    1383   void _findNodes(  const Ray &t,   std::list < SceneNode * > &list,  
           const Ogre::SceneNode * const exclude,  
           const bool full,   PagingLandScapeOctree *octant )
           {
           bool isFull = full;
           if (  !full )
           {
           AxisAlignedBox obox;
           octant->_getCullBounds(  &obox );
          
           const Intersection isect = intersect(  t,   obox );
          
           if (  isect == OUTSIDE )
           return ;
          
           isFull = (  isect == INSIDE );
           }
          
          
           const bool b_full = isFull;
           if (  !octant->mNodes.empty (   ) )
           {
           NodeList::iterator it = octant->mNodes.begin(   );
           while (  it != octant->mNodes.end(   ) )
           {
           PagingLandScapeOctreeNode * const on = (  *it );
           if (  on != exclude )
           {
           if (  b_full )
           {
           list.push_back(  on );
           }
           else
           {
           const Intersection nsect = intersect(  t,   on->_getWorldAABB(   ) );
           if (  nsect != OUTSIDE )
           list.push_back(  on );
           }
           }
           ++it;
           }
           }
           if (  octant->hasChildren (   ) )
           {
           if (  octant->mChildren[ 0 ][ 0 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 0 ][ 0 ] );
          
           if (  octant->mChildren[ 1 ][ 0 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 0 ][ 0 ] );
          
           if (  octant->mChildren[ 0 ][ 1 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 1 ][ 0 ] );
          
           if (  octant->mChildren[ 1 ][ 1 ][ 0 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 1 ][ 0 ] );
          
           if (  octant->mChildren[ 0 ][ 0 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 0 ][ 1 ] );
          
           if (  octant->mChildren[ 1 ][ 0 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 0 ][ 1 ] );
          
           if (  octant->mChildren[ 0 ][ 1 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 0 ][ 1 ][ 1 ] );
          
           if (  octant->mChildren[ 1 ][ 1 ][ 1 ] != 0 )
           _findNodes(  t,   list,   exclude,   b_full,   octant->mChildren[ 1 ][ 1 ][ 1 ] );
           }
           }
           //---------------------------------------------------------------------
    1453   void PagingLandScapeOctreeSceneManager::findNodesIn(  const AxisAlignedBox &box,   std::list < SceneNode * > &list,   const SceneNode* const exclude )
           {
           _findNodes(  box,   list,   exclude,   false,   mPagingLandScapeOctree );
           }
           //---------------------------------------------------------------------
    1458   void PagingLandScapeOctreeSceneManager::findNodesIn(  const Sphere &sphere,   std::list < SceneNode * > &list,   const SceneNode* const exclude )
           {
           _findNodes(  sphere,   list,   exclude,   false,   mPagingLandScapeOctree );
           }
           //---------------------------------------------------------------------
    1463   void PagingLandScapeOctreeSceneManager::findNodesIn(  const PlaneBoundedVolume &volume,   std::list < SceneNode * > &list,   const SceneNode* const exclude )
           {
           _findNodes(  volume,   list,   exclude,   false,   mPagingLandScapeOctree );
           }
           //---------------------------------------------------------------------
    1468   void PagingLandScapeOctreeSceneManager::findNodesIn(  const Ray &r,   std::list < SceneNode * > &list,   const SceneNode* const exclude )
           {
           _findNodes(  r,   list,   exclude,   false,   mPagingLandScapeOctree );
           }
           //---------------------------------------------------------------------
    1473   void PagingLandScapeOctreeSceneManager::resize(  const AxisAlignedBox &box,   const int depth )
           {
           mMaxDepth = depth;
           resize(  box );
           }
           //---------------------------------------------------------------------
    1479   void PagingLandScapeOctreeSceneManager::resize(  const AxisAlignedBox &box )
           {
           std::list < SceneNode * > nodes;
          
           _findNodes(  mPagingLandScapeOctree->getBoundingBox (   ),   nodes,   0,   true,   mPagingLandScapeOctree );
          
           if (  mPagingLandScapeOctree )
           deleteOctree (  mPagingLandScapeOctree );
          
           mBox = box;
           mPagingLandScapeOctree = mOctreeSet.getPoolable(   );
           assert (  mPagingLandScapeOctree );
           mPagingLandScapeOctree->setSceneManager (  this );
           mPagingLandScapeOctree ->setBoundingBox (  box.getMinimum(   ),   box.getMaximum(   ) );
           registeredNodeInCamera (  mPagingLandScapeOctree );
          
           if (  !nodes.empty(   ) )
           {
           std::list < SceneNode * > ::iterator it;
           it = nodes.begin(   );
          
           while (  it != nodes.end(   ) )
           {
           PagingLandScapeOctreeNode * const on = static_cast < PagingLandScapeOctreeNode * > (  *it );
           on->setOctant(  0 );
           _updatePagingLandScapeOctreeNode(  on );
           ++it;
           } // while (  it != nodes.end(   ) )
           }
           }
           //---------------------------------------------------------------------
    1510   bool PagingLandScapeOctreeSceneManager::setOption(  const String & key,   const void * val )
           {
           if (  key == "Size" )
           {
           resize(  * static_cast < const AxisAlignedBox * > (  val ) );
           return true;
           }
          
           else if (  key == "Depth" )
           {
           assert (  mPagingLandScapeOctree );
           mMaxDepth = * static_cast < const int * > (  val );
           // copy the box since resize will delete mOctree and reference won't work
           AxisAlignedBox box = mPagingLandScapeOctree->getBoundingBox(   );
           resize(  box );
           return true;
           }
           else if (  key == "NextCullMode" )
           {
           if (  val )
           {
           CameraList::iterator it = mCameras.find (  static_cast < const PagingLandScapeOctreeCamera * > (  val )->getName(   ) );
           if (  it != mCameras.end(   ) )
           {
           static_cast < PagingLandScapeOctreeCamera * > (  it->second )->setNextOcclusionMode(   );
           return true;
           }
           }
           return false;
           }
           else if (  key == "setNumberOfConservativeFrames" )
           {
           mOcclusion.setNumberOfConservativeFrames(  *(  static_cast < const unsigned int * > (  val ) ) );
           }
           else if (  key == "CurrentOptionCamera" )
           {
           if (  val )
           {
           CameraList::iterator it = mCameras.find (  static_cast < const PagingLandScapeOctreeCamera * > (  val )->getName(   ) );
           if (  it != mCameras.end(   ) )
           {
           mCurrentOptionCamera = static_cast < PagingLandScapeOctreeCamera * > (  it->second );
           }
           return true;
           }
           }
           else if (  key == "setCullingMode" )
           {
           assert (  mCurrentOptionCamera );
           mCurrentOptionCamera->setOcclusionModeAsString(  * static_cast < const String * > (  val ) );
           return true;
           }
           #ifdef _VISIBILITYDEBUG
           else if (  key == "ShowPagingLandScapeOctree" )
           {
           mShowBoxes = * static_cast < const bool * > (  val );
           return true;
           }
           else if (  key == "CullDebug" )
           {
           mCullDebug = * static_cast < const bool * > (  val );
           return true;
           }
           else if (  key == "CullCamera" )
           {
           mCullCamera = * static_cast < const bool * > (  val );
           return true;
           }
           #endif //_VISIBILITYDEBUG
           return SceneManager::setOption(  key,   val );
          
          
           }
           //---------------------------------------------------------------------
    1584   bool PagingLandScapeOctreeSceneManager::getOption(  const String & key,   void *val )
           {
           if (  key == "Size" )
           {
           AxisAlignedBox * b = static_cast < AxisAlignedBox * > (  val );
           b->setExtents(  mPagingLandScapeOctree->getBoundingBox (   ).getMinimum(   ),   mPagingLandScapeOctree->getBoundingBox(   ).getMaximum(   ) );
           return true;
           }
          
           else if (  key == "Depth" )
           {
           * static_cast < int * > (  val ) = mMaxDepth;
           return true;
           }
           else if (  key == "setNumberOfConservativeFrames" )
           {
           * static_cast < unsigned int * > (  val ) = mOcclusion.getNumberOfConservativeFrames(   );
           return true;
           }
           else if (  key == "CurrentOptionCamera" )
           {
           *static_cast < String * > (  val ) = mCurrentOptionCamera->getName(   );
           return true;
           }
           else if (  key == "getCullingMode" )
           {
           assert (  mCurrentOptionCamera );
           *static_cast < String * > (  val ) = mCurrentOptionCamera->getOcclusionModeAsString(   );
           return true;
           }
          
           #ifdef _VISIBILITYDEBUG
           else if (  key == "ShowPagingLandScapeOctree" )
           {
          
           * static_cast < bool * > (  val ) = mShowBoxes;
           return true;
           }
           else if (  key == "CullCamera" )
           {
           * static_cast < bool * > (  val ) = mCullCamera;
           return true;
           }
           else if (  key == "CullDebug" )
           {
           * static_cast < bool * > (  val ) = mCullDebug;
           return true;
           }
           else if (  key == "DebugText" )
           {
           * static_cast < String * > (  val ) = mDebugText;
           return true;
           }
           #endif //_VISIBILITYDEBUG
          
           return SceneManager::getOption(  key,   val );
           }
           //---------------------------------------------------------------------
    1642   void PagingLandScapeOctreeSceneManager::clearScene(  void )
           {
           SceneManager::clearScene(   );
          
           // reset cameras
           //CameraList::iterator iCam = mCameras.begin(   );
           //for (  ; iCam != mCameras.end(   ); ++iCam )
           //{
           // PagingLandScapeOctreeCamera *cam = static_cast <PagingLandScapeOctreeCamera *> (  iCam->second );
           // if (  cam->isRegisteredInOcclusionSystem (   ) )
           // {
           // mPagingLandScapeOctree->traversal (  UnregisterCameraTraversal(  cam ) );
           // cam->setRegisteredInOcclusionSystem (  false );
           // }
           //}
          
           init(  mBox,   mMaxDepth );
          
           }
           //---------------------------------------------------------------------
           AxisAlignedBoxSceneQuery*
    1663   PagingLandScapeOctreeSceneManager::createAABBQuery(  const AxisAlignedBox& box,   unsigned long mask )
           {
           PagingLandScapeOctreeAxisAlignedBoxSceneQuery* q = new PagingLandScapeOctreeAxisAlignedBoxSceneQuery(  this );
           q->setBox(  box );
           q->setQueryMask(  mask );
           return q;
           }
           //---------------------------------------------------------------------
           SphereSceneQuery*
    1672   PagingLandScapeOctreeSceneManager::createSphereQuery(  const Sphere& sphere,   unsigned long mask )
           {
           PagingLandScapeOctreeSphereSceneQuery* q = new PagingLandScapeOctreeSphereSceneQuery(  this );
           q->setSphere(  sphere );
           q->setQueryMask(  mask );
           return q;
           }
           //---------------------------------------------------------------------
           PlaneBoundedVolumeListSceneQuery*
    1681   PagingLandScapeOctreeSceneManager::createPlaneBoundedVolumeQuery(  const PlaneBoundedVolumeList& volumes,  
           unsigned long mask )
           {
           PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery* q = new PagingLandScapeOctreePlaneBoundedVolumeListSceneQuery(  this );
           q->setVolumes(  volumes );
           q->setQueryMask(  mask );
           return q;
           }
          
           //---------------------------------------------------------------------
           RaySceneQuery*
    1692   PagingLandScapeOctreeSceneManager::createRayQuery(  const Ray& ray,   unsigned long mask )
           {
           PagingLandScapeOctreeRaySceneQuery* q = new PagingLandScapeOctreeRaySceneQuery(  this );
           q->setRay(  ray );
           q->setQueryMask(  mask );
           return q;
           }
           //---------------------------------------------------------------------
           IntersectionSceneQuery*
    1701   PagingLandScapeOctreeSceneManager::createIntersectionQuery(  unsigned long mask )
           {
          
           // PagingLandScapeOctree implementation performs WORSE for < 500 objects
           // TODO: optimize it so it's better in all cases
           //PagingLandScapeOctreeIntersectionSceneQuery* q = new PagingLandScapeOctreeIntersectionSceneQuery(  this );
           DefaultIntersectionSceneQuery* q;
           if (  mPagingLandScapeOctree->numNodes (   ) > 500 )
           q = new PagingLandScapeOctreeIntersectionSceneQuery(  this );
           else
           q = new DefaultIntersectionSceneQuery(  this );
           q->setQueryMask(  mask );
           return q;
           }
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOctreeSphereSceneQuery.cpp

       1  /*
          -----------------------------------------------------------------------------
          This source file is part of OGRE
          (  Object-oriented Graphics Rendering Engine )
          For the latest info,   see http://www.ogre3d.org/
          
          Copyright 2000-2006 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 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 General Public License for more details.
          
          You should have received a copy of the GNU 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.
          -----------------------------------------------------------------------------
          */
          /***************************************************************************
          OgrePagingLandScapeOctreeSphereSceneQuery.cpp - description
          -------------------
          begin : Tues July 20,   2004
          copyright : (  C ) 2004by Jon Anderson
          email : janders@users.sf.net
          
          
          
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgrePagingLandScapeOctreeSphereSceneQuery.h"
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          #include "OgreEntity.h"
          
          namespace Ogre
          {
          
          //---------------------------------------------------------------------
      46  PagingLandScapeOctreeSphereSceneQuery::PagingLandScapeOctreeSphereSceneQuery(  SceneManager* creator )
           : DefaultSphereSceneQuery(  creator )
          {
          }
          
          //---------------------------------------------------------------------
      52  PagingLandScapeOctreeSphereSceneQuery::~PagingLandScapeOctreeSphereSceneQuery(  void )
          {
          }
          
          //---------------------------------------------------------------------
      57  void PagingLandScapeOctreeSphereSceneQuery::execute(  SceneQueryListener* listener )
          {
           std::list < SceneNode* > list;
           //find the nodes that intersect the AAB
           static_cast< PagingLandScapeOctreeSceneManager* >(  mParentSceneMgr )->findNodesIn(  mSphere,   list,   0 );
          
           //grab all moveables from the node that intersect...
           std::list< SceneNode* >::iterator it = list.begin(   );
           while(  it != list.end(   ) )
           {
           SceneNode::ObjectIterator oit = (  *it )->getAttachedObjectIterator(   );
           while (  oit.hasMoreElements(   ) )
           {
           MovableObject* m = oit.getNext(   );
           if (  (  m->getQueryFlags(   ) & mQueryMask )
           && m->isInScene(   )
           && mSphere.intersects(  m->getWorldBoundingBox(   ) ) )
           {
           listener->queryResult(  m );
           }
           }
           ++it;
           }
          }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeOptions.cpp

       1  /***************************************************************************
           OgrePagingLandScapeOptions.cpp - description
           -------------------
           begin : Sun Mar 02 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreRoot.h"
          #include "OgreSceneManager.h"
          #include "OgreRenderSystem.h"
          #include "OgreGpuProgramManager.h"
          
          #include "OgreStringConverter.h"
          #include "OgreVector2.h"
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          #include "OgreConfigFile.h"
          
          #include "OgreImage.h"
          #include "OgreMaterialManager.h"
          #include "OgreMaterial.h"
          #include "OgreTechnique.h"
          
          #include "OgreCamera.h"
          #include "OgreViewport.h"
          
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeCamera.h"
          #include "OgrePagingLandScapeTileInfo.h"
          
          #include "fileutils.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      49   PagingLandScapeOptions::PagingLandScapeOptions(  PagingLandScapeSceneManager * scnMgr ):
           mScnMgr(  scnMgr )
           {
           cfgGroupName = "";
           primaryCamera = 0;
           isInit = false;
           setDefault(   );
           };
          
           //-----------------------------------------------------------------------
      59   PagingLandScapeOptions::~PagingLandScapeOptions(   )
           {
           clearTileInfo(   );
           }
           //-----------------------------------------------------------------------
      64   void PagingLandScapeOptions::setDefault(   )
           {
          
           mUseLodMapCache = false;
           materialPerPage = false;
           textureModifiable = true;
           roughnessLod = true;
          
           data2DFormat = "HeightField";
           textureFormat = "Image";
          
           image_filename = "";
           ImageNameLoad = false;
           LandScape_filename = "";
           LandScape_export_filename = "";
           ColorMapName = "";
          
           groupName = cfgGroupName;
          
           LandScape_extension = "png";
           LandScape_export_extension = "png";
           TextureExtension = "png";
          
           maxValue = 5000;
           minValue = 0;
          
           PageSize = 513;
           TileSize = 65;
           maxRenderLevel = 100;
          
           world_width = 0;
           world_height = 0;
          
           maxScaledZ = 0;
           maxScaledX = 0;
           maxUnScaledZ = 0;
           maxUnScaledX = 0;
          
           max_adjacent_pages = 2;
           max_preload_pages = 3;
           PageLoadInterval = 30;
          
           change_factor = 1;
           distanceLOD = 4;
           LOD_factor = 10;
          
           scale = Ogre::Vector3::UNIT_SCALE;
           invScale = Ogre::Vector3::UNIT_SCALE;
           position = Ogre::Vector3::ZERO;
          
           num_renderables = 64;
           num_renderables_increment = 64;
           num_tiles = 64;
           num_tiles_increment = 64;
          
           visible_renderables = 75;
           cameraThreshold = 5;
          
           num_renderables_loading = 10;
           RenderableLoadInterval = 3;
          
           normals = false;
           lit = false;
          
           colored = false;
           vertex_shadowed = false;
           base_vertex_color = false;
           coverage_vertex_color = false;
           vertex_instant_colored = false;
          
           RawHeight = 0;
           RawWidth = 0;
          
           lightmoved = false;
          
           Deformable = false;
           saveDeformation = true;
           VertexCompression = false;
          
           BigImage = false;
          
           lodMorphStart = 0.2f;
           lodMorph = false;
          
           maxPixelError = 0;
          
           TextureStretchFactor = 1.0f;
          
           NumMatHeightSplat = 0;
           matHeight.reserve (  0 );
           matHeight.resize (  0 );
           matColor.reserve (  0 );
           matColor.resize (  0 );
          
           NumSplatMapToSplit = 0;
           SplatMapNames.reserve (  0 );
           SplatMapNames.resize (  0 );
          
           NumTextureFormatSupported = 0;
           TextureFormatSupported.reserve (  0 );
           TextureFormatSupported.resize (  0 );
          
           MaxLodUnderCam = false;
           VisMap = false;
           BigImage = false;
          
           PageInvisibleUnloadFrames = 300;
           TileInvisibleUnloadFrames = 300;
          
           lodMaterialDistanceList.clear(   );
           lodMaterialDistanceList.push_back (  80000.0f );
          
           mResourceFilesystem.clear (   );
           mResourceZip.clear(   );
          
           queryNoInterpolation = false;
           queryResolutionFactor = 1.0f;
          #ifdef _MAPSPLITTER
          
           Blur = 0.0f;
           Amb = 0.5f;
           Diff = 0.5f;
          
           Blur = 0.0f;
           HeightMapBlurFactor = 0.0f;
           Paged = true;
           MiniMap = false;
           BaseMap = false;
           ColorMapGenerate = false;
           ColorMapSplit = false;
           LightMap = false;
           NormalMap = false;
           HeightMap = false;
           AlphaMaps = false;
           LitBaseMap = false;
           InfiniteMap = false;
           CoverageMap = false;
           LitColorMapGenerate = false;
           LitColorMapSplit = false;
           HeightNormalMap = false;
           Equalize = false;
           ZHorizon = false;
           SRTM_water = false;
          
          #endif
           }
           //-----------------------------------------------------------------------
     211   void PagingLandScapeOptions::init(   )
           {
           // sets options that doesn't depend on maps.
           if (  !isInit )
           {
           const RenderSystem *renderer = Root::getSingleton(   ).getRenderSystem(   );
           if (  renderer )
           {
           const RenderSystemCapabilities* caps = renderer->getCapabilities(   );
           hasVertexShader = caps->hasCapability(  RSC_VERTEX_PROGRAM ) && !(  StringUtil::startsWith(  caps->getMaxFragmentProgramVersion (   ),   "vs_1_0",   true ) );
           hasVertexShader = caps->hasCapability(  RSC_BLENDING ) && !(  StringUtil::startsWith(  caps->getMaxFragmentProgramVersion (   ),   "vs_1_0",   true ) );
           hasFragmentShader = caps->hasCapability(  RSC_FRAGMENT_PROGRAM );
           const String &maxShaderVersion = caps->getMaxFragmentProgramVersion (   );
           hasFragmentShader2 = hasFragmentShader && !(  maxShaderVersion == "ps_1_1" || maxShaderVersion == "ps_1_0" );
           numTextureUnits = caps->getNumTextureUnits (   );
           isRenderGL = StringUtil::startsWith(  renderer->getName(   ),   "OpenGL",   false );
           isInit = true;
           }
           }
           }
           //-----------------------------------------------------------------------
     232   void PagingLandScapeOptions::loadcfg (  const String &filename,   ConfigFile& config )
           {
           std::ifstream fs;
           fs.open(  filename.c_str(   ),   std::ios::in | std::ios::binary );
           if (  fs )
           {
           // Wrap as a stream
           DataStreamPtr stream(  
           new FileStreamDataStream(  filename,   &fs,   false ) );
          
           config.load(  stream );
          
           }
           else
           {
           // otherwise try resource system
           DataStreamPtr stream =
           ResourceGroupManager::getSingleton(   ).openResource(  filename );
          
           config.load(  stream );
           }
           }
           //-----------------------------------------------------------------------
     255   bool PagingLandScapeOptions::load(  const String &filename )
           {
           ConfigFile config;
           loadcfg(  filename,   config );
           return load(  filename,   config );
           }
           //-----------------------------------------------------------------------
     262   bool PagingLandScapeOptions::load(  DataStreamPtr &stream )
           {
           ConfigFile config;
           config.load(  stream );
           return load(  stream->getName (   ),   config );
           }
           //-----------------------------------------------------------------------
     269   bool PagingLandScapeOptions::load(  const String &filename,   ConfigFile& config )
           {
           init(   );
          
           // Set up the options :
           // List of map associated with map names.
           // or directly a map.
          
          
           if (  config.getSetting (  "DefaultMap" ).empty(   ) )
           {
           mConfig = &config;
           mCurrentMap = filename;
           loadMapOptions (  filename );
           return true;
           }
           else
           {
           // Go through all sections & settings in the file
           ConfigFile::SettingsIterator setIt = config.getSettingsIterator(   );
           while (  setIt.hasMoreElements(   ) )
           {
           const String name = setIt.peekNextKey(   );
           const String value = setIt.getNext(   );
           mMapList.insert(  LandScapeFileNames::value_type(  name,   value ) );
           }
          
           LandScapeFileNames::iterator i = mMapList.find(  "GroupName" );
           if (  i == mMapList.end(   ) )
           {
           OGRE_EXCEPT(  Exception::ERR_ITEM_NOT_FOUND,  
           "You need to define a GroupName where to find the map definition file ",  
           "PagingLandScapeOptions::load" );
           }
           cfgGroupName = i->second;
           mMapList.erase (  i );
          
          
           i = mMapList.find(  "BatchMode" );
           if (  (  i != mMapList.end(   ) ) && (  i->second == "yes" ) )
           {
           mBatchMode = true;
           mMapList.erase (  i );
           }
           else
           {
           mBatchMode = false;
           }
          
           i = mMapList.find(  "TextureFormatDebug" );
           if (  i != mMapList.end(   ) )
           {
           TextureFormatDebug = config.getSetting(  "TextureFormatDebug" ) == "yes";
           mMapList.erase (  i );
           }
          
          
          
           i = mMapList.find(  "DefaultMap" );
           if (  i == mMapList.end(   ) )
           {
           if(   mBatchMode == false )
           {
           OGRE_EXCEPT(  Exception::ERR_ITEM_NOT_FOUND,  
           "You need to define a DefaultMap= ",  
           "PagingLandScapeOptions::load" );
           }
           }
           else
           {
           mCurrentMap = i->second;
           }
           if (  i != mMapList.end(   ) )
           mMapList.erase (  i );
          
          
          #ifndef _MAPSPLITTER
           ResourceGroupManager * const rgsm = ResourceGroupManager::getSingletonPtr(   );
          
           rgsm->initialiseResourceGroup (  cfgGroupName );
          
           LandScapeFileNames::iterator iend = mMapList.end(   );
           LandScapeFileNames::iterator itCheck = mMapList.begin(   );
           const String cfgExt(  ".cfg" );
           for (  ; itCheck != iend;  )
           {
           const String mapName (  itCheck->first );
           const String mapFileName (  itCheck->second );
           if (  
           !rgsm->resourceExists(  cfgGroupName,   mapFileName )
           &&
           !rgsm->resourceExists(  cfgGroupName,   mapFileName + cfgExt )
           &&
           !rgsm->resourceExists(  cfgGroupName,   mapName + cfgExt )
           &&
           !rgsm->resourceExists(  cfgGroupName,   mapName )
            )
           {
           mMapList.erase (  itCheck++ );
           }
           else
           {
           ++itCheck;
           }
           }
          #endif //_MAPSPLITTER
          
           if (  !mBatchMode && !StringUtil::startsWith(  mCurrentMap,   "none",   true ) )
           {
           loadMap(  mCurrentMap );
           return true;
           }
           }
          
           return false;
           }
           //-----------------------------------------------------------------------
     386   const String &PagingLandScapeOptions::getCurrentTextureFormat(   ) const
           {
           return textureFormat;
           }
           //-----------------------------------------------------------------------
     391   void PagingLandScapeOptions::setTextureFormat (  const String &format )
           {
           if (  TextureFormatSupported.end(   ) == std::find(  TextureFormatSupported.begin(   ),  
           TextureFormatSupported.end(   ),  
           format ) )
           {
           TextureFormatSupported.push_back (  format );
           }
           textureFormat = format;
           // sort of debugging hack til BigImage itself becomes a chunked Lod thing.
           BigImage = BigImage && textureFormat == "Image";
           }
           //-----------------------------------------------------------------------
     404   void PagingLandScapeOptions::insertTextureFormat (  const String &format )
           {
           if (  TextureFormatSupported.end(   ) == std::find(  TextureFormatSupported.begin(   ),  
           TextureFormatSupported.end(   ),  
           format ) )
           {
           TextureFormatSupported.push_back (  format );
           }
           }
          
           //-----------------------------------------------------------------------
     415   LandScapeFileNames& PagingLandScapeOptions::getMapList(   )
           {
           return mMapList;
           }
           //-----------------------------------------------------------------------
     420   const String& PagingLandScapeOptions::getPreviousMapName(   ) const
           {
           if (  !mMapList.empty (   ) )
           {
           if (  StringUtil::startsWith(  mCurrentMap,   "none",   true ) )
           return mMapList.rbegin(   )->first;
           LandScapeFileNames::const_reverse_iterator iend = mMapList.rend(   );
           LandScapeFileNames::const_reverse_iterator i = mMapList.rbegin(   );
           for (  ; i != iend; ++i )
           {
           if (  i->first == mCurrentMap || i->second == mCurrentMap )
           {
           ++i;
           if (  i == iend )
           i = mMapList.rbegin(   );
           return i->first;
           }
           }
           }
           return StringUtil::BLANK;
           }
           //-----------------------------------------------------------------------
     442   const String& PagingLandScapeOptions::getNextMapName(   ) const
           {
           if (  !mMapList.empty (   ) )
           {
           if (  StringUtil::startsWith(  mCurrentMap,   "none",   true ) )
           return mMapList.begin(   )->first;
          
           LandScapeFileNames::const_iterator iend = mMapList.end(   );
           LandScapeFileNames::const_iterator i = mMapList.begin(   );
           for (  ; i != iend; ++i )
           {
           if (  i->first == mCurrentMap || i->second == mCurrentMap )
           {
           ++i;
           if (  i == iend )
           i = mMapList.begin(   );
           return i->first;
           }
           }
           }
           return StringUtil::BLANK;
           }
           //-----------------------------------------------------------------------
     465   const String& PagingLandScapeOptions::getCurrentMapName(   ) const
           {
           return mCurrentMap;
           }
           //-----------------------------------------------------------------------
     470   void PagingLandScapeOptions::setCurrentMapName(  const String& mapName )
           {
           if (  StringUtil::BLANK != mapName )
           {
           LandScapeFileNames::iterator ifind = mMapList.find (  mapName );
           if (  ifind == mMapList.end(   ) )
           {
           mMapList.insert(  LandScapeFileNames::value_type(  mapName,   mapName ) );
           }
           mCurrentMap = mapName;
           }
           loadMap(  mapName );
           }
           //-----------------------------------------------------------------------
     484   void PagingLandScapeOptions::loadMap(  const String& mapName )
           {
           ConfigFile config;
           mConfig = &config;
           const String fileMapName (  getMapFilename(  mapName ) +
           (  StringUtil::endsWith(  mapName,   ".cfg",   true ) ? StringUtil::BLANK : String(  ".cfg" ) ) );
           if (  !cfgGroupName.empty (   ) )
           {
           std::vector<Ogre::String>::iterator itFileSystem = mResourceFilesystem.begin(   );
           for(  ; itFileSystem != mResourceFilesystem.end(   ); ++itFileSystem )
           {
           ResourceGroupManager::getSingleton(   ).removeResourceLocation(  
           *itFileSystem,   cfgGroupName );
           }
           std::vector<Ogre::String>::iterator itZip = mResourceZip.begin(   );
           for(  ; itZip != mResourceZip.end(   ); ++itZip )
           {
           ResourceGroupManager::getSingleton(   ).removeResourceLocation(  
           *itZip,   cfgGroupName );
           }
           // Set up the options For a Map
           mConfig->load (  fileMapName,   cfgGroupName,   String(  "=" ),   true );
           }
           else
           {
           mConfig->load (  fileMapName,   ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME,   String(  "=" ),   true );
           }
           /* Set up the options For a Map*/
           loadMapOptions (  fileMapName );
           }
           //-----------------------------------------------------------------------
     515   const String &PagingLandScapeOptions::getMapFilename(  const String &currMapName ) const
           {
           LandScapeFileNames::const_iterator i = mMapList.find(  currMapName );
           LandScapeFileNames::const_iterator iEnd = mMapList.end(   );
           if (  i != iEnd )
           return i->second;
          
          
           for (  i = mMapList.begin(   ); i != iEnd; ++i )
           {
           if (  StringUtil::match(  i->second,   currMapName,   false ) ||
           StringUtil::match(  i->first,   currMapName,   false ) )
           {
           return i->second;
           }
           }
           return currMapName;
           }
           //-----------------------------------------------------------------------
     534   void PagingLandScapeOptions::insertMap(  const String& mapName )
           {
           LandScapeFileNames::iterator ifind = mMapList.find (  mapName );
           if (  ifind == mMapList.end(   ) )
           {
           mMapList.insert(  LandScapeFileNames::value_type(  mapName,   mapName ) );
           }
           }
           //-----------------------------------------------------------------------
     543   bool PagingLandScapeOptions::setUint (  unsigned int &u,   const String &ValuetoGet )
           {
           const String valString = mConfig->getSetting(  ValuetoGet );
           if (  !valString.empty(   ) )
           {
           u = static_cast<unsigned int> (  StringConverter::parseReal(  valString ) );
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
     554   bool PagingLandScapeOptions::setBool (  bool &b,   const String &ValuetoGet )
           {
           const String valString = mConfig->getSetting (  ValuetoGet );
           if (  !valString.empty(   ) )
           {
           b = StringUtil::startsWith(  valString,   "yes",   true );
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
     565   bool PagingLandScapeOptions::setReal (  Real &r,   const String &ValuetoGet )
           {
           const String valString = mConfig->getSetting(  ValuetoGet );
           if (  !valString.empty(   ) )
           {
           const Ogre::Real val = StringConverter::parseReal(  valString );
           r = val;
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
     577   bool PagingLandScapeOptions::setColourValue(  ColourValue &r,   const String &ValuetoGet )
           {
           const String valString = mConfig->getSetting(  ValuetoGet );
           if (  !valString.empty(   ) )
           {
           const ColourValue val = StringConverter::parseColourValue(  valString );
           r = val;
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
     589   bool PagingLandScapeOptions::setString (  String &s,   const String &ValuetoGet )
           {
           const String val = mConfig->getSetting (  ValuetoGet );
           if (  !val.empty(   ) )
           {
           s = val;
           return true;
           }
           return false;
           }
           //-----------------------------------------------------------------------
     600   void PagingLandScapeOptions::loadMapOptions(  const String& mapName )
           {
           unsigned int i;
          
           init (   );
           setDefault (   );
          
           ///By Ember start
           // Set up the options For a Map
           ConfigFile config;
           config.load (  mapName,   cfgGroupName,   String(  "=" ),   true );
           mConfig = &config;
           ///By Ember end
          
          
           // Set up the dimensions For a Map
           #if !defined(  _MAPSPLITTER ) && !defined(  _MAPEDITOR )
          
           setUint (  world_height,   "Height" );
           setUint (  world_width,   "Width" );
           if (  world_width == 0 || world_height == 0 )
           {
           OGRE_EXCEPT(  1,  
           "Your map must at least have a width and height defined in the config file ",  
           "PagingLandScapeOptions::loadMapOptions" );
           }
           #endif // !defined(  _MAPSPLITTER ) && !defined(  _MAPEDITOR )
          
          
           setUint (  PageSize,   "PageSize" );
           setUint (  TileSize,   "TileSize" );
          
           invPageSizeMinusOne = 1.0 / (  PageSize - 1 );
           invTileSizeMinusOne = 1.0 / (  TileSize - 1 );
          
           NumTiles = static_cast<unsigned int> (  static_cast <Real> (  PageSize ) / (  TileSize - 1 ) );
           NumPages = static_cast<unsigned int> (  static_cast <Real> (  world_height * world_width ) );
           const unsigned int totalNumTiles = NumPages * (  NumTiles*NumTiles ) + 1;
          
           ///EMBER: added for ember,   since we never want the scale to be different from the page size
           scale.x = scale.z = PageSize;
           scale.y = 1;
          // setReal (  scale.x,   "ScaleX" );
          // setReal (  scale.y,   "ScaleY" );
          // setReal (  scale.z,   "ScaleZ" );
          
           setReal(   position.x,   "PositionX" );
           setReal(   position.y,   "PositionY" );
           setReal(   position.z,   "PositionZ" );
          
           // secret tweak helping joining tile using vertex compression
           // leads to texture distortion at page breaks otherwise.
           const double scalemodif = 1.0f;//static_cast <double> (  PageSize - 1 ) / PageSize;
           ScaledPageSizeX = scale.x * scalemodif;
           ScaledPageSizeZ = scale.z * scalemodif;
           ScaledHeightY = scale.y / 65535;
          
           setReal (  TextureStretchFactor,   "TextureStretchFactor" );
          
          #if !defined(  _MAPSPLITTER ) && !defined(  _MAPEDITOR )
          
           // Scale x/z relative to page size
           scale.x /= (  PageSize - 1 );
           scale.z /= (  PageSize - 1 );
          
          #else// defined(  _MAPSPLITTER ) || defined(  _MAPEDITOR )
           //scale.y = scale.y;
           scale.x /= (  PageSize - 1 ) * TextureStretchFactor;
           scale.z /= (  PageSize - 1 ) * TextureStretchFactor;
          
          #endif// defined(  _MAPSPLITTER ) || defined(  _MAPEDITOR )
          
           invScale.x = 1 / scale.x;
           invScale.y = 1 / scale.y;
           invScale.z = 1 / scale.z;
          
           maxUnScaledZ = world_height * (  PageSize - 1 ) * 0.5f;
           maxUnScaledX = world_width * (  PageSize - 1 ) * 0.5f;
          
           maxScaledZ = scale.z * maxUnScaledZ;
           maxScaledX = scale.x * maxUnScaledX;
          
          
           // Set up the names For a Map
          
           setString (  groupName,   "GroupName" );
          
           if (  !setString (  LandScape_filename,   "HeightMapFileName" ) )
           setString (  LandScape_filename,   "LandScapeFileName" );
          
           if (  !setString (  TerrainName,   "TerrainName" ) )
           TerrainName = LandScape_filename;
          
           //add Resources Group to Ogre if needed.
           StringVector mResourceFilesystem = mConfig->getMultiSetting(  "FileSystem" );
           std::vector<Ogre::String>::iterator itFileSystem = mResourceFilesystem.begin(   );
           for(  ; itFileSystem != mResourceFilesystem.end(   ); ++itFileSystem )
           {
           String resourceFileSystem = *itFileSystem;
           String BasePath,   FilePath;
           StringUtil::splitFilename(  resourceFileSystem,   BasePath,   FilePath );
           if (  StringUtil::endsWith (  BasePath,   "terrainname",   true ) )
           {
           BasePath = TerrainName;
           }
           else if (  StringUtil::endsWith (  BasePath,   "landscapefilename",   true ) )
           {
           BasePath = LandScape_filename;
           }
           else if (  StringUtil::endsWith (  BasePath,   "landscapeexportfilename",   true ) )
           {
           BasePath = LandScape_export_filename;
           }
          
           if (  !cfgGroupName.empty(   ) && FilePath.empty (   ) && !mapName.empty(   ) )
           {
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo(  
           cfgGroupName,  
           mapName );
           FilePath = (  finfo->begin(   ) != finfo->end(   ) )? (  finfo->begin(   ) )->archive->getName(   ) : ".";
           }
           if (  !FilePath.empty (   ) )
           {
          
           FilePath = FilePath + "/";
           }
          
           ResourceGroupManager::getSingleton(   ).addResourceLocation(  
           FilePath + BasePath,   "FileSystem",   groupName );
           }
          
          
           StringVector mResourceZip = mConfig->getMultiSetting(  "Zip" );
           std::vector<Ogre::String>::iterator itZip = mResourceZip.begin(   );
           for(  ; itZip != mResourceZip.end(   ); ++itZip )
           {
           String resourceZip = *itZip;
          
           if (  resourceZip != StringUtil::BLANK )
           {
           ResourceGroupManager::getSingleton(   ).addResourceLocation(  
           resourceZip,   "Zip",   groupName );
           }
           }
          
           if (  !setString (  LandScape_filename,   "HeightMapFileName" ) )
           setString (  LandScape_filename,   "LandScapeFileName" );
          
           if (  !setString (  LandScape_export_filename,   "LandScapeExportFileName" ) )
           LandScape_export_filename = LandScape_filename;
          
           if (  !setString (  LandScape_extension,   "HeightMapExtension" ) )
           setString (  LandScape_extension,   "LandScapeExtension" );
          
           if (  !setString (  LandScape_export_extension,   "HeightMapExportExtension" ) )
           setString (  LandScape_export_extension,   "LandScapeExportExtension" );
          
          
           if (  !setString (  TextureExtension,   "ImageExtension" ) )
           if (  !setString (  TextureExtension,   "ColorMapExtension" ) )
           setString (  TextureExtension,   "TextureExtension" );
          
           if (  !setString (  TextureExportExtension,   "ImageExportExtension" ) )
           if (  !setString (  TextureExportExtension,   "ColorMapExportExtension" ) )
           setString (  TextureExportExtension,   "TextureExportExtension" );
          
           ImageNameLoad = setString (  image_filename,   "ImageFilename" );
           if (  !ImageNameLoad )
           ImageNameLoad = setString (  image_filename,   "ColorMapFileName" );
          
           // Set up the data source For a Map
          
           setString (  data2DFormat,   "Data2DFormat" );
          
           bool HeightField = StringUtil::endsWith(  data2DFormat,   "HeightField",   false );
           bool HeightFieldN = StringUtil::endsWith(  data2DFormat,   "HeightFieldN",   false );
           bool HeightFieldTC = StringUtil::endsWith(  data2DFormat,   "HeightFieldTC",   false );
           bool HeightFieldNTC = StringUtil::endsWith(  data2DFormat,   "HeightFieldNTC",   false );
           bool HeightFieldRawTC = StringUtil::endsWith(  data2DFormat,   "HeightFieldRawC",   false );
           bool HeightFieldRaw = StringUtil::endsWith(  data2DFormat,   "HeightFieldRaw",   false );
          
          
           if (  StringUtil::endsWith(  LandScape_extension,   "raw",   true ) )
           {
           isRaw = true;
           setUint (  RawHeight,   "RawHeight" );
           setUint (  RawWidth,   "RawWidth" );
          
           if (  HeightField || HeightFieldN )
           {
           data2DFormat = "HeightFieldRaw";
           HeightField = false;
           HeightFieldN = false;
           HeightFieldRaw = true;
           }
           else if (  HeightFieldTC || HeightFieldNTC )
           {
           data2DFormat = "HeightFieldRawTC";
           HeightFieldTC = false;
           HeightFieldNTC = false;
           HeightFieldRawTC = true;
           }
           }
           else
           isRaw = false;
          
           if (  HeightFieldRawTC
           || HeightFieldTC
           || HeightFieldNTC )
           {
           setUint (  maxValue,   "MaxValue" );
           maxValue *= static_cast<unsigned int>(  scale.y );
           setUint (  minValue,   "MinValue" );
           minValue *= static_cast<unsigned int>(  scale.y );
           }
           else
           {
           maxValue = static_cast<unsigned int> (  scale.y );
           minValue = 0;
           }
          
           setBool (  materialPerPage,   "MaterialPerPage" );
           setBool (  textureModifiable,   "TextureModifiable" );
           setBool(  mUseLodMapCache,   "UseLodMapCache" );
          
           setBool(  roughnessLod,   "RoughnessLod" );
          
          
          
           // Set up the splatting options For a Map
          
           setUint (  NumMatHeightSplat,   "NumMatHeightSplat" );
           matHeight.reserve (  NumMatHeightSplat );
           matHeight.resize (  NumMatHeightSplat );
           matColor.reserve (  NumMatHeightSplat );
           matColor.resize (  NumMatHeightSplat );
           SplatDetailMapNames.reserve (  NumMatHeightSplat );
           SplatDetailMapNames.resize (  NumMatHeightSplat );
          
           // Init to 0.0f for lazy config files omitting some.
           for (  i = 0; i < NumMatHeightSplat; i++ )
           {
           matHeight[i] = 0.0f;
           }
           const Ogre::Real divider = (  maxValue - minValue ) / (  100.0f );
           for (  i = 0; i < NumMatHeightSplat; i++ )
           {
           setReal (  matHeight[i],  
           "MaterialHeight" + StringConverter::toString(  i ) );
           matHeight[i] *= divider;
           }
          
           const String baseSplatName (  "SplatFilename" );
           for (  i = 0; i < NumMatHeightSplat; i++ )
           setString (  SplatDetailMapNames[i],  
           baseSplatName + StringConverter::toString (  i ) );
           getAvgColors (   );
          
           Ogre::Real MaterialDistanceLod = 0.0f;
           setReal (  MaterialDistanceLod,  "MaterialDistanceLod" );
           if (  MaterialDistanceLod != 0.0f )
           {
           lodMaterialDistanceList.clear(   );
           lodMaterialDistanceList.push_back (  MaterialDistanceLod );
           }
          
          #ifndef _MAPSPLITTER
          
           // PLUGIN OPTIONS ONLY
          
           // Set up the vertexes options For a Map
          
           setBool (  colored,   "VertexColors" );
           setBool (  coverage_vertex_color,   "CoverageVertexColor" );
           setBool (  base_vertex_color,   "BaseVertexColor" );
           setBool (  vertex_shadowed,   "BaseVertexShadow" );
           setBool (  vertex_instant_colored,   "BaseVertexInstantColor" );
          
           // ensure combination are correct
           if (  vertex_shadowed )
           vertex_instant_colored = true;
          
           if (  coverage_vertex_color || base_vertex_color
            )// || vertex_shadowed || vertex_instant_colored )
           colored = true;
          
           // Set up the paging options For a Map
          
           setUint (  num_renderables,   "MaxNumRenderables" );
           num_renderables = (  totalNumTiles < num_renderables )?totalNumTiles:num_renderables;
           setUint (  num_renderables_increment,   "IncrementRenderables" );
          
           setUint (  num_tiles,   "MaxNumTiles" );
           num_tiles = (  totalNumTiles < num_tiles )? totalNumTiles : num_tiles;
           setUint (  num_tiles_increment,   "IncrementTiles" );
          
          
           setUint (  num_renderables_loading,   "NumRenderablesLoading" );
           setUint (  RenderableLoadInterval,   "RenderableLoadInterval" );
          
           setUint (  max_adjacent_pages,   "MaxAdjacentPages" );
           setUint (  max_preload_pages,   "MaxPreloadedPages" );
           setUint (  PageLoadInterval,   "PageLoadInterval" );
          
           // Set up the LOD options For a Map
           setUint (  maxRenderLevel,   "MaxRenderLevel" );
           if (  maxRenderLevel == 100 )
           {
           maxRenderLevel = 0;
           const unsigned int halftileSize = static_cast<unsigned int>(  TileSize * 0.5f );
           while (  static_cast<unsigned int> (  (  1 << maxRenderLevel ) ) < halftileSize  )
           maxRenderLevel++;
           }
          
          
           setReal (  change_factor,   "ChangeFactor" );
           change_factor *= (  static_cast <Real> (  PageSize * (  scale.z + scale.x ) * 0.5f ) / 9 );
          
           // Set up the distance options For a Map
          
           setReal (  visible_renderables,   "VisibleRenderables" );
          
           // compute the actual distance as a square
           // Factor is a Tile distance squared
           const Ogre::Real Factor = TileSize * scale.x * TileSize * scale.z;
          
          
           // max distance upon which renderables are not rendered anymore
           renderable_factor = visible_renderables * Factor;
           //renderable_factor *= renderable_factor;
          
           //setReal (  cameraThreshold,   "CameraThreshold" );
           // To avoid the use of a square root.
           //cameraThreshold *= cameraThreshold;
           cameraThreshold = (  (  scale.x < scale.z  ) ? TileSize * scale.x : TileSize * scale.z ) * 0.25;
          
           setReal (  distanceLOD,   "DistanceLOD" );
           // Compute the actual distance as a square
           LOD_factor = distanceLOD * Factor;
           loadMapInfo(   );
          
           setBool (  lit,   "VertexLit" );
           setBool (  normals,   "VertexNormals" );
          
           setBool (  Deformable,   "Deformable" );
           if (  !Deformable )
           saveDeformation = false;
           else
           setBool (  saveDeformation,   "SaveDeformation" );
          
           //Morphing
           if (  maxRenderLevel > 1 )
           {
           setBool (  lodMorph,   "VertexProgramMorph" );
           setReal (  lodMorphStart,   "LODMorphStart" );
           }
           setUint (  maxPixelError,   "MaxPixelError" );
          
          
           setBool (  BigImage,   "BigImage" );
           setBool (  VisMap,   "HorizonVisibilityComputing" );
           setBool (  MaxLodUnderCam,   "MaxLodUnderCam" );
           setBool (  VertexCompression,   "VertexCompression" );
           VertexCompression = VertexCompression && hasVertexShader;
          
          
           setUint (  NumTextureFormatSupported,   "NumTextureFormatSupported" );
           TextureFormatSupported.reserve (  NumTextureFormatSupported );
           TextureFormatSupported.resize (  NumTextureFormatSupported );
           for (  i = 0; i < NumTextureFormatSupported; i++ )
           {
           setString (  TextureFormatSupported[i],   "TextureFormatSupported" + StringConverter::toString(  i ) );
           }
           String tempTexformat;
           setString (  tempTexformat,   "TextureFormat" );
           // must be after getting supported formats
           setTextureFormat (  tempTexformat );
          
           setUint (  TileInvisibleUnloadFrames,   "TileInvisibleUnloadFrames" );
           setUint (  PageInvisibleUnloadFrames,   "PageInvisibleUnloadFrames" );
          
          
           setReal (  BaseCameraViewpoint.x,   "BaseCameraViewpoint.x" );
           setReal (  BaseCameraViewpoint.y,   "BaseCameraViewpoint.y" );
           setReal (  BaseCameraViewpoint.z,   "BaseCameraViewpoint.z" );
          
           setReal (  Baselookat.x,   "Baselookat.x" );
           setReal (  Baselookat.y,   "Baselookat.y" );
           setReal (  Baselookat.z,   "Baselookat.z" );
          
          
           ResourceGroupManager::getSingleton(   ).initialiseResourceGroup (  groupName );
          #else
          
           // MAP TOOL OPTIONS ONLY
          
           setBool (  Paged,   "Paged" );
          
           setString (  OutDirectory,   "OutDirectory" );
          
           String BasePath,   FilePath;
           StringUtil::splitFilename(  OutDirectory,   BasePath,   FilePath );
           if (  StringUtil::endsWith (  BasePath,   "landscapefilename",   true ) )
           {
           BasePath = LandScape_filename;
           }
           if (  StringUtil::endsWith (  BasePath,   "landscapeexportfilename",   true ) )
           {
           BasePath = LandScape_export_filename;
           }
           if (  FilePath.empty(   ) )
           {
           //Get cfg current Directory
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           cfgGroupName,   mapName );
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           FilePath = (  it )->archive->getName(   );
           }
           }
           if (  StringUtil::endsWith (  FilePath,   "/",   true ) )
           {
           FilePath.resize (  FilePath.size(   ) - 1 );
           }
           OutDirectory = FilePath + "/" + BasePath;
          
           setBool (  MiniMap,   "MiniMap" );
           setBool (  BaseMap,   "BaseMap" );
          
          
           setBool (  ColorMapGenerate,   "ColorMapGenerate" );
          
           if (  !setBool (  ColorMapSplit,   "ImageSplit" ) )
           setBool (  ColorMapSplit,   "ColorMapSplit" );
          
           setBool (  LightMap,   "LightMap" );
           setBool (  NormalMap,   "NormalMap" );
           setBool (  HeightMap,   "HeightMap" );
           setBool (  AlphaMaps,   "AlphaMaps" );
           setBool (  LitBaseMap,   "LitBaseMap" );
           setBool (  InfiniteMap,   "InfiniteMap" );
           setBool (  CoverageMap,   "CoverageMap" );
           setBool (  LitColorMapGenerate,   "LitColorMapGenerate" );
          
           if (  !setBool (  LitColorMapSplit,   "LitImageSplit" ) )
           setBool (  LitColorMapSplit,   "LitColorMapSplit" );
          
           setBool (  HeightNormalMap,   "HeightNormalMap" );
          
           if (  !setString (  ColorMapName,   "ImageFileName" ) )
           if (  !setString (  ColorMapName,   "ColorMapFileName" ) )
           setString (  ColorMapName,   "ColorMapName" );
          
           if (  (  BaseMap || CoverageMap || AlphaMaps )
           && NumMatHeightSplat == 0 )
           OGRE_EXCEPT (  Exception::ERR_INVALIDPARAMS,  
           "Generating a texture set from a heightmap needs some MaterialHeights in cfg file.",  
           "PagingLandScapeData2D_HeightField::getScale" );
          
           setReal (  HeightMapBlurFactor,   "HeightMapBlurFactor" );
          
           setReal (  Sun.x,   "Sunx" );
           setReal (  Sun.y,   "Suny" );
           setReal (  Sun.z,   "Sunz" );
          
          
           setReal (  Amb,   "Ambient" );
           setReal (  Diff,   "Diffuse" );
           setUint (  Blur,   "Blur" );
          
           setBool (  Equalize,   "Equalize" );
           setBool (  ZHorizon,   "ZHorizon" );
          
           setBool (  SRTM_water,   "SRTM_water" );
          
           setUint (  MiniMapHeight,   "MiniMapHeight" );
           setUint(  MiniMapWidth,   "MiniMapWidth" );
          
          
           setUint (  NumSplatMapToSplit,   "NumSplatMapToSplit" );
           SplatMapNames.reserve (  NumSplatMapToSplit );
           SplatMapNames.resize (  NumSplatMapToSplit );
          
           for (  i = 0; i < NumSplatMapToSplit; i++ )
           {
           setString (  SplatMapNames[i],   "SplatMapName" + StringConverter::toString(  i ) );
           }
           #endif
           }
           //-----------------------------------------------------------------------
    1092   void PagingLandScapeOptions::calculateCFactor(   )
           {
           // ConstOgre::Real A = 1 / Math::Tan(  Math::AngleUnitsToRadians(  opts.primaryCamera->getFOVy(   ) ) );
           // Turn off detail compression at higher FOVs
           const Ogre::Real A = 1.0f;
          
           assert (  primaryCamera );
           const Viewport *v = primaryCamera->getViewport(   );
           if (  v )
           {
           const int vertRes = v->getActualHeight(   );
          
           assert (  vertRes != 0 );
          
           const Ogre::Real T = 2 * static_cast <Ogre::Real > (  maxPixelError ) / vertRes;
          
           if (  T != 0 )
           CFactor = A / T;
           else
           CFactor = A * vertRes * 0.5f;
           }
           }
           //-----------------------------------------------------------------------
    1115   void PagingLandScapeOptions::setPrimaryCamera(  PagingLandScapeCamera *cam )
           {
           primaryCamera = cam;
           if (  cam && cam->getViewport(   ) )
           calculateCFactor (   );
           }
           //-----------------------------------------------------------------------
    1122   bool PagingLandScapeOptions::setOption(  const String& strKey,   const void* pValue )
           {
           if (  strKey == "saveDeformation" )
           {
           saveDeformation = * static_cast < const bool * > (  pValue );
           return true;
           }
           if (  strKey == "MaxLodUnderCam" )
           {
           MaxLodUnderCam = * static_cast < const bool * > (  pValue );
           return true;
           }
          // if (  strKey == "VisibleRenderables" )
          // {
          // visible_renderables = * static_cast < const int * > (  pValue );
          // // compute the actual distance as a square
          // Ogre::Real Factor = TileSize;
          // Factor = Factor * scale.x * Factor * scale.z;
          //
          // renderable_factor = visible_renderables * Factor;
          // return true;
          // }
           if (  strKey == "DistanceLOD" )
           {
           distanceLOD = * static_cast < const Ogre::Real * > (  pValue );
           // Compute the actual distance as a square
           Ogre::Real Factor = TileSize;
           Factor = Factor * scale.x * Factor * scale.z;
           LOD_factor = distanceLOD * Factor;
           return true;
           }
           if (  strKey == "Sun" )
           {
           Sun = * static_cast < const Ogre::Vector3 * > (  pValue );
           lightmoved = true;
           return true;
           }
           if (  strKey == "SunAngle" )
           {
           SunAngle = * static_cast < const Ogre::Real * > (  pValue );
           lightmoved = true;
           return true;
           }
           if (  strKey == "Width" )
           {
           world_width = * static_cast < const unsigned int * > (  pValue ) ;
          #ifndef _MAPSPLITTER
          #ifndef _MAPEDITOR
           assert (  primaryCamera );
           static_cast <PagingLandScapeSceneManager *> (  primaryCamera->getSceneManager(   ) )->WorldDimensionChange(   );
          
          #endif //_MAPEDITOR
          #endif //_MAPSPLITTER
           return true;
           }
           if (  strKey == "Height" )
           {
           world_height = * static_cast < const unsigned int * > (  pValue );
          #ifndef _MAPSPLITTER
          #ifndef _MAPEDITOR
           assert (  primaryCamera );
           static_cast <PagingLandScapeSceneManager *> (  primaryCamera->getSceneManager(   ) )->WorldDimensionChange(   );
          #endif //_MAPEDITOR
          #endif //_MAPSPLITTER
           return true;
           }
           if (  strKey == "WorldDimension" )
           {
           Vector2 dim = * static_cast < const Vector2 * > (  pValue );
           world_height = static_cast < unsigned int > (  dim.x );
           world_width = static_cast < unsigned int > (  dim.y );
           #ifndef _MAPSPLITTER
           #ifndef _MAPEDITOR
           assert (  primaryCamera );
           static_cast <PagingLandScapeSceneManager *> (  primaryCamera->getSceneManager(   ) )->WorldDimensionChange(   );
           #endif //_MAPEDITOR
           #endif //_MAPSPLITTER
           return true;
           }
           if (  strKey == "primaryCamera" )
           {
           setPrimaryCamera (  const_cast < PagingLandScapeCamera * > (  static_cast < const PagingLandScapeCamera * > (  pValue ) ) );
           return true;
           }
          
           if (  strKey == "TextureNameLayer0" )
           {
           SplatDetailMapNames[0] = * static_cast < const String * > (  pValue );
           return true;
           }
           if (  strKey == "TextureNameLayer1" )
           {
           SplatDetailMapNames[1] = * static_cast < const String * > (  pValue );
           return true;
           }
           if (  strKey == "TextureNameLayer2" )
           {
           SplatDetailMapNames[2] = * static_cast < const String * > (  pValue );
           return true;
           }
           if (  strKey == "TextureNameLayer3" )
           {
           SplatDetailMapNames[3] = * static_cast < const String * > (  pValue );
           return true;
           }
          
          
           if (  strKey == "MaxAdjacentPages" )
           {
           max_adjacent_pages = * static_cast < const unsigned int * > (  pValue );
           return true;
           }
           if (  strKey == "MaxPreloadedPages" )
           {
           max_preload_pages = * static_cast < const unsigned int * > (  pValue );
           return true;
           }
           if (  strKey == "PositionX" )
           {
           position.x = * static_cast < const Ogre::Real * > (  pValue );
           return true;
           }
           if (  strKey == "PositionY" )
           {
           position.y = * static_cast < const Ogre::Real * > (  pValue );
           return true;
           }
           if (  strKey == "PositionZ" )
           {
           position.z = * static_cast < const Ogre::Real * > (  pValue );
           return true;
           }
          
           if (  strKey == "ConfigGroupName" )
           {
           cfgGroupName = * static_cast < const String * > (  pValue );
           return true;
           }
           if (  strKey == "queryNoInterpolation" )
           {
           queryNoInterpolation = * static_cast < const bool * > (  pValue );
           return true;
           }
           if (  strKey == "queryResolutionFactor" )
           {
           queryResolutionFactor = * static_cast < const Ogre::Real * > (  pValue );
           return true;
           }
           return false;
           }
          
           //-----------------------------------------------------------------------
    1274   bool PagingLandScapeOptions::getOption(  const String& strKey,   void* pDestValue )
           {
           if (  strKey == "saveDeformation" )
           {
           * static_cast < bool * > (  pDestValue ) = saveDeformation;
           return true;
           }
           if (  strKey == "VisibleRenderables" )
           {
           * static_cast < int * > (  pDestValue ) = static_cast<int> (  visible_renderables );
           return true;
           }
           if (  strKey == "DistanceLOD" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = static_cast<Real> (  distanceLOD );
           return true;
           }
           if (  strKey == "VisibleDistance" )
           {
           // we need to return the square root of the distance
           * static_cast <Ogre::Real * > (  pDestValue ) = Math::Sqrt (  renderable_factor );
           return true;
           }
           if (  strKey == "VisibleLOD" )
           {
           // we need to return the square root of the distance
           * static_cast <Ogre::Real * > (  pDestValue ) = Math::Sqrt (  LOD_factor );
           return true;
           }
           // Some options proposed by Praetor
           if (  strKey == "Width" )
           {
           * static_cast < int * > (  pDestValue ) = world_width;
           return true;
           }
           if (  strKey == "Height" )
           {
           * static_cast < int * > (  pDestValue ) = world_height;
           return true;
           }
           if (  strKey == "MaxHeight" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = scale.y;
           return true;
           }
           if (  strKey == "PageSize" )
           {
           * static_cast < int * > (  pDestValue ) = PageSize;
           return true;
           }
           if (  strKey == "Scale" )
           {
           * static_cast < Ogre::Vector3 * > (  pDestValue ) = scale;
           return true;
           }
           if (  strKey == "ScaleX" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = scale.x;
           return true;
           }
           if (  strKey == "ScaleY" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = scale.y;
           return true;
           }
           if (  strKey == "ScaleZ" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = scale.z;
           return true;
           }
           if (  strKey == "PositionX" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = position.x;
           return true;
           }
           if (  strKey == "PositionY" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = position.y;
           return true;
           }
           if (  strKey == "PositionZ" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = position.z;
           return true;
           }
          
           if (  strKey == "TextureNameLayer0" )
           {
           * static_cast < String * > (  pDestValue ) = SplatDetailMapNames[0];
           return true;
           }
           if (  strKey == "TextureNameLayer1" )
           {
           * static_cast < String * > (  pDestValue ) = SplatDetailMapNames[1];
           return true;
           }
           if (  strKey == "TextureNameLayer2" )
           {
           * static_cast < String * > (  pDestValue ) = SplatDetailMapNames[2];
           return true;
           }
           if (  strKey == "TextureNameLayer3" )
           {
           * static_cast < String * > (  pDestValue ) = SplatDetailMapNames[3];
           return true;
           }
          
           if (  strKey == "GroupName" )
           {
           * static_cast < String * > (  pDestValue ) = groupName;
           return true;
           }
          
           if (  strKey == "BaseCameraViewpoint" )
           {
           * static_cast < Ogre::Vector3 * > (  pDestValue ) = BaseCameraViewpoint;
           return true;
           }
          
           if (  strKey == "Baselookat" )
           {
           * static_cast < Ogre::Vector3 * > (  pDestValue ) = Baselookat;
           return true;
           }
          
           if (  strKey == "MaxAdjacentPages" )
           {
           * static_cast < unsigned int * > (  pDestValue ) = max_adjacent_pages;
           return true;
           }
           if (  strKey == "MaxPreloadedPages" )
           {
           * static_cast < unsigned int * > (  pDestValue ) = max_preload_pages;
           return true;
           }
           if (  strKey == "ConfigGroupName" )
           {
           * static_cast < String * > (  pDestValue ) = cfgGroupName;
           return true;
           }
           if (  strKey == "queryNoInterpolation" )
           {
           * static_cast < bool * > (  pDestValue ) = queryNoInterpolation;
           return true;
           }
           if (  strKey == "queryResolutionFactor" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = queryResolutionFactor;
           return true;
           }
           return false;
           }
          
           //-----------------------------------------------------------------------
    1428   bool PagingLandScapeOptions::hasOption(  const String& strKey ) const
           {
           if (  strKey == "VisibleRenderables" )
           {
           return true;
           }
           if (  strKey == "DistanceLOD" )
           {
           return true;
           }
           if (  strKey == "VisibleDistance" )
           {
           return true;
           }
           if (  strKey == "VisibleLOD" )
           {
           return true;
           }
           // Some options proposed by Praetor
           if (  strKey == "Width" )
           {
           return true;
           }
           if (  strKey == "Height" )
           {
           return true;
           }
           if (  strKey == "PageSize" )
           {
           return true;
           }
           if (  strKey == "ScaleX" )
           {
           return true;
           }
           if (  strKey == "ScaleY" )
           {
           return true;
           }
           if (  strKey == "ScaleZ" )
           {
           return true;
           }
           if (  strKey == "PositionX" )
           {
           return true;
           }
           if (  strKey == "PositionY" )
           {
           return true;
           }
           if (  strKey == "PositionZ" )
           {
           return true;
           }
           return false;
           }
          
           //-----------------------------------------------------------------------
    1487   bool PagingLandScapeOptions::getOptionValues(  const String & key,   StringVector &refValueList )
           {
           // if (  key == "VisibleRenderables" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           // if (  key == "DistanceLOD" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           // if (  key == "VisibleDistance" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           // if (  key == "VisibleLOD" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           // if (  key == "Width" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           // if (  key == "Height" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           // if (  key == "PageSize" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           // if (  key == "ScaleX" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           // if (  key == "ScaleY" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           // if (  key == "ScaleZ" )
           // {
           // refValueList.push_back(  DataStreamPtr(   ) );
           // return true;
           // }
           return false;
           }
          
           //-----------------------------------------------------------------------
    1543   bool PagingLandScapeOptions::getOptionKeys(  StringVector &refKeys )
           {
           refKeys.push_back(  "VisibleRenderables" );
           refKeys.push_back(  "DistanceLOD" );
           refKeys.push_back(  "VisibleDistance" );
           refKeys.push_back(  "VisibleLOD" );
           // Some options from Praetor
           refKeys.push_back(  "Width" );
           refKeys.push_back(  "Height" );
           refKeys.push_back(  "PageSize" );
           refKeys.push_back(  "ScaleX" );
           refKeys.push_back(  "ScaleY" );
           refKeys.push_back(  "ScaleZ" );
           refKeys.push_back(  "PositionX" );
           refKeys.push_back(  "PositionY" );
           refKeys.push_back(  "PositionZ" );
           return true;
           }
           //-----------------------------------------------------------------------
    1562   void PagingLandScapeOptions::getAvgColors(   )
           {
           bool AvgColorsExists = false;
           setBool (  AvgColorsExists,   "AvgColorsExists" );
           if (  AvgColorsExists )
           {
           const String baseName (  "MaterialColor" );
           for (  unsigned int i = 0; i < NumMatHeightSplat; i++ )
           {
           const String matColorString (  baseName + StringConverter::toString (  i ) );
           setColourValue (  matColor[i],   matColorString );
           }
           }
           else
           {
           for (  unsigned int i = 0; i < NumMatHeightSplat; i++ )
           matColor[i] = _getAvgColor(  SplatDetailMapNames[i] );
           }
           }
           //-----------------------------------------------------------------------
    1582   ColourValue PagingLandScapeOptions::_getAvgColor(  const String &tex ) const
           {
           if (  tex.empty(   ) )
           return ColourValue::White;
          
           Image img;
          
           img.load (  tex,   groupName );
           const uchar * const ogre_restrict data = img.getData(   );
           if (  !data )
           {
           OGRE_EXCEPT(  Exception::ERR_ITEM_NOT_FOUND,  
           "You need to define SplatFilename that has at least 3 or 4 bytes componennts (  RGB or RGBA )",  
           "PagingLandScapeOptions::_getAvgColor" );
           }
           size_t bpp = PixelUtil::getNumElemBytes (  img.getFormat (   ) );
           if (  bpp < 3 )
           {
           OGRE_EXCEPT(  Exception::ERR_ITEM_NOT_FOUND,  
           "You need to define SplatFilename that has at least 3 or 4 bytes componennts (  RGB or RGBA )",  
           "PagingLandScapeOptions::_getAvgColor" );
           }
           int cr = 0,   cg = 0,   cb = 0,   s = 0;
           const size_t imgSize = img.getSize(   );
           for (  size_t i = 0; i < imgSize; i += bpp )
           {
           cr += data[i];
           cg += data[i+1];
           cb += data[i+2];
          
           s++;
           }
           assert (  s > 0 );
           Ogre::Real divider = 1.0f / (  s * 255 );
           return ColourValue (  cr * divider,   cg * divider,   cb * divider,   1.0f );
           }
           //-----------------------------------------------------------------------
    1619   void PagingLandScapeOptions::clearTileInfo(   )
           {
           if (  !mTileInfoCache.empty(   ) )
           {
           ///don't do thses things when run in Ember
           //assert (  mCurrentMap != "" );
           //saveMapInfo(   );
           std::for_each(  mTileInfoCache.begin (   ),  
           mTileInfoCache.end (   ),  
           delete_object(   ) );
           mTileInfoCache.clear(   );
           }
           }
           //-----------------------------------------------------------------------
    1633   PagingLandScapeTileInfo *PagingLandScapeOptions::getTileInfo(  const uint pageX,   const uint pageZ,  
    1634   const uint tileX,   const uint tileZ )
           {
           PagingLandScapeTileInfo *t = 0;
          
           std::deque<PagingLandScapeTileInfo*>::iterator q = mTileInfoCache.begin (   );
           std::deque<PagingLandScapeTileInfo*>::iterator qend = mTileInfoCache.end (   );
           while (  q != qend )
           {
           t = *q;
           if (  pageX == t->mPageX &&
           pageZ == t->mPageZ &&
           tileX == t->mTileX &&
           tileZ == t->mTileZ )
           {
           return t;
           }
           ++q;
           }
           // no info in cache.
           t = new PagingLandScapeTileInfo(  pageX,   pageZ,   tileX,   tileZ );
           setTileInfo (  t );
           return t;
           }
           //-----------------------------------------------------------------------
    1658   void PagingLandScapeOptions::setTileInfo(  PagingLandScapeTileInfo *t )
           {
           mTileInfoCache.push_back (  t );
           }
           //-----------------------------------------------------------------------
    1663   void PagingLandScapeOptions::loadMapInfo(   )
           {
           // load terrain.info.cfg into the deque.
           if (  mUseLodMapCache )
           {
           assert (  !mCurrentMap.empty (   ) );
           const String fName (  mCurrentMap + ".info.cfg" );
           if (  ResourceGroupManager::getSingleton(   ).resourceExists(  groupName,   fName ) )
           {
           ConfigFile config;
          
           config.load (  fName,   cfgGroupName,   String(  "=" ),   true );
          
           // those info are dependent of Pagesize and Tilesize.
           // if not the same as when generated...
           // we must recompute them.
           const String pageSizeString = config.getSetting(  String(  "PageSize" ) );
           if (  pageSizeString.empty(   ) || PageSize != StringConverter::parseUnsignedInt (  pageSizeString ) )
           return;
          
           const String tileSizeString = config.getSetting(  String(  "TileSize" ) );
           if (  tileSizeString.empty(   ) || TileSize != StringConverter::parseUnsignedInt (  tileSizeString ) )
           return;
          
           ConfigFile::SettingsIterator setIt = config.getSettingsIterator(   );
           const size_t numLod = maxRenderLevel;
           PagingLandScapeTileInfo *t;
           while (  setIt.hasMoreElements(   ) )
           {
           const String name = setIt.peekNextKey(   );
           const String value = setIt.getNext(   );
           if (  name != "PageSize" && name != "TileSize" )
           {
           // name to pageX,   uint pageZ,   uint tileX,   uint tileZ
           {
           std::vector<String> coordinates = StringUtil::split(  name,   "_" );
          
           const uint pageX = StringConverter::parseUnsignedInt(  coordinates[0] );
           const uint pageZ = StringConverter::parseUnsignedInt(  coordinates[1] );
           const uint tileX = StringConverter::parseUnsignedInt(  coordinates[2] );
           const uint tileZ = StringConverter::parseUnsignedInt(  coordinates[3] );
          
           t = new PagingLandScapeTileInfo(  pageX,   pageZ,   tileX,   tileZ );
           }
          
           // name to LOD roughness value.
           {
           std::vector<String> minLevelDistSqr = StringUtil::split(  value,   "_" );
           assert (  minLevelDistSqr.size (   ) == numLod );
          
           t->mMinLevelDistSqr = new std::vector<Real>(   );
          
           t->mMinLevelDistSqr->reserve(  numLod );
           t->mMinLevelDistSqr->resize(  numLod );
          
           for (  size_t i = 0; i < numLod; i++ )
           {
           (  *(  t->mMinLevelDistSqr ) )[i] = StringConverter::parseReal(  minLevelDistSqr[i] );
           }
           }
           mTileInfoCache.push_back(  t );
           }
          
           }
           }
           }
           }
           //-----------------------------------------------------------------------
    1731   void PagingLandScapeOptions::saveMapInfo(   )
           {
           if (  mUseLodMapCache )
           {
           //if(  modif ||was_empty when loaded. ) ??
          
           assert (  !mCurrentMap.empty (   ) );
           const String fInfoName (  getMapFilename(  mCurrentMap ) + ".cfg" );
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           groupName,   fInfoName );
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           // save deque into terrain.info.cfg
           const size_t numLod = maxRenderLevel;
           const String eol(  "\n" );
           const String coordinateSeparator(  "_" );
           const String valueSeparator(  "=" );
           PagingLandScapeTileInfo *t;
          
           String tilesInfo(  "" );
          
           // those info are dependent of Pagesize and Tilesize.
           // if not the same as when generated...
           // we must recompute them.
           tilesInfo += String(  "PageSize=" )+StringConverter::toString(  PageSize ) + eol;
           tilesInfo += String(  "TileSize=" )+StringConverter::toString(  TileSize ) + eol;
          
           std::deque<PagingLandScapeTileInfo*>::iterator q = mTileInfoCache.begin (   );
           std::deque<PagingLandScapeTileInfo*>::iterator qend = mTileInfoCache.end (   );
           while (  q != qend )
           {
           t = *q;
          
           if (  t->mMinLevelDistSqr )
           {
           bool notEmpty = false;
           for (  size_t i = 0; i < numLod; i++ )
           {
           if (  (  *(  t->mMinLevelDistSqr ) )[i] != 0.0f )
           {
           notEmpty = true;
           break;
           }
           }
           if (  notEmpty )
           {
           tilesInfo += StringConverter::toString(  t->mPageX ) + coordinateSeparator;
           tilesInfo += StringConverter::toString(  t->mPageZ ) + coordinateSeparator;
           tilesInfo += StringConverter::toString(  t->mTileX ) + coordinateSeparator;
           tilesInfo += StringConverter::toString(  t->mTileZ );
          
           tilesInfo += valueSeparator;
          
           for (  size_t i = 0; i < numLod; i++ )
           {
           tilesInfo += StringConverter::toString(  (  *(  t->mMinLevelDistSqr ) )[i] ) + coordinateSeparator;
           }
           tilesInfo += eol;
           }
           }
           ++q;
           }
          
          
           const String fConfigName (  mCurrentMap + ".info.cfg" );
          
           char *olddir = ChangeToDir (  const_cast< char * > (  (  (  it )->archive->getName(   ) ).c_str(   ) ) );
           std::ofstream outfile;
           outfile.open (  const_cast< char * > (  fConfigName.c_str(   ) )
           //,  std::ios:binary
            );
           // Write out
           outfile << tilesInfo;
           outfile.close (   );
          
           RetablishDir (  olddir );
           }
           }
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapePage.cpp

       1  /***************************************************************************
           OgrePagingLandScapePage.cpp - description
           -------------------
           begin : Sat Mar 08 2003
           copyright : (  C ) 2003-2006 by Jose A. Milan and Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreMovableObject.h"
          #include "OgreAxisAlignedBox.h"
          
          #include "OgreCamera.h"
          
          #include "OgreStringConverter.h"
          #include "OgreSceneNode.h"
          #include "OgreException.h"
          
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeCamera.h"
          #include "OgrePagingLandScapePageManager.h"
          #include "OgrePagingLandScapeRenderableManager.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeTileInfo.h"
          #include "OgrePagingLandScapeTile.h"
          #include "OgrePagingLandScapeTileManager.h"
          #include "OgrePagingLandScapeTextureManager.h"
          
          #include "OgrePagingLandScapePage.h"
          #include "OgrePagingLandScapePageRenderable.h"
          #include "OgrePagingLandScapeListenerManager.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          
          #include "OgrePagingLandScapeHorizon.h"
          
          namespace Ogre
          {
      53   PagingLandScapePage::PagingLandScapePage(  PagingLandScapePageManager *pageMgr ) :
           mParent (  pageMgr ),  
           mIsLoading (  false ),  
           mIsPreLoading (  false ),  
           mIsTextureLoading (  false ),  
           mIsUnloading (  false ),  
           mIsPostUnloading (  false ),  
           mIsTextureunloading (  false ),  
           mIsLoaded (  false ),  
           mIsTextureLoaded (  false ),  
           mIsPreLoaded (  false ),  
           mIsLoadable(  true ),  
           mPageNode (  0 ),  
           mRenderable(  0 )
           {
           for (  unsigned int i = 0; i < 4; i++ )
           {
           mNeighbors[i] = 0;
           }
           }
           //-----------------------------------------------------------------------
      74   PagingLandScapePage::~PagingLandScapePage(   )
           {
           }
           //-----------------------------------------------------------------------
      78   void PagingLandScapePage::init (  const unsigned int tableX,   const unsigned int tableZ )
           {
           assert (  !mIsLoading );
           assert (  !mIsPreLoading );
           assert (  !mIsTextureLoading );
           assert (  !mIsUnloading );
          
           assert (  !mIsPostUnloading );
           assert (  !mIsTextureunloading );
           assert (  !mIsLoaded );
           assert (  !mIsTextureLoaded );
           assert (  !mIsPreLoaded );
           assert (  mIsLoadable );
          
          
          
           mTableX = tableX;
           mTableZ = tableZ;
           //create a LandScape node that handles pages and tiles
           const String NodeName = "PagingLandScapePage."
           + StringConverter::toString(  mTableX ) + "." +
           StringConverter::toString(  mTableZ );
          
           mPageNode = mParent->getSceneManager(   )->createSceneNode (  NodeName + ".Node" );
          
          
           const PagingLandScapeOptions * const opt = mParent->getOptions(   );
           mNumTiles = opt->NumTiles;
          
           const unsigned int size = opt->PageSize - 1;
           // Boundaries of this page
           // the middle page is at world coordinates 0,  0
           const Real factorX = size * opt->scale.x;
           const Real factorZ = size * opt->scale.z;
          
           mIniX = static_cast<Real> (  static_cast<int> (  mTableX + mTableX - opt->world_width ) ) * 0.5f * factorX + opt->position.x;
           mIniZ = static_cast<Real> (  static_cast<int> (  mTableZ + mTableZ - opt->world_height ) ) * 0.5f * factorZ + opt->position.z;
          
           // Set node position
           mPageNode->setPosition(  static_cast<Real> (  mIniX ) ,  
           opt->position.y,  
           static_cast<Real> (  mIniZ ) );
          
           const Real EndX = mIniX + factorX;
           const Real EndZ = mIniZ + factorZ;
           const Real MaxHeight = mParent->getSceneManager(   )->getData2DManager(   )->getMaxHeight(  mTableX,   mTableZ );
           const Real chgfactor = opt->change_factor;
          
           mBounds.setExtents(  mIniX ,  
           0.0f,  
           mIniZ ,  
           EndX ,  
           MaxHeight,  
           EndZ );
          
           //Change Zone of this page
           mBoundsInt.setExtents(  mIniX + chgfactor,  
           0.0f,  
           mIniZ + chgfactor,  
           EndX - chgfactor,  
           MaxHeight,  
           EndZ - chgfactor  );
          
          
           mBoundsExt.setExtents(  mIniX - factorX * 1.5f,  
           - MaxHeight * 1.5f,  
           mIniZ - factorZ * 1.5f,  
          
           mIniX + factorX * 1.5f,  
           MaxHeight * 1.5f ,  
           mIniZ + factorZ * 1.5f );
          
           mWorldPosition = mBounds.getCenter(   );
          
          
          
           if (  opt->BigImage )
           {
           mRenderable = new PagingLandScapePageRenderable(  mParent,  
           mPageNode->getName (   ) + "rend",  
           mTableX,   mTableZ,  
           mBounds );
           mPageNode->attachObject(  mRenderable );
           mRenderable->load (   );
           }
          
           PagingLandScapePageManager * const pageMgr = mParent;
           PagingLandScapePage *n;
           n = pageMgr->getPage (  tableX,   tableZ + 1,   false );
           _setNeighbor(  SOUTH,   n );
           if (  n )
           n->_setNeighbor(  NORTH,   this );
          
           n = pageMgr->getPage (  tableX,   tableZ - 1,   false );
           _setNeighbor(  NORTH,   n );
           if (  n )
           n->_setNeighbor(  SOUTH,   this );
          
           n = pageMgr->getPage (  tableX + 1,   tableZ,   false );
           _setNeighbor(  EAST,   n );
           if (  n )
           n->_setNeighbor(  WEST,   this );
          
           n = pageMgr->getPage (  tableX - 1,   tableZ,   false );
           _setNeighbor(  WEST,   n );
           if (  n )
           n->_setNeighbor(  EAST,   this );
          
           mVisible = false;
          
           touch (   );
           }
           //-----------------------------------------------------------------------
     191   void PagingLandScapePage::uninit (   )
           {
           postUnload (   );
           assert (  mTiles.empty(   ) );
          
           if (  mParent->getOptions(   )->BigImage )
           {
           mPageNode->detachObject (  mRenderable->getName(   ) );
           delete mRenderable;
           }
          
           assert (  mPageNode );
           mPageNode->removeAndDestroyAllChildren (   );
           mParent->getSceneManager(   )->destroySceneNode (  mPageNode->getName (   ) );
           mPageNode = 0;
          
          
           PagingLandScapePage *n = mNeighbors[NORTH];
           if (  n )
           {
           n->_setNeighbor(  SOUTH,   0 );
           mNeighbors[NORTH] = 0;
           }
           n = mNeighbors[SOUTH];
           if (  n )
           {
           n->_setNeighbor(  NORTH,   0 );
           mNeighbors[SOUTH] = 0;
           }
           n = mNeighbors[EAST];
           if (  n )
           {
           n->_setNeighbor(  WEST,   0 );
           mNeighbors[EAST] = 0;
           }
           n = mNeighbors[WEST];
           if (  n )
           {
           n->_setNeighbor(  EAST,   0 );
           mNeighbors[WEST] = 0;
           }
           // restore init state.
           mIsLoading = false;
           mIsPreLoading = false;
           mIsTextureLoading = false;
          
           mIsUnloading = false;
           mIsPostUnloading = false;
           mIsTextureunloading = false;
          
           mIsLoaded = false;
           mIsTextureLoaded = false;
           mIsPreLoaded = false;
          
           mIsLoadable = true;
           }
           //-----------------------------------------------------------------------
     248   void PagingLandScapePage::_setNeighbor(  const Neighbor& n,   PagingLandScapePage* p )
           {
           mNeighbors[ n ] = p;
          
           const bool thisLoaded = mIsLoaded;
           const bool neighLoaded = p && p->isLoaded(   ) && p->isLoadable(   );
          
           if (  !thisLoaded && !neighLoaded )
           return;
          
           assert (  !thisLoaded || (  thisLoaded && !mTiles.empty(   ) ) );
           const unsigned int numTiles = mNumTiles;
           switch (  n )
           {
           case EAST:
           {
           const unsigned int i = numTiles - 1;
           for (  unsigned int j = 0; j < numTiles; j++ )
           {
           PagingLandScapeTile *t_nextpage = 0;
           PagingLandScapeTile *t_currpage = 0;
           if (  thisLoaded )
           t_currpage = mTiles[ i ][ j ];
           if (  neighLoaded )
           t_nextpage = p->getTile (  0 ,   j );
           if (  thisLoaded )
           t_currpage->_setNeighbor(  EAST,   t_nextpage );
           if (  neighLoaded )
           t_nextpage->_setNeighbor(  WEST,   t_currpage );
           }
          
           }
           break;
           case WEST:
           {
           const unsigned int i = numTiles - 1;
           for (  unsigned int j = 0; j < numTiles; j++ )
           {
           PagingLandScapeTile *t_nextpage = 0;
           PagingLandScapeTile *t_currpage = 0;
           if (  thisLoaded )
           t_currpage = mTiles[ 0 ][ j ];
           if (  neighLoaded )
           t_nextpage = p->getTile (  i ,   j );
           if (  thisLoaded )
           t_currpage->_setNeighbor(  WEST,   t_nextpage );
           if (  neighLoaded )
           t_nextpage->_setNeighbor(  EAST,   t_currpage );
           }
           }
           break;
           case NORTH:
           {
           const unsigned int j = numTiles - 1;
           for (  unsigned int i = 0; i < numTiles; i++ )
           {
           PagingLandScapeTile *t_nextpage = 0;
           PagingLandScapeTile *t_currpage = 0;
           if (  thisLoaded )
           t_currpage = mTiles[ i ][ 0 ];
           if (  neighLoaded )
           t_nextpage = p->getTile (  i ,   j );
           if (  thisLoaded )
           t_currpage->_setNeighbor(  NORTH,   t_nextpage );
           if (  neighLoaded )
           t_nextpage->_setNeighbor(  SOUTH,   t_currpage );
           }
           }
           break;
           case SOUTH:
           {
           const unsigned int j = numTiles - 1;
           for (  unsigned int i = 0; i < numTiles; i++ )
           {
           PagingLandScapeTile *t_nextpage = 0;
           PagingLandScapeTile *t_currpage = 0;
           if (  thisLoaded )
           t_currpage = mTiles[ i ][ j ];
           if (  neighLoaded )
           t_nextpage = p->getTile (  i ,   0 );
           if (  thisLoaded )
           t_currpage->_setNeighbor(  SOUTH,   t_nextpage );
           if (  neighLoaded )
           t_nextpage->_setNeighbor(  NORTH,   t_currpage );
           }
           }
           break;
           default:
           break;
           }
           }
           //-----------------------------------------------------------------------
     340   void PagingLandScapePage::setMapMaterial(   )
           {
           if (  mParent->getOptions(   )->BigImage )
           {
           mRenderable->setMaterial (  mParent->getSceneManager(   )->getTextureManager(   )->getMapMaterial(   ) );
           }
           }
           //-----------------------------------------------------------------------
     348   void PagingLandScapePage::touch (   )
           {
           mTimeUntouched = mParent->getOptions(   )->PageInvisibleUnloadFrames;
           }
           //-----------------------------------------------------------------------
     353   const bool PagingLandScapePage::unloadUntouched (   )
           {
           if (  mTimeUntouched == 0 )
           return true;
           mTimeUntouched--;
           return false;
           }
           //-----------------------------------------------------------------------
     361   void PagingLandScapePage::preload(   )
           {
           touch (   );
          
           if (  mIsPreLoaded )
           return;
          
           mIsLoadable = mParent->getSceneManager(   )->getData2DManager(   )->load (  mTableX,   mTableZ );
          
           mIsPreLoaded = true;
          
           mParent->getSceneManager(   )->getListenerManager(   )->firePagePreloaded(  mTableX,   mTableZ,  
           mParent->getSceneManager(   )->getData2DManager(   )->getData2D(  mTableX,   mTableZ )->getHeightData(   ),  
           mBounds );
           }
           //-----------------------------------------------------------------------
     377   void PagingLandScapePage::loadTexture(   )
           {
           touch (   );
           if (  !mIsPreLoaded )
           preload (   );
           if (  !mIsTextureLoaded )
           {
           if (  mIsLoadable )
           mParent->getSceneManager(   )->getTextureManager(   )->load(  mTableX,   mTableZ );
           mIsTextureLoaded = true;
           }
           }
           //-----------------------------------------------------------------------
     390   void PagingLandScapePage::load(   )
           {
           touch (   );
           if (  mIsLoaded )
           return;
           if (  !mIsPreLoaded )
           preload (   );
           if (  !mIsTextureLoaded )
           loadTexture (   );
          
           assert (  mTiles.empty(   ) );
          
           //mVisibletouch = 0;
           mIsLoaded = true;
           //mPageNode->showBoundingBox (  true ) ;
           if (  mIsLoadable )
           {
           const unsigned int numTiles = mNumTiles;
           unsigned int i,   j;
          
           mTiles.reserve (  numTiles );
           mTiles.resize (  numTiles );
          
           for (  i = 0; i < numTiles; ++i )
           {
           mTiles[i].reserve (  numTiles );
           mTiles[i].resize (  numTiles );
           }
          
           PagingLandScapeTile *tile;
           PagingLandScapeTileManager * const tileMgr = mParent->getSceneManager(   )->getTileManager(   );
           for (  i = 0; i < numTiles; ++i )
           {
           for (  j = 0; j < numTiles; ++j )
           {
           //char name[ 24 ];
           //sprintf(  name,   "page[%d,  %d][%d,  %d]",   mTableX,   mTableZ,   i,   j );
          
           tile = tileMgr->getTile (   );
           assert (  tile );
           mTiles[ i ][ j ] = tile;
           tile->init (  mPageNode,   mTableX,   mTableZ,   i,   j );
           }
           }
           for (  i = 0; i < numTiles; ++i )
           {
           for (  j = 0; j < numTiles; ++j )
           {
           if (  j != numTiles - 1 )
           {
           mTiles[ i ][ j ]-> _setNeighbor(  SOUTH,   mTiles[ i ][ j + 1 ] );
           mTiles[ i ][ j + 1 ] ->_setNeighbor(  NORTH,   mTiles[ i ][ j ] );
           }
           if (  i != numTiles - 1 )
           {
           mTiles[ i ][ j ]->_setNeighbor(  EAST,   mTiles[ i + 1 ][ j ] );
           mTiles[ i + 1 ][ j ]->_setNeighbor(  WEST,   mTiles[ i ][ j ] );
           }
           }
           }
          
           PagingLandScapePageManager * const pageMgr = mParent;
           PagingLandScapePage *n;
          
           n = pageMgr->getPage (  mTableX,   mTableZ + 1,   false );
           _setNeighbor(  SOUTH,   n );
           if (  n )
           n->_setNeighbor(  NORTH,   this );
          
           n = pageMgr->getPage (  mTableX,   mTableZ - 1,   false );
           _setNeighbor(  NORTH,   n );
           if (  n )
           n->_setNeighbor(  SOUTH,   this );
          
           n = pageMgr->getPage (  mTableX + 1,   mTableZ,   false );
           _setNeighbor(  EAST,   n );
           if (  n )
           n->_setNeighbor(  WEST,   this );
          
           n = pageMgr->getPage (  mTableX - 1,   mTableZ,   false );
           _setNeighbor(  WEST,   n );
           if (  n )
           n->_setNeighbor(  EAST,   this );
          
           }
          
           mParent->getSceneManager(   )->getListenerManager(   )->firePageLoaded(  mTableX,   mTableZ,  
           mParent->getSceneManager(   )->getData2DManager(   )->getData2D(  mTableX,   mTableZ )->getHeightData(   ),  
           mBounds );
          
           _Show(  true );
           }
          
           //-----------------------------------------------------------------------
     484   void PagingLandScapePage::unload(   )
           {
           if (  mIsLoaded )
           {
          
           assert (  !mTiles.empty(   ) );
          
           // must be 0 to make sure page is really set as non visible
           //mVisibletouch = 0;
           //if (  mVisible )
           _Show (  false );
          
           // Unload the Tiles
           PagingLandScapeTiles::iterator iend = mTiles.end(   );
           for (  PagingLandScapeTiles::iterator it = mTiles.begin(   );
           it != iend;
           ++it )
           {
          
           std::for_each(  it->begin (   ),  
           it->end (   ),  
           std::mem_fun(  &PagingLandScapeTile::uninit ) );
          
           it->clear(   );
           }
           mTiles.clear(   );
           assert (  mTiles.empty(   ) );
          
           mIsLoaded = false;
          
           mParent->getSceneManager(   )->getListenerManager(   )->firePageUnloaded(  mTableX,   mTableZ,  
           mParent->getSceneManager(   )->getData2DManager(   )->getData2D(  mTableX,   mTableZ )->getHeightData(   ),  
           mBounds );
           assert (  mPageNode );
           assert (  mPageNode->getParent (   ) == 0 );
          
           }
           }
           //-----------------------------------------------------------------------
     523   void PagingLandScapePage::unloadTexture(   )
           {
           unload(   );
           if (  mIsTextureLoaded )
           {
           if (  mIsLoadable )
           mParent->getSceneManager(   )->getTextureManager(   )->unload(  mTableX,   mTableZ );
           mIsTextureLoaded = false;
           }
           }
           //-----------------------------------------------------------------------
     534   void PagingLandScapePage::postUnload(   )
           {
           unloadTexture (   );
           if (  mIsPreLoaded )
           {
           mIsPreLoaded = false;
          
           if (  mIsLoadable )
           mParent->getSceneManager(   )->getData2DManager(   )->unload(  mTableX,   mTableZ );
          
           mParent->getSceneManager(   )->getListenerManager(   )->firePagePostunloaded (  mTableX,   mTableZ );
           }
           }
          
           //-----------------------------------------------------------------------
     549   int PagingLandScapePage::isCameraIn(  const Vector3 & pos ) const
           {
           if (  mBounds.intersects(  pos ) )
           {
           if (  mBoundsInt.intersects(  pos ) )
           {
           // Full into this page
           return PAGE_INSIDE;
           }
           else
           {
           // Over the change zone
           return PAGE_CHANGE;
           }
           }
           else
           {
           // Not in this page
           return PAGE_OUTSIDE;
           }
           }
           //-----------------------------------------------------------------------
     571   void PagingLandScapePage::_Show(  const bool do_show )
           {
           assert (  mPageNode );
           if (  do_show )
           {
           assert (  !mVisible );
          
           if (  !mPageNode->getParent (   ) )
           mParent->getSceneManager(   )->getRootSceneNode(   )->addChild (  mPageNode );
          
           mParent->getSceneManager(   )->getListenerManager(   )->firePageShow (  mTableX,   mTableZ,  
           mParent->getSceneManager(   )->getData2DManager(   )->getData2D(  mTableX,   mTableZ )->getHeightData(   ),  
           mBounds );
          
           if (  mIsLoadable )
           {
           unsigned int i,  k;
           for (  i = 0; i < mNumTiles; ++i )
           {
           PagingLandScapeTileRow &tr = mTiles[ i ];
           for (  k = 0; k < mNumTiles; ++k )
           {
           tr[ k ]->setInUse(  true );
           }
           }
           }
           mVisible = true;
           }
           else if (  mVisible )
           {
           assert (  do_show == false );
           //if (  mVisibletouch == 0 )
           {
           if (  mPageNode->getParent (   ) )
           mParent->getSceneManager(   )->getRootSceneNode(   )->removeChild (  mPageNode->getName (   ) );
          
           mParent->getSceneManager(   )->getListenerManager(   )->firePageHide (  mTableX,   mTableZ,  
           mParent->getSceneManager(   )->getData2DManager(   )->getData2D(  mTableX,   mTableZ )->getHeightData(   ),  
           mBounds );
           if (  mIsLoadable )
           {
           unsigned int i,  k;
           for (  i = 0; i < mNumTiles; ++i )
           {
           PagingLandScapeTileRow &tr = mTiles[ i ];
           for (  k = 0; k < mNumTiles; ++k )
           {
           tr[ k ]->setInUse (  false );
           }
           }
           }
           mVisible = false;
           }
           //else
           //{
           // mVisibletouch--;
           //}
           }
           }
           //-----------------------------------------------------------------------
     631   bool PagingLandScapePage::_Notify(  const Vector3 &pos,   const PagingLandScapeCamera * const Cam )
           {
           if (  mIsLoaded && mIsLoadable )
           {
           // (  (  pos - mWorldPosition ).squaredLength(   ) < mParent->getOptions(   )->page_factor ?
           if (  
           1
           //Cam->isVisible (  mBoundsExt )
           //&&
           // if we use an Horizon Visibility Map
           //(   !(  mParent->getOptions(   )->VisMap )
           // || (  mParent->getOptions(   )->VisMap
           // && mParent->getSceneManager(   )->getHorizon(   )->IsPageVisible (  Cam,   mTableX,   mTableZ ) ) )
          
            )
           {
           touch(   );
           //if (  !mVisible )
           // _Show (  true );
           //mVisibletouch = 30;
           for (  unsigned int i = 0; i < mNumTiles; i++ )
           {
           PagingLandScapeTileRow &tr = mTiles[ i ];
           for (  unsigned int k = 0; k < mNumTiles; k++ )
           {
           tr[ k ]->_Notify(  pos,   Cam );
           }
           }
           return true;
           }
           else if (  mVisible )
           {
           // if it was visible it needs to change its state
           //_Show (  false );
           return false;
           }
           }
           return false;
           }
          
           //-----------------------------------------------------------------------
     672   PagingLandScapeTile *PagingLandScapePage::getTile(  const Vector3& pos )
           {
           if (  mIsLoaded && mIsLoadable )
           {
           const unsigned int x = static_cast<unsigned int> (  pos.x / mParent->getOptions(   )->scale.x / (  mParent->getOptions(   )->TileSize ) );
           const unsigned int z = static_cast<unsigned int> (  pos.z / mParent->getOptions(   )->scale.z / (  mParent->getOptions(   )->TileSize ) );
          
           assert (  mTiles[x][z] && mTiles[x][z]-> isLoaded (   ) );
           return mTiles[x][z];
           }
           return 0;
           }
           //-------------------------------------------------------------------------
     685   void PagingLandScapePage::_updateLod(   )
           {
           if (  mIsLoaded && mIsLoadable )
           {
           unsigned int i,  k;
           for (  i = 0; i < mNumTiles; ++i )
           {
           PagingLandScapeTileRow &tr = mTiles[ i ];
           for (  k = 0; k < mNumTiles; ++k )
           {
           PagingLandScapeTile *t = tr[ k ];
           if (  t->isVisible(   ) )
           t->_updateLod(   );
           }
           }
           }
           }
           //-------------------------------------------------------------------------
     703   void PagingLandScapePage::setRenderQueue(  uint8 qid )
           {
           if (  mVisible &&
           mIsLoadable )
           {
           unsigned int i,  k;
           for (  i = 0; i < mNumTiles; ++i )
           {
           PagingLandScapeTileRow &tr = mTiles[ i ];
           for (  k = 0; k < mNumTiles; ++k )
           {
           PagingLandScapeTile *t = tr[ k ];
           if (  t->isVisible(   ) )
           t->setRenderQueueGroup(  qid );
           }
           }
           }
           }
           //-------------------------------------------------------------------------
     722   PagingLandScapeTile* PagingLandScapePage::getTile(  const unsigned int i ,   const unsigned int j ) const
           {
           if (  mIsLoaded )
           {
           assert (  !mTiles.empty(   ) );
          
           assert (  i < mParent->getOptions(   )->NumTiles );
           assert (  j < mParent->getOptions(   )->NumTiles );
          
           assert (  i < mTiles.size(   ) );
           assert (  j < mTiles[i].size(   ) );
          
           return mTiles[i][j];
           }
           return 0;
           }
          
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapePageManager.cpp

       1  /***************************************************************************
           OgrePagingLandScapePageManager.cpp - description
           -------------------
           begin : Sat May 01 2004
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreMovableObject.h"
          #include "OgreAxisAlignedBox.h"
          
          #include "OgreCamera.h"
          
          
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeCamera.h"
          #include "OgrePagingLandScapePage.h"
          #include "OgrePagingLandScapePageManager.h"
          #include "OgrePagingLandScapeTileManager.h"
          #include "OgrePagingLandScapeRenderableManager.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeTextureManager.h"
          #include "OgrePagingLandScapeTexture.h"
          #include "OgrePagingLandScapeTileInfo.h"
          #include "OgrePagingLandScapeTile.h"
          #include "OgrePagingLandScapeRenderable.h"
          #include "OgrePagingLandScapeListenerManager.h"
          #include "OgrePagingLandScapePageRenderable.h"
          #include "OgrePagingLandScapeHorizon.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      49   PagingLandScapePageManager::PagingLandScapePageManager(  PagingLandScapeSceneManager * scnMgr ) :
           mSceneManager(  scnMgr ),  
           mOptions(  scnMgr->getOptions(   ) ),  
           mData2d(  scnMgr->getData2DManager(   ) ),  
           mTexture(  scnMgr->getTextureManager(   ) ),  
           mRenderablesMgr(  scnMgr->getRenderableManager(   ) ),  
           mWidth(  0 ),  
           mHeight(  0 ),  
           mNextQueueFrameCount(  0 ),  
           mPause(  99 ),  
           mCurrentcam(  0 ),  
           mTerrainReady(  false ),  
           mTimePreLoaded(  0 ),  
           mRenderQueueGroupID (  static_cast<Ogre::RenderQueueGroupID>(  scnMgr->getWorldGeometryRenderQueue(   ) ) ),  
           //mRenderQueueGroupID (  RENDER_QUEUE_WORLD_GEOMETRY_2 ),  
           mPageLoadInterval (  mOptions->PageLoadInterval ),  
           mOnFrame(  false ),  
           mEnabled(  false )
           {
           mPagePool.clear(   );
           mActivePages.clear(   );
           mFreePages.clear(   );
           }
           //-----------------------------------------------------------------------
      73   PagingLandScapePageManager::~PagingLandScapePageManager(  void )
           {
           reset(   );
           // could save a delete if texture type is the same... ?
           if (  !mPagePool.empty(   ) )
           {
           std::for_each (  mPagePool.begin (   ),   mPagePool.end (   ),  
           delete_object (   ) );
           mPagePool.clear(   );
           mFreePages.clear(   );
           }
           }
           //-----------------------------------------------------------------------
      86   void PagingLandScapePageManager::reset(  void )
           {
           std::for_each(  mActivePages.begin(   ),   mActivePages.end(   ),  
           std::mem_fun(  &PagingLandScapePage::uninit ) );
          
           // Insert actives into free list
           mFreePages.insert(  mFreePages.end(   ),   mActivePages.begin(   ),   mActivePages.end(   ) );
           // Remove all active instances
           mActivePages.clear(   );
          
           mPageLoadQueue.clear(   );
           mPagePreloadQueue.clear(   );
           mPageTextureloadQueue.clear(   );
          
           mLoadedPages.clear(   );
           mTextureLoadedPages.clear(   );
           mPreLoadedPages.clear(   );
          
           mWidth = 0;
           mHeight = 0;
           mOnFrame = false;
           mEnabled = false;
           }
           //-----------------------------------------------------------------------
     110   void PagingLandScapePageManager::load(  void )
           {
           WorldDimensionChange (   );
           mEnabled = true;
           }
           //-----------------------------------------------------------------------
     116   void PagingLandScapePageManager::clear(  void )
           {
           // before calling the scene manager node clearing
           reset(   );
           }
           //-----------------------------------------------------------------------
     122   void PagingLandScapePageManager::WorldDimensionChange(  void )
           {
           const unsigned int newWidth = mOptions->world_width;
           const unsigned int newHeight = mOptions->world_height;
          
           reset(   );
          
           mPageLoadInterval = mOptions->PageLoadInterval;
           mWidth = newWidth;
           mHeight = newHeight;
           }
           //-----------------------------------------------------------------------
     134   void PagingLandScapePageManager::setMapMaterial(  void )
           {
           std::for_each(  mActivePages.begin(   ),   mActivePages.end(   ),  
           std::mem_fun(  &PagingLandScapePage::setMapMaterial ) );
           }
           //-----------------------------------------------------------------------
     140   void PagingLandScapePageManager::_updateLod(  void )
           {
           PagingLandScapePageList::iterator lend = mLoadedPages.end(   );
           for (  PagingLandScapePageList::iterator l = mLoadedPages.begin(   ); l != lend; ++l )
           {
           (  *l )->_updateLod(   );
           }
           }
           //-----------------------------------------------------------------------
     149   bool PagingLandScapePageManager::frameStarted(  const FrameEvent& evt )
           {
           if (  mEnabled )//if not queued to be removed from framelistener or Paused
           {
           --mTimePreLoaded;
           if (  mOptions->VisMap )
           {
           mSceneManager->getHorizon (   )->prepare(  static_cast< PagingLandScapeCamera* >(  mOptions->primaryCamera ) );
           }
           mOnFrame = false;
           }
           return true;
           }
           //-----------------------------------------------------------------------
     163   bool PagingLandScapePageManager::frameEnded(  const FrameEvent& evt )
           {
           // mOnFrame If This Frame has seen any Camera,  
           // We won't unload anything.
           // since un-focusing rendering may make this method unload all renderables.
           // mEnabled sm paused or frame listener queued for deletion
           if (  !mOnFrame || !mEnabled )
           return true;
          
           // unload some pages if no more in use
           processUnloadQueues(   );
           // load some pages that are still queued
           processLoadQueues(   );
          
           if (  !mTerrainReady &&
           mPagePreloadQueue.empty(   ) &&
           mPageLoadQueue.empty(   ) &&
           mPageTextureloadQueue.empty(   ) )
           {
           mSceneManager->getListenerManager(   )->fireTerrainReady(   );// no more to load
           mTerrainReady = true;
           }
          
           if (  mOptions->VisMap )
           mSceneManager->getHorizon(   )->update(   );
          
           mSceneManager->getTileManager(   )->unloadUntouched(   );
           mRenderablesMgr->resetVisibles(   );
           return true;
           }
           //-----------------------------------------------------------------------
     194   PagingLandScapePage *PagingLandScapePageManager::getNewPage(  const unsigned int x,   const unsigned int z )
           {
           PagingLandScapePage *p;
          
           // should we resize page pool
           if (  mFreePages.empty(   ) )
           {
           const size_t pool_size = mPagePool.size (   );
           const size_t new_pool_size = (  pool_size == 0 ) ? 9 : pool_size * 2;
          
           mPagePool.reserve(  new_pool_size );
           mPagePool.resize(  new_pool_size );
          
           // Create new pages
           for (  size_t i = pool_size; i < new_pool_size; ++i )
           {
           p = new PagingLandScapePage (  this );
           mPagePool[i] = p;
           mFreePages.push_back (  p );
           }
           }
          
           // Get a pre-allocated new page.
           p = mFreePages.front (   );
           mFreePages.pop_front (   );
           mActivePages.push_back (  p );
          
           p->init (  x,   z );
          
           return p;
           }
           //-----------------------------------------------------------------------
     226   void PagingLandScapePageManager::releasePage(  PagingLandScapePage *p )
           {
           removeFromQueues (  p );
           p->uninit (   );
           mActivePages.remove (  p );
           mFreePages.push_back (  p );
           }
           //-----------------------------------------------------------------------
     234   PagingLandScapePage *PagingLandScapePageManager::getPage(  const unsigned int x,   const unsigned int z,  
     235   const bool alwaysReturn )
           {
           if (  x < mWidth && z < mHeight )
           {
           if (  !mActivePages.empty(   ) )
           {
           PagingLandScapePageList::iterator l,   lend = mActivePages.end(   );
           for (  l = mActivePages.begin(   ); l != lend; ++l )
           {
           if (  (  *l )->isCoord(  x,   z ) )
           return (  *l );
           }
           }
           if (  alwaysReturn )
           return getNewPage(  x,   z );
           }
           assert (  !alwaysReturn );
           return 0;
           }
           //-----------------------------------------------------------------------
     255   void PagingLandScapePageManager::LoadFirstPage(  PagingLandScapeCamera* cam )
           {
          
           const Vector3 CamPos = cam->getDerivedPosition(   );
           //gets page indices (  if outside Terrain gets nearest page )
           unsigned int i,   j;
           getPageIndices (  CamPos.x,   CamPos.z,   i,   j,   true );
           // update the camera page position
           // does modify mIniX,   mFinX,   mIniZ,   mFinZ
          
           PagingLandScapePage *p = getPage (  i,   j );
           makePageLoadedNow (  p );
           }
           //-----------------------------------------------------------------------
     269   void PagingLandScapePageManager::makePageLoadedNow(  PagingLandScapePage * p )
           {
           // Have the current page be loaded now !
           if (  !p->isLoaded(   ) )
           {
           // remove from lists it does belongs to
           if (  p->isTextureLoaded(   ) )
           mTextureLoadedPages.remove (  p );
           else if (  p->isPreLoaded(   ) )
           mPreLoadedPages.remove (  p );
           // remove from queue it does belongs to
           removeFromQueues (  p );
          
           p->load(   );
           assert (   std::find(  mLoadedPages.begin(   ),   mLoadedPages.end(   ),   p ) == mLoadedPages.end(   ) );
           mLoadedPages.push_back (  p );
           // make sure this brutal loading doesn't impact on fps
           mNextQueueFrameCount = mPageLoadInterval;
           }
           else
           {
           p->touch (   );
           }
           }
          
           //-----------------------------------------------------------------------
     295   void PagingLandScapePageManager::updateLoadedPages(   )
           {
           PagingLandScapeCamera * const cam = mCurrentcam;
          
           // Make any pending updates to the calculated frustum
           cam->updateView(   );
          
           const Vector3 pos (  cam->getDerivedPosition(   ).x,   127.0f,  cam->getDerivedPosition(   ).z );
           // hide page not visible by this Camera
           // Notify those Page (  update tile vis/ rend load on cam distance )
           // update Page Texture if needed
          
           const unsigned int iniX = cam->mIniX;
           const unsigned int finX = cam->mFinX;
          
           const unsigned int iniZ = cam->mIniZ;
           const unsigned int finZ = cam->mFinZ;
          
           PagingLandScapePage *p;
           const bool lightchange = mOptions->lightmoved;
           PagingLandScapePageList::iterator l,   lend = mLoadedPages.end (   );
           for (  l = mLoadedPages.begin (   ); l != lend; ++l )
           {
           p = (  *l );
           unsigned int x,   z;
           p->getCoordinates (  x,   z );
           if (  (  z >= iniZ ) && (  z <= finZ ) && (  x >= iniX ) && (  x <= finX ) )
           {
           // inform pages we are near Camera on next render.
           if (  p->_Notify (  pos,   cam ) )
           {
           // get pages that needs modification and Are visible..
           PagingLandScapeTexture * const tex = mTexture->getTexture(  x,   z );
           assert(  tex );
           if (  lightchange )
           tex->lightUpdate(   );
           if (  tex->needUpdate(   ) )
           tex->update(   );
           }
           }
           else
           {
           p->_Show (  false );
           }
           }
          
          
          
           if (  lightchange )
           mOptions->lightmoved = false;
           }
           //-----------------------------------------------------------------------
     347   void PagingLandScapePageManager::loadNow(  PagingLandScapeCamera *cam )
           {
           updatePaging (  cam );
           const Vector3 pos (  cam->getDerivedPosition(   ).x,   127.0f,   cam->getDerivedPosition(   ).z );
           while (  !mTerrainReady ||
           !mPagePreloadQueue.empty(   ) ||
           !mPageLoadQueue.empty(   ) ||
           !mPageTextureloadQueue.empty(   ) )
           {
           processLoadQueues(   );// fill pages queues
           updateLoadedPages(   );// fill tiles queues
           mTerrainReady = mRenderablesMgr->executeRenderableLoading(  pos ); // load renderables
           mNextQueueFrameCount = -1;
           }
           //assert (   )
           }
           //-----------------------------------------------------------------------
     364   void PagingLandScapePageManager::queuePageNeighbors(   )
           {
           const PagingLandScapeCamera * const cam = mCurrentcam;
           // Queue the rest
           // Loading must be done one by one to avoid FPS drop,   so they are queued.
           // We must load the next visible LandScape pages,  
           // check the LandScape boundaries
          
           const unsigned int preIniX = cam->mPreIniX;
           const unsigned int preFinX = cam->mPreFinX;
          
           const unsigned int preIniZ = cam->mPreIniZ;
           const unsigned int preFinZ = cam->mPreFinZ;
          
           const unsigned int iniX = cam->mIniX;
           const unsigned int finX = cam->mFinX;
          
           const unsigned int iniZ = cam->mIniZ;
           const unsigned int finZ = cam->mFinZ;
          
           PagingLandScapePage *p;
           for (  unsigned int i = preIniX; i <= preFinX; i++ )
           {
           for (  unsigned int j = preIniZ; j <= preFinZ; j++ )
           {
           // pages here,   in this zone around camera,  
           // must be at least preloading.
           // that means they can be loaded too.
           p = getPage (  i,   j,   true );
          
           if (  !(  p->mIsLoading || p->isLoaded(   ) ) )
           {
           if(  (  j >= iniZ ) && (  j <= finZ ) && (  i >= iniX ) && (  i <= finX ) )
           {
           // pages here,   in this tighter zone around camera,  
           // must be Loading or Loaded as they may
           // be below camera very soon.
           removeFromQueues (  p );
           mPageLoadQueue.push (  p );
           p->mIsLoading = true;
           }
           else if (  !p->mIsTextureLoading &&
           !p->isTextureLoaded(   ) &&
           !p->mIsPreLoading &&
           !p->isPreLoaded(   ) )
           {
           // must be at least preloading.
           removeFromQueues (  p );
           mPagePreloadQueue.push (  p );
           p->mIsPreLoading = true;
           }
           }
           p->touch (   );
           }
           }
           mTimePreLoaded = mPageLoadInterval;
           }
           //-----------------------------------------------------------------------
     422   void PagingLandScapePageManager::updatePaging(  PagingLandScapeCamera *cam )
           {
           mCurrentcam = cam;
           // Here we have to look if we have to load,   unload any of the LandScape Pages
           // Fix from Praetor,   so the camera used gives you "world-relative" coordinates
           // make sure in the bounding box of LandScape
           const Vector3 pos (  cam->getDerivedPosition(   ).x,  
           127.0f,  
           cam->getDerivedPosition(   ).z );
          
           //updateStats(  pos );
          
           bool need_touch = false;//(  mTimePreLoaded < 0 );
          
           if (  mWidth == 0 && mHeight == 0 ) {
           //just return if we haven't got any world yet
           return;
           }
          
           if (  cam->mLastCameraPos != pos
           && (  mOptions->cameraThreshold < fabs (  cam->mLastCameraPos.x - pos.x ) ||
           mOptions->cameraThreshold < fabs (  cam->mLastCameraPos.z - pos.z ) ) )
           {
           // Update only if the camera was moved
           PagingLandScapePage * const oldPage = getPage (  cam->mCurrentCameraPageX,   cam->mCurrentCameraPageZ,   false );
           PagingLandScapeTile * const oldTile = (  oldPage && oldPage->isLoaded(   ) ?
           oldPage->getTile (  cam->mCurrentCameraTileX,   cam->mCurrentCameraTileZ ) : 0 );
          
           unsigned int i,   j;
          
           //gets page indices (  if outside Terrain gets nearest page )
           getPageIndices (  pos.x,   pos.z,   i,   j,   true );
           PagingLandScapePage *p = getPage (  i,   j );
          
           if (  !p ) {
           return;
           }
           makePageLoadedNow (  p );
          
           // update current Cam Page info
           if (  oldPage != p )
           {
           // update the camera info :
           cam->updatePaging(  i,   j );
           // need to inform neighbors pages
           need_touch = true;
           }
          
           // Update current Cam Tile info.
           if (  p->isLoadable(   ) )
           {
           PagingLandScapeTile * const t = getTile (  pos.x,   pos.z,   i,   j,   true );
           if (  t && t != oldTile )
           {
           if (  mOptions->MaxLodUnderCam )
           {
           // reset previous tile at normal LOD mechanism.
           if (  oldTile && oldTile->isLoaded(   ) )
           {
           assert (  oldTile->getRenderable(   ) );
           oldTile->getRenderable(   )->setMaxLod (  false );
           }
           // set current tile at max LOD whatever complexity it is.
           if (  t->isLoaded(   ) )
           {
           assert (  t->getRenderable(   ) );
           t->getRenderable(   )->setMaxLod (  true );
           }
           }
          
           PagingLandScapeTileInfo * const CurrentTileInfo = t->getInfo(   );
           cam->mCurrentCameraTileX = CurrentTileInfo->mTileX;
           cam->mCurrentCameraTileZ = CurrentTileInfo->mTileZ;
           }
           }
           // Update the last camera position
           if (  mOptions->cameraThreshold < fabs (  cam->mLastCameraPos.x - pos.x ) )
           cam->mLastCameraPos.x = pos.x;
           if (  mOptions->cameraThreshold < fabs (  cam->mLastCameraPos.z - pos.z ) )
           cam->mLastCameraPos.z = pos.z;
           }
          
           if (  need_touch )
           queuePageNeighbors(   );
           updateLoadedPages(   );
           //if (  mNextQueueFrameCount < 0 )
           mRenderablesMgr->executeRenderableLoading(  pos );
          
           // This Frame has seen a Camera.
           mOnFrame = true;
           }
           //-----------------------------------------------------------------------
     514   void PagingLandScapePageManager::processUnloadQueues(   )
           {
           // Check for pages that need to be unloaded.
           // if touched,   that means they didn't have been touch by any cameras
           // for several frames and thus need to be unloaded.
           PagingLandScapePage *p;
           // LIST CHECKS
           PagingLandScapePageList::iterator itl;
           for (  itl = mPreLoadedPages.begin (   ); itl != mPreLoadedPages.end (   ); )
           {
           if (  (  *itl )->unloadUntouched (   ) )
           {
           p = *itl;
           releasePage (  p );
           itl = mPreLoadedPages.erase (  itl );
           }
           else
           {
           ++itl;
           }
           }
           for (  itl = mTextureLoadedPages.begin (   ); itl != mTextureLoadedPages.end (   ); )
           {
           if (  (  *itl )->unloadUntouched (   ) )
           {
           p = *itl;
           releasePage (  p );
           itl = mTextureLoadedPages.erase (  itl );
           }
           else
           {
           ++itl;
           }
           }
           for (  itl = mLoadedPages.begin (   ); itl != mLoadedPages.end (   ); )
           {
           if (  (  *itl )->unloadUntouched (   ) )
           {
           p = *itl;
           releasePage (  p );
           itl = mLoadedPages.erase (  itl );
           }
           else
           {
           ++itl;
           }
           }
          
           // QUEUES CHECKS
           // check queues for page that need to be excluded from queues
           PagingLandScapeQueue<PagingLandScapePage>::MsgQueType::iterator itq;
           for (  itq = mPagePreloadQueue.begin (   ); itq != mPagePreloadQueue.end (   ); )
           {
           assert (  !(  *itq )->isLoaded(   ) && !(  *itq )->isPreLoaded(   ) && !(  *itq )->isTextureLoaded(   ) );
           assert (  !(  *itq )->mIsLoading && !(  *itq )->mIsTextureLoading );
           if (  (  *itq )->unloadUntouched (   ) )
           {
           p = *itq;
           // remove from queue
           p->mIsPreLoading = false;
           itq = mPagePreloadQueue.erase (  itq );
           // remove from active pages
           //(  must be removed from queue first )
           releasePage (  p );
           }
           else
           {
           ++itq;
           }
           }
           for (  itq = mPageTextureloadQueue.begin(   ); itq != mPageTextureloadQueue.end(   ); )
           {
           assert (  !(  *itq )->isLoaded(   ) && (  *itq )->isPreLoaded(   ) && !(  *itq )->isTextureLoaded(   ) );
           assert (  !(  *itq )->mIsLoading && (  *itq )->mIsTextureLoading && !(  *itq )->mIsPreLoading );
           if (  (  *itq )->unloadUntouched (   ) )
           {
           p = *itq;
           // remove from queue
           p->mIsTextureLoading = false;
           itq = mPageTextureloadQueue.erase (  itq );
           // remove from active pages
           //(  must be removed from queue first )
           releasePage (  p );
           }
           else
           {
           ++itq;
           }
           }
           for (  itq = mPageLoadQueue.begin (   ); itq != mPageLoadQueue.end (   ); )
           {
           assert (  !(  *itq )->isLoaded(   ) );
           assert (  (  *itq )->mIsLoading && !(  *itq )->mIsTextureLoading && !(  *itq )->mIsPreLoading );
           if (  (  *itq )->unloadUntouched (   ) )
           {
           p = *itq;
           // remove from queue
           p->mIsLoading = false;
           itq = mPageLoadQueue.erase (  itq );
           // remove from active pages
           //(  must be removed from queue first )
           releasePage (  p );
           }
           else
           {
           ++itq;
           }
           }
           }
           //-----------------------------------------------------------------------
     624   void PagingLandScapePageManager::processLoadQueues(   )
           {
           // Should be called every count frame only
           // to minimize fps impact
           if (  mNextQueueFrameCount-- < 0 )
           {
           SceneManager::CameraIterator camIt = mSceneManager->getCameraIterator(   );
           while (  camIt.hasMoreElements(   ) )
           {
           Camera const * const currentCamera = camIt.getNext(   );
           const Vector3 pos (  currentCamera->getDerivedPosition(   ).x,  
           127.0f,  
           currentCamera->getDerivedPosition(   ).z );
          
           // We to Load nearest page in non-empty queue
           if (  !mPageLoadQueue.empty (   ) )
           {
           // We to Load nearest page in non-empty queue
           PagingLandScapePage *p = mPageLoadQueue.find_nearest (  pos );
           assert (  p && !p->isLoaded (   ) );
           assert (  !p->mIsTextureLoading && !p->mIsPreLoading );
           p->load (   );
          
           p->mIsLoading = false;
           mLoadedPages.push_back (  p );
           mTextureLoadedPages.remove (  p );
           mNextQueueFrameCount = mPageLoadInterval;
           }
           else if (  !mPageTextureloadQueue.empty (   ) )
           {
           // We TextureLoad nearest page in non-empty queue
           PagingLandScapePage *p = mPageTextureloadQueue.find_nearest (  pos );
           assert (  p && !p->isTextureLoaded(   ) );
           assert (  !p->mIsLoading && !p->mIsPreLoading );
           p->loadTexture (   );
          
           p->mIsTextureLoading = false;
           mTextureLoadedPages.push_back (  p );
           mPreLoadedPages.remove (  p );
           // do not automatically push to level up.
           //mPageLoadQueue.push (  p );
           mNextQueueFrameCount = mPageLoadInterval;
           }
           else if (  !mPagePreloadQueue.empty (   ) )
           {
           // We PreLoad nearest page in non-empty queue
           PagingLandScapePage *p = mPagePreloadQueue.find_nearest (  pos );
           assert (  p && !p->isPreLoaded(   ) );
           assert (  !p->mIsLoading && !p->mIsTextureLoading );
           p->preload (   );
          
           p->mIsPreLoading = false;
           mPreLoadedPages.push_back (  p );
           mPageTextureloadQueue.push (  p );
           p->mIsTextureLoading = true;
           mNextQueueFrameCount = mPageLoadInterval;
           }
           }
           } // if (  mNextQueueFrameCount-- < 0 )
           }
           //-----------------------------------------------------------------------
     685   void PagingLandScapePageManager::removeFromQueues(  PagingLandScapePage* p )
           {
           assert (  p );
           if (  p->mIsLoading )
           {
           p->mIsLoading = false;
           mPageLoadQueue.remove (  p );
           }
           else if (  p->mIsTextureLoading )
           {
           p->mIsTextureLoading = false;
           mPageTextureloadQueue.remove (  p );
           }
           else if (  p->mIsPreLoading )
           {
           p->mIsPreLoading = false;
           mPagePreloadQueue.remove (  p );
           }
           assert (  !p->mIsLoading && !p->mIsTextureLoading && !p->mIsPreLoading );
           }
           //-----------------------------------------------------------------------
     706   unsigned int PagingLandScapePageManager::getCurrentCameraPageX(  void ) const
           {
           if (  mCurrentcam )
           {
          
           return mCurrentcam->mCurrentCameraPageX;
           }
           return 0;
           }
          
           //-----------------------------------------------------------------------
     717   unsigned int PagingLandScapePageManager::getCurrentCameraPageZ(  void ) const
           {
           if (  mCurrentcam )
           {
           return mCurrentcam->mCurrentCameraPageZ;
           }
           return 0;
           }
          
           //-----------------------------------------------------------------------
     727   unsigned int PagingLandScapePageManager::getCurrentCameraTileX(  void ) const
           {
           if (  mCurrentcam )
           {
           return mCurrentcam->mCurrentCameraTileX;
           }
           return 0;
           }
          
           //-----------------------------------------------------------------------
     737   unsigned int PagingLandScapePageManager::getCurrentCameraTileZ(  void ) const
           {
           if (  mCurrentcam )
           {
           return mCurrentcam->mCurrentCameraTileZ;
           }
           return 0;
           }
           //-----------------------------------------------------------------------
     746   void PagingLandScapePageManager::addLoadedPage(  PagingLandScapePage *p )
           {
           mLoadedPages.push_back (  p );
           }
           //-----------------------------------------------------------------------
     751   int PagingLandScapePageManager::getLoadedPageSize(  void ) const
           {
           return static_cast< int >(  mLoadedPages.size(   ) );
           }
           //-----------------------------------------------------------------------
     756   int PagingLandScapePageManager::getUnloadedPagesSize(  void ) const
           {
           return static_cast< int >(  mWidth*mHeight - mLoadedPages.size(   ) );
           }
           //-----------------------------------------------------------------------
     761   int PagingLandScapePageManager::getTextureLoadedPageSize(  void ) const
           {
           return static_cast< int >(  mTextureLoadedPages.size(   ) );
           }
          
           //-----------------------------------------------------------------------
     767   int PagingLandScapePageManager::getPreLoadedPageSize(  void ) const
           {
           return static_cast< int >(  mPreLoadedPages.size(   ) );
           }
           //-----------------------------------------------------------------------
     772   int PagingLandScapePageManager::getPagePreloadQueueSize(  void ) const
           {
           return static_cast< int >(  mPagePreloadQueue.getSize(   ) );
           }
          
           //-----------------------------------------------------------------------
     778   int PagingLandScapePageManager::getPageTextureloadQueueSize(  void ) const
           {
           return static_cast< int >(  mPageTextureloadQueue.getSize(   ) );
           }
          
           //-----------------------------------------------------------------------
     784   int PagingLandScapePageManager::getPageLoadQueueSize(  void ) const
           {
           return static_cast< int >(  mPageLoadQueue.getSize(   ) );
           }
          
           //-----------------------------------------------------------------------
     790   void PagingLandScapePageManager::getGlobalToPage(  Real& x,   Real& z ) const
           {
           const Real inv_pSize = 1.0f / (  mOptions->PageSize - 1 );
          
           x = static_cast< int >(  (  (  x / mOptions->scale.x ) + mOptions->maxUnScaledX ) * inv_pSize );
           z = static_cast< int >(  (  (  z / mOptions->scale.z ) + mOptions->maxUnScaledZ ) * inv_pSize );
           }
          
           //-----------------------------------------------------------------------
     799   void PagingLandScapePageManager::getNearestPageIndicesUnscaled(  const Real posx,   const Real posz,   unsigned int& x,   unsigned int& z ) const
           {
           // adjust x and z to be local to page
           const Real inv_pSize = 1.0f / (  mOptions->PageSize - 1 );
          
           const int lx = static_cast< int >(  (  posx + mOptions->maxUnScaledX ) * inv_pSize );
           const int lz = static_cast< int >(  (  posz + mOptions->maxUnScaledZ ) * inv_pSize );
          
           const int w = static_cast< int >(  mOptions->world_width );
           const int h = static_cast< int >(  mOptions->world_height );
          
           // make sure indices are not negative or outside range of number of pages
           if (  lx >= w )
           {
           x = static_cast< unsigned int >(  w - 1 );
           }
           else if (  lx < 0 )
           {
           x = 0;
           }
           else
           {
           x = static_cast< unsigned int >(  lx );
           }
          
           if (  lz >= h )
           {
           z = static_cast< unsigned int >(  h - 1 );
           }
           else if (  lz < 0 )
           {
           z = 0;
           }
           else
           {
           z = static_cast< unsigned int >(  lz );
           }
           }
          
          
          
           //-----------------------------------------------------------------------
     841   void PagingLandScapePageManager::getNearestTileIndicesUnscaled(  const Real posx,   const Real posz,  
           const unsigned int pagex,   const unsigned int pagez,  
           unsigned int& x,   unsigned int& z ) const
           {
           // adjust x and z to be local to page
           const Real inv_tSize = 1.0f / (  mOptions->TileSize - 1 );
           const int pSize = mOptions->PageSize - 1;
          
           const int tilex = static_cast< int >(  (  posx - (  (  pagex * pSize ) - mOptions->maxUnScaledX ) ) * inv_tSize );
           //- mOptions->maxUnScaledX
          
           const int tilez = static_cast< int >(  (  posz - (  (  pagez * pSize ) - mOptions->maxUnScaledZ ) ) * inv_tSize );
           //- mOptions->maxUnScaledZ
          
           const int tilesPerPage = static_cast< int >(  (  pSize * inv_tSize ) - 1 );
          
           if (  tilex > tilesPerPage )
           {
           x = static_cast< unsigned int >(  tilesPerPage );
           }
           else if (  tilex < 0 )
           {
           x = 0;
           }
           else
           {
           x = static_cast< unsigned int >(  tilex );
           }
          
           if (  tilez > tilesPerPage )
           {
           z = static_cast< unsigned int >(  tilesPerPage );
           }
           else if(  tilez < 0 )
           {
           z = 0;
           }
           else
           {
           z = static_cast< unsigned int >(  tilez );
           }
           }
           //-----------------------------------------------------------------------
     884   bool PagingLandScapePageManager::getTileIndices(  const Real posx,   const Real posz,  
           const unsigned int pagex,   const unsigned int pagez,  
     886   unsigned int& x,   unsigned int& z,   bool alwaysAnswer ) const
           {
           if (  alwaysAnswer )
           {
           getNearestTileIndicesUnscaled(  posx / mOptions->scale.x,   posz / mOptions->scale.z,   pagex,   pagez,   x,   z );
           return true;
           }
           else
           {
           return getRealTileIndicesUnscaled(  posx / mOptions->scale.x,   posz / mOptions->scale.z,   pagex,   pagez,   x,   z );
           }
           }
           //-----------------------------------------------------------------------
     899   PagingLandScapeTile* PagingLandScapePageManager::getTileUnscaled(  const Real posx,   const Real posz,   const unsigned int pagex,   const unsigned int pagez,   bool alwaysAnswer )
           {
           unsigned int tilex,   tilez;
           if (  alwaysAnswer )
           {
           getNearestTileIndicesUnscaled(  posx,   posz,   pagex,   pagez,   tilex,   tilez );
           PagingLandScapePage * const p = getPage (  pagex ,   pagez,   false );
           if (  p )
           return p->getTile(  tilex,   tilez );
           }
           else
           {
           if (  getRealTileIndicesUnscaled(  posx,   posz,   pagex,   pagez,   tilex,   tilez ) )
           {
           PagingLandScapePage * const p = getPage (  pagex ,   pagez,   false );
           if (  p )
           return p->getTile(  tilex,   tilez );
           }
           }
           return 0;
           }
           //-----------------------------------------------------------------------
     921   PagingLandScapeTile* PagingLandScapePageManager::getTile(  const Real posx,   const Real posz,   const unsigned int pagex,   const unsigned int pagez,   bool alwaysAnswer )
           {
           return getTileUnscaled(  posx / mOptions->scale.x,   posz / mOptions->scale.z,   pagex,   pagez,   alwaysAnswer );
           }
           //-----------------------------------------------------------------------
     926   PagingLandScapeTile* PagingLandScapePageManager::getTile(  const Real posx,   const Real posz,   bool alwaysAnswer )
           {
           return getTileUnscaled(  posx / mOptions->scale.x,   posz / mOptions->scale.z,   alwaysAnswer );
           }
           //-----------------------------------------------------------------------
     931   PagingLandScapeTile* PagingLandScapePageManager::getTileUnscaled(  const Real posx,   const Real posz,   bool alwaysAnswer )
           {
           unsigned int pagex,   pagez;
           if (  alwaysAnswer )
           {
           unsigned int tilex,   tilez;
           getNearestPageIndicesUnscaled(  posx,   posz,   pagex,   pagez );
           getNearestTileIndicesUnscaled(  posx,   posz,   pagex,   pagez,   tilex,   tilez );
           return getPage (  pagex ,   pagez )->getTile(  tilex,   tilez );
           }
           else
           {
           if (  getRealPageIndicesUnscaled(  posx,   posz,   pagex,   pagez ) )
           {
           unsigned int tilex,   tilez;
           if (  getRealTileIndicesUnscaled(  posx,   posz,   pagex,   pagez,   tilex,   tilez ) )
           {
           PagingLandScapePage * const p = getPage (  pagex ,   pagez,   false );
           if (  p )
           return p->getTile(  tilex,   tilez );
           }
           }
           }
           return 0;
           }
           //-------------------------------------------------------------------------
     957   PagingLandScapeTile* PagingLandScapePageManager::getTilePage (  unsigned int &posx,   unsigned int &posz,  
           const unsigned int pagex,   const unsigned int pagez )
           {
           const Real tSize = mOptions->TileSize - 1;
           const Real inv_tSize = 1.0f / tSize;
           const int tilex = static_cast< int >(  posx * inv_tSize );
           const int tilez = static_cast< int >(  posz * inv_tSize );
          
           const int pSize = mOptions->PageSize - 1;
           const int tilesPerPage = static_cast< int > (  mOptions->NumTiles - 1 );
          
           unsigned int x;
           if (  tilex > tilesPerPage )
           {
           x = static_cast< unsigned int >(  tilesPerPage );
           }
           else if (  tilex < 0 )
           {
           x = 0;
           }
           else
           {
           x = static_cast< unsigned int >(  tilex );
           }
          
           unsigned int z;
           if (  tilez > tilesPerPage )
           {
           z = static_cast< unsigned int >(  tilesPerPage );
           }
           else if(  tilez < 0 )
           {
           z = 0;
           }
           else
           {
           z = static_cast< unsigned int >(  tilez );
           }
           posx = posx - static_cast< unsigned int > (  x * tSize );
           posz = posz - static_cast< unsigned int > (  z * tSize );
           PagingLandScapePage *p = getPage (  pagex ,   pagez );
           if (  p )
           return p->getTile(  x,   z );
           return 0;
           }
           //-------------------------------------------------------------------------
    1003   void PagingLandScapePageManager::setWorldGeometryRenderQueue(  uint8 qid )
           {
           PagingLandScapePageList::iterator l,   lend = mLoadedPages.end(   );
           for (  l = mLoadedPages.begin(   ); l != lend; ++l )
           {
           PagingLandScapePage *p = (  *l );
           {
           p->setRenderQueue(  qid );
           }
           }
           }
          
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapePageRenderable.cpp

       1  /***************************************************************************
           OgrePagingLandScapePageRenderable.cpp - description
           -------------------
           begin : Thu Feb 27 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreRoot.h"
          #include "OgreHardwareBufferManager.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreMovableObject.h"
          #include "OgreAxisAlignedBox.h"
          
          #include "OgreCamera.h"
          #include "OgreViewport.h"
          
          #include "OgreSceneNode.h"
          
          #include "OgreSimpleRenderable.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeCamera.h"
          
          #include "OgrePagingLandScapePageRenderable.h"
          
          #include "OgrePagingLandScapeTile.h"
          #include "OgrePagingLandScapeTileInfo.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeData2DManager.h"
          
          #include "OgrePagingLandScapeTextureManager.h"
          #include "OgrePagingLandScapePageManager.h"
          
          namespace Ogre
          {
          
          
          // Renderable Buffer definitions
          #define MAIN_BINDING 0
          
           PagingLandScapeOptions *PagingLandScapePageRenderable::mOpt;
           String PagingLandScapePageRenderable::mType = "PagingLandScapePageBillBoard";
          
           //-----------------------------------------------------------------------
      61   PagingLandScapePageRenderable::PagingLandScapePageRenderable(  PagingLandScapePageManager *pageMgr,   const String& name,   const unsigned int pageX,   const unsigned int pageZ,  
      62   const AxisAlignedBox &bounds ) :
           Renderable(   ),  
           MovableObject(  name ),  
           mParent(  pageMgr ),  
           mX(  pageX ),  
           mZ(  pageZ ),  
           mBounds(  bounds ),  
           mCurrVertexes (  0 ),  
           mCurrIndexes (  0 )
           {
           // No shadow projection
           MovableObject::mCastShadows = false;
           // Default query flags to top bit so users can exclude it if they wish
           //MovableObject::mQueryFlags = SceneManager::WORLD_GEOMETRY_QUERY_MASK;
          
           // Setup render op
           mCurrIndexes = new IndexData(   );
          
           const unsigned int Numtiles = mParent->getOptions(   )->NumTiles + 1;
           const size_t new_length = (  (  Numtiles - 1 ) * (  Numtiles - 1 ) * 2 * 2 * 2 );
           mCurrIndexes->indexCount = new_length;
           mCurrIndexes->indexStart = 0;
           mCurrIndexes->indexBuffer =
           HardwareBufferManager::getSingleton(   ).createIndexBuffer(  
           HardwareIndexBuffer::IT_16BIT,  
           new_length,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY );
          
          
           mCurrVertexes = new VertexData(   );
           mCurrVertexes->vertexStart = 0;
           mCurrVertexes->vertexCount = Numtiles * Numtiles + 1;
          
          
           // Vertex declaration
           VertexDeclaration* decl = mCurrVertexes->vertexDeclaration;
           VertexBufferBinding* bind = mCurrVertexes->vertexBufferBinding;
          
           // Vertex buffer #1,   position
           // positions
           size_t offset = 0;
           decl->addElement(  MAIN_BINDING,   0,   VET_FLOAT3,   VES_POSITION );
           offset += VertexElement::getTypeSize (  VET_FLOAT3 );
           decl->addElement(  MAIN_BINDING,   offset,   VET_FLOAT2,   VES_TEXTURE_COORDINATES,   0 );
           offset += VertexElement::getTypeSize(  VET_FLOAT2 );
          
           HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton (   ).createVertexBuffer(  
           decl->getVertexSize (  MAIN_BINDING ),  
           mCurrVertexes->vertexCount,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY );
          
           bind->setBinding(  MAIN_BINDING,   vbuf );
          
          
           }
          
           //-----------------------------------------------------------------------
     119   PagingLandScapePageRenderable::~PagingLandScapePageRenderable(   )
           {
           delete mCurrVertexes;
           delete mCurrIndexes;
          
           mMaterial.setNull(   );
           }
          
           //-----------------------------------------------------------------------
     128   void PagingLandScapePageRenderable::load(   )
           {
          
           // case renderable was queued before page was unloaded
           // when loaded,   page exists no more.
          
           VertexDeclaration* decl = mCurrVertexes->vertexDeclaration;
           VertexBufferBinding* bind = mCurrVertexes->vertexBufferBinding;
          
           const VertexElement* poselem = decl->findElementBySemantic(  VES_POSITION );
           const VertexElement* texelem = decl->findElementBySemantic(  VES_TEXTURE_COORDINATES,   0 );
          
          
           HardwareVertexBufferSharedPtr vVertices = bind->getBuffer(  MAIN_BINDING );
           uchar* pMain = static_cast<uchar*>(  vVertices->lock(  HardwareBuffer::HBL_DISCARD ) );
          
           const unsigned int Numtiles = mParent->getOptions(   )->NumTiles + 1;
          
           const Real invpagesizeX = 1.0f / (  (  Numtiles - 1 ) * mParent->getOptions(   )->world_width );
           const Real invpagesizeZ = 1.0f / (  (  Numtiles - 1 )* mParent->getOptions(   )->world_height );
          
           const Real texOffsetX = mX * (  Numtiles - 1 ) * invpagesizeX;
           const Real texOffsetZ = mZ * (  Numtiles - 1 ) * invpagesizeZ;
          
          
           const Real scale_x = mOpt->scale.x * (  mOpt->TileSize - 1 );
           const Real scale_z = mOpt->scale.z * (  mOpt->TileSize - 1 );
           unsigned int i,   j;
           for (  j = 0; j < Numtiles ; j ++ )
           {
           // This allow to reuse the variables in the loop
           const Real h_pos = j * scale_z;
           const Real Tex_pos = texOffsetZ + j * invpagesizeZ;
          
           for (  i = 0; i < Numtiles; i ++ )
           {
           // vertices are relative to the scene node
          
           float *pPos;
          
           poselem->baseVertexPointerToElement(  pMain,   &pPos );
          
           *pPos++ = static_cast <float> (  i * scale_x ); //X
           *pPos++ = static_cast <float> (  0.0 ); //Y
           *pPos = static_cast <float> (  h_pos ); //Z
          
           float *pTex;
           texelem->baseVertexPointerToElement(  pMain,   &pTex );
          
           *pTex++ = static_cast <float> (  texOffsetX + i * invpagesizeX );
           *pTex = static_cast <float> (  Tex_pos );
          
           pMain += vVertices->getVertexSize (   );
          
           }
           }
           // Unlock the buffers
           vVertices->unlock(   );
          
          
           ushort* pIdx = static_cast<ushort*>(  mCurrIndexes->indexBuffer->lock(  0,  
           mCurrIndexes->indexBuffer->getSizeInBytes(   ),  
           HardwareBuffer::HBL_DISCARD ) );
           unsigned int height_count = 0;
           unsigned int NumIndexes = 0;
           for (  j = 0; j < Numtiles - 1; j ++ )
           {
           for (  i = 0; i < Numtiles - 1; i ++ )
           {
           // Indexes
           *pIdx++ = static_cast<ushort> (  i + height_count ); NumIndexes++;
           *pIdx++ = static_cast<ushort> (  i + height_count + Numtiles ); NumIndexes++;
           *pIdx++ = static_cast<ushort> (  i + 1 + height_count ); NumIndexes++;
          
           *pIdx++ = static_cast<ushort> (  i + height_count + Numtiles ); NumIndexes++;
           *pIdx++ = static_cast<ushort> (  i + 1 + height_count + Numtiles ); NumIndexes++;
           *pIdx++ = static_cast<ushort> (  i + 1 + height_count ); NumIndexes++;
          
           }
           height_count += Numtiles;
           }
          
           mCurrIndexes->indexBuffer->unlock(   );
          
           assert (  NumIndexes < mCurrIndexes->indexCount );
          
          
           const Real max =
           mParent->getSceneManager(   )->getData2DManager(   )->getMaxHeight(  mX,  
           mZ );
          
           // Calculate the bounding box for this renderable
           mBounds.setExtents(  0.0f,  
           0.0f,  
           0.0f,  
           0.0f + Numtiles * scale_x,  
           max,  
           0.0f + Numtiles * scale_z );
          
           assert (  mParentNode );
           mCenter = mBounds.getCenter(   ) + mParentNode->getWorldPosition(   );
           mWorldBoundingSphere.setCenter(  mCenter );
           mWorldBoundingSphere.setRadius(  mBounds.getMaximum(   ).length(   ) );
          
           mParentNode->needUpdate(   );
          
          
           MovableObject::setRenderQueueGroup(  mParent->getSceneManager(   )->getPageManager(   )->getRenderQueueGroupID(   ) );
          
           }
           //-----------------------------------------------------------------------
     239   void PagingLandScapePageRenderable::_updateRenderQueue(  RenderQueue* queue )
           {
           queue->addRenderable(  this );
           }
           //-----------------------------------------------------------------------
     244   Technique* PagingLandScapePageRenderable::getTechnique(  void ) const
           {
           return mMaterial->getBestTechnique (   );
           }
           //-----------------------------------------------------------------------
     249   const LightList& PagingLandScapePageRenderable::getLights(  void ) const
           {
          #ifdef PLSM2_EIHORT
           return queryLights(   );
          #else
           return MovableObject::getParentSceneNode(   )->findLights(  this->getBoundingRadius(   ) );
          #endif
           }
           //-----------------------------------------------------------------------
     258   Real PagingLandScapePageRenderable::getSquaredViewDepth(  const Camera* cam ) const
           {
           // Use squared length to avoid square root
           return (  mCenter -
           cam->getDerivedPosition (   ) ).squaredLength(   );
           }
          
           //-----------------------------------------------------------------------
     266   Real PagingLandScapePageRenderable::getBoundingRadius(  void ) const
           {
           return mWorldBoundingSphere.getRadius(   );
           }
           //-----------------------------------------------------------------------
     271   void PagingLandScapePageRenderable::getRenderOperation(  RenderOperation& op )
           {
           //setup indexes for vertices and uvs...
           op.useIndexes = true;
           op.operationType = RenderOperation::OT_TRIANGLE_LIST;
           op.vertexData = mCurrVertexes;
           op.indexData = mCurrIndexes;
          
           }
           //-----------------------------------------------------------------------
     281   void PagingLandScapePageRenderable::getWorldTransforms(  Matrix4* xform ) const
           {
           *xform = mParentNode->_getFullTransform(   );
           }
           //-----------------------------------------------------------------------
     286   const Quaternion& PagingLandScapePageRenderable::getWorldOrientation(  void ) const
           {
           return mParentNode->_getDerivedOrientation(   );
           }
           //-----------------------------------------------------------------------
     291   const Vector3& PagingLandScapePageRenderable::getWorldPosition(  void ) const
           {
           return mCenter;
           }
           //-----------------------------------------------------------------------
     296   void PagingLandScapePageRenderable::setMaterial(  const MaterialPtr &mat )
           {
           mMaterial = mat;
           }
           //-----------------------------------------------------------------------
     301   uint32 PagingLandScapePageRenderable::getTypeFlags(  void ) const
           {
           // return world flag
           return SceneManager::WORLD_GEOMETRY_TYPE_MASK;
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapePrecompiledHeaders.cpp

       1  /***************************************************************************
          OgrePagingLandScapePrecompiledHeaders.cpp - description
          -------------------
          copyright : (  C ) 2006 Tuan Kuranes
          email : tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeRaySceneQuery.cpp

       1  /***************************************************************************
          OgrePagingLandScapeRaySceneQuery.cpp - description
          -------------------
          begin : Fri Sep 10 2003
          copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
          email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreEntity.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreSceneManager.h"
          #include "OgrePagingLandScapeOctreeSceneManager.h"
          
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeRaySceneQuery.h"
          
          namespace Ogre
          {
          
          //----------------------------------------------------------------------------
          // This function return the vertex interpolated height.
          // Supplied by Praetor. Thanks a lot. ]: )
      39  void PagingLandScapeRaySceneQuery::execute(  RaySceneQueryListener* listener )
          {
           ///Ember start
           ///Make sure that there really is some world geometry first
           if (  (  static_cast<PagingLandScapeSceneManager*>(  mParentSceneMgr )->mWorldGeomIsSetup ) && (  getQueryTypeMask(   ) & SceneManager::WORLD_GEOMETRY_TYPE_MASK ) )
           ///Ember end
           {
           mWorldFrag.fragmentType = SceneQuery::WFT_SINGLE_INTERSECTION;
          
           const Vector3& dir = mRay.getDirection(   );
           const Vector3& origin = mRay.getOrigin(   );
          
           PagingLandScapeSceneManager* mSceneMgr = static_cast<PagingLandScapeSceneManager*>(  mParentSceneMgr );
           if (  mWorldFragmentType & WFT_SINGLE_INTERSECTION )
           {
           if (  dir == Vector3::UNIT_Y ||
           dir == Vector3::NEGATIVE_UNIT_Y )
           {
           Real height;
           if (  mSceneMgr->getOptions(   )->queryNoInterpolation )
           height = mSceneMgr->getData2DManager(   )->getWorldHeight(  origin.x,   origin.z );
           else
           height = mSceneMgr->getData2DManager(   )->getInterpolatedWorldHeight(  origin.x,   origin.z );
          
           mWorldFrag.singleIntersection.x = origin.x;
           mWorldFrag.singleIntersection.z = origin.z;
           mWorldFrag.singleIntersection.y = height;
          
           mWorldFrag.singleIntersection += mSceneMgr->getOptions(   )->position; //consider terrain offset
          
           listener->queryResult(  &mWorldFrag,   (  Math::Abs(  mWorldFrag.singleIntersection.y - origin.y ) ) );
           return;
           }
           else if (  mSceneMgr->intersectSegmentTerrain(  
           origin,  
           dir * mSceneMgr->getOptions(   )->queryResolutionFactor,  
           &mWorldFrag.singleIntersection ) )
           {
           listener->queryResult(  &mWorldFrag,   (  mWorldFrag.singleIntersection - origin ).length(   ) );
           ///Ember start
           PagingLandScapeOctreeRaySceneQuery::execute(  listener );
           ///Ember end
           return;
           }
           }
           else
           {
           // multiple terrain intersection
           const Vector3 raydir (  mRay.getDirection(   ) );
           const Vector3 raymove (  raydir * mSceneMgr->getOptions(   )->queryResolutionFactor );
           const Real distmove = mSceneMgr->getOptions(   )->queryResolutionFactor;
           const Real maxHeight = mSceneMgr->getData2DManager(   )->getMaxHeight (   );
           const Real MaxTerrainX = mSceneMgr->getOptions(   )->maxScaledX;
           const Real MaxTerrainZ = mSceneMgr->getOptions(   )->maxScaledZ;
          
           Vector3 ray (  mRay.getOrigin(   ) );
           Real dist = 0.0f;
          
           // while ray is inside or ray is outside but raydir going inside
           while (  (  ray.y < 0 && raydir.y > 0 ) ||
           (  ray.y > maxHeight && raydir.y < 0 ) ||
           (  ray.x < -MaxTerrainX && raydir.x > 0 ) ||
           (  ray.x > MaxTerrainX && raydir.x < 0 ) ||
           (  ray.z < -MaxTerrainZ && raydir.z > 0 ) ||
           (  ray.z > MaxTerrainZ && raydir.z < 0 ) )
           {
           ray += raymove;
           dist += distmove;
           if (  ray.y < maxHeight )// no need to do complex tests
           {
           const Vector3 land (  getHeightAt(  ray ) );
           if (  ray.y < land.y )
           {
           WorldFragment* frag = new WorldFragment(   );
           //fragmentList.push_back(  frag );
          
           frag->fragmentType = SceneQuery::WFT_SINGLE_INTERSECTION;
           frag->singleIntersection = land;
          
           if (  !listener->queryResult(  frag,   dist ) )
           return;
           }
           }
           }
           }
          
           }
           // if anything else is queried,   ask underlying Octree Scene Manager.
           PagingLandScapeOctreeRaySceneQuery::execute(  listener );
          }
          //----------------------------------------------------------------------------
     130  Vector3 PagingLandScapeRaySceneQuery::getHeightAt(  const Vector3& origin ) const
          {
          
           PagingLandScapeSceneManager * mSceneMgr = static_cast<PagingLandScapeSceneManager*>(  mParentSceneMgr );
           return Vector3(  origin.x,   mSceneMgr->getData2DManager(   )->getInterpolatedWorldHeight(  origin.x,   origin.z ),   origin.z );
          
          }
          
          } // namespace Ogre

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeRenderable.cpp

          /***************************************************************************
           OgrePagingLandScapeRenderable.cpp - description
           -------------------
           begin : Thu Feb 27 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreRoot.h"
          #include "OgreHardwareBufferManager.h"
          
          #include "OgreLogManager.h"
          
          #include "OgreStringConverter.h"
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreMovableObject.h"
          #include "OgreAxisAlignedBox.h"
          
          
          #include "OgreSceneNode.h"
          
          #include "OgreSimpleRenderable.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeCamera.h"
          
          #include "OgrePagingLandScapeRenderable.h"
          #include "OgrePagingLandScapeRenderableManager.h"
          
          //caches
          #include "OgrePagingLandScapeIndexBuffer.h"
          #include "OgrePagingLandScapeTextureCoordinatesManager.h"
          
          #include "OgrePagingLandScapeTile.h"
          #include "OgrePagingLandScapeTileInfo.h"
          
          #include "OgrePagingLandScapeData2D.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeListenerManager.h"
          
          #include "OgrePagingLandScapePageManager.h"
          #include "OgrePagingLandScapeHorizon.h"
          
          namespace Ogre
          {
          
          
          // Renderable Buffer definitions
          #define MAIN_BINDING 0
          #define DELTA_BINDING 2
          #define TEXTURE_BINDING 1
          
           String PagingLandScapeRenderable::mType = "PagingLandScapeRenderable";
          
           //-----------------------------------------------------------------------
           //-----------------------------------------------------------------------
      70   PagingLandScapeRenderable::PagingLandScapeRenderable(  PagingLandScapeRenderableManager *renderableMgr ) :
           Renderable(   ),  
           MovableObject(   ),  
           mParent(  renderableMgr ),  
           mCurrVertexes (  0 ),  
           mCurrIndexes (  0 ),  
           mInfo (  0 ),  
           mMaterialLODIndex (  0 ),  
           mInUse (  false ),  
           mIsLoaded (  false ),  
           mDeltaBuffers (  0 ),  
           mLastNextLevel (  -1 ),  
           mLODMorphFactor (  0.0f ),  
      83   mHeightfield (  0 ),  
           mMinLevelDistSqr (  0 ),  
           mRenderLevel (  -1 ),  
           mIsRectModified (  false ),  
           mRect (  0,   0,   0,   0,   0,   1 ),  
           mForcedMaxLod (  false )
           ///Ember added start
           ,   mNeedReload(  false )
           ///Ember added stop
          
           {
           // No shadow projection
           MovableObject::mCastShadows = false;
          
           // Default query flags to top bit so users can exclude it if they wish
           MovableObject::mQueryFlags = SceneManager::WORLD_GEOMETRY_TYPE_MASK;
           MovableObject::setRenderQueueGroup(  
           mParent->getSceneManager(   )->getPageManager(   )->getRenderQueueGroupID(   ) );
          
           for (  unsigned int i = 0; i < 4; i++ )
           mNeighbors[ i ] = 0;
          
           // Setup render op
           mCurrVertexes = new VertexData(   );
           mCurrVertexes->vertexStart = 0;
           const unsigned int tileSize = mParent->getOptions (   )->TileSize;
           mCurrVertexes->vertexCount = tileSize * tileSize;
          
           // Vertex declaration
           VertexDeclaration* decl = mCurrVertexes->vertexDeclaration;
           VertexBufferBinding* bind = mCurrVertexes->vertexBufferBinding;
          
          
           // Vertex buffer #1,   position
           // positions
           size_t offset = 0;
           VertexElementType t;
           if (  mParent->getOptions(   )->VertexCompression )
           {
           t = VET_SHORT2;
           }
           else
           {
           t = VET_FLOAT3;
           }
           decl->addElement(  MAIN_BINDING,   0,   t,   VES_POSITION );
           offset += VertexElement::getTypeSize (  t );
           if (  mParent->getOptions(   )->normals )
           {
           decl->addElement(  MAIN_BINDING,   offset,   VET_FLOAT3,   VES_NORMAL );
           offset += VertexElement::getTypeSize (  VET_FLOAT3 );
           }
           if (  mParent->getOptions(   )->colored )
           {
           decl->addElement (  MAIN_BINDING,   offset,   VET_COLOUR,   VES_DIFFUSE );
           offset += VertexElement::getTypeSize (  VET_COLOUR );
           }
          
          
           HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton (   ).createVertexBuffer(  
           decl->getVertexSize (  MAIN_BINDING ),  
           mCurrVertexes->vertexCount,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY );
           //HardwareBuffer::HBU_STATIC );
          
           bind->setBinding(  MAIN_BINDING,   vbuf );
          
           if (  mParent->getOptions (   )->lodMorph )
           {
           // Create delta buffer for all except the lowest mipmap
           assert (  mParent->getOptions (   )->maxRenderLevel > 1 );
           const unsigned int maxmip = mParent->getOptions (   )->maxRenderLevel - 1;
           mDeltaBuffers = new HardwareVertexBufferSharedPtr[maxmip];
          
           // Create additional element for delta
           decl->addElement(  DELTA_BINDING,   0,   VET_SHORT2,   VES_BLEND_WEIGHTS );
           //decl->addElement(  DELTA_BINDING,   0,   VET_SHORT1,   VES_BLEND_WEIGHTS );
          
           //decl->addElement(  DELTA_BINDING,   0,   VET_FLOAT1,   VES_BLEND_WEIGHTS );
          
           //decl->addElement(  DELTA_BINDING,   0,   VET_SHORT1,   VES_TEXTURE_COORDINATES,   1 );
           //decl->addElement(  DELTA_BINDING,   0,   VET_SHORT2,   VES_TEXTURE_COORDINATES,   1 );
          
           for (  unsigned int k = 0; k < maxmip; k++ )
           {
           assert (  mDeltaBuffers[k].isNull(   ) );
           mDeltaBuffers[k] = createDeltaBuffer(   );
           }
           // NB binding is not set here,   it is set when deriving the LOD
           }
           //No need to set the indexData since it is shared from LandScapeIndexBuffer class
           mCustomGpuParameters = Vector4(  mParent->getOptions (   )->ScaledPageSizeX,  
           mParent->getOptions (   )->ScaledHeightY,  
           mParent->getOptions (   )->ScaledPageSizeZ,  
           mLODMorphFactor );
          
           mQueued = false;
           mParentTile = 0;
           }
           //-----------------------------------------------------------------------
     183   PagingLandScapeRenderable::~PagingLandScapeRenderable(   )
           {
           delete mCurrVertexes;
           delete [] mDeltaBuffers;
           }
          
           //------------------------------------------------------------------------
     190   void PagingLandScapeRenderable::uninit(   )
           {
           if (  mIsLoaded )
           unload (   );
          
           mParentTile = 0;
          
           mParent->freeRenderable(  this );
           mInfo = 0;
           mHeightfield = 0;
           mCurrIndexes = 0;
           mLastNextLevel = -1;
           mRenderLevel = -1;
           mVisible = false;
           mInUse = false;
           mMaterial.setNull(   );
           mLightListDirty = true;
           mQueued = false;
           mParentTile = 0;
           mMinLevelDistSqr = 0;
           }
           //-----------------------------------------------------------------------
     212   void PagingLandScapeRenderable::init(  PagingLandScapeTileInfo* info )
           {
           mMinLevelDistSqr = 0;
           mQueued = false;
           mParentTile = 0;
           mLightListDirty = true;
           mInfo = info;
           mInUse = true;
           mName = StringConverter::toString(  mInfo->mPageX ) + "." +
           StringConverter::toString(  mInfo->mPageZ ) + "." +
           StringConverter::toString(  mInfo->mTileX ) + "." +
           StringConverter::toString(  mInfo->mTileZ ) + "Rend";
          
           mForcedMaxLod = false;
           mUpperDistance = mParent->getOptions (   )->renderable_factor;
           mIsLoaded = false;
          
           //we can init texcoord buffer as it's data independent.
           VertexDeclaration * const decl = mCurrVertexes->vertexDeclaration;
           VertexBufferBinding * const bind = mCurrVertexes->vertexBufferBinding;
          
           // make sure buffer isn't binded to another texture coordinate buffer
           if (  decl->findElementBySemantic (  VES_TEXTURE_COORDINATES,   0 ) != 0 )
           {
           decl->removeElement(  VES_TEXTURE_COORDINATES,   0 );
           bind->unsetBinding (  TEXTURE_BINDING );
           }
          
           // Bind to an existing texture coordinate buffer if it exists
           // or create a new one for this (  x,  y ) combination tile position.
           //(  texture coordinate buffer are shared across buffers )
           const VertexElementType t = VET_FLOAT2;
           //const VertexElementType t = VET_SHORT2;
           decl->addElement(  TEXTURE_BINDING,   0,   t,   VES_TEXTURE_COORDINATES,   0 );
          
           bind->setBinding(  TEXTURE_BINDING,  
           mParent->getSceneManager(   )->getTextureCoordinatesManager(   )->getBuffer(  
           info->mTileX,  
           info->mTileZ ) );
           }
           //-----------------------------------------------------------------------
     253   bool PagingLandScapeRenderable::load(   )
           {
           assert (  mQueued || mNeedReload );
           assert (  mInfo );
          
           //if (  !mInUse )
           //{
           // if not in use,   do not load.
           //if (  mIsLoaded )
           // return true;
           //else
           // return false;
           //}
           // case renderable was queued before page was unloaded
           // when loaded,   page exists no more.
           PagingLandScapeData2D *data = mParent->getSceneManager(   )->getData2DManager(   )->getData2D(  mInfo->mPageX,   mInfo->mPageZ );
           // Page could be unloaded since renderable queued...
           if (  data == 0 || !data->isLoaded(   ) )
           return false;
           mHeightfield = data->getHeightData (   );
           if (  mHeightfield == 0 )
           return false;
          
           const bool b_lit = mParent->getOptions (   )->normals;
          
           const bool b_coverage = mParent->getOptions (   )->coverage_vertex_color;
           const bool b_colored = mParent->getOptions (   )->colored;
          
           const Real scale_x = mParent->getOptions (   )->scale.x;
           const Real scale_z = mParent->getOptions (   )->scale.z;
          
           VertexDeclaration* decl = mCurrVertexes->vertexDeclaration;
           VertexBufferBinding* bind = mCurrVertexes->vertexBufferBinding;
          
           const VertexElement* poselem = decl->findElementBySemantic(  VES_POSITION );
           const VertexElement* colorelem;
           if (  b_colored )
           colorelem= decl->findElementBySemantic(  VES_DIFFUSE );
          
           const VertexElement* normelem;
           if (  b_lit )
           normelem = decl->findElementBySemantic(  VES_NORMAL );
          
          
           // Calculate the offset in the data
           Real min,   max;
           const unsigned int tileSize = mParent->getOptions (   )->TileSize;
          
           Image::Box oldrect = mRect;
           if (  !mIsRectModified )
           {
           mRect.left = 0;
           mRect.right = tileSize;
           mRect.top = 0;
           mRect.bottom = tileSize;
          
           // Make sure we get a new min and max
           min = mParent->getSceneManager(   )->getData2DManager(   )->getMaxHeight (   );
           max = 0.0f;
           }
           else
           {
           mRect.right += 1;
           mRect.bottom += 1;
          
          
          // LogManager::getSingleton(   ).logMessage(  LML_CRITICAL,  
          // String(  "PLSM2 : Deformation on tile " ) + StringConverter::toString(  mInfo->tileX ) + ",   " + StringConverter::toString(  mInfo->tileZ )
          // + " : " + StringConverter::toString(  mRect.left ) + " - " + StringConverter::toString(  mRect.right )
          // + " | " + StringConverter::toString(  mRect.top ) + " - " + StringConverter::toString(  mRect.bottom ) );
          
           // Make sure we get a new min and max
           // only if modified heights exceed current bounds
           min = mBounds.getMinimum(   ).y;
           max = mBounds.getMaximum(   ).y;
           }
          
           const unsigned int offSetX = static_cast <unsigned int> (  mInfo->mTileX * (  tileSize - 1 ) + mRect.left );
           const unsigned int endx = static_cast <unsigned int> (  offSetX + (  mRect.right - mRect.left ) );
          
           const unsigned int offSetZ = static_cast <unsigned int> (  mInfo->mTileZ * (  tileSize - 1 ) + mRect.top );
           const unsigned int endz = static_cast <unsigned int> (  offSetZ + (  mRect.bottom - mRect.top ) );
          
          
           const double inv_scale = 65535.0 / mParent->getOptions (   )->scale.y;
          
           const unsigned int pageSize = mParent->getOptions (   )->PageSize;
           const Real * const ogre_restrict mheightField = mHeightfield;
           const bool vs = mParent->getOptions(   )->VertexCompression;
          
           HardwareVertexBufferSharedPtr vVertices = bind->getBuffer(  MAIN_BINDING );
           const size_t VertexSize = vVertices->getVertexSize (   );
           const size_t VertexTileSize = VertexSize * tileSize;
           uchar* pMain = static_cast<uchar*>(  
           vVertices->lock(  VertexTileSize * mRect.top + mRect.left * VertexSize,   // offset
           VertexTileSize *(  mRect.bottom - mRect.top ) - (  tileSize - mRect.right ) * VertexSize,  //length
           HardwareBuffer::HBL_DISCARD ) );// buffer mode
          
           // initial up-down shift and left-right shift
           const Real * const heightField = mheightField + offSetZ * pageSize;
           unsigned int K_heightFieldPos = 0;
           for (  unsigned int k = offSetZ; k < endz; k ++ )
           {
           // This allow to reuse the variables in the loop
           const Real k_pos = k * scale_z;
           uchar *pMainLocal = pMain;
           for (  unsigned int i = offSetX; i < endx; i ++ )
           {
           const Real height = heightField[ i + K_heightFieldPos ];
          
           min = std::min (  height,   min );
           max = std::max (  height,   max );
          
           // vertices are relative to the scene node
           if (  vs )
           {
           ushort *pPos;
           poselem->baseVertexPointerToElement(  pMainLocal,   &pPos );
           *pPos = static_cast<short> (  (  height * inv_scale ) - 32768 ); //Y
           }
           else
           {
           float *pPos;
          
           poselem->baseVertexPointerToElement(  pMainLocal,   &pPos );
          
           *pPos++ = static_cast <float> (  i * scale_x ); //X
           *pPos++ = static_cast <float> (  height ); //Y
           *pPos = static_cast <float> (  k_pos ); //Z
           }
          
           // normals
           if (  b_lit )
           {
           float *pNorm;
           normelem->baseVertexPointerToElement(  pMainLocal,   &pNorm );
          
           const Vector3 norm = data->getNormal (  i,   k );
           *pNorm++ = static_cast <float> (  norm.x );
           *pNorm++ = static_cast <float> (  norm.y );
           *pNorm = static_cast <float> (  norm.z );
          
           }
           if (  b_colored )
           {
           ColourValue RGBA_precalc;
          
           if (  b_coverage )
           {
           RGBA_precalc = data->getCoverage (  i,   k );
           Real a1;
           const Real a2 = 1.0f - RGBA_precalc.a;
           if (  a2 != 0.0f )
           {
           a1 = RGBA_precalc.r / a2 ;
           }
           else
           a1 = 0.0f;
          
          
           RGBA_precalc.r = a1;
           RGBA_precalc.g = a1;
           RGBA_precalc.b = a1;
           RGBA_precalc.a = a2;
           }
           RGBA *pColor;
           colorelem->baseVertexPointerToElement(  pMainLocal,   &pColor );
           Root::getSingleton(   ).convertColourValue (  RGBA_precalc,  
           pColor );
           }
           pMainLocal += VertexSize;
           }
           pMain += VertexTileSize;;
           K_heightFieldPos += pageSize;
           }
          
           // Unlock the buffers
           vVertices->unlock(   );
          
           // Calculate the bounding box for this renderable
           if (  !mIsRectModified )
           {
           mBounds.setExtents(  offSetX * scale_x,  
           min,  
           offSetZ * scale_z,  
           endx * scale_x,  
           max,  
           endz * scale_z );
           } // if (  !mIsRectModified )
           else
           {
           const Vector3 maxbound = mBounds.getMaximum(   );
           const Vector3 minbound = mBounds.getMinimum(   );
           mBounds.setExtents(  minbound.x,   min,   minbound.z,  
           maxbound.x,   max,   maxbound.z );
           }
           mBoundingRadius = Math::Sqrt(  
           Math::Sqr(  max - min ) +
           Math::Sqr(  (  endx - 1 - offSetX ) * scale_x ) +
           Math::Sqr(  (  endz - 1 - offSetZ ) * scale_z ) ) / 2;
          
          
          
          
           if (  mParent->getOptions (   )->VisMap )
           mParent->getSceneManager(   )->getHorizon(   )->registerMinMaxHeightTile (  mInfo,   min,   max );
          
           mMinLevelDistSqr = 0;
           _calculateMinLevelDist2(  mParent->getOptions (   )->CFactor );
           if (  !mIsLoaded )
           {
           mParent->getSceneManager(   )->getListenerManager(   )->fireTileLoaded (  mInfo->mPageX,   mInfo->mPageZ,  
           mInfo->mTileX,   mInfo->mTileZ,   mParentTile->getWorldBbox (   ) );
           mIsLoaded = true;
           }
           else if (  mNeedReload )
           {
           mParent->getSceneManager(   )->getListenerManager(   )->fireTileDeformed (  mInfo->mPageX,   mInfo->mPageZ,  
           mInfo->mTileX,   mInfo->mTileZ,   mParentTile->getWorldBbox (   ) );
           mNeedReload = false;
           }
           mRect.left = 0;
           mRect.right = 0;
           mRect.top = 0;
           mRect.bottom = 0;
           mIsRectModified = false;
           mVisible = false;
           mChangedRenderLevel = false;
           mIndex = 0;
           return true;
           }
          
           //-----------------------------------------------------------------------
     486   void PagingLandScapeRenderable::unload(   )
           {
           assert (  mIsLoaded && mInfo );
           assert (  !mQueued );
           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 (  unsigned int i = 0; i < 4; i++ )
           {
           mNeighbors[i] = 0;
           }
           assert (  mParentNode );
           {
           SceneNode * const s = static_cast <SceneNode*>(  mParentNode );
           s->detachObject (  mName );
           s->needUpdate (   );
           }
           mInUse = false;
           mIsLoaded = false;
           mInfo = 0;
           mLastNextLevel = -1;
           mRenderLevel = -1;
           mVisible = false;
           mNeedReload = false;
           mRect.left = 0;
           mRect.right = 0;
           mRect.top = 0;
           mRect.bottom = 0;
           mIsRectModified = false;
           mMinLevelDistSqr = 0;
           }
           //-----------------------------------------------------------------------
     523   void PagingLandScapeRenderable::_notifyCurrentCamera(  Camera* cam )
           {
           if (  mInUse && mIsLoaded && mVisible )
           {
           // if some deformation
           if (  mNeedReload )
           {
           // if between deformation and now,   tile have been unloaded
           if (  !load (   ) )
           {
           mVisible = false;
           return;
           }
           }
           // Horizon occlusion. (  needs data to be loaded or reloaded )
           if (  mParent->getOptions (   )->VisMap )
           {
           PagingLandScapeCamera* plscam = static_cast<PagingLandScapeCamera*> (  cam );
           if(  !mParent->getSceneManager(   )->getHorizon(   )->IsTileVisible(  plscam,   mInfo ) )
           {
           mVisible = false;
           return;
           }
           }
           const int oldRenderLevel = mRenderLevel;
           if (  mForcedMaxLod )
           {
           mRenderLevel = 0;
           mMaterialLODIndex = 0;
           }
           else
           {
           // get distance between renderable and tile and adjust it by the camera bias
           mDistanceToCam = (  getWorldPosition(   ) - cam -> getDerivedPosition(   ) ).squaredLength(   ) * cam->getLodBias (   );
          
           // Material LOD
           if (  !mMaterial.isNull(   )
           && mMaterial->getNumLodLevels(  MaterialManager::getSingleton(   )._getActiveSchemeIndex(   ) ) > 1
            )
           {
           const unsigned short LODIndex = mMaterial->getLodIndexSquaredDepth (  mDistanceToCam );
           if (  LODIndex != mMaterialLODIndex )
           mMaterialLODIndex = LODIndex;
           }
           mRenderLevel = -1;
           const int maxMipmap = static_cast <int> (  mParent->getOptions (   )->maxRenderLevel );
           assert (  mMinLevelDistSqr );
           for (  int i = 0; i < maxMipmap; i++ )
           {
          
           if (  (  *mMinLevelDistSqr )[ i ] > mDistanceToCam )
           {
           mRenderLevel = i - 1;
           break;
           }
           }
           if (  mRenderLevel < 0 )
           mRenderLevel = maxMipmap - 1;
          
           // Get the next LOD level down
           if (  mParent->getOptions (   )->lodMorph )
           {
           // Get the next LOD level down
           const int nextLevel = mNextLevelDown[mRenderLevel];
           if (  nextLevel == 0 )
           {
           // No next level,   so never morph
           mLODMorphFactor = 0.0f;
           mCustomGpuParameters.w = mLODMorphFactor;
           }
           else
           {
           // Set the morph such that the morph happens in the last 0.25 of
           // the distance range
           const Real range = (  *mMinLevelDistSqr )[nextLevel] - (  *mMinLevelDistSqr )[mRenderLevel];
           if (  range )
           {
           const Real percent = (  mDistanceToCam - (  *mMinLevelDistSqr )[mRenderLevel] ) / range;
           // scale result so that msLODMorphStart == 0,   1 == 1,   clamp to 0 below that
           const Real rescale = 1.0f / (  1.0f - mParent->getOptions (   )->lodMorphStart );
           mLODMorphFactor = std::max(  (  percent - mParent->getOptions (   )->lodMorphStart ) * rescale,  
           static_cast<Real>(  0.0f ) );
           mCustomGpuParameters.w = mLODMorphFactor;
           assert (  mLODMorphFactor <= 1.0f );
           }
           else
           {
           // Identical ranges
           mLODMorphFactor = 0.0f;
           mCustomGpuParameters.w = mLODMorphFactor;
           }
           }
           // Bind the correct delta buffer if it has changed
           // nextLevel - 1 since the first entry is for LOD 1 (  since LOD 0 never needs it )
           if (  mLastNextLevel != nextLevel )
           {
           assert (  mDeltaBuffers );
          
           if (  nextLevel > 1 )
           {
           mCurrVertexes->vertexBufferBinding->setBinding(  DELTA_BINDING,  
           mDeltaBuffers[nextLevel - 1] );
           }
           else
           {
           // bind dummy (  in case bindings checked )
           mCurrVertexes->vertexBufferBinding->setBinding(  DELTA_BINDING,  
           mDeltaBuffers[0] );
           }
           }
           mLastNextLevel = nextLevel;
           }
           }
           //// If we change LOD update self and neighbor
           if (  oldRenderLevel != mRenderLevel || mCurrIndexes == 0 )
           {
           update (   );
           for (  unsigned int i = 0; i < 4; i++ )
           {
           PagingLandScapeRenderable * const r = mNeighbors[i];
           if (  r && r->isLoaded (   ) && r->isVisible (   ) )
           r->update (   );
           }
           }
           mVisible = true;
           }
           else
           {
           mVisible = false;
           }
           }
           //-----------------------------------------------------------------------
     655   void PagingLandScapeRenderable::update(   )
           {
           mChangedRenderLevel = true;
           }
           //-----------------------------------------------------------------------
     660   void PagingLandScapeRenderable::_updateRenderQueue(  RenderQueue* queue )
           {
           // Notify need to calculate light list when our sending to render queue
           mLightListDirty = true;
           assert (  mInUse && mParentNode && mIsLoaded && mVisible );
          
           if (  mChangedRenderLevel )
           {
           for (  unsigned int i = 0; i < 4; i++ )
           {
           PagingLandScapeRenderable * const r = mNeighbors[i];
           if (  r && r->isLoaded (   ) && r->isVisible (   ) )
           r->update (   );
           }
           }
           queue->addRenderable(  this );
           }
           //-----------------------------------------------------------------------
     678   Technique* PagingLandScapeRenderable::getTechnique(  void ) const
           {
           return mMaterial->getBestTechnique (  mMaterialLODIndex );
           }
           //-----------------------------------------------------------------------
     683   const LightList& PagingLandScapeRenderable::getLights(  void ) const
           {
           if (  mLightListDirty )
           {
           getParentSceneNode(   )->getCreator(   )->_populateLightList(  
           mCenter,  
           this->getBoundingRadius(   ),  
           mLightList );
           mLightListDirty = false;
           }
           return mLightList;
           }
           //-----------------------------------------------------------------------
     696   Real PagingLandScapeRenderable::getSquaredViewDepth(  const Camera* cam ) const
           {
           // Use squared length to avoid square root
           return (  PagingLandScapeRenderable::getWorldPosition(   ) -
           cam->getDerivedPosition (   ) ).squaredLength(   );
           }
          
           //-----------------------------------------------------------------------
     704   void PagingLandScapeRenderable::getRenderOperation(  RenderOperation& op )
           {
           assert (  mIsLoaded );
           assert (  mInUse );
           assert (  mVisible );
           assert (  mParentNode );
          
           //setup indexes for vertices and uvs...
           op.useIndexes = true;
           op.operationType = RenderOperation::OT_TRIANGLE_LIST;
           op.vertexData = mCurrVertexes;
          
           if (  mChangedRenderLevel )
           {
           mIndex = mParent->getSceneManager(   )->getIndexBufferManager(   )->getIndexData(  mRenderLevel,  
           mNeighbors );
           mChangedRenderLevel = false;
           }
           assert (  mIndex );
           op.indexData = mIndex;
           mParent->addVisible (   );
           }
           //-----------------------------------------------------------------------
     727   void PagingLandScapeRenderable::getWorldTransforms(  Matrix4* xform ) const
           {
           *xform = mParentNode->_getFullTransform(   );
           }
           //-----------------------------------------------------------------------
     732   const Quaternion& PagingLandScapeRenderable::getWorldOrientation(  void ) const
           {
           return mParentNode->_getDerivedOrientation(   );
           }
           //-----------------------------------------------------------------------
     737   const Vector3& PagingLandScapeRenderable::getWorldPosition(  void ) const
           {
           return mCenter;
           }
           //-----------------------------------------------------------------------
     742   void PagingLandScapeRenderable::setMaterial(  const MaterialPtr &mat )
           {
           mMaterial = mat;
           }
           //-----------------------------------------------------------------------
     747   void PagingLandScapeRenderable::_calculateMinLevelDist2(  const Real C )
           {
           //level 0 has no delta.
           PagingLandScapeOptions * const opt = mParent->getOptions(   );
           const bool lodMorph = opt->lodMorph;
           const bool roughnessLod = opt->roughnessLod;
          
           bool doComputeMinLevelDistSqr = mIsRectModified;
           if (  mMinLevelDistSqr == 0 )
           {
           if (  mInfo->mMinLevelDistSqr == 0 )
           {
           mMinLevelDistSqr = new std::vector<Real>(   );
           const size_t numLod = mParent->getOptions (   )->maxRenderLevel;
           mMinLevelDistSqr->reserve(  numLod );
           mMinLevelDistSqr->resize(  numLod );
           doComputeMinLevelDistSqr = true;
          
           mInfo->mMinLevelDistSqr = mMinLevelDistSqr;
           }
           else
           {
           // already computed and in cache.
           mMinLevelDistSqr = mInfo->mMinLevelDistSqr;
           fillNextLevelDown(   );
          
           if (  !doComputeMinLevelDistSqr )
           {
           // no deformation modified
           // no need to recompute it.
           if (  !lodMorph )
           {
           // already computed and in cache.
           // and no lodMorphing...
           // so no need to recompute
           return;
           }
           }
           }
           }
           if (  doComputeMinLevelDistSqr )
           (  *mMinLevelDistSqr )[ 0 ] = 0.0f;
          
           const double inv_scale = 65535.0 / opt->scale.y;
           //const double scale = mParent->getOptions (   )->scale.y / 65535;
          
           const int maxMip = static_cast <int> (  opt->maxRenderLevel );
           const int tilesize = static_cast <int> (  opt->TileSize );
          
           const unsigned int tileSize = opt->TileSize;
          
          // should change if we're just refilling a part
           if (  mIsRectModified )
           {
           // until we find a way to adjust the modification rect
           // on step size
          
           // should also refill the vertex map with deformed point
           // (  BaseHeight )
           mRect.left = 0;
           mRect.right = tileSize;
           mRect.top = 0;
           mRect.bottom = tileSize;
          
           } // if (  mIsRectModified )
          
           const int offSetX = static_cast <int> (  mInfo->mTileX * (  tileSize - 1 ) + mRect.left );
           const int endx = static_cast <int> (  offSetX + static_cast <int> (  mRect.right - mRect.left ) );
          
           const int offSetZ = static_cast <int> (  mInfo->mTileZ * (  tileSize - 1 ) + mRect.top );
           const int IntervallModifiedZ = static_cast <int> (  mRect.bottom - mRect.top );
           const int endz = offSetZ + IntervallModifiedZ;
          
           const int pageSize = static_cast <int> (  opt->PageSize );
          
          
           const size_t blendWeights = 2;
           //const size_t blendWeights = 1;
           assert (  IntervallModifiedZ * tilesize > 0 );
          
           // until we found a way to upload part of the data.
           assert (  IntervallModifiedZ == tilesize );
          
           const size_t size = blendWeights * IntervallModifiedZ * tilesize;
           const size_t buffsize = size * sizeof(  ushort ); // sizeof(  Real );
          
           int K_heightFieldPos;
           ushort *BaseHeight = 0;
           //Real *BaseHeight = 0;
           int i,   j;
          
           const Real * const ogre_restrict heightField = mHeightfield + offSetZ * pageSize;
           if (  lodMorph )// && mIsRectModified ) )
           {
           BaseHeight = new ushort [size];
           //BaseHeight = new Real [size];
           K_heightFieldPos = 0;
           int k = 0;
           for (  j = offSetZ; j < endz; j ++ )
           {
          // should change if we're just refilling a part to whole tile (  only if using discard,   tough )
           for (  i = offSetX; i < endx; i ++ )
           {
           // Save height
           assert (  k < static_cast<int> (  size ) );
           BaseHeight[k] = static_cast<short>
           (  (  heightField[ i + K_heightFieldPos]
           * inv_scale ) - 32768 );
          
           //BaseHeight[k] = static_cast<Real>
           //(  mheightField[ i + K_heightFieldPos] );
          
          
           // should change if we're just refilling a part to whole tile,   using a
           //k += tilesize - IntervalleZ;
           k += blendWeights;
          
           }
           // should change if we're just refilling a part to whole tile,   using a
           //k += tilesize - IntervalleX;
           K_heightFieldPos += pageSize;
           }
           }
           //const ushort * const heightField = BaseHeight;
           //const Real * const heightField = BaseHeight;
          
          
           Plane t1,   t2;
           const Real Csqr = C * C;
           for (  int level = 1; level < maxMip; level++ )
           {
           ushort *pDeltaInit = 0;
           //Real *pDeltaInit = 0;
           if (  BaseHeight )
           {
           const size_t lvl_minus_one = level - 1;
          
           // Create a set of delta values (  store at index - 1 since 0 has none )
          
          // should change to an interval locking (  as in load ) ? if we're just refilling a part to whole tile
           pDeltaInit = static_cast<ushort*> (  
           mDeltaBuffers[lvl_minus_one]->lock(  HardwareBuffer::HBL_DISCARD ) );
          
           memcpy (  pDeltaInit,   BaseHeight,   buffsize );
           assert (  pDeltaInit );
           } // if (  BaseHeight )
          
           ushort * const pDeltas = pDeltaInit;
          // should keep previous change in case of partial tile refilling ?
          // But how could we lower value ? (  if terrain goes smoother )
           if (  doComputeMinLevelDistSqr )
           (  *mMinLevelDistSqr )[ level ] = 0.0f;
          
           const int step = 1 << level;
          
          // find a way to take a good step end and start
          // even with offset that would make us in "middle of a step"
           const int tilesizeMinusstepZ = endz - step;
           const int tilesizeMinusstepX = endx - step;
           const Real invStep = 1.0f / step;
          
           K_heightFieldPos = 0;
           const int ZShift = step * pageSize;
          
           for (  j = offSetZ; j < tilesizeMinusstepZ; j += step )
           {
           for (  i = offSetX; i < tilesizeMinusstepX; i += step )
           {
           //added for Ember
           bool isInValidVertex;
           {
           const Vector3 v1(  i,   heightField[ i + K_heightFieldPos ],   j );
           const Vector3 v2(  i + step,   heightField[ i + step + K_heightFieldPos ],   j );
           const Vector3 v3(  i,   heightField[ i + K_heightFieldPos + ZShift],   j + step );
           const Vector3 v4(  i + step,   heightField[ i + step + K_heightFieldPos + ZShift],   j + step );
          
           t1.redefine(  v1,   v3,   v2 );
           t2.redefine(  v2,   v3,   v4 );
           //only update the distance if none of the heights are -1.0
           //this is to allow for invalid Mercator::Segments without messing up the tricount
           //the reason is that Ember will set the height for all invalid segments to -1
           //if such a segment was to be next to a normal segment,   the delta would be way to high,  
           //resulting in a tile which was always in LOD 0
           isInValidVertex = v1.y == -1.0 || v2.y == -1.0 || v3.y == -1.0 || v4.y == -1.0;
           }
          
           if (  !isInValidVertex ) {
           // include the bottommost row of vertices if this is the last row
           const int zubound = (  j == (  tilesizeMinusstepZ )? step : step - 1 );
           for (  int z = 0; z <= zubound; z++ )
           {
           const int fulldetailz = j + z;
           const Real zpct = z * invStep;
           const bool isFullDetailZ = (  fulldetailz % step == 0 );
           const int zPageSize = z * pageSize;
           {
           // include the rightmost col of vertices if this is the last col
           const int xubound = (  i == (  tilesizeMinusstepX )? step : step - 1 );
           for (  int x = 0; x <= xubound; x++ )
           {
           const int fulldetailx = i + x;
          
           if (  isFullDetailZ &&
           fulldetailx % step == 0 )
           {
           // Skip,   this one is a vertex at this level
           continue;
           }
           const Real xpct = x * invStep;
          
           //interpolated height
           Real interp_h;
           // Determine which triangle we're on
           if (  xpct + zpct <= 1.0f )
           {
           // Solve for x/z
           interp_h =
           (  -(  t1.normal.x * fulldetailx )
           - t1.normal.z * fulldetailz
           - t1.d ) / t1.normal.y;
           }
           else
           {
           // Second triangle
           interp_h =
           (  -(  t2.normal.x * fulldetailx )
           - t2.normal.z * fulldetailz
           - t2.d ) / t2.normal.y;
           }
          
           assert (  (  fulldetailx + K_heightFieldPos + zPageSize ) < (  pageSize*pageSize ) );
          
           const Real actual_h = heightField[ fulldetailx + K_heightFieldPos + zPageSize];
           const Real delta = interp_h - actual_h;
           if (  doComputeMinLevelDistSqr )
           {
           // need to recompute it.
           const Real D2 = (  roughnessLod )? delta * delta * Csqr: Csqr;
          
           if (  (  *mMinLevelDistSqr )[ level ] < D2 )
           (  *mMinLevelDistSqr )[ level ] = D2;
           }
          
           // Should be save height difference?
           // Don't morph along edges
           if (  lodMorph )
           {
           // Save height difference
           if (  delta != 0.0f )
           {
           const int tileposx = fulldetailx - offSetX;
           const int tileposy = fulldetailz - offSetZ;
          
           if (  tileposx != 0 && tileposx != (  tilesize - 1 ) &&
           tileposy != 0 && tileposy != (  tilesize - 1 ) )
           {
          
           assert (  (  tileposx + (  tileposy * tilesize ) )*blendWeights < size );
          
           pDeltas[(  tileposx + (  tileposy * tilesize ) )*blendWeights] =
           static_cast<short>
           (  (  interp_h * inv_scale ) - 32768 );
           // pDeltas[(  tileposx + (  tileposy * tilesize ) )*blendWeights] =
           // interp_h;
           }
           }
           }
           }
          
           }
           }
           }
           }
           K_heightFieldPos += pageSize * step;
           }
          
           // Unlock morph deltas if required
           if (  lodMorph )
           mDeltaBuffers[level - 1]->unlock(   );
           }
           // delete Height Data cache and Buffer initial value.
           delete[] BaseHeight;
          
          
           if (  doComputeMinLevelDistSqr )
           {
           if (  roughnessLod )
           {
           // Post validate the whole set
           for (  i = 1; i < maxMip; i++ )
           {
          
           // Make sure no LOD transition within the tile
           // This is especially a problem when using large tiles with flat areas
          
           /* Hmm,   this can look bad on some areas,   disable for now
           Vector3 delta(  _vertex(  0,  0,  0 ),   mCenter.y,   _vertex(  0,  0,  2 ) );
           delta = delta - mCenter;
           Real minDist = delta.squaredLength(   );
           mMinLevelDistSqr[ i ] = std::max(  mMinLevelDistSqr[ i ],   minDist );
           */
          
           //make sure the levels are increasing...
           if (  (  *mMinLevelDistSqr )[ i ] < (  *mMinLevelDistSqr )[ i - 1 ] )
           (  *mMinLevelDistSqr )[ i ] = (  *mMinLevelDistSqr )[ i - 1 ];
           }
           }
           else
           {
           const int maxMip = static_cast <int> (  mParent->getOptions (   )->maxRenderLevel ) - 1;
           Real distanceLod = mParent->getOptions (   )->LOD_factor;
           for (  int level = 1; level < maxMip; level++ )
           {
           (  *mMinLevelDistSqr )[level] = distanceLod;
           distanceLod *= 2;
          
           }
           }
           fillNextLevelDown(   );
           }
           }
           //-----------------------------------------------------------------------
    1069   void PagingLandScapeRenderable::fillNextLevelDown(  void )
           {
           // reverse traverse the mMinLevelDistSqr list in order to set
           // the 'next level down'
           Real lastDist = -1;
           int lastIndex = 0;
           const int maxMip = static_cast <int> (  mParent->getOptions (   )->maxRenderLevel ) - 1;
           for (  int i = maxMip; i >= 0; --i )
           {
           assert (  i >= 0 );
           if (  i == maxMip  )
           {
           // Last one is always 0
           lastIndex = i;
           lastDist = (  *mMinLevelDistSqr )[i];
           mNextLevelDown[i] = 0;
           }
           else
           {
           mNextLevelDown[i] = lastIndex;
           if (  (  *mMinLevelDistSqr )[i] != lastDist )
           {
           lastIndex = i;
           lastDist = (  *mMinLevelDistSqr )[i];
           }
           }
           }
           }
          
           //-----------------------------------------------------------------------
    1099   HardwareVertexBufferSharedPtr PagingLandScapeRenderable::createDeltaBuffer(  void ) const
           {
           // Delta buffer is a 1D Real buffer of height offsets
           HardwareVertexBufferSharedPtr buf =
           HardwareBufferManager::getSingleton(   ).createVertexBuffer(  
           VertexElement::getTypeSize(  VET_SHORT2 ),  
           //VertexElement::getTypeSize(  VET_SHORT1 ),  
           //VertexElement::getTypeSize(  VET_FLOAT1 ),  
           mParent->getOptions (   )->TileSize * mParent->getOptions (   )->TileSize,  
           HardwareBuffer::HBU_STATIC_WRITE_ONLY );
           // HardwareBuffer::HBU_STATIC );
          
           return buf;
          
           }
           //-----------------------------------------------------------------------
    1115   Real PagingLandScapeRenderable::_vertex(  const int x,   const int z,   const int n ) const
           {
           const unsigned int tilesize = mParent->getOptions (   )->TileSize - 1;
           switch (  n )
           {
           case 0:
           return (  (  mInfo->mTileX * tilesize ) + x )* mParent->getOptions (   )->scale.x;
           case 1:
           return mHeightfield[(  (  mInfo->mTileX * tilesize ) + x ) +
           (  (  mInfo->mTileZ * tilesize ) + z ) * mParent->getOptions (   )->PageSize ];
           case 2:
           return (  (  mInfo->mTileZ * tilesize ) + z )* mParent->getOptions (   )->scale.z;
           default:
           return 0.0f;
           }
           }
           //-----------------------------------------------------------------------
    1132   void PagingLandScapeRenderable::_updateCustomGpuParameter(  
    1133   const GpuProgramParameters::AutoConstantEntry& constantEntry,  
    1134   GpuProgramParameters* params ) const
           {
           if (  constantEntry.data == MORPH_CUSTOM_PARAM_ID )
           {
           // Update morph LOD factor
           //params->setConstant(  constantEntry.index,   mLODMorphFactor );
           params->setNamedConstant(  "compressionSettings",   mCustomGpuParameters );
           }
           else
           {
           Renderable::_updateCustomGpuParameter(  constantEntry,   params );
           }
          
           }
           //-----------------------------------------------------------------------
    1149   void PagingLandScapeRenderable::adjustDeformationRectangle(  unsigned int x,   unsigned int z )
           {
           assert (  x < mParent->getOptions (   )->TileSize && z < mParent->getOptions (   )->TileSize );
           if (  mIsRectModified )
           {
           if (  mRect.left > x )
           mRect.left = x;
           if (  mRect.right < x )
           mRect.right = x;
          
           if (  mRect.top > z )
           mRect.top = z;
           if (  mRect.bottom < z )
           mRect.bottom = z;
           }
           else
           {
           // first modification :
           // deformation rectangle is the point
          
           mRect.left = x;
           mRect.right = x;
           mRect.top = z;
           mRect.bottom = z;
           mIsRectModified = true;
           mNeedReload = true;
           }
           }
          
           //-----------------------------------------------------------------------
    1179   uint32 PagingLandScapeRenderable::getTypeFlags(  void ) const
           {
           // return world flag
           return SceneManager::WORLD_GEOMETRY_TYPE_MASK;
           }
           //-----------------------------------------------------------------------
    1185   void PagingLandScapeRenderable::_notifyAttached(  Node* parent,   bool isTagPoint )
           {
           MovableObject::_notifyAttached(  parent,   isTagPoint );
           if (  parent )
           {
           assert (  mIsLoaded );
           mCenter = mBounds.getCenter(   ) + mParentNode->getWorldPosition(   );
           mWorldBoundingSphere.setCenter(  mCenter );
           mWorldBoundingSphere.setRadius(  (  mBounds.getMaximum(   ) - mBounds.getMinimum(   ) ).length(   ) / 2 );
           mParentNode->needUpdate(   );
           }
           }
           //-----------------------------------------------------------------------
    1198   Vector3 PagingLandScapeRenderable::_getvertex(  const int x,   const int z ) const
           {
           const unsigned int tilesize = mParent->getOptions (   )->TileSize - 1;
           const unsigned int pSize = mParent->getOptions (   )->PageSize -1;
           Vector3 vertex;
          
           vertex.x = (  mInfo->mTileX * tilesize ) + x;
          
           vertex.z = (  mInfo->mTileZ * tilesize ) + z;
          
           vertex.y = mHeightfield[static_cast<unsigned int>(  vertex.x + (  vertex.z *mParent->getOptions (   )->PageSize )  )];
          
           vertex.x += mInfo->mPageX * pSize - mParent->getOptions (   )->maxUnScaledX;
           vertex.z += mInfo->mPageZ * pSize - mParent->getOptions (   )->maxUnScaledZ;
          
           vertex.x *= mParent->getOptions (   )->scale.x;
           vertex.z *= mParent->getOptions (   )->scale.z;
           return vertex;
           }
          
           /**
           * This returns the actual Polygon assignments for this renderable at the given renderLevel
           * @param renderlevel LODLevel to get the Index data at
           * @return the queried IndexData
           */
    1223   IndexData* PagingLandScapeRenderable::getRawIndexData(  const int renderlevel )
           {
           return mParent->getSceneManager(   )->getIndexBufferManager(   )->getRawIndexes(   renderlevel );
           }
          
           /**
           * Returns the Vertices for this renderable in world space
           * @param pVerts >Pre-allocated< buffer to hold the vertices. The number of Vertices can be
           * retrieved by a call to getVertexCount
           * @note no checking is done on the array whatsoever
           */
    1234   void PagingLandScapeRenderable::getRawVertexData(  Vector3* pVerts )
           {
           // pVerts should be pre-allocated to tilesize*tilesize
           // using getVertexCount(   )
           const unsigned int tilesize = mParent->getOptions (   )->TileSize -1 ;
          
           Vector3 *vert = pVerts;
           Vector3 snPosition = mParent->getOptions (   )->position;
           Vector3 tmpVertex;
          
           for (  unsigned int i=0; i<=tilesize; ++i )
           {
           for (  unsigned int j=0; j<=tilesize; ++j )
           {
           tmpVertex = _getvertex(  j,   i );
           tmpVertex += snPosition; // translate current vertex relatively parent SN position
           *vert++= tmpVertex;
           }
           }
           }
          
           /**
           * Returns the number of this Renderable's vertices
           * @return the number of this Renderable's vertices
           */
    1259   const unsigned int PagingLandScapeRenderable::getVertexCount(   )
           {
           return mParent->getOptions (   )->TileSize * mParent->getOptions (   )->TileSize ;
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeRenderableManager.cpp

       1  /***************************************************************************
           OgrePagingLandScapeRenderableManager.cpp - description
           -------------------
           begin : Mon Jun 16 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreMovableObject.h"
          
          #include "OgreCamera.h"
          
          #include "OgreSceneNode.h"
          
          #include "OgreSimpleRenderable.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeCamera.h"
          
          #include "OgrePagingLandScapeRenderable.h"
          #include "OgrePagingLandScapeIndexBuffer.h"
          
          #include "OgrePagingLandScapeRenderableManager.h"
          
          #include "OgrePagingLandScapeTile.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
      46   PagingLandScapeRenderableSet::PagingLandScapeRenderableSet(   ):
           PoolSet<PagingLandScapeRenderable>(   ),  
           mRenderableManager(  0 )
           {
           }
           //-----------------------------------------------------------------------
      52   PagingLandScapeRenderable* PagingLandScapeRenderableSet::allocate (   )
           {
           return new PagingLandScapeRenderable(  mRenderableManager );
           }
           //-----------------------------------------------------------------------
      57   void PagingLandScapeRenderableSet::deallocate (  PagingLandScapeRenderable *r )
           {
           delete r;
           }
           //-----------------------------------------------------------------------
      62   PagingLandScapeRenderableManager::PagingLandScapeRenderableManager(  PagingLandScapeSceneManager * scnMgr ):
           mSceneManager(  scnMgr ),  
           mOptions(  scnMgr->getOptions (   ) ),  
           mRenderableLoadInterval (  0 ),  
           mLoadInterval(  0 ),  
           mNumRenderableLoading(  0 )
           {
           // auto extend ourself as we rather check
           //if we can found non Freed Renderables before
           mRenderablePool.setAutoextend (  false );
           // don't Double renderables num each time... too much.
           mRenderablePool.setExtendFactor (  1.2f );
           }
           //-----------------------------------------------------------------------
      76   PagingLandScapeRenderableManager::~PagingLandScapeRenderableManager(   )
           {
           mRenderablePool.deletePool (   );
           }
           //-----------------------------------------------------------------------
      81   void PagingLandScapeRenderableManager::clear(   )
           {
           if (  !mTilesLoadRenderableQueue.empty (   ) )
           {
           PagingLandScapeTile *t = mTilesLoadRenderableQueue.pop(   );
           while (  t )
           {
           t->uninit (   );
           t = mTilesLoadRenderableQueue.pop (   );
           }
           assert (  mTilesLoadRenderableQueue.empty (   ) );
           }
           // As Renderables change too much over maps (  +- lit,   normals,   etc... )
           mRenderablePool.deletePool (   );
           }
           //-----------------------------------------------------------------------
      97   void PagingLandScapeRenderableManager::load(   )
           {
           mRenderablePool.setRenderableManager (  this );
          
           PagingLandScapeOptions *opt = mOptions;
          
           mNumRenderableLoading = opt->num_renderables_loading;
           mNumRenderablesIncrement = opt->num_renderables_increment;
           mRenderableLoadInterval = opt->RenderableLoadInterval;
           mRenderablePool.setPoolSize (  opt->num_renderables );
           mTilesLoadRenderableQueue.clear(   );
           }
           //-----------------------------------------------------------------------
     110   PagingLandScapeRenderable *PagingLandScapeRenderableManager::getRenderable(   )
           {
           PagingLandScapeRenderable *r = mRenderablePool.getPoolable (   );
           if (  r == 0 )
           {
           // unload some Tiles/renderables no more used to free some space.
           processTileUnload (   );
          
           r = mRenderablePool.getPoolable (   );
           if (  r == 0 )
           {
           mRenderablePool.autoExtend(   );
           r = mRenderablePool.getPoolable(   );
           }
           }
           return r;
           }
           //-----------------------------------------------------------------------
     128   void PagingLandScapeRenderableManager::freeRenderable(  PagingLandScapeRenderable *rend )
           {
           assert (  rend->mParentTile == 0 );
           mRenderablePool.removePoolable(  rend );
           }
           //-----------------------------------------------------------------------
     134   void PagingLandScapeRenderableManager::queueRenderableLoading(  PagingLandScapeTile *tile )
           {
           assert (  tile );
          
           assert (  !tile->isLoading(   ) );
           assert (  tile->getRenderable (   ) );
           assert (  !tile->getRenderable (   )->mQueued );
          
           assert (  tile->isLoaded (   ) );
           assert (  !tile->getRenderable (   )->isLoaded (   ) );
           assert (  tile->getRenderable (   )->isInUse (   ) );
          
           //
           tile->setLoading(  true );
           tile->getRenderable (   )->mQueued = true;
          
           //
           mTilesLoadRenderableQueue.push (  tile );
          
           }
           //-----------------------------------------------------------------------
     155   void PagingLandScapeRenderableManager::unqueueRenderable (  PagingLandScapeTile *tile )
           {
           assert (  tile->isLoading(   ) );
           assert (  tile->getRenderable (   ) );
           assert (  tile->getRenderable (   )->mQueued );
          
           assert (  tile->isLoaded (   ) );
           assert (  !tile->getRenderable (   )->isLoaded (   ) );
           //assert (  !tile->getRenderable (   )->isInUse (   ) );
          
           //
           tile->setLoading (  false );
           tile->getRenderable (   )->mQueued = false;
          
           //
           mTilesLoadRenderableQueue.remove (  tile );
           }
           //-----------------------------------------------------------------------
     173   void PagingLandScapeRenderableManager::processTileUnload(   )
           {
           if (  mTilesLoadRenderableQueue.empty(   ) )
           return;
          
           PagingLandScapeTile *tile;
           for (  PagingLandScapeQueue<PagingLandScapeTile>::MsgQueType::iterator itq = mTilesLoadRenderableQueue.begin(   );
           itq != mTilesLoadRenderableQueue.end(   ); )
           {
           tile = *itq;
           assert (  tile != 0 );
          
           assert (  tile->isLoading(   ) );
           assert (  tile->getRenderable (   ) );
           assert (  tile->getRenderable (   )->mQueued );
          
           assert (  tile->isLoaded (   ) );
           assert (  tile->getSceneNode(   ) );
           assert (  !tile->getRenderable (   )->isLoaded (   ) );
          
           if (  !tile->getRenderable (   )->isInUse (   ) )
           {
           tile->setLoading (  false );
           tile->getRenderable (   )->mQueued = false;
           tile->unload (   );
           itq = mTilesLoadRenderableQueue.erase (  itq );
           }
           else
           {
           ++itq;
           }
           }
           }
           //-----------------------------------------------------------------------
     207   bool PagingLandScapeRenderableManager::executeRenderableLoading(  const Vector3 &Cameraposition )
           {
           if (  mTilesLoadRenderableQueue.empty(   ) )
           {
           return true;
           }
           else
           {
           if (  mLoadInterval-- < 0 )
           {
           const size_t queueSize = mTilesLoadRenderableQueue.getSize (   ) ;
           mTilesLoadRenderableQueue.sortNearest(  Cameraposition );
           const size_t k = mNumRenderableLoading > queueSize ? queueSize : mNumRenderableLoading;
           for (  size_t i = 0; i < k; i++ )
           {
          
           PagingLandScapeTile * const tile = mTilesLoadRenderableQueue.pop (   );
           // no more in queues.
           assert (  tile != 0 );
           assert (  tile->isLoaded (   ) );
           assert (  tile->isLoading(   ) );
           PagingLandScapeRenderable * const rend = tile->getRenderable (   );
          
           assert (  rend != 0 );
           assert (  rend->mParentTile == tile );
           assert (  rend->mQueued );
           assert (  !rend->isLoaded (   ) );
           SceneNode * const tileSceneNode = tile->getSceneNode (   );
           assert (  tileSceneNode != 0 );
          
          
           // if renderable can be loaded
           if (  rend->load (   ) )
           {
           tileSceneNode->attachObject (  rend );
           tile->_linkRenderableNeighbor (   );
           }
           else
           {
           // (  no data yet. ) empty tile.
           tile->unload (   );
           }
          
           tile->setLoading(  false );
           rend->mQueued = false;
          
           tileSceneNode->needUpdate (   );
           }
           mLoadInterval = mRenderableLoadInterval;
           }
           }
           return false;
           }
          
           //-----------------------------------------------------------------------
     262   size_t PagingLandScapeRenderableManager::numRenderables(  void ) const
           {
           return static_cast< size_t > (  mRenderablePool.getPoolSize(   ) );
           }
          
           //-----------------------------------------------------------------------
     268   size_t PagingLandScapeRenderableManager::numFree(  void ) const
           {
           return mRenderablePool.getPoolSize(   ) - mRenderablePool.getActivePoolablesSize (   );
           }
          
           //-----------------------------------------------------------------------
     274   size_t PagingLandScapeRenderableManager::numLoading(  void ) const
           {
           return mTilesLoadRenderableQueue.getSize(   );
           }
           //-----------------------------------------------------------------------
     279   void PagingLandScapeRenderableManager::_addBatch(  const unsigned int num )
           {
           mRenderablePool.setPoolSize (  mRenderablePool.getPoolSize(   ) + num );
           #ifdef _DEBUG
           std::cout << "Renderables addBatch : " << mRenderablePool.getPoolSize(   ) << "\n";
           #endif
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeSceneManager.cpp

          /***************************************************************************
           OgrePagingLandScapeSceneManager.cpp - description
           -------------------
           begin : Mon May 12 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          
          
          #include "OgreRoot.h"
          #include "OgreSceneManager.h"
          #include "OgreVector2.h"
          #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 "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeRenderableManager.h"
          #include "OgrePagingLandScapeTextureCoordinatesManager.h"
          #include "OgrePagingLandScapeRenderable.h"
          #include "OgrePagingLandScapeTextureManager.h"
          #include "OgrePagingLandScapeTexture.h"
          #include "OgrePagingLandScapePageManager.h"
          #include "OgrePagingLandScapeTile.h"
          #include "OgrePagingLandScapeTileInfo.h"
          #include "OgrePagingLandScapeTileManager.h"
          #include "OgrePagingLandScapeRenderable.h"
          #include "OgrePagingLandScapeRenderableManager.h"
          #include "OgrePagingLandScapeAxisAlignedBoxSceneQuery.h"
          #include "OgrePagingLandScapeRaySceneQuery.h"
          #include "OgrePagingLandScapeCamera.h"
          #include "OgrePagingLandScapeMeshDecal.h"
          
          #include "OgrePagingLandScapeListenerManager.h"
          
          #include "OgrePagingLandScapeSceneManager.h"
          
          #include "OgrePagingLandScapeHorizon.h"
          
          namespace Ogre
          {
          
           //-----------------------------------------------------------------------
           const String PagingLandScapeSceneManagerFactory::FACTORY_TYPE_NAME = "PagingLandScapeSceneManager";
           //-----------------------------------------------------------------------
      65   void PagingLandScapeSceneManagerFactory::initMetaData(  void ) const
           {
           mMetaData.typeName = FACTORY_TYPE_NAME;
           mMetaData.description = "Scene manager organising the scene on the basis of an octree,   and paging heightmap when needed.";
           mMetaData.sceneTypeMask = ST_EXTERIOR_REAL_FAR; // support all types
           mMetaData.worldGeometrySupported = true;
           }
           //-----------------------------------------------------------------------
      73   SceneManager* PagingLandScapeSceneManagerFactory::createInstance(  
      74   const String& instanceName )
           {
           return new PagingLandScapeSceneManager(  instanceName );
           }
           //-----------------------------------------------------------------------
      79   void PagingLandScapeSceneManagerFactory::destroyInstance(  SceneManager* instance )
           {
           delete instance;
           }
           //-----------------------------------------------------------------------
      84   PagingLandScapeSceneManager::PagingLandScapeSceneManager(  const String& name ) :
           PagingLandScapeOctreeSceneManager(  name ),  
           mData2DManager (  0 ),  
           mTextureManager (  0 ),  
           mTileManager (  0 ),  
           mRenderableManager (  0 ),  
           mIndexesManager (  0 ),  
           mTexCoordManager (  0 ),  
           mPageManager (  0 ),  
           mHorizon (  0 ),  
           mNeedOptionsUpdate (  false ),  
           //JEFF
           mWorldGeomIsSetup (  false ),  
           // TK
           mWorldGeomIsInit (  false ),  
           mBrushSize (  5 ),  
           mBrushScale (  0.2f ),  
     101   mImpactInfo (  0 ),  
           mBrushCenter (  Vector3::ZERO ),  
           mBrushArray (  0 ),   mCraterArray(  0 ),  
           mBrushArrayHeight (  0 ),  
           mBrushArrayWidth (  0 ),  
           mListenerManager(  0 ),  
           mOptions(  0 ),  
           textureFormatChanged (  false )
           {
           //showBoundingBoxes(  true );
           //setDisplaySceneNodes(  true );
          
           mMeshDecalFactory = new PagingLandScapeMeshDecalFactory;
           if(   !(  Root::getSingleton(   ).hasMovableObjectFactory(  "PagingLandScapeMeshDecal" ) )  )
           Root::getSingleton(   ).addMovableObjectFactory(   mMeshDecalFactory  );
           }
           //-------------------------------------------------------------------------
     118   const String& PagingLandScapeSceneManager::getTypeName(  void ) const
           {
           return PagingLandScapeSceneManagerFactory::FACTORY_TYPE_NAME;
           }
           //-----------------------------------------------------------------------
     123   void PagingLandScapeSceneManager::PagingLandScapeOctreeResize(   )
           {
           const Ogre::Real x = mOptions->maxScaledX;
           assert (  mData2DManager );
           const Ogre::Real y = mData2DManager->getMaxHeight (   ) * 4;
           const Ogre::Real z = mOptions->maxScaledZ;
           PagingLandScapeOctreeSceneManager::resize(  AxisAlignedBox(  -x ,   0,   -z,   x,   y,   z ) );
           }
           //-----------------------------------------------------------------------
     132   void PagingLandScapeSceneManager::WorldDimensionChange(   )
           {
           PagingLandScapeOctreeResize(   );
          
           assert (  mPageManager );
           assert (  mData2DManager );
           assert (  mTextureManager );
           mPageManager->WorldDimensionChange(   );
           mData2DManager->WorldDimensionChange(   );
           mTextureManager->WorldDimensionChange(   );
           }
           //-------------------------------------------------------------------------
     144   void PagingLandScapeSceneManager::shutdown(  void )
           {
           clearScene(   );
          
           delete mOptions;
           mOptions = 0;
          
           delete mData2DManager;
           mData2DManager = 0;
           delete mTextureManager;
           mTextureManager = 0;
          
           if (  mPageManager )
           Root::getSingleton(   ).removeFrameListener (  mPageManager );
           delete mPageManager;
           mPageManager = 0;
          
           delete mListenerManager;
           mListenerManager = 0;
           delete mTileManager;
           mTileManager = 0;
           delete mRenderableManager;
           mRenderableManager = 0;
          
           delete mIndexesManager;
           mIndexesManager = 0;
           delete mTexCoordManager;
           mTexCoordManager = 0;
          
           delete[] mCraterArray;
           mCraterArray = 0;
          
           Root::getSingleton(   ).removeMovableObjectFactory(   mMeshDecalFactory  );
           delete mMeshDecalFactory;
           }
           //-----------------------------------------------------------------------
     180   PagingLandScapeSceneManager::~PagingLandScapeSceneManager(   )
           {
           shutdown(   );
           }
           //-------------------------------------------------------------------------
     185   void PagingLandScapeSceneManager::setWorldGeometry(  DataStreamPtr& stream,   const String& typeName )
           {
           if (  !mListenerManager )
           mListenerManager = new PagingLandScapeListenerManager(  this );
           // Clear out any existing world resources (  if not default )
           if (  ResourceGroupManager::getSingleton(   ).getWorldResourceGroupName(   ) !=
           ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME )
           {
           ResourceGroupManager::getSingleton(   ).clearResourceGroup(  
           ResourceGroupManager::getSingleton(   ).getWorldResourceGroupName(   ) );
           }
          
           if (  mWorldGeomIsSetup )
           clearScene(   );
           if (  !mOptions )
           mOptions = new PagingLandScapeOptions(  this );
           InitScene (   );
           // Load the configuration file
           if (  !stream.isNull (   ) )
           {
           if (  mOptions->load(  stream ) )
           loadScene (   );
           }
           // Check if we need to set the camera
           if (  !mOptions->primaryCamera && !mCameras.empty (   ) )
           {
           PagingLandScapeCamera* c = static_cast <PagingLandScapeCamera*> (  mCameras.begin(   )->second );
           mOptions->setPrimaryCamera (  c );
           }
           }
           //-----------------------------------------------------------------------
     216   void PagingLandScapeSceneManager::setWorldGeometry(  const String& filename )
           {
           if (  filename.empty(   ) )
           {
          #ifdef PLSM2_EIHORT
           DataStreamPtr myStream;
          #else
           DataStreamPtr myStream (  0 );
          #endif
           myStream.setNull(   );
           setWorldGeometry (  myStream );
           return;
           }
          
           // try to open in the current folder first
           std::ifstream fs;
           fs.open(  filename.c_str(   ),   std::ios::in | std::ios::binary );
           if (  fs )
           {
           // Wrap as a stream
           DataStreamPtr myStream (  new FileStreamDataStream (  filename,   &fs,   false ) );
           setWorldGeometry (  myStream );
           return;
           }
          
           // otherwise try resource system
           DataStreamPtr myStream (  ResourceGroupManager::getSingleton(   ).openResource(  filename ) );
           setWorldGeometry (  myStream );
           }
           //-----------------------------------------------------------------------
     246   void PagingLandScapeSceneManager::InitScene (   )
           {
           // Only initialized once
           // not to loose use listeners
           if (  !mListenerManager )
           mListenerManager = new PagingLandScapeListenerManager(  this );
           if (  !mTileManager )
           mTileManager = new PagingLandScapeTileManager(  this );
           if (  !mData2DManager )
           mData2DManager = new PagingLandScapeData2DManager(  this,   mOptions ); //
           if (  !mTextureManager )
           mTextureManager = new PagingLandScapeTextureManager(  this );
           if (  !mIndexesManager )
           mIndexesManager = new PagingLandScapeIndexBufferManager(  this );
           if (  !mTexCoordManager )
           mTexCoordManager = new PagingLandScapeTextureCoordinatesManager(  this );
           if (  !mRenderableManager )
           mRenderableManager = new PagingLandScapeRenderableManager(  this );
           if (  !mCraterArray )
           resizeCrater(   );
           if (  !mPageManager )
           {
           mPageManager = new PagingLandScapePageManager(  this );
           Root::getSingleton(   ).addFrameListener(  mPageManager );
          
           mPageManager->setWorldGeometryRenderQueue (  static_cast<Ogre::RenderQueueGroupID>(  SceneManager::getWorldGeometryRenderQueue(   ) ) );
           mData2DManager->setPageManager(  this );
           }
           }
           //-----------------------------------------------------------------------
     276   void PagingLandScapeSceneManager::loadScene(   )
           {
           if (  !mWorldGeomIsSetup )
           {
           // listen to frames to update queues independently of cam numbers.
           // cannot do that if remove is called in same frame before it removes it
           // ...
           //Root::getSingleton(   ).addFrameListener(  mPageManager );
           mPageManager->setEnabled (  true );
          
           mTileManager->load(   );
           mData2DManager->load(   );
           mTextureManager->load(   );
           mIndexesManager->load(   );
           mTexCoordManager->load(   );
           if (  mOptions->VisMap )
           {
           assert (  !mHorizon );
           mHorizon = new PagingLandScapeHorizon(  mOptions );
           }
           mPageManager->load(   );
           mRenderableManager->load(   );
          
           // reset camera paging
           // register existing camera in node
           CameraList::iterator i = mCameras.begin(   );
           for (  ; i != mCameras.end(   ); ++i )
           {
           // Notify occlusion system
           PagingLandScapeCamera *c = static_cast <PagingLandScapeCamera *> (  i->second );
           assert (  c );
           c->resetPaging (   );
           }
           PagingLandScapeOctreeResize(   );
          
          
          
           mWorldGeomIsSetup = true;
          
          
           }
           }
           //-----------------------------------------------------------------------
     319   void PagingLandScapeSceneManager::clearScene(  void )
           {
           //SceneManager::getRenderQueue(   )->clear(   );
           PagingLandScapeSceneManager::resetScene(   );
           //Call the default
           PagingLandScapeOctreeSceneManager::clearScene(   );
           }
           //-----------------------------------------------------------------------
     327   void PagingLandScapeSceneManager::resetScene(  void )
           {
           if (  mWorldGeomIsSetup )
           {
           //Root::getSingleton(   ).removeFrameListener (  mPageManager );
           mPageManager->setEnabled (  false );
           // clear the Managers
           mPageManager->clear(   );
           mTextureManager->clear(   );
           mData2DManager->clear(   );
           if (  mHorizon )
           {
           delete mHorizon;
           mHorizon = 0;
           }
           // clear queues
           mRenderableManager->clear(   );
           mTileManager->clear(   );
          
           // unload cached map info
           mOptions->clearTileInfo(   );
          
           // clear hardware buffer caches
           //mIndexesManager->clear(   ); //don't clear to keep index buffer if tilesize
           //mTexCoordManager->clear(   ); //don't clear to keep index buffer if tilesize
          
           mWorldGeomIsSetup = false;
           mWorldGeomIsInit = false;
          
           //PagingLandScapeOctreeSceneManager::clearScene(   );
           }
           }
           //-----------------------------------------------------------------------
     360   void PagingLandScapeSceneManager::_updateSceneGraph(  Camera * cam )
           {
           // entry into here could come before setWorldGeometry
           // got called which could be disastrous
           // so check for init
           assert(  mPageManager );
           if (  isRenderQueueToBeProcessed(  mPageManager->getPageRenderQueue(   ) ) )
           {
           if (  mWorldGeomIsInit )
           {
           mPageManager->updatePaging (  static_cast<PagingLandScapeCamera *> (  cam ) );
           }
           else
           {
           if (  mWorldGeomIsSetup )
           {
           mOptions->calculateCFactor (   );
           assert (  mPageManager );
           if (  mOptions->BigImage )
           {
           assert (  mTextureManager );
          
           mTextureManager->setMapMaterial(   );
           mPageManager->setMapMaterial(   );
           }
           mWorldGeomIsInit = true;
           mPageManager->updatePaging (  static_cast<PagingLandScapeCamera *> (  cam ) );
           }
           }
           }
           // Call the default
           PagingLandScapeOctreeSceneManager::_updateSceneGraph(  cam );
           }
           //-----------------------------------------------------------------------
          // void PagingLandScapeSceneManager::_renderVisibleObjects(  void )
          // {
          // SceneManager::_renderVisibleObjects(   );
          // }
          
           //-----------------------------------------------------------------------
          // void PagingLandScapeSceneManager::_findVisibleObjects (  Camera * cam,   bool onlyShadowCasters )
          // {
          // PagingLandScapeOctreeSceneManager::_findVisibleObjects(  cam,   onlyShadowCasters );
          // }
          
          
           //----------------------------------------------------------------------------
          // IntersectionSceneQuery* PagingLandScapeSceneManager::createIntersectionQuery(  unsigned long mask )
          // {
          // PagingLandScapeIntersectionSceneQuery* q = new PagingLandScapeIntersectionSceneQuery(  this );
          // q->setQueryMask(  mask );
          // return q;
          // }
          
     414   AxisAlignedBoxSceneQuery* PagingLandScapeSceneManager::createAABBQuery(   const AxisAlignedBox& box,  
           unsigned long mask  )
           {
           PagingLandScapeAxisAlignedBoxSceneQuery* q = new PagingLandScapeAxisAlignedBoxSceneQuery(  this );
           q->setBox(  box );
           q->setQueryMask(  mask );
           return q;
           }
          
           //----------------------------------------------------------------------------
     424   RaySceneQuery* PagingLandScapeSceneManager::createRayQuery(  const Ray& ray,   unsigned long mask )
           {
           PagingLandScapeRaySceneQuery* q = new PagingLandScapeRaySceneQuery(  this );
           q->setRay(  ray );
           q->setQueryMask(  mask );
           return q;
           }
           //-------------------------------------------------------------------------
     432   bool PagingLandScapeSceneManager::intersectSegment(  const Ogre::Vector3 & raybegin,  
     433   const Ogre::Vector3 & rayend,  
     434   Ogre::Vector3 * rayresult )
           {
           return intersectSegmentTerrain (  raybegin,   rayend,   rayresult );
           }
           //-------------------------------------------------------------------------
     439   bool PagingLandScapeSceneManager::intersectSegmentTerrain (  const Ogre::Vector3 & raybegin,  
     440   const Ogre::Vector3 & raydir,  
     441   Ogre::Vector3 * rayresult )
           {
           Ogre::Vector3 raystart (  raybegin );
           assert (  mPageManager && mData2DManager );
          
           const Ogre::Real maxHeight = mData2DManager->getMaxHeight (   );
          
           if (  raystart.y > maxHeight )
           {
           // find an new ray start that is under highest terrain height
           // so that we do not test intersection between terrain and ray
           // on ray part where Y > maxHeight
          
           // First check if not parallel to terrain
           if (  Math::Abs(  raydir.y ) < std::numeric_limits<Real>::epsilon(   ) )
           {
           // Parallel ?
           *rayresult = Ogre::Vector3(  -1.0f,   -1.0f,   -1.0f );
           return false;
           }
           // now ray should begin at a pertinent place.
           const Ogre::Real t = -(  raystart.y-maxHeight )/raydir.y;
           raystart += raydir*t;
           if (  raystart.y <= mData2DManager->getInterpolatedWorldHeight(  raystart.x,   raystart.z ) )
           {
           *rayresult = raystart;
           return true;
           }
           }
          
           PagingLandScapeTile * t = mPageManager->getTile (  raystart.x,   raystart.z,   false );
           if (  t == 0 )
           {
           // we're outside LandScape
           #ifndef _STRICT_LandScape
           // if you want to be able to intersect from a point outside the canvas
           //const int pageSize = mOptions->PageSize - 1;
           const Ogre::Real W = mOptions->maxScaledX;
           const Ogre::Real H = mOptions->maxScaledZ;
           const Ogre::Real maxHeight = mData2DManager->getMaxHeight (   );
          
           if (  W != 0 && H != 0 ) {
           // while ray is outside but raydir going inside
           while (  (  raystart.y < 0.0f && raydir.y > 0.0f ) ||
           (  raystart.y > maxHeight && raydir.y < 0.0f ) ||
          
           (  raystart.x < -W && raydir.x > 0.0f ) ||
           (  raystart.x > W && raydir.x < 0.0f ) ||
          
           (  raystart.z < -H && raydir.z > 0.0f ) ||
           (  raystart.z > H && raydir.z < 0.0f ) )
           raystart += raydir;
           }
          
           if (  raystart.y < 0.0f || raystart.y >= maxHeight ||
           raystart.x < -W || raystart.x > W ||
           raystart.z < -H || raystart.z > H )
           {
           *rayresult = Ogre::Vector3(  -1.0f,   -1.0f,   -1.0f );
           return false;
           }
           t = mPageManager->getTile (  raystart.x,   raystart.z,   false );
           if (  t == 0 )
           return false;
           #else //_STRICT_LandScape
           // if you don't want to be able to intersect from a point outside the canvas
           *rayresult = Ogre::Vector3(  -1.0f,   -1.0f,   -1.0f );
           return false;
           #endif //_STRICT_LandScape
           }
          
           bool impact;
          
          
           //special case...
          // if (  raydir.x == 0.0f && raydir.z == 0.0f )
          // {
          // if (  raystart.y <= mData2DManager->getInterpolatedWorldHeight(  raystart.x,   raystart.z ) )
          // {
          // *rayresult = raystart;
          // impact = true;
          // }
          // impact = false;
          // }
          // else
           {
           // should we scale ?
          // const Ogre::Vector3 rayDirScaled (  
          // raydir.x * mOptions->scale.x,  
          // raydir.y * mOptions->scale.y,  
          // raydir.z * mOptions->scale.z );
          
           if (  raystart.y >= mData2DManager->getInterpolatedWorldHeight(  raystart.x,   raystart.z ) )
           {
           impact = t->intersectSegmentFromAbove(  raystart,   raydir,   rayresult );
           }
           else
           {
           impact = t->intersectSegmentFromBelow(  raystart,   raydir,   rayresult );
           }
          
           }
           return true;
           }
           //-------------------------------------------------------------------------
     546   void PagingLandScapeSceneManager::resizeCrater (   )
           {
           const int radius = mBrushSize;
           const unsigned int diameter = static_cast <unsigned int> (  radius ) * 2;
          
           mBrushArrayHeight = diameter;
           mBrushArrayWidth = diameter;
          
           delete [] mCraterArray;
           const unsigned int array_size = diameter * diameter;
           mCraterArray = new Real[array_size];
           memset (  mCraterArray,   0,   array_size * sizeof(  Real ) );
          
           // Calculate the minimum X value
           // make sure it is still on the height map
           const int Zmin = -radius;
           const int Zmax = radius;
          
           const int Xmin = -radius;
           const int Xmax = radius;
          
           // (  goes through each X value )
           unsigned int array_indx = 0;
           const int radiussquare = radius * radius;
           //const Ogre::Real scaler = mOptions->scale.y;// / radius;
           const Ogre::Real scaler = 1.0 / radius;
           for (  int Zcurr = Zmin; Zcurr < Zmax; Zcurr++ )
           {
           const Ogre::Real Precalc = radiussquare - (  Zcurr * Zcurr );
           if (  Precalc > 1.0f )
           {
           // Determine the minimum and maximum X value for that
           // line in the circle (  that Z value )
           //const int Xmax = static_cast<int> (  Math::Sqrt(  Precalc ) );
           //const int Xmin = - Xmax;
          
           unsigned int curr_indx = array_indx;// + Xmin + radius;
           // For each of those Z values,   calculate the new Y value
           for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           {
           assert (  curr_indx < array_size );
           // Calculate the new theoretical height for the current point on the circle
           const Ogre::Real val = static_cast <Real> (  Xcurr * Xcurr );
           const Ogre::Real diffPrecalc = Precalc - val;
           mCraterArray[curr_indx] = std::min(  static_cast <Real> (  1.0 ),  
           std::max(  static_cast <Real> (  0.0 ),  
           Math::Sqrt (  diffPrecalc )* scaler ) ) ;
           curr_indx++;
           } // for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           } // if (  Precalc > 1.0f )
           array_indx += diameter;
           //array_indx += diameter;
           } // for (  int Zcurr = Zmin; Zcurr < radius; Zcurr++ )
           mBrushArray = mCraterArray;
           }
           //-----------------------------------------------------------------------
     602   void PagingLandScapeSceneManager::paint (  const Ogre::Vector3 &impact )
           {
           if (  mOptions->textureModifiable )
           {
           const int X = static_cast<int> (  impact.x / mOptions->scale.x );
           const int Z = static_cast<int> (  impact.z / mOptions->scale.z );
          
           //const int pageSize = mOptions->PageSize - 1;
          
           const int W = static_cast<int> (  mOptions->maxUnScaledX );
           const int H = static_cast<int> (  mOptions->maxUnScaledZ );
          
           if (  X < -W || X > W || Z < -H || Z > H )
           return;
          
           const int brushW = static_cast<int> (  mBrushArrayWidth );
           // Calculate the minimum X value
           // make sure it is still on the height map
           unsigned int xshift = 0;
           int Xmin = static_cast<int> (  -brushW * 0.5f ) ;
           if (  Xmin + X < -W )
           {
           //assert (  Xmin + X + W > 0 );
           xshift = static_cast <unsigned int> (  abs (  Xmin + X + W ) );
           Xmin = - X - W;
           }
           // Calculate the maximum X value
           // make sure it is still on the height map
           int Xmax = static_cast<int> (  brushW * 0.5f ) ;
           if (  Xmax + X > W )
           Xmax = W - X;
           const int brushH = static_cast<int> (  mBrushArrayHeight );
           // Calculate the minimum Z value
           // make sure it is still on the height map
           unsigned int zshift = 0;
           int Zmin = - static_cast<int> (  brushH * 0.5 ) ;
           if (  Zmin + Z < -H )
           {
           //assert (  Zmin + Z + H > 0 );
           zshift = static_cast <unsigned int> (  abs (  Zmin + Z + H ) );
           Zmin = - Z - H;
           }
           // Calculate the maximum Z value
           // make sure it is still on the height map
           int Zmax = static_cast<int> (  brushH * 0.5 );
           if (  Zmax + Z > H )
           Zmax = H - Z;
          
           // Main loop to draw the circle on the height map
           // (  goes through each X value )
           unsigned int array_indx = zshift*brushW;
           for (  int Zcurr = Zmin; Zcurr < Zmax; Zcurr++ )
           {
           // For each of those Z values,   calculate the new Y value
           unsigned int curr_indx = array_indx + xshift;
           for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           {
           // get results by page index ?
           const Ogre::Real h = mBrushArray[curr_indx];
           // Make sure we do it for something.
           if (  h - 0.005f > 0 )
           {
           assert (  h >= 0.0f && h <= 1.0f );
           const Ogre::Real bushForce = std::min(  static_cast <Real> (  1.0 ),   h*mBrushScale );
           if (  bushForce - 0.005f > 0 )
           {
           const Ogre::Vector3 currpoint (  X + Xcurr,   static_cast <Real> (  0.0 ),   Z + Zcurr );
           assert (  mPageManager&& mData2DManager && mTextureManager );
           PagingLandScapeTile * t = mPageManager->getTileUnscaled (  currpoint.x,   currpoint.z,   false );
           if (  t && t->isLoaded (   ) )
           {
           mImpactInfo = t->getInfo (   );
           // check page boundaries to modify any page,   tile neighbour
           // tells any tile modified to update at next frame
           assert (  curr_indx < mBrushArrayWidth*mBrushArrayHeight );
           mTextureManager->paint (  currpoint,   bushForce,   mImpactInfo );
           }// if (  t && t->isLoaded (   ) )
           }
           } // if (  h != 0.0f )
           curr_indx++;
           } // for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           array_indx += brushW;
           } // for (  int Zcurr = Zmin; Zcurr < Zmax; Zcurr++ )
           }
           }//-----------------------------------------------------------------------
     687   void PagingLandScapeSceneManager::setHeight (  const Ogre::Vector3 &impact )
           {
           if (  mOptions->Deformable )
           {
           const int X = static_cast<int> (  impact.x / mOptions->scale.x );
           const int Z = static_cast<int> (  impact.z / mOptions->scale.z );
          
           //const int pageSize = mOptions->PageSize - 1;
          
           const int W = static_cast<int> (  mOptions->maxUnScaledX );
           const int H = static_cast<int> (  mOptions->maxUnScaledZ );
          
           if (  X < -W || X > W || Z < -H || Z > H )
           return;
          
           const int brushW = static_cast<int> (  mBrushArrayWidth );
           // Calculate the minimum X value
           // make sure it is still on the height map
           unsigned int xshift = 0;
           int Xmin = static_cast<int> (  -brushW * 0.5f );
           if (  Xmin + X < -W )
           {
           //assert (  Xmin + X + W > 0 );
           xshift = static_cast <unsigned int> (  abs (  Xmin + X + W ) );
           Xmin = - X - W;
           }
           // Calculate the maximum X value
           // make sure it is still on the height map
           int Xmax = static_cast<int> (  brushW * 0.5f ) ;
           if (  Xmax + X > W )
           Xmax = W - X;
           const int brushH = static_cast<int> (  mBrushArrayHeight );
           // Calculate the minimum Z value
           // make sure it is still on the height map
           unsigned int zshift = 0;
           int Zmin = static_cast<int> (  - brushH * 0.5f ) ;
           if (  Zmin + Z < -H )
           {
           //assert (  Zmin + Z + H > 0 );
           zshift = static_cast <unsigned int> (  abs (  Zmin + Z + H ) );
           Zmin = - Z - H;
           }
           // Calculate the maximum Z value
           // make sure it is still on the height map
           int Zmax = static_cast<int> (  brushH * 0.5f ) ;
           if (  Zmax + Z > H )
           Zmax = H - Z;
          
           const Ogre::Real Hscale = mOptions->scale.y * mBrushScale;
           // Main loop to draw the circle on the height map
           // (  goes through each X value )
           unsigned int array_indx = zshift*brushW;
           for (  int Zcurr = Zmin; Zcurr < Zmax; Zcurr++ )
           {
           // For each of those Z values,   calculate the new Y value
           unsigned int curr_indx = array_indx + xshift;
           for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           {
           // get results by page index ?
           const Ogre::Real h = - mBrushArray[curr_indx] * mBrushScale * Hscale;
           // Make sure we do it for something.
           if (  h != 0.0f )
           {
           const Ogre::Vector3 currpoint (  X + Xcurr,   0.0f,   Z + Zcurr );
           assert (  mPageManager&& mData2DManager && mTextureManager );
           PagingLandScapeTile * t = mPageManager->getTileUnscaled (  currpoint.x,   currpoint.z,   false );
           if (  t && t->isLoaded (   ) )
           {
           mImpactInfo = t->getInfo (   );
           // check page boundaries to modify any page,   tile neighbour
           // tells any tile modified to update at next frame
           assert (  curr_indx < mBrushArrayWidth*mBrushArrayHeight );
           if (  mData2DManager->setHeight (  currpoint,   h,   mImpactInfo ) )
           mTextureManager->deformHeight (  currpoint,   mImpactInfo );
           } // if (  t && t->isLoaded (   ) )
           } // if (  h != 0.0f )
           curr_indx++;
           } // for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           array_indx += brushW;
           } // for (  int Zcurr = Zmin; Zcurr < Zmax; Zcurr++ )
           } // if (  mOptions->Deformable )
           }
           //-----------------------------------------------------------------------
     770   void PagingLandScapeSceneManager::deformHeight (  const Ogre::Vector3 &impact )
           {
           if (  mOptions->Deformable )
           {
           const int X = static_cast<int> (  impact.x / mOptions->scale.x );
           const int Z = static_cast<int> (  impact.z / mOptions->scale.z );
          
           //const int pageSize = mOptions->PageSize - 1;
          
           const int W = static_cast<int> (  mOptions->maxUnScaledX );
           const int H = static_cast<int> (  mOptions->maxUnScaledZ );
          
           if (  X < -W || X > W || Z < -H || Z > H )
           return;
          
           const int brushW = static_cast<int> (  mBrushArrayWidth );
           // Calculate the minimum X value
           // make sure it is still on the height map
           unsigned int xshift = 0;
           int Xmin = static_cast<int> (  -brushW * 0.5f );
           if (  Xmin + X < -W )
           {
           //assert (  Xmin + X + W > 0 );
           xshift = static_cast <unsigned int> (  abs (  Xmin + X + W ) );
           Xmin = - X - W;
           }
           // Calculate the maximum X value
           // make sure it is still on the height map
           int Xmax = static_cast<int> (  brushW * 0.5f ) ;
           if (  Xmax + X > W )
           Xmax = W - X;
           const int brushH = static_cast<int> (  mBrushArrayHeight );
           // Calculate the minimum Z value
           // make sure it is still on the height map
           unsigned int zshift = 0;
           int Zmin = static_cast<int> (  - brushH * 0.5f ) ;
           if (  Zmin + Z < -H )
           {
           //assert (  Zmin + Z + H > 0 );
           zshift = static_cast <unsigned int> (  abs (  Zmin + Z + H ) );
           Zmin = - Z - H;
           }
           // Calculate the maximum Z value
           // make sure it is still on the height map
           int Zmax = static_cast<int> (  brushH * 0.5f ) ;
           if (  Zmax + Z > H )
           Zmax = H - Z;
          
           const Ogre::Real Hscale = mOptions->scale.y * mBrushScale;
          
           // Main loop to draw the circle on the height map
           // (  goes through each X value )
           unsigned int array_indx = zshift*brushW;
           for (  int Zcurr = Zmin; Zcurr < Zmax; Zcurr++ )
           {
           // For each of those Z values,   calculate the new Y value
           unsigned int curr_indx = array_indx + xshift;
           for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           {
           // get results by page index ?
           const Ogre::Real h = - mBrushArray[curr_indx] * Hscale;
           // Make sure we do it for something.
           if (  h != 0.0f )
           {
           const Ogre::Vector3 currpoint (  X + Xcurr,   0.0f,   Z + Zcurr );
           assert (  mPageManager&& mData2DManager && mTextureManager );
           PagingLandScapeTile * t = mPageManager->getTileUnscaled (  currpoint.x,   currpoint.z,   false );
           if (  t && t->isLoaded (   ) )
           {
           mImpactInfo = t->getInfo (   );
           // check page boundaries to modify any page,   tile neighbour
           // tells any tile modified to update at next frame
           assert (  curr_indx < mBrushArrayWidth*mBrushArrayHeight );
           if (  mData2DManager->deformHeight (  currpoint,   h,   mImpactInfo ) )
           mTextureManager->deformHeight (  currpoint,   mImpactInfo );
           } // if (  t && t->isLoaded (   ) )
           } // if (  h != 0.0f )
           curr_indx++;
           } // for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           array_indx += brushW;
           } // for (  int Zcurr = Zmin; Zcurr < Zmax; Zcurr++ )
           } // if (  mOptions->Deformable )
           }
           //-----------------------------------------------------------------------
     854   void PagingLandScapeSceneManager::getAreaHeight (  const Ogre::Vector3 &impact )
           {
           const int X = static_cast<int> (  impact.x / mOptions->scale.x );
           const int Z = static_cast<int> (  impact.z / mOptions->scale.z );
          
           //const int pageSize = mOptions->PageSize - 1;
          
           const int W = static_cast<int> (  mOptions->maxUnScaledX );
           const int H = static_cast<int> (  mOptions->maxUnScaledZ );
          
           if (  X < -W || X > W || Z < -H || Z > H )
           return;
          
           const int brushW = static_cast<int> (  mBrushArrayWidth );
           // Calculate the minimum X value
           // make sure it is still on the height map
           unsigned int xshift = 0;
           int Xmin = static_cast<int> (  -brushW * 0.5f );
           if (  Xmin + X < -W )
           {
           //assert (  Xmin + X + W > 0 );
           xshift = static_cast <unsigned int> (  abs (  Xmin + X + W ) );
           Xmin = - X - W;
           }
           // Calculate the maximum X value
           // make sure it is still on the height map
           int Xmax = static_cast<int> (  brushW * 0.5f ) ;
           if (  Xmax + X > W )
           Xmax = W - X;
           const int brushH = static_cast<int> (  mBrushArrayHeight );
           // Calculate the minimum Z value
           // make sure it is still on the height map
           unsigned int zshift = 0;
           int Zmin = static_cast<int> (  - brushH * 0.5f ) ;
           if (  Zmin + Z < -H )
           {
           //assert (  Zmin + Z + H > 0 );
           zshift = static_cast <unsigned int> (  abs (  Zmin + Z + H ) );
           Zmin = - Z - H;
           }
           // Calculate the maximum Z value
           // make sure it is still on the height map
           int Zmax = static_cast<int> (  brushH * 0.5f ) ;
           if (  Zmax + Z > H )
           Zmax = H - Z;
          
           const unsigned int pSize = mOptions->PageSize - 1;
           const Ogre::Real Hscale = 1 / (  mOptions->scale.y * mBrushScale );
           // Main loop to draw the circle on the height map
           // (  goes through each X value )
           unsigned int array_indx = zshift*brushW;
           for (  int Zcurr = Zmin; Zcurr < Zmax; Zcurr++ )
           {
           // For each of those Z values,   calculate the new Y value
           unsigned int curr_indx = array_indx + xshift;
           for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           {
           const Ogre::Vector3 currpoint (  X + Xcurr,   0.0f,   Z + Zcurr );
           assert (  mPageManager&& mData2DManager && mTextureManager );
           PagingLandScapeTile * t = mPageManager->getTileUnscaled (  currpoint.x,   currpoint.z,   false );
           if (  t && t->isLoaded (   ) )
           {
           mImpactInfo = t->getInfo (   );
           // check page boundaries to modify any page,   tile neighbour
           // tells any tile modified to update at next frame
           assert (  curr_indx < mBrushArrayWidth*mBrushArrayHeight );
          
           // adjust x and z to be local to page
           const unsigned int x = static_cast<unsigned int> (  currpoint.x
           - mImpactInfo->mPageX * pSize
           + W );
           const unsigned int z = static_cast<unsigned int> (  currpoint.z
           - mImpactInfo->mPageZ * pSize
           + H );
           mBrushArray[curr_indx] = mData2DManager->getHeight(  mImpactInfo->mPageX,  
           mImpactInfo->mPageZ,  
           x,  
           z )
           *
           Hscale;
          
          
           } // if (  t && t->isLoaded (   ) )
          
           curr_indx++;
           } // for (  int Xcurr = Xmin; Xcurr < Xmax; Xcurr++ )
           array_indx += brushW;
           } // for (  int Zcurr = Zmin; Zcurr < Zmax; Zcurr++ )
           }
           //-----------------------------------------------------------------------
     944   bool PagingLandScapeSceneManager::setOption(  const String& strKey,   const void* pValue )
           {
           //listeners
           if (  StringUtil::endsWith(  strKey,   "listener",   true ) )
           {
           if (  mListenerManager->setOption (  strKey,   pValue ) )
           return true;
           }
          
           if (  StringUtil::startsWith(  strKey,   "pause",   true ) )
           {
           mPageManager->setEnabled(   ! *(  const_cast < bool * > (  static_cast < const bool * >(  pValue ) ) ) );
           }
          
           // deformation and painting
           if (  strKey == "BrushArray" )
           {
           mBrushArray = const_cast <Ogre::Real * > (  static_cast < const Ogre::Real * >(  pValue ) );
           return true;
           }
           if (  strKey == "BrushArrayHeight" )
           {
           mBrushArrayHeight = * static_cast < const unsigned int * > (  pValue );
           return true;
           }
           if (  strKey == "BrushArrayWidth" )
           {
           mBrushArrayWidth = * static_cast < const unsigned int * > (  pValue );
           return true;
           }
           if (  strKey == "BrushScale" )
           {
           mBrushScale = * static_cast < const Ogre::Real * > (  pValue ) ;
           return true;
           }
           if (  strKey == "BrushSize" )
           {
           mBrushSize = * static_cast < const unsigned int * > (  pValue );
           resizeCrater(   );
           return true;
           }
           if (  strKey == "setHeightCenter" )
           {
           mBrushCenter = * static_cast < const Ogre::Vector3 * > (  pValue );
           setHeight (  mBrushCenter );
           return true;
          
           }
           if (  strKey == "DeformationCenter" )
           {
           mBrushCenter = * static_cast < const Ogre::Vector3 * > (  pValue );
           deformHeight (  mBrushCenter );
           return true;
          
           }
           if (  strKey == "fillBrushArray" )
           {
           mBrushCenter = * static_cast < const Ogre::Vector3 * > (  pValue );
           getAreaHeight (  mBrushCenter );
           return true;
           }
           if (  strKey == "PaintCenter" )
           {
           mBrushCenter = * static_cast < const Ogre::Vector3 * > (  pValue );
           paint(  mBrushCenter );
           return true;
           }
           if (  strKey == "setPaintChannelValues" )
           {
           mTextureManager->setPaintChannelValues (  
           static_cast < const std::vector<Real> *>
           (  pValue )
            );
           return true;
           }
          
           if (  strKey == "renderTextureModeToBaseTextures" )
           {
           const String alternateMaterial = *static_cast < const String * > (  pValue );
           renderBaseTextures(  alternateMaterial );
           }
          
           // Map Changes
           if (  strKey == "LoadMap" )
           {
           const String textureFormatName(  mOptions->getCurrentTextureFormat (   ) );
          
           PagingLandScapeSceneManager::resetScene(   );
           PagingLandScapeSceneManager::loadScene (   );
          
           textureFormatChanged = false;
          
           return true;
           }
          
           if (  strKey == "CurrentMap" )
           {
           const String CurrentMapName = *static_cast < const String * > (  pValue );
           mOptions->setCurrentMapName (  CurrentMapName );
           return true;
           }
           if (  strKey == "InsertNewMap" )
           {
           const String CurrentMapName = *static_cast < const String * > (  pValue );
           mOptions->insertMap(  CurrentMapName );
           return true;
           }
           // TextureFormat changes
           if (  strKey == "CurrentTextureFormat" )
           {
           // Override File TextureFormat
           mOptions->setTextureFormat (  *static_cast < const String * > (  pValue ) );
           textureFormatChanged = true;
           return true;
           }
           // TextureFormat changes
           if (  strKey == "InsertTextureFormat" )
           {
           // Override File TextureFormat
           mOptions->insertTextureFormat (  *static_cast < const String * > (  pValue ) );
           return true;
           }
           if (  strKey == "PageUpdate" )
           {
           const Vector2 page = *static_cast < const Vector2 * > (  pValue );
          
           // Reload Data. ALso must reload pages that depend on this
           mData2DManager->reload (  page.x,   page.y );
           mTextureManager->reload(  page.x,   page.y );
           if (  page.x > 0 )
           {
           mData2DManager->reload (  page.x-1,   page.y );
           mTextureManager->reload(  page.x-1,   page.y );
           }
           if (  page.y > 0 )
           {
           mTextureManager->reload(  page.x,   page.y-1 );
           mData2DManager->reload (  page.x,   page.y-1 );
           }
           if (  page.x > 0 && page.y > 0 )
           {
           mData2DManager->reload (  page.x-1,   page.y-1 );
           mTextureManager->reload(  page.x-1,   page.y-1 );
           }
          
           // Now reload pages
           //mPageManager::getSingleton(   ).getPage(  page.x,   page.y )->reload(   );
           }
          
           if (  strKey == "LoadNow" )
           {
           assert (  mPageManager );
           if (  mOptions->max_preload_pages*mOptions->max_preload_pages >= mOptions->NumPages )
           {
           // Configuration file is telling us to pre-load all pages at startup.
           for (  unsigned int pageY = 0; pageY < mOptions->world_height; pageY++ )
           {
           for (  unsigned int pageX = 0; pageX < mOptions->world_width; pageX++ )
           {
           PagingLandScapePage * const p = mPageManager->getPage(  pageX,   pageY );
           p->load(   );
           mPageManager->addLoadedPage(  p );
          
           }
           }
           if (  mOptions->primaryCamera )
           mPageManager->loadNow (  mOptions->primaryCamera );
           }
           else if (  pValue )
           {
           PagingLandScapeCamera *cam = const_cast <PagingLandScapeCamera *> (  static_cast < const PagingLandScapeCamera * > (  pValue ) );
           mPageManager->loadNow (  cam );
           }
           }
           if (  strKey == "ResetScene" )
           {
           if(   * static_cast < const bool * > (  pValue )  )
           PagingLandScapeSceneManager::resetScene(   );
          
           return true;
           }
           if (  mOptions->setOption(  strKey,   pValue ) == true )
           {
           return true;
           }
           if (  PagingLandScapeOctreeSceneManager::setOption (  strKey,   pValue ) == true )
           {
           return true;
           }
          
          
           return false;
           }
          
           //-----------------------------------------------------------------------
    1139   bool PagingLandScapeSceneManager::getOption(  const String& strKey,   void* pDestValue )
           {
           if (  strKey == "h" || strKey == "getHeightAt" )
           {
           Ogre::Vector3 *p = static_cast < Ogre::Vector3 * > (  pDestValue );
           p->y = getHeightAt (  p->x,   p->z );
           return true;
           }
           if (  strKey == "s" || strKey == "getSlopeAt" )
           {
           Ogre::Vector3 *p = static_cast < Ogre::Vector3 * > (  pDestValue );
           p->y = getSlopeAt (  p->x,   p->z );
           return true;
           }
           if (  StringUtil::startsWith(  strKey,   "pause",   true ) )
           {
           * (  static_cast < bool * > (  pDestValue ) ) = !mPageManager->isEnabled(   );
           return true;
           }
          
           // heightfield data an pos info
           if (  strKey == "MapBoundaries" )
           {
           AxisAlignedBox *box = static_cast < AxisAlignedBox * > (  pDestValue );
          
           box->setExtents(  -mOptions->maxScaledX,  
           0,  
           -mOptions->maxScaledZ,  
           mOptions->maxScaledX,  
           mOptions->scale.y,  
           mOptions->maxScaledZ );
           return true;
          
           }
           if (  strKey == "GlobalToPage" )
           {
           Ogre::Vector3 *pos = static_cast < Ogre::Vector3 * > (  pDestValue );
           mPageManager->getGlobalToPage (  pos->x,   pos->z );
           return true;
           }
           if (  strKey == "getAreaSize" )
           {
           Ogre::Vector3 *vertices_array = static_cast < Ogre::Vector3 * > (  pDestValue );
          
           mPageManager->getGlobalToPage (  vertices_array[0].x,   vertices_array[0].z );
           mPageManager->getGlobalToPage (  vertices_array[1].x,   vertices_array[1].z );
           mPageManager->getGlobalToPage (  vertices_array[2].x,   vertices_array[2].z );
           mPageManager->getGlobalToPage (  vertices_array[3].x,   vertices_array[3].z );
          
           // define an area an get number of point in it.
           const Ogre::Real maxx = std::max (  vertices_array[0].x,  
           std::max (  vertices_array[1].x,  
           std::max (  vertices_array[2].x,  
           vertices_array[3].x ) ) );
           const Ogre::Real minx = std::min (  vertices_array[0].x,  
           std::min (  vertices_array[1].x,  
           std::min (  vertices_array[2].x,  
           vertices_array[3].x ) ) );
          
           const Ogre::Real maxz = std::max (  vertices_array[0].z,  
           std::max (  vertices_array[1].z,  
           std::max (  vertices_array[2].z,  
           vertices_array[3].z ) ) );
           const Ogre::Real minz = std::min (  vertices_array[0].z,  
           std::min (  vertices_array[1].z,  
           std::min (  vertices_array[2].z,  
           vertices_array[3].z ) ) );
          
           const unsigned int xpoints = static_cast<unsigned int> (  maxx - minx );
           const unsigned int zpoints = static_cast<unsigned int> (  maxz - minz );
           vertices_array[4].x = zpoints * xpoints;
          
           return true;
           }
          
           // Visibility info
           if (  strKey == "VisibilityMaterial" )
           {
           if (  mHorizon )
           {
           * static_cast < MaterialPtr * > (  pDestValue ) = mHorizon->getVisibilityMaterial(   );
           return true;
           }
           else
           return false;
           }
           // TextureFormat info
           if (  strKey == "NextTextureFormat" )
           {
           * static_cast < String * > (  pDestValue ) = mTextureManager->getNextTextureFormat(   );
           return true;
           }
           if (  strKey == "CurrentTextureFormat" )
           {
           * static_cast < String * > (  pDestValue ) = mTextureManager->getCurrentTextureFormat(   );
           return true;
           }
          
          
           // Map Info
           if (  strKey == "NextMap" )
           {
           * static_cast < String * > (  pDestValue ) = mOptions->getNextMapName(   );
           return true;
           }
           if (  strKey == "PreviousMap" )
           {
           * static_cast < String * > (  pDestValue ) = mOptions->getPreviousMapName(   );
           return true;
           }
           if (  strKey == "CurrentMap" )
           {
           * static_cast < String * > (  pDestValue ) = mOptions->getCurrentMapName(   );
           return true;
           }
           if (  strKey == "CurrentMapFileName" )
           {
           * static_cast < String * > (  pDestValue ) = mOptions->LandScape_filename;
           return true;
           }
          
          
           // PAGEINFO
           if (  strKey == "CurrentCameraPageX" )
           {
           if (  mPageManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getCurrentCameraPageX(   );
           return true;
           }
           if (  strKey == "CurrentCameraPageZ" )
           {
           if (  mPageManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getCurrentCameraPageZ(   );
           return true;
           }
          
          
          
           if (  strKey == "PagePreloadQueue" )
           {
           if (  mPageManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getPagePreloadQueueSize(   );
           return true;
           }
           if (  strKey == "PageTextureloadQueue" )
           {
           if (  mPageManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getPageTextureloadQueueSize(   );
           return true;
           }
           if (  strKey == "PageLoadQueue" )
           {
           if (  mPageManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getPageLoadQueueSize(   );
           return true;
           }
          
           if (  strKey == "PreLoadedPages" )
           {
           if (  mPageManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getPreLoadedPageSize(   );
           return true;
           }
           if (  strKey == "TextureLoadedPages" )
           {
           if (  mPageManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getTextureLoadedPageSize(   );
           return true;
           }
           if (  strKey == "LoadedPages" )
           {
           if (  mPageManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getLoadedPageSize(   );
           return true;
           }
          
           if (  strKey == "UnloadedPages" )
           {
           if (  mPageManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getUnloadedPagesSize(   );
           return true;
           }
           //TILES INFO
           if (  strKey == "MaxNumTiles" )
           {
           if (  mTileManager )
           * static_cast < int * > (  pDestValue ) = mTileManager->numTiles(   );
           return true;
           }
           if (  strKey == "TileFree" )
           {
           if (  mTileManager )
           * static_cast < int * > (  pDestValue ) = (  int )mTileManager->numFree(   );
           return true;
           }
           if (  strKey == "CurrentCameraTileX" )
           {
           if (  mTileManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getCurrentCameraTileX(   );
           return true;
           }
           if (  strKey == "CurrentCameraTileZ" )
           {
           if (  mTileManager )
           * static_cast < int * > (  pDestValue ) = mPageManager->getCurrentCameraTileZ(   );
           return true;
           }
          
           //RENDERABLES INFO
           if (  strKey == "MaxNumRenderables" )
           {
           if (  mRenderableManager )
           * static_cast < int * > (  pDestValue ) = mRenderableManager->numRenderables(   );
           return true;
           }
           if (  strKey == "RenderableFree" )
           {
           if (  mRenderableManager )
           * static_cast < int * > (  pDestValue ) = (  int )mRenderableManager->numFree(   );
           return true;
           }
           if (  strKey == "RenderableLoading" )
           {
           if (  mRenderableManager )
           * static_cast < int * > (  pDestValue ) = (  int )mRenderableManager->numLoading(   );
           return true;
           }
           if (  strKey == "VisibleRenderables" )
           {
           if (  mRenderableManager )
           * static_cast < unsigned int * > (  pDestValue ) = mRenderableManager->numVisibles(   );
           else
           * static_cast < unsigned int * > (  pDestValue ) = 0;
           return true;
           }
          
           // IMPACT INFO
           if (  strKey == "Impact" )
           {
           * static_cast < Ogre::Vector3 * > (  pDestValue ) = mImpact;
           return true;
           }
           if (  strKey == "ImpactPageX" )
           {
           if (  mImpactInfo )
           * static_cast < int * > (  pDestValue ) = mImpactInfo->mPageX;
           return true;
           }
           if (  strKey == "ImpactPageZ" )
           {
           if (  mImpactInfo )
           * static_cast < int * > (  pDestValue ) = mImpactInfo->mPageZ;
           return true;
           }
           if (  strKey == "ImpactTileX" )
           {
           if (  mImpactInfo )
           * static_cast < int * > (  pDestValue ) = mImpactInfo->mTileZ;
           return true;
           }
           if (  strKey == "ImpactTileZ" )
           {
           if (  mImpactInfo )
           * static_cast < int * > (  pDestValue ) = mImpactInfo->mTileZ;
           return true;
           }
           if (  strKey == "numModifiedTile" )
           {
           if (  mRenderableManager )
           * static_cast < int * > (  pDestValue ) = mRenderableManager->numRenderables(   );
           return true;
           }
           if (  strKey == "BrushSize" )
           {
           * static_cast < int * > (  pDestValue ) = mBrushSize;
           return true;
           }
           if (  strKey == "BrushScale" )
           {
           * static_cast <Ogre::Real * > (  pDestValue ) = mBrushScale;
           return true;
           }
          
           // Paint
           if (  strKey == "NumChannels" )
           {
           * static_cast < unsigned int * > (  pDestValue ) = mTextureManager->getNumChannels(   );
           return true;
           }
           if (  strKey == "getNumChannelsperTexture" )
           {
           unsigned int requestChannel = *static_cast<unsigned int *>(  pDestValue );
           * static_cast < unsigned int * > (  pDestValue ) = mTextureManager->getNumChannelsperTexture(  requestChannel );
           return true;
           }
           if (  strKey == "currentColors" )
           {
           //
           return true;
           }
           //added for Vertex data retrieval
           if (  strKey == "PageGetTileVertexData_2" )
           {
           /**
           * This is the optimized,   yet a bit fuzzy implementation of the getVertexDataPatch
           * Usage: Pass in a std::vector<void*> Pointer to the getOption call containing at least 5 Elements
           * [0](  Ogre::unsigned int* ) = X Index of the Page to retrieve data from
           * [1](  Ogre::unsigned int* ) = Z Index of the Page to retrieve data from
           * [2](  Ogre::unsigned int* ) = X Index of the Tile within the Page to retrieve data from
           * [3](  Ogre::unsigned int* ) = Z Index of the Tile within the Page to retrieve data from
           * [4](  Ogre::unsigned int* ) = LodLevel to get the data at (  note that level 0 means highest detail )
           * The getData call will then append 3 entries to the end of the vector. In Detail(  in order )
           * [End-2](  Ogre::unsigned int* ) = Number of vertices returned
           * [End-1] (  Ogre::Vector3* ) = The actual vertices,   this is a array containing as many elements as returned in [End-2]
           * [End] (  Ogre::IndexData* ) = The index data for the terrain polygons at the queried LodLevel
           * @remark note that the caller is in charge of deleting the vector array,   vertices array and indice array.
           */
           unsigned int requestPageX = *static_cast<unsigned int *>(  (  *static_cast<std::vector<void*>*>(  pDestValue ) )[0] );
           unsigned int requestPageZ = *static_cast<unsigned int *>(  (  *static_cast<std::vector<void*>*>(  pDestValue ) )[1] );
           unsigned int requestTileX = *static_cast<unsigned int *>(  (  *static_cast<std::vector<void*>*>(  pDestValue ) )[2] );
           unsigned int requestTileZ = *static_cast<unsigned int *>(  (  *static_cast<std::vector<void*>*>(  pDestValue ) )[3] );
           unsigned int requestLodLevel = *static_cast<unsigned int *>(  (  *static_cast<std::vector<void*>*>(  pDestValue ) )[4] );
           PagingLandScapePage* page = mPageManager->getPage(  requestPageX,  requestPageZ );
           if(  page )
           {
           PagingLandScapeTile* tile = page->getTile(  requestTileX,  requestTileZ );
           if(  tile )
           {
           PagingLandScapeRenderable* rend = tile->getRenderable(   );
           if(  rend )
           {
           Vector3* tempPointer; //This will hold the vertexData and needs to be deleted by the caller
           unsigned int* numPtr = new unsigned int;
           *numPtr = rend->getVertexCount(   );
           (  *static_cast<std::vector<void*>*>(  pDestValue ) ).push_back(  numPtr );
           tempPointer = new Ogre::Vector3[*numPtr];
           //warning! make sure that the allocated space for the vertices is big enough!
           rend->getRawVertexData(  tempPointer );
           (  *static_cast<std::vector<void*>*>(  pDestValue ) ).push_back(  tempPointer );
           (  *static_cast<std::vector<void*>*>(  pDestValue ) ).push_back(  rend->getRawIndexData(  requestLodLevel ) );
           return true;
           }
           }
           }
           return false;
           }
           if (  strKey == "getMaterialPageName" )
           {
          
           if (  mPageManager )
           {
           // convert position
           Vector3 **pos = static_cast < Ogre::Vector3 ** > (  pDestValue );
           mPageManager->getGlobalToPage (  (  *pos )->x,   (  *pos )->z );
          
           // get the texture
           Ogre::PagingLandScapeTexture* texture_ptr =
           mTextureManager->getTexture(  (  *pos )->x,   (  *pos )->z,   false );
          
           // check for valid texture
           if(   texture_ptr  )
           {
           // get texture name
           String* name_ptr = const_cast<String*>(  &texture_ptr->getMaterialName(   ) );
          
           // convert void pointer to a string**
           String** target_ptr = static_cast<String**>(  pDestValue );
          
           // save name at target position
           *target_ptr = name_ptr;
           }
           }
           return true;
          
           }
           //end of addition
           if (  mOptions && mOptions->getOption(  strKey,   pDestValue ) == false )
           {
           return PagingLandScapeOctreeSceneManager::getOption (  strKey,   pDestValue );
           }
           return true;
           }
          
           //-----------------------------------------------------------------------
    1523   bool PagingLandScapeSceneManager::hasOption(  const String& strKey ) const
           {
           if (  strKey == "AddNewHeight" )
           {
           return true;
           }
           if (  strKey == "RemoveNewHeight" )
           {
           return true;
           }
           if (  strKey == "CurrentCameraPageX" )
           {
           return true;
           }
           if (  strKey == "CurrentCameraPageZ" )
           {
           return true;
           }
           if (  strKey == "MaxNumTiles" )
           {
           return true;
           }
           if (  strKey == "TileFree" )
           {
           return true;
           }
           if (  strKey == "MaxNumRenderables" )
           {
           return true;
           }
           if (  strKey == "RenderableFree" )
           {
           return true;
           }
           if (  strKey == "RenderableLoading" )
           {
           return true;
           }
           if (  strKey == "PagePreloadQueue" )
           {
           return true;
           }
           if (  strKey == "PageLoadQueue" )
           {
           return true;
           }
           if (  strKey == "PageUnloadQueue" )
           {
           return true;
           }
           if (  strKey == "PagePostUnloadQueue" )
           {
           return true;
           }
           //added for Vertex data retrieval
           if (  strKey == "PageGetTileVertexData" )
           {
           return true;
           }
           //end of addition
           if (  mOptions && mOptions->hasOption(  strKey ) == false )
           {
           return PagingLandScapeOctreeSceneManager::hasOption (  strKey );
           }
           return true;
           }
          
           //-----------------------------------------------------------------------
    1591   bool PagingLandScapeSceneManager::getOptionValues(  const String & key,   StringVector &refValueList )
           {
          // if (  key == "CurrentCameraPageX" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "CurrentCameraPageZ" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "MaxNumTiles" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "TileFree" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "MaxNumRenderables" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "RenderableFree" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "RenderableLoading" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "PagePreloadQueue" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "PageLoadQueue" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "PageUnloadQueue" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          // if (  key == "PagePostUnloadQueue" )
          // {
          // refValueList.push_back(  MemoryDataStreamPtr(   ) );
          // return true;
          // }
          
           if (  mOptions->getOptionValues(  key,   refValueList ) == false )
           {
           return PagingLandScapeOctreeSceneManager::getOptionValues (  key,   refValueList );
           }
           return true;
           }
          
           //-----------------------------------------------------------------------
    1657   bool PagingLandScapeSceneManager::getOptionKeys(  StringVector &refKeys )
           {
           refKeys.clear(   );
           refKeys.push_back(  "AddNewHeight" );
           refKeys.push_back(  "RemoveNewHeight" );
           refKeys.push_back(  "CurrentCameraPageX" );
           refKeys.push_back(  "CurrentCameraPageZ" );
           refKeys.push_back(  "MaxNumTiles" );
           refKeys.push_back(  "TileFree" );
           refKeys.push_back(  "MaxNumRenderables" );
           refKeys.push_back(  "RenderableFree" );
           refKeys.push_back(  "RenderableLoading" );
           refKeys.push_back(  "PagePreloadQueue" );
           refKeys.push_back(  "PageLoadQueue" );
           refKeys.push_back(  "PageUnloadQueue" );
           refKeys.push_back(  "PagePostUnloadQueue" );
           mOptions->getOptionKeys(  refKeys );
           return PagingLandScapeOctreeSceneManager::getOptionKeys (  refKeys );
           }
           //-------------------------------------------------------------------------
    1677   void PagingLandScapeSceneManager::setWorldGeometryRenderQueue (  uint8 qid )
           {
           PagingLandScapeOctreeSceneManager::setWorldGeometryRenderQueue(  qid );
           if (  mPageManager )
           mPageManager->setWorldGeometryRenderQueue (  qid );
           }
           //-----------------------------------------------------------------------
    1684   Camera * PagingLandScapeSceneManager::createCamera(  const String &name )
           {
           if (  mCameras.find(  name ) != mCameras.end(   ) )
           {
           OGRE_EXCEPT(  
           Exception::ERR_DUPLICATE_ITEM,  
           "A camera with the name " + name + " already exists",  
           "PagingLandScapeSceneManager::createCamera" );
           }
          
           Camera * c = new PagingLandScapeCamera(  name,   this );
           mCameras.insert(  CameraList::value_type(  name,   c ) );
           PagingLandScapeOctreeSceneManager::addCamera (  c );
           // Check if we need to set the primaryCamera
           if (  mOptions && !mOptions->primaryCamera )
           {
           mOptions->setPrimaryCamera (  static_cast <PagingLandScapeCamera*> (  c ) );
           }
           //default values
           c->setNearClipDistance(   1  );
           // Infinite far plane?
           if (  Root::getSingleton(   ).getRenderSystem(   )->getCapabilities(   )->hasCapability(  RSC_INFINITE_FAR_PLANE ) )
           {
           c->setFarClipDistance(  0 );
           }
           else if (  mOptions )
           {
           float tmp;
           getOption(   "VisibleDistance",   &tmp );
           c->setFarClipDistance(   tmp  );
           }
          #ifdef PLSM2_EIHORT
           // create visible bounds aab map entry
           mCamVisibleObjectsMap[c] = VisibleObjectsBoundsInfo(   );
          #endif
           return c;
           }
           //-----------------------------------------------------------------------
    1722   void PagingLandScapeSceneManager::destroyCamera(  Camera *cam )
           {
           if (  mOptions->primaryCamera && cam->getName(   ) == mOptions->primaryCamera->getName(   ) )
           {
           mOptions->setPrimaryCamera (  0 );
           }
           PagingLandScapeOctreeSceneManager::destroyCamera(  cam );
           }
           //-----------------------------------------------------------------------
    1731   void PagingLandScapeSceneManager::destroyCamera(  const String& name )
           {
           if (  mOptions->primaryCamera && name == mOptions->primaryCamera->getName(   ) )
           {
           mOptions->setPrimaryCamera (  0 );
           }
           PagingLandScapeOctreeSceneManager::destroyCamera(  name );
           }
           //-----------------------------------------------------------------------
    1740   void PagingLandScapeSceneManager::destroyAllCameras(  void )
           {
           mOptions->setPrimaryCamera (  0 );
           PagingLandScapeOctreeSceneManager::destroyAllCameras(   );
           }
           //-----------------------------------------------------------------------
           void _OgrePagingLandScapeExport PagingLandScapeSceneManager::getWorldSize(  Real *worldSizeX,  Ogre::Real *worldSizeZ )
           {
    1748   *worldSizeX = mOptions->maxScaledX * 2.0f;
    1749   *worldSizeZ = mOptions->maxScaledZ * 2.0f;
          // *worldSizeX = (  float )mOptions->world_width * mOptions->scale.x;
          // *worldSizeZ = (  float )mOptions->world_height * mOptions->scale.z;
           }
           //-----------------------------------------------------------------------
           float _OgrePagingLandScapeExport PagingLandScapeSceneManager::getMaxSlope(  Vector3 location1,   Ogre::Vector3 location2,   float maxSlopeIn )
           {
           return mData2DManager->getMaxSlope(  location1,   location2,   maxSlopeIn );
           }
           //-----------------------------------------------------------------------
           void PagingLandScapeSceneManager::renderBaseTextures(  const String& alternateMatName )
           {
          
           //only currently works for PLSplattingShaderLit mode
           //because I can't figure out how to elegantly handle all texture modes (  yet )
           if(  mOptions->textureFormat != "PLSplattingShaderLit" || alternateMatName != "PLSplattingShaderUnlit" )
           {
           OGRE_EXCEPT(  
           Exception::ERR_NOT_IMPLEMENTED,  
           "Only currently supports PLSplattingShaderLit texture mode and alternate material SplattingShader",  
           "PagingLandScapeSceneManager::renderBaseTextures" );
           }
          
           PagingLandScapeTexture* t = NULL;
           String matName;
           TexturePtr texture;
           RenderTexture *renderTexture;
           Camera *rttCam;
           texture = TextureManager::getSingleton (   ).createManual(  "PLRTTBaseTexture",  
           ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,  
           TEX_TYPE_2D,  
           256,  
           256,  
           0,  
           PF_A8R8G8B8,  
           TU_RENDERTARGET );
          
           renderTexture = texture->getBuffer(   )->getRenderTarget(   );
           renderTexture->setAutoUpdated(  false );
           rttCam = createCamera(  "PLRTTBaseTextureCam" );
           rttCam->setNearClipDistance(  1.0f );
           rttCam->setFarClipDistance(  0 );
           rttCam->setPosition(  Vector3(  0,  0,  2 ) );
           rttCam->lookAt(  Vector3(  0,  0,  0 ) );
           Viewport* const v = renderTexture->addViewport(  rttCam );
           v->setClearEveryFrame(  true );
           v->setBackgroundColour(  ColourValue(  0.0f,   0.0f,   0.0f,   0.0f ) );
          
           //addSpecialCaseRenderQueue(  Ogre::RENDER_QUEUE_6 );
           //setSpecialCaseRenderQueueMode(  Ogre::SceneManager::SCRQM_INCLUDE );
          
           Rectangle2D* rect = new Rectangle2D(  true );
           rect->setBoundingBox(  AxisAlignedBox(  -100000.0*Vector3::UNIT_SCALE,   100000.0*Vector3::UNIT_SCALE ) );
           rect->setCorners(  -1,   1,   1,   -1 );
           rect->setRenderQueueGroup(  Ogre::RENDER_QUEUE_OVERLAY );
           SceneNode* node = getRootSceneNode(   )->createChildSceneNode(  "PLBaseTextureRectNode" );
           rect->setVisible(  true );
           node->attachObject(  rect );
           String textureName;
           size_t strPos = 0;
           MaterialPtr material;
           MaterialPtr alternateMaterial;
           //this->setAmbientLight(  ColourValue::White );
          
           for(  uint x = 0; x < mOptions->world_width; ++x )
           {
           for(  uint z = 0; z < mOptions->world_height; ++z )
           {
           t = mTextureManager->getTexture(  x,   z );
           if(  !t->isLoaded(   ) )
           t->load(  x,   z );
          
           textureName = mOptions->LandScape_filename + ".Base." + StringConverter::toString(  z ) + "." + StringConverter::toString(  x ) + ".png";
           matName = t->getMaterialName(   );
          
           //if an alternate material name is specified,   we'll use the texture units from our original material
           //and the passes from our new material
           if(  alternateMatName != "" )
           {
           alternateMaterial = MaterialManager::getSingleton(   ).getByName(  alternateMatName + "_Clone" );
           if(  alternateMaterial.isNull(   ) )
           {
           alternateMaterial = MaterialManager::getSingleton(   ).getByName(  alternateMatName );
           if(  alternateMaterial.isNull(   ) )
           {
           OGRE_EXCEPT(  
           Exception::ERR_ITEM_NOT_FOUND,  
           "Could not find alternate material " + alternateMatName,  
           "PagingLandScapeSceneManager::renderBaseTextures" );
           }
           alternateMaterial = alternateMaterial->clone(  alternateMatName + "_Clone" );
           }
           matName = alternateMaterial->getName(   );
           material = t->getMaterial(   );
          
           //we know that pass 2 of PLSplattingShaderLitDecompress has our coverage and
           //splatting textures in specific texture units
           //I think if we want this to be completely generic we'll have to load the original
           //texture mode's material,   iterate through and find the "Coverage" and "Splatting" references from it,  
           //and do the same for alternate material,   and attempt to hook them up the same
           for(  uint i = 0; i < 5; ++i )
           {
           alternateMaterial->getTechnique(  0 )->getPass(  0 )->getTextureUnitState(  i )->setTextureName(  material->getTechnique(  0 )->getPass(  1 )->getTextureUnitState(  i )->getTextureName(   ) );
           }
           }
          
           //assign the material to the rectangle
           rect->setMaterial(  matName );
           _updateSceneGraph(  rttCam );
           renderTexture->update(   );
           renderTexture->writeContentsToFile(  "../../../Media/paginglandscape2/terrains/" + mOptions->LandScape_filename + "/" + textureName );
           TexturePtr texture = TextureManager::getSingleton(   ).getByName(  textureName );
           if(  !texture.isNull(   ) )
           texture->reload(   );
          
           if(  mOptions->VertexCompression )
           {
           MaterialManager::getSingleton(   ).remove(  material->getHandle(   ) );
           }
           }
           }
          
           TextureManager::getSingleton(   ).remove(  texture->getHandle(   ) );
           destroyCamera(  "PLRTTBaseTextureCam" );
           node->detachObject(  rect );
           destroySceneNode(  "PLBaseTextureRectNode" );
          
           }
          } //namespace

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeSceneManagerDll.cpp

          /***************************************************************************
           OgrePagingLandScapeSceneManagerDll.cpp - description
           -------------------
           begin : Mon May 12 2003
           copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
           email : spoke2@supercable.es && tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as *
          * published by the Free Software Foundation; either version 2 of the *
          * License,   or (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreRoot.h"
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeSceneManager.h"
          
          namespace Ogre
          {
           PagingLandScapeSceneManagerFactory* PagingLandScapePlugin;
          
           extern "C" void _OgrePagingLandScapeExport dllStartPlugin(  void )
           {
           // Create new scene manager Factory
      34   PagingLandScapePlugin = new PagingLandScapeSceneManagerFactory(   );
          
           // Register Factory
      37   Root::getSingleton(   ).addSceneManagerFactory(  PagingLandScapePlugin );
           }
          
           extern "C" void _OgrePagingLandScapeExport dllShutdownPlugin(  void )
           {
           Root::getSingleton(   ).removeSceneManagerFactory(  PagingLandScapePlugin );
           }
          
           extern "C" void _OgrePagingLandScapeExport dllStopPlugin(  void )
           {
           delete PagingLandScapePlugin;
           }
          }

./components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeTexture.cpp

       1  /***************************************************************************
          OgrePagingLandScapeTexture.cpp - description
          -------------------
          begin : Fri Apr 16 2004
          copyright : (  C ) 2003-2006 by Jose A Milan && Tuan Kuranes
          email : spoke@supercable.es & tuan.kuranes@free.fr
          ***************************************************************************/
          
          /***************************************************************************
          * *
          * This program is free software; you can redistribute it and/or modify *
          * it under the terms of the GNU General Public License as published by *
          * the Free Software Foundation; either version 2 of the License,   or *
          * (  at your option ) any later version. *
          * *
          ***************************************************************************/
          
          #include "OgrePagingLandScapePrecompiledHeaders.h"
          
          #include "OgreVector3.h"
          #include "OgreColourValue.h"
          
          #include "OgreStringConverter.h"
          #include "OgreMaterialManager.h"
          #include "OgreTextureManager.h"
          #include "OgreTechnique.h"
          #include "OgrePass.h"
          
          #include "OgrePagingLandScapeTexture.h"
          
          #include "OgrePagingLandScapeOptions.h"
          #include "OgrePagingLandScapeSceneManager.h"
          #include "OgrePagingLandScapeTextureManager.h"
          #include "OgrePagingLandScapeData2DManager.h"
          #include "OgrePagingLandScapeData2D.h"
          
          #include "fileutils.h"
          
          namespace Ogre
          {
           //-----------------------------------------------------------------------
      42   PagingLandScapeTexture::PagingLandScapeTexture(  PagingLandScapeTextureManager *textureMgr,  
      43   const String materialBaseName,  
           const unsigned int numTexture,  
      45   const bool isSplatMode ) :
           mParent(  textureMgr ),  
           mMaterialBaseName(  materialBaseName ),  
           mIsLoaded (  false ),  
           mIsModified (  false ),  
           mDataX (  0 ),  
           mDataZ (  0 ),  
           mPaintRect (  0,   0,   0,   0,   0,   1 ),  
           mIsPaintRectModified(  false ),  
           mDeformRect (  0,   0,   0,   0,   0,   1 ),  
           mIsDeformRectModified(  false ),  
           mIsSplatMode(  isSplatMode ),  
           mNumTexture(  numTexture ),  
           mIsShadowed(  false ),  
           mIsShaderShadowed(  false ),  
           mIsBaseMode(  false )
           {
           mMaterial.setNull(   );
           }
           //-----------------------------------------------------------------------
      65   PagingLandScapeTexture::~PagingLandScapeTexture(   )
           {
           mNumChannelperTexture.clear(   );
           mImages.clear(   );
           mTextures.clear(   );
           mBuffers.clear(   );
           doTextureNeedUpdate.clear(   );
           isTextureModified.clear(   );
           }
           //-----------------------------------------------------------------------
      75   void PagingLandScapeTexture::setNumTexture(   )
           {
           if (  mNumTexture > 0 )
           {
           mNumChannelperTexture.reserve(  mNumTexture );
           doTextureNeedUpdate.reserve(  mNumTexture );
           isTextureModified.reserve(  mNumTexture );
           mTextures.reserve(  mNumTexture );
           mBuffers.reserve(  mNumTexture );
          
           mImages.reserve(  mNumTexture );
          
           mNumChannelperTexture.resize(  mNumTexture );
           doTextureNeedUpdate.resize(  mNumTexture );
           isTextureModified.resize(  mNumTexture );
           mTextures.resize(  mNumTexture );
           mBuffers.resize(  mNumTexture );
          
           mImages.resize(  mNumTexture );
          
           for (  size_t i = 0; i < mNumTexture; i++ )
           {
           mImages[i].loadDynamicImage (  0,   0,   0,   1,   PF_R8G8B8A8,   true,   1,   0 );
           }
          
           }
           }
           //-----------------------------------------------------------------------
     103   const String &PagingLandScapeTexture::getMaterialName(   )
           {
           return mMaterial->getName (   );
           }
           //-----------------------------------------------------------------------
     108   void PagingLandScapeTexture::bindCompressionSettings(   )
           {
           const PagingLandScapeOptions * const opt = mParent->getOptions(   );
          
           Material::TechniqueIterator tIt = mMaterial->getTechniqueIterator (   );
           while (  tIt.hasMoreElements (   ) )
           {
           Technique * const t = tIt.getNext (   );
           Technique::PassIterator pIt = t->getPassIterator (   );
           while (  pIt.hasMoreElements (   ) )
           {
           Pass *p = pIt.getNext (   );
           if (  p->hasVertexProgram (   ) )
           {
           // vertex compression setting
           GpuProgramParametersSharedPtr params = p->getVertexProgramParameters(   );
           if (  opt->VertexCompression )
           {
           bindCompressionSettings (  params );
           bindCompressionSettings (  p->getShadowReceiverVertexProgramParameters (   ) );
           }
          
           // splat settings.
          #ifdef PLSM2_EIHORT
           GpuConstantDefinition const * const e = params->_findNamedConstantDefinition(  "splatSettings",   false );
           if (  e )
           {
           // use index to get RealConstantEntry
           params->_writeRawConstant(  e->physicalIndex + 0,   opt->matHeight[1] );
           params->_writeRawConstant(  e->physicalIndex + 1,   opt->matHeight[2] );
           params->_writeRawConstant(  e->physicalIndex + 2,   float(  opt->maxValue ) );
           params->_writeRawConstant(  e->physicalIndex + 3,   0.0f );
           }
          #else
           GpuProgramParameters::RealConstantEntry * const e = params->getNamedRealConstantEntry (  "splatSettings" );
           if (  e )
           {
           e->val[0] = static_cast <float> (  opt->matHeight[1] );
           e->val[1] = static_cast <float> (  opt->matHeight[2] );
           e->val[2] = static_cast <float> (  opt->maxValue );
           e->val[3] = static_cast <float> (  0.0 );
           e->isSet = true;
           }
          #endif
          
          
           }
           }
           }
           }
           //-----------------------------------------------------------------------
     159   void PagingLandScapeTexture::bindCompressionSettings(  GpuProgramParametersSharedPtr params )
           {
           GpuProgramParameters::AutoConstantIterator aci = params->getAutoConstantIterator(   );
           bool found = false;
           while (  aci.hasMoreElements(   ) )
           {
           const GpuProgramParameters::AutoConstantEntry& ace = aci.getNext(   );
           if (  ace.paramType == GpuProgramParameters::ACT_CUSTOM &&
           ace.data == MORPH_CUSTOM_PARAM_ID )
           {
           found = true;
           }
           }
           if (  !found )
           {
           params->setNamedAutoConstant(  "compressionSettings",  
           GpuProgramParameters::ACT_CUSTOM,   MORPH_CUSTOM_PARAM_ID );
           }
           }
           //-----------------------------------------------------------------------
     179   void PagingLandScapeTexture::loadTexturesToModify(   )
           {
           if (  mNumTexture > 0 || (  mIsShadowed && !mIsShaderShadowed ) )
           {
           const String nameSep(  "." );
           const PagingLandScapeOptions * const opt = mParent->getOptions(   );
           const String filename (  opt->LandScape_filename );
           const String commonName (  StringConverter::toString(  mDataZ ) +
           nameSep + StringConverter::toString(  mDataX ) );
          
           unsigned int channel = 0;
           TextureManager* texMgr = TextureManager::getSingletonPtr(   );
          
           const unsigned short numLodLevels =
           mMaterial->getNumLodLevels(  MaterialManager::getSingleton(   )._getActiveSchemeIndex(   ) );
           // some texture are shared between techniques,   ensure it's loaded once.
           bool imageLoaded = false;
           bool baseLoaded = false;
           bool coverageLoaded = false;
           bool lightLoaded = false;
           bool horizonLoaded = false;
          
           for(  unsigned short k = 0; k < numLodLevels; k++ )
           {
           Technique *t = mMaterial->getBestTechnique (  k );
           Technique::PassIterator pIt = t->getPassIterator (   );
           String texType;
           channel = 0;
           while (  pIt.hasMoreElements (   ) )
           {
           Pass *p = pIt.getNext (   );
           Pass::TextureUnitStateIterator tuIt = p->getTextureUnitStateIterator (   );
           while (  tuIt.hasMoreElements (   ) )
           {
           TextureUnitState *tu = tuIt.getNext (   );
          
           const String texName (  tu->getTextureName(   ) );
           if (  !imageLoaded && opt->ImageNameLoad &&
           StringUtil::startsWith (  texName,   opt->image_filename ) )
           {
           // if it's an Image Texture mode
           mTextures[channel] = texMgr->getByName (  texName );
           assert (  !mTextures[channel].isNull(   ) &&
           String(  texName + " is missing" ).c_str(   ) );
           mBuffers[channel] = mTextures[channel]->getBuffer(   );
           loadColorTexture (  texName,   channel );
           channel++;
           imageLoaded = true;
           }
           else if (  StringUtil::startsWith (  texName,   filename,   false ) )
           {
           // if it's a dynamic texture updated by texture mode
           // subtracts filename from texname
           String texNameInfo = texName.substr (  filename.size (   ) );
           //then split on Dot (  in case of filename with dot in it. )
           const StringVector texNameInfos =
           StringUtil::split(  texNameInfo,   nameSep );
           texType = texNameInfos[0];
          
           if (  texType == "Alpha" )
           {
           mTextures[channel] = texMgr->getByName (  texName );
           assert (  !mTextures[channel].isNull(   ) &&
           String(  texName + " is missing" ).c_str(   ) );
           mBuffers[channel] = mTextures[channel]->getBuffer(   );
           loadAlphaTexture (  texName,   channel );
           channel++;
           }
           else if (  texType == "Coverage" )
           {
           mTextures[channel] = texMgr->getByName (  texName );
           assert (  !mTextures[channel].isNull(   ) &&
           String(  texName + " is missing" ).c_str(   ) );
           mBuffers[channel] = mTextures[channel]->getBuffer(   );
           loadColorTexture (  texName,   channel );
           coverageLoaded = true;
           channel++;
           }
           else if (  !lightLoaded && !mIsShaderShadowed
           && texType == "Light"  )
           {
           mLightTexture = texMgr->getByName (  texName );
           assert (  !mLightTexture.isNull(   ) &&
           String(  texName + " is missing" ).c_str(   ) );
           mLightBuffer = mLightTexture->getBuffer(   );
           loadTexture (  texName,   mLightImage );
          
           assert (  mLightBuffer->getWidth (   ) == mLightImage.getWidth (   ) &&
           mLightBuffer->getHeight (   ) == mLightImage.getHeight (   ) );
          
           String shadowTexName (  filename + nameSep + "HS" );
           for (  size_t k = 1; k < texNameInfos.size(   ); k++ )
           shadowTexName += nameSep + texNameInfos[k];
           if (  ResourceGroupManager::getSingleton(   ).
           resourceExists (  opt->groupName,   shadowTexName ) )
           {
           loadTexture (  shadowTexName,   mShadow );
           assert (  mShadow.getWidth (   ) == mLightImage.getWidth (   ) &&
           mShadow.getHeight (   ) == mLightImage.getHeight (   ) );
           lightUpdate (   );
           }
           else
           {
           mIsShadowed = false;
           }
           lightLoaded = true;
           }
           else if (  !coverageLoaded && !baseLoaded && texType == "Base" )
           {
           mTextures[channel] = texMgr->getByName (  texName );
           assert (  !mTextures[channel].isNull(   ) &&
           String(  texName + " is missing" ).c_str(   ) );
           mBuffers[channel] = mTextures[channel]->getBuffer(   );
           loadColorTexture (  texName,   channel );
           channel++;
           baseLoaded = true;
           }
           }
           }
           }
           for (  unsigned int i = 0; i < mNumTexture; i++ )
           {
           mNumChannelperTexture[i] = mImages[i].getBPP (   ) / 8;
           doTextureNeedUpdate[i] = false;
           isTextureModified[i] = false;
           }
           }
           }
           }
           //-----------------------------------------------------------------------
     309   void PagingLandScapeTexture::setOptions(  void )
           {
           PagingLandScapeOptions * const opt = mParent->getOptions(   );
           String matClassName (  
           (  opt->VertexCompression ?
           String(  mMaterialBaseName + "Decompress" )
           :
           mMaterialBaseName ) );
          
           MaterialPtr material = MaterialManager::getSingleton(   ).getByName (  matClassName );
           if (  opt->VertexCompression && material.isNull(   ) )
           {
           matClassName = mMaterialBaseName;
           opt->VertexCompression = false;
           opt->lodMorph = false;
           material = MaterialManager::getSingleton(   ).getByName (  matClassName );
           }
           assert (  !material.isNull(   ) &&
           String(  matClassName + "Must exists in the" + opt->groupName + "group" ).c_str (   ) );
          
           bool hasVertexProgram = false;
           bool hasFragmentProgram = false;
          
           Material::TechniqueIterator tIt = material->getTechniqueIterator (   );
           while (  tIt.hasMoreElements (   ) )
           {
           Technique * const t = tIt.getNext (   );
           Technique::PassIterator pIt = t->getPassIterator (   );
           while (  pIt.hasMoreElements (   ) )
           {
           Pass * const p = pIt.getNext (   );
          
           // vertex shaders.
           if (   p->hasVertexProgram (   ) )
           {
           if (  hasVertexProgram == false )
           {
           hasVertexProgram = p->hasVertexProgram (   );
           }
           GpuProgramParametersSharedPtr params = p->getVertexProgramParameters(   );
          
          #ifdef PLSM2_EIHORT
           GpuConstantDefinition const * const e = params->_findNamedConstantDefinition(  "splatSettings" );
          #else
           GpuProgramParameters::RealConstantEntry * const e = params->getNamedRealConstantEntry (  "splatSettings" );
          #endif
           if (  e )
           {
           opt->normals = true;
           }
           }
          
           // pixel shaders.
           if (  hasFragmentProgram == false )
           {
           hasFragmentProgram = p->hasFragmentProgram (   );
           }
           }
           }
           if (  !hasVertexProgram )
           {
           opt->VertexCompression = false;
           opt->lodMorph = false;
           }
           }
           //-----------------------------------------------------------------------
     375   bool PagingLandScapeTexture::isMaterialSupported(  bool recursive )
           {
           const PagingLandScapeOptions * const opt = mParent->getOptions(   );
          
           if (  opt->VertexCompression && recursive )
           {
           const String MatClassName (  mMaterialBaseName );
           mMaterialBaseName = mMaterialBaseName + "Decompress";
           const bool isOk = MaterialManager::getSingleton (   ).resourceExists (  mMaterialBaseName ) &&
           isMaterialSupported(  false );
           mMaterialBaseName = MatClassName;
           if (  isOk )
           return true;
           }
          
           MaterialPtr material = MaterialManager::getSingleton(   ).getByName (  mMaterialBaseName );
           assert (  !material.isNull(   ) &&
           String(  mMaterialBaseName + " Must exists in the" + opt->groupName + "group" ).c_str (   ) );
          
           unsigned short numPasses = 0;
          
           //these will store the maximum number of texture units,   alpha textures,  
           //coverage textures,   etc. after iterating through all passes in the material
           size_t numTextureUnits = 0;
           size_t numAlphaTexture = 0;
           size_t numCoverageTexture = 0;
           size_t numSplats = 0;
           unsigned int numDynamicTexture = 0;
          
           //per pass count
           size_t passNumTextureUnits;
           size_t passNumAlphaTextures;
           size_t passNumCoverageTextures;
           size_t passNumSplats;
           unsigned int passNumDynamicTextures;
          
           bool needVertexProgram = false;
           bool needFragmentProgram = false;
           bool isImageMode = false;
           bool isSplatMode = false;
           bool isBaseMode = false;
          
           Material::TechniqueIterator tIt = material->getTechniqueIterator (   );
           while (  tIt.hasMoreElements (   ) )
           {
           Technique * const t = tIt.getNext (   );
           numPasses = std::max (  numPasses,   t->getNumPasses(   ) );
           Technique::PassIterator pIt = t->getPassIterator (   );
           while (  pIt.hasMoreElements (   ) )
           {
          
           passNumTextureUnits = 0;
           passNumAlphaTextures = 0;
           passNumCoverageTextures = 0;
           passNumSplats = 0;
           passNumDynamicTextures = 0;
           Pass * const p = pIt.getNext (   );
           if (  needVertexProgram == false )
           needVertexProgram = p->hasVertexProgram (   );
           if (  needFragmentProgram == false )
           needFragmentProgram = p->hasFragmentProgram (   );
          #ifdef PLSM2_EIHORT
           numTextureUnits = std::max<unsigned int>(  static_cast<unsigned int>(  numTextureUnits ),   static_cast<unsigned int>(  p->getNumTextureUnitStates(   ) ) );
          #else
           numTextureUnits = std::max (  numTextureUnits,   p->getNumTextureUnitStates(   ) );
          #endif
           Pass::TextureUnitStateIterator tuIt = p->getTextureUnitStateIterator (   );
           while (  tuIt.hasMoreElements (   ) )
           {
           TextureUnitState * const tu = tuIt.getNext (   );
           const String texType (  tu->getTextureName(   ) );
           if (  std::string::npos == texType.find(  "." ) )
           {
           // This Texture Name is A keyword,  
           // check how many are dynamic in this material
           if (  !isBaseMode &&
           StringUtil::startsWith (  texType,   "base",   true ) )
           {
           isBaseMode = true;
           passNumDynamicTextures++;
           }
           else if (  !isImageMode &&
           StringUtil::startsWith (  texType,   "image",   true ) )
           {
           isImageMode = true;
           passNumDynamicTextures++;
           }
           else if (  texType == "Alpha" &&
           StringUtil::startsWith (  texType,   "alpha",   true ) )
           {
           isSplatMode = true;
           passNumAlphaTextures++;
           passNumDynamicTextures++;
           }
           else if (  texType == "Coverage" &&
           StringUtil::startsWith (  texType,   "coverage",   true ) )
           {
           isSplatMode = true;
           passNumDynamicTextures++;
           passNumCoverageTextures++;
           }
           else if (  texType == "Splatting" &&
           StringUtil::startsWith (  texType,   "splatting",   true ) )
           {
           mIsSplatMode = true;
           passNumSplats++;
           }
           else if (  texType == "Light" &&
           StringUtil::startsWith (  texType,   "light",   true ) )
           {
           //dynamic light... but in software
           mIsShadowed = true;
           }
           else if (  texType == "Horizon" &&
           StringUtil::startsWith (  texType,   "horizon",   true ) )
           {
           //dynamic light... but shader
           mIsShaderShadowed = true;
           mIsShadowed = true;
           }
           }
           }
          
           if(  passNumTextureUnits > numTextureUnits )
           numTextureUnits = passNumTextureUnits;
          
           numAlphaTexture += passNumAlphaTextures;
           numCoverageTexture += passNumCoverageTextures;
           numSplats += passNumSplats;
           numDynamicTexture += passNumDynamicTextures;
          
           }
           }
           if (  isImageMode && !opt->ImageNameLoad )
           return false;
           if (  opt->numTextureUnits < numTextureUnits )
           return false;
           if (  needVertexProgram && opt->hasVertexShader == false )
           return false;
           if (  needFragmentProgram && opt->hasFragmentShader == false )
           return false;
          
           if (  isSplatMode && numAlphaTexture && opt->NumMatHeightSplat < numAlphaTexture )
           return false;
          
           // does all coverage must be 4 alpha ?
           //if (  isSplatMode && numCoverageTexture && opt->NumMatHeightSplat < numCoverageTexture * 4 )
           // return false;
           if (  isSplatMode && numCoverageTexture && opt->NumMatHeightSplat < 4 )
           return false;
          
           if (  mIsShaderShadowed && !opt->hasFragmentShader2 )
           return false;
          
           mIsSplatMode = isSplatMode;
           mIsBaseMode = !mIsSplatMode && isBaseMode;
           mNumTexture = (  mParent->getOptions(   )->textureModifiable )? numDynamicTexture : 0;
           return true;
           }
           //-----------------------------------------------------------------------
     535   void PagingLandScapeTexture::_loadMaterial(   )
           {
           if (  mMaterial.isNull(   ) )
           {
           const PagingLandScapeOptions * const opt = mParent->getOptions(   );
           const String nameSep(  "." );
           const String commonName (  StringConverter::toString(  mDataZ ) +
           nameSep + StringConverter::toString(  mDataX ) );
           if (  opt->materialPerPage )
           {
           // JEFF - all material settings configured through material script
           mMaterial = MaterialManager::getSingleton(   ).getByName(  
           mMaterialBaseName + commonName );
           }
           else
           {
           const String filename (  opt->LandScape_filename );
           const bool compressed = opt->VertexCompression;
           const String MatClassName (  
           (  compressed ?
           String(  mMaterialBaseName + "Decompress" )
           :
           mMaterialBaseName ) );
           const String matname (  MatClassName + nameSep
           + commonName + nameSep
           + filename );
           mMaterial = MaterialManager::getSingleton(   ).getByName(  matname );
           if (  mMaterial.isNull(   ) )
           {
           mMaterial = MaterialManager::getSingleton(   ).getByName(  MatClassName );
           assert (  !mMaterial.isNull(   ) &&
           String(  MatClassName + "Must exists in the" + opt->groupName + "group" ).c_str (   ) );
           mMaterial = mMaterial->clone(  matname );
           const String extName (  opt->TextureExtension );
           const String beginName (  filename + nameSep );
           const String endName (  nameSep + commonName +
           nameSep );
           bool deformable;
           String texName,   finalTexName;
           unsigned int channel = 0;
           unsigned int splat = 0;
          
           unsigned int alphachannel = 0;
           unsigned int coveragechannel = 0;
          
           Material::TechniqueIterator tIt = mMaterial->getTechniqueIterator (   );
           while (  tIt.hasMoreElements (   ) )
           {
           splat = 0;
           channel = 0;
           coveragechannel = 0;
           alphachannel = 0;
           Technique * const t = tIt.getNext (   );
           Technique::PassIterator pIt = t->getPassIterator (   );
           while (  pIt.hasMoreElements (   ) )
           {
           Pass * const p = pIt.getNext (   );
           Pass::TextureUnitStateIterator tuIt = p->getTextureUnitStateIterator (   );
           while (  tuIt.hasMoreElements (   ) )
           {
           TextureUnitState * const tu = tuIt.getNext (   );
           const String texType (  tu->getTextureName(   ) );
           if (  std::string::npos == texType.find(  "." ) )
           {
           // This Texture Name is A keyword,  
           // meaning we have to dynamically replace it
           deformable = false;
           // check by what texture to replace keyword
           if (  StringUtil::startsWith (  texType,   "image",   true ) )
           {
           texName = opt->image_filename + endName;
           deformable = true;
           }
           else if (  StringUtil::startsWith (  texType,   "splatting",   true ) )
           {
           texName = opt->SplatDetailMapNames[splat % opt->NumMatHeightSplat];
           splat++;
           }
           else if (  StringUtil::startsWith (  texType,   "base",   true ) )
           {
           texName = beginName + texType + endName;
           channel++;
           deformable = true;
           }
           else if (  StringUtil::startsWith (  texType,   "alpha",   true ) )
           {
           texName = beginName + texType + nameSep +
           StringConverter::toString(  alphachannel ) + endName;
           deformable = true;
           alphachannel++;
           channel++;
           }
           else if (  StringUtil::startsWith (  texType,   "coverage",   true ) )
           {
           texName = beginName + texType + nameSep +
           StringConverter::toString(  (  coveragechannel * 4 ) % opt->NumMatHeightSplat ) + endName;
           deformable = true;
           channel++;
           coveragechannel++;
           }
           else if (  StringUtil::startsWith (  texType,   "light",   true ) )
           {
           texName = beginName + texType + endName + extName;
           }
           else if (  StringUtil::startsWith (  texType,   "horizon",   true ) )
           {
           texName = beginName + "HSP" + endName + extName;
           mPositiveShadow = true;
           }
           if (  deformable )
           {
           if(  opt->Deformable &&
           ResourceGroupManager::getSingleton(   ).resourceExists(  
           opt->groupName,  
           texName + "modif." + extName ) )
           {
           finalTexName = texName + "modif." + extName;
           }
           else
           {
           finalTexName = texName + extName;
           }
           }
           else
           {
           finalTexName = texName;
           }
           tu->setTextureName (  finalTexName );
           }
           }
           }
           }
           }
           }
           }
           }
           //-----------------------------------------------------------------------
     672   void PagingLandScapeTexture::_unloadMaterial(   )
           {
          
          
           }
           //-----------------------------------------------------------------------
     678   void PagingLandScapeTexture::load(  unsigned int x,   unsigned int z )
           {
           if (  !mIsLoaded && isMaterialSupported(   ) )
           {
           mDataX = x;
           mDataZ = z;
           updated(   );
           setNumTexture (   );
           _loadMaterial(   );
           const PagingLandScapeOptions * const opt = mParent->getOptions(   );
           mMaterial->setLightingEnabled (  opt->lit );
           mMaterial->setLodLevels (  opt->lodMaterialDistanceList );
           mMaterial->setReceiveShadows (  true );
           // If vertex shader,   have to bind parameters
           bindCompressionSettings (   );
           mMaterial->load (   );
           // load texture in main memory if we want to update it Real-Time
           loadTexturesToModify(   );
          
           mIsLoaded = true;
           mIsModified = false;
           }
           }
           //-----------------------------------------------------------------------
     702   void PagingLandScapeTexture::unload(   )
           {
           if (  mIsLoaded )
           {
           if (  mIsModified && mParent->getOptions(   )->saveDeformation )
           _save(   );
          
           if (  !mMaterial.isNull(   ) )
           mMaterial->unload(   );
          
           for (  unsigned int i = 0; i < mNumTexture; i++ )
           {
           doTextureNeedUpdate[i] = false;
           isTextureModified[i] = false;
           mBuffers[i].setNull (   );
           mTextures[i].setNull (   );
           mImages[i].loadDynamicImage (  0,   0,   0,   1,   PF_R8G8B8A8,   true,   1,   0 );
           }
           // Anyway,   they're surely null already,   as they're freed by delete page(   )
          
           _unloadMaterial(   );
          
           const String resourceName (  mMaterial->getName (   ) );
          
           assert (  !mMaterial.isNull(   ) && "PagingLandScapeTexture::unload" );
           mMaterial->unload(   );
           mMaterial.setNull(   );
           MaterialManager::getSingleton(   ).remove (  resourceName );
          
           mIsLoaded = false;
           }
          
           }
           //-----------------------------------------------------------------------
     736   void PagingLandScapeTexture::_save(  void )
           {
           assert (  !mMaterial.isNull(   ) && "PagingLandScapeTexture::::_save" );
          
           const PagingLandScapeOptions * const opt = mParent->getOptions(   );
           if (  mNumTexture > 0 && opt->textureModifiable )
           {
           const String extname (  opt->TextureExtension );
           for (  unsigned int i = 0; i < mNumTexture; i++ )
           {
           if (  isTextureModified[i] )
           {
           String texName = mTextures[i]->getName (   );
          
           FileInfoListPtr finfo = ResourceGroupManager::getSingleton(   ).findResourceFileInfo (  
           opt->groupName,   texName );
           FileInfoList::iterator it = finfo->begin(   );
           if (  it != finfo->end(   ) )
           {
           char *olddir = ChangeToDir (  const_cast< char * > (  (  (  it )->archive->getName(   ) ).c_str(   ) ) );
           //FileSystemArchive::pushDirectory(   )
          
           assert (  mImages[i].getData (   ) );
           // check if we have to add modif to the name.
           const String baseTexName (  texName,   0,   texName.size (   ) - extname.size(   ) );
           if (  !StringUtil::endsWith (  baseTexName,   "modif." ) )
           {
           texName = baseTexName + "modif." + extname;
           }
           mImages[i].save (  texName );
          
           RetablishDir (  olddir );
           //FileSystemArchive::popDirectory(   );
          
           } // if (  it != finfo->end(   ) )
           } // if (  doTextureNeedUpdate[i] )
           } // for (  unsigned int i = 0; i < mNumTexture; i++ )
           }
           }
           //-----------------------------------------------------------------------
     776   void PagingLandScapeTexture::upload(  const Image::Box& textureRect )
           {
           assert (  mNumTexture > 0 );
  &nb