./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;