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.