O3dManager.cpp

Go to the documentation of this file.
00001 /*
00002 SagaEngine library
00003 Copyright (c) 2002-2006 Skalden Studio AS
00004 
00005 This software is provided 'as-is', without any express or implied 
00006 warranty. In no event will the authors be held liable for any 
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to distribute the library under the terms of the 
00010 Q Public License version 1.0. Be sure to read and understand the license
00011 before using the library. It should be included here, or you may read it
00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl
00013 
00014 The original version of this library can be located at:
00015 http://www.sagaengine.com/
00016 
00017 Rune Myrland
00018 rune@skalden.com
00019 */
00020 
00021 
00022 #include "O3dPre.hpp"
00023 #include "O3dManager.hpp"
00024 #include "all.hpp"
00025 #include "../config/o3d_config.hpp"
00026 #include "../input/InputHandler.hpp"
00027 #include "../input/InputManager.hpp"
00028 #include "../event/RenderEventListeners.hpp"
00029 #include "../schema/all.hpp"
00030 #include "../thing/O3dThingComponent.hpp"
00031 #include "sim/pos/PosComponent.hpp"
00032 #include "comp/CompositeFactory.hpp"
00033 #include "sim/SimEngine.hpp"
00034 #include "client/thing/CameraComponent.hpp"
00035 #include "util/system/RealClock.hpp"
00036 #include "util/math/all.hpp"
00037 #include <OgreOverlayElement.h>
00038 #include <OgreCamera.h>
00039 #include <OgreMaterialManager.h>
00040 #include <OgreOverlayManager.h>
00041 #include <OgreRenderTarget.h>
00042 #include <OgreRenderWindow.h>
00043 #include <OgreStringConverter.h>
00044 #include <OgreSceneManager.h>
00045 #include <cstring>
00046 
00047 using namespace se_client;
00048 using namespace se_core;
00049 
00050 namespace se_ogre {
00051     O3dManager
00052     ::O3dManager() 
00053         : RootComponent(sct_RENDER), shouldStop_(false), debugOverlay_(0)
00054         , lastRenderClock_(0), isShowingDebugInfo_(false), isEditLightsOn_(false) {
00055         showDebugOverlay(false);
00056     }
00057 
00058 
00059     O3dManager
00060     ::~O3dManager() {
00061         if (debugOverlay_) {
00062             debugOverlay_->hide();
00063         }
00064         //clear();
00065     }
00066 
00067 
00068     void O3dManager
00069     ::clear() {
00070         /*
00071         NodeComponentList::Iterator it(children_);
00072         while(it.hasNext()) {
00073             O3dAreaComponent& c = static_cast<O3dAreaComponent&>(it.next());
00074             c.clear();
00075         }
00076         */
00077 
00078     }
00079 
00080 
00081     void O3dManager
00082     ::setEditLights(bool flag) {
00083         if(isEditLightsOn_ == flag)
00084             return;
00085         isEditLightsOn_ = flag;
00086         if(isEditLightsOn_) {
00087             ambientCache_ = O3dSchema::sceneManager->getAmbientLight();
00088             O3dSchema::sceneManager->setAmbientLight(Ogre::ColourValue(.6f, .6f, .6f, 1));
00089         }
00090         else {
00091             O3dSchema::sceneManager->setAmbientLight(ambientCache_);
00092         }
00093     }
00094 
00095 
00096     bool O3dManager
00097     ::frameStarted(const Ogre::FrameEvent& evt) {
00098         // Any in game events caused the game to end?
00099         if(SimSchema::simEngine.isGameOver()) {
00100             // Will cause renderloop to end
00101             return false;
00102         }
00103 
00104         long renderClock = SimSchema::realClock->millis();
00105 
00106         // We are inbetwen AI steps. Calculate exactly where.
00107         // stepDelta 0.0f means we are at Thing::pos, 1.0f at nextPos.
00108         float stepDelta = (renderClock - SimSchema::simEngine.when())
00109             / static_cast<float>(TIMESTEP_INTERVAL);
00110         if(stepDelta < 0.0f || stepDelta > 1.0f) {
00111             //LogDetail(stepDelta);
00112             // When in doubt, show thing at nextPos.
00113             stepDelta = 1.0f;
00114         }
00115 
00116         AssertFatal(ClientSchema::camera, "No camera. Save or init file corrupt?");
00117 
00118         // Eliminate jumps caused by interpolation when teleporting between levels.
00119         if(!ClientSchema::camera->pos().isKeyFramePath(ClientSchema::camera->nextPos())) {
00120             stepDelta = 1.0f;
00121         }
00122         // Interpolate new camera position
00123         moveCamera(stepDelta);
00124 
00125         // Cast UI update events
00126         float rc = renderClock / 1000.0f;
00127         O3dSchema::renderEventListeners().castUpdateLights(rc);
00128         O3dSchema::renderEventListeners().castUpdateMaterials(rc);
00129         O3dSchema::renderEventListeners().castUpdateImpostors(rc);
00130 
00131         //
00132         float timeSinceLastFrame = (renderClock - lastRenderClock_) / 1000.0f;
00133 
00134         // Interpolate world positions at this stepDelta for all Things in scene.
00135         NodeComponentList::Iterator it(children_);
00136         while(it.hasNext()) {
00137             O3dAreaComponent& c = static_cast<O3dAreaComponent&>(it.next());
00138             c.move(renderClock, stepDelta, timeSinceLastFrame);
00139         }
00140 
00141         // Store time
00142         lastRenderClock_ = renderClock;
00143 
00144         // true continues renderloop
00145         return true;
00146     }
00147 
00148 
00149     bool O3dManager
00150     ::frameEnded(const Ogre::FrameEvent& evt) {
00151         // Any in game events caused the game to end?
00152         if(SimSchema::simEngine.isGameOver()) {
00153             // Will cause renderloop to end
00154             return false;
00155         }
00156 
00157         // Update debug info
00158         if(debugOverlay_) updateStats();
00159 
00160         // Auto quit for debug use
00161         //static int frameCount = 0;
00162         //if(++frameCount >= 11) {
00163         //  SimSchema::simEngine.setGameOver(true);
00164         //  return false;
00165         //}
00166 
00167         // Renderloop ends on false
00168         return !shouldStop_;
00169     }
00170 
00171 
00172     void O3dManager
00173     ::moveCamera(float stepDelta) {
00174         if(O3dSchema::inputManager().active()) {
00175             if(O3dSchema::inputManager().active()->moveCamera(stepDelta)) {
00176                 return;
00177             }
00178         }
00179         if(!O3dSchema::playerCamera)
00180             return;
00181 
00182         // Don't try to move the camera if the camera is not in an area
00183         if(!ClientSchema::camera->pos().hasArea() || !ClientSchema::camera->nextPos().hasArea()) {
00184             return;
00185         }
00186 
00187         // Global coor
00188         const scale_t alpha = ScaleT::fromFloat(stepDelta);
00189         static ViewPoint camera;
00190         ClientSchema::camera->worldViewPoint(alpha, camera);
00191 
00192         // Convert from Euler3 if necessary
00193         Quat4 face(camera.face_);
00194 
00195         // Feed Ogre
00196         if(CameraComponent::Ptr(*ClientSchema::camera)->doesSee()) {
00197             Ogre::Quaternion f(face.w_, face.x_, face.y_, face.z_);
00198             O3dSchema::playerCamera->setOrientation(f);
00199             O3dSchema::playerCamera->setPosition(camera.coor_.x_, camera.coor_.y_, camera.coor_.z_);
00200         }
00201         else {
00202             O3dSchema::playerCamera->setDirection(Ogre::Vector3(0, 1, 0));
00203             O3dSchema::playerCamera->setPosition(0, 10000000, 0);
00204         }
00205     }
00206 
00207 
00208     void O3dManager
00209     ::showDebugOverlay(bool show) {
00210         if (show) {
00211             if (!debugOverlay_) {
00212                 debugOverlay_ = Ogre::OverlayManager::getSingleton().getByName("SagaEngine/DebugOverlay");
00213                 O3dSchema::window->resetStatistics();
00214             }
00215 
00216             debugOverlay_->show();
00217         }
00218         else {
00219             if (debugOverlay_) {
00220                 debugOverlay_->hide();
00221             }
00222         }
00223         showDebugInfo(show);
00224         try {
00225             Ogre::MaterialPtr m = Ogre::MaterialManager::getSingleton().getByName("Basic/NavMesh");
00226             Ogre::CompareFunction cmp = show ? Ogre::CMPF_LESS_EQUAL : Ogre::CMPF_ALWAYS_FAIL;
00227             if(!m.isNull())
00228                 m->setDepthFunction(cmp);
00229         } catch(...) {
00230             LogWarning("No navmesh material");
00231         }
00232     }
00233 
00234 
00235     void O3dManager
00236     ::flipDebugOverlay() {
00237         if(!debugOverlay_) {
00238             showDebugOverlay(true);
00239             return;
00240         }
00241         showDebugOverlay(!debugOverlay_->isVisible());
00242     }
00243 
00244     void O3dManager
00245     ::updateStats(void) {
00246         using namespace Ogre;
00247 
00248 
00249         static Ogre::String currFps = "Current FPS: ";
00250         static Ogre::String avgFps = "Average FPS: ";
00251         static Ogre::String bestFps = "Best FPS: ";
00252         static Ogre::String worstFps = "Worst FPS: ";
00253         static Ogre::String tris = "Triangle Count: ";
00254 
00255         // update stats when necessary
00256         try {
00257             OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("SagaEngine/AverageFps");
00258             OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("SagaEngine/CurrFps");
00259             OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("SagaEngine/BestFps");
00260             OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("SagaEngine/WorstFps");
00261 
00262             const RenderTarget::FrameStats& stats = O3dSchema::window->getStatistics();
00263 
00264             guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
00265             guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
00266             guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
00267                                 +" "+StringConverter::toString(stats.bestFrameTime)+" ms");
00268             guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
00269                                  +" "+StringConverter::toString(stats.worstFrameTime)+" ms");
00270 
00271             OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("SagaEngine/NumTris");
00272             guiTris->setCaption(tris + StringConverter::toString(static_cast<int>(stats.triangleCount)));
00273 
00274             static char buffer[255];
00275             PosComponent* a = ClientSchema::player->nextPos().area();
00276             sprintf(buffer, "Area: %s (%s)", a->owner()->name(), a->owner()->factory()->name()); 
00277             OverlayElement* guiArea = OverlayManager::getSingleton().getOverlayElement("SagaEngine/Area");
00278             guiArea->setCaption(buffer);
00279 
00280             se_core::ViewPoint& vp = ClientSchema::player->nextPos().local_;
00281 
00282             sprintf(buffer, "Coor: %.2f, %.2f, %.2f", vp.coor_.x_, vp.coor_.y_, vp.coor_.z_);
00283             OverlayElement* guiCoor = OverlayManager::getSingleton().getOverlayElement("SagaEngine/Coor");
00284             guiCoor->setCaption(buffer);
00285 
00286             sprintf(buffer, "Face: %.2f, %.2f, %.2f", vp.face_.yaw_ / (float)(BRAY_RES), vp.face_.pitch_ / (float)(BRAY_RES), vp.face_.roll_ / (float)(BRAY_RES));
00287             OverlayElement* guiFace = OverlayManager::getSingleton().getOverlayElement("SagaEngine/Face");
00288             guiFace->setCaption(buffer);
00289 
00290             OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("SagaEngine/DebugText");
00291             guiDbg->setCaption(debugText_);
00292 
00293             //sprintf(buffer, "Area: %s (%s) T(%.2f, %.2f, %.2f) R(%.2f, %.2f, %.2f)", a->owner()->name(), a->owner()->factory()->name(), vp.coor_.x_, vp.coor_.y_, vp.coor_.z_, vp.face_.yaw_ / (float)(BRAY_RES), vp.face_.pitch_ / (float)(BRAY_RES), vp.face_.roll_ / (float)(BRAY_RES));
00294             //guiDbg->setCaption(buffer);
00295         }
00296         catch(...) {
00297             // ignore
00298         }
00299     }
00300 
00301 }

Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:04 2007 by Doxygen version 1.3.9.1.

SourceForge.net Logo