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 "O3dConfigParser.hpp" 00023 #include "../schema/O3dSchema.hpp" 00024 #include "../area/O3dManager.hpp" 00025 #include "../RenderEngine.hpp" 00026 #include "io/parse/all.hpp" 00027 #include "io/stream/all.hpp" 00028 #include "io/schema/IoSchema.hpp" 00029 #include "util/type/String.hpp" 00030 #include "util/error/Log.hpp" 00031 #include "O3dPre.hpp" 00032 #include <cstring> 00033 #include <cstdio> 00034 #include <OgreSceneManager.h> 00035 #include <OgreLight.h> 00036 #include <OgreCamera.h> 00037 #include <OgreRoot.h> 00038 #include <OgreRenderWindow.h> 00039 #include <OgreEntity.h> 00040 #include <OgreStaticGeometry.h> 00041 00042 00043 using namespace se_core; 00044 00045 00046 namespace se_ogre { 00047 O3dConfigParser 00048 ::O3dConfigParser(ParseManager& parser) 00049 : Parser(parser, Parser::OGRE, Parser::CONFIG, 1) { 00050 } 00051 00052 00053 void O3dConfigParser 00054 ::parse(InputStream& in) { 00055 if(O3dSchema::sceneManager) { 00056 if(!O3dSchema::sceneManager->hasStaticGeometry("Scenery")) 00057 O3dSchema::sceneManager->createStaticGeometry("Scenery"); 00058 else { 00059 O3dSchema::sceneManager->getStaticGeometry("Scenery")->destroy(); 00060 O3dSchema::sceneManager->getStaticGeometry("Scenery")->reset(); 00061 } 00062 O3dSchema::sceneManager->setSkyDome(false, "no_dome"); 00063 } 00064 00065 int code; 00066 while((code = in.readInfoCode()) != 'Q') { 00067 switch(code) { 00068 case 'I': 00069 { // Include 00070 String file; 00071 in.readString(file); 00072 if(!IoSchema::fileManager->exists(file.get())) { 00073 LogFatal("Included config file " << file.get() << " does not exist."); 00074 } 00075 IoSchema::fileManager->load(file.get()); 00076 } 00077 break; 00078 00079 case 'R': 00080 { // Level resource 00081 readResources(in); 00082 } 00083 break; 00084 00085 case 'S': 00086 { // SceneManager 00087 String sceneManager; 00088 in.readString(sceneManager); 00089 chooseSceneManager(sceneManager.get()); 00090 } 00091 break; 00092 00093 case 'C': 00094 { 00095 float vnear = in.readFloat(); 00096 float vfar = in.readFloat(); 00097 float vfovy = in.readFloat(); 00098 createCamera(vnear, vfar, vfovy); 00099 createViewports(); 00100 break; 00101 } 00102 00103 case 'M': 00104 { 00105 String tmp; 00106 in.readString(tmp); 00107 float x = in.readFloat(); 00108 float y = in.readFloat(); 00109 float z = in.readFloat(); 00110 00111 static int unique = 0; 00112 char buffer[256]; 00113 sprintf(buffer, "%s_%d(%02f,%02f,%02f)", tmp.get(), unique++, x, y, z); 00114 00115 Ogre::SceneNode* node = O3dSchema::sceneManager->createSceneNode(); 00116 Ogre::Entity* entity = O3dSchema::sceneManager->createEntity(buffer, tmp.get()); 00117 O3dSchema::sceneManager->getStaticGeometry("Scenery")->addEntity(entity, Ogre::Vector3(x, y, z)); 00118 } 00119 break; 00120 00121 case 'L': // Light 00122 readLight(in); 00123 break; 00124 00125 case 'D': 00126 try { // Dome 00127 String material; 00128 in.readString(material); 00129 float curvature = in.readFloat(); 00130 float tiling = in.readFloat(); 00131 00132 AssertFatal(O3dSchema::sceneManager, 00133 "SceneManager must be created before loading ogre config file"); 00134 O3dSchema::sceneManager->setSkyDome(true, material.get(), curvature, tiling, 512); 00135 LogDetail("Created skydome with material " << material); 00136 } 00137 catch(...) { 00138 LogDetail("Couldn't create skydome for ogre config file " << in.name()); 00139 } 00140 break; 00141 00142 case 'E': 00143 try { // No dome 00144 } catch(...) { 00145 LogDetail("Couldn't remove skydome for ogre config file " << in.name()); 00146 } 00147 break; 00148 00149 case 'B': 00150 try { // Box 00151 String material; 00152 in.readString(material); 00153 00154 AssertFatal(O3dSchema::sceneManager, 00155 "SceneManager must be created before loading ogre config file"); 00156 O3dSchema::sceneManager->setSkyBox(true, material.get()); 00157 } 00158 catch(...) { 00159 LogDetail("Couldn't create skybox for ogre config file " << in.name()); 00160 } 00161 break; 00162 00163 case 'A': 00164 { 00165 // Area alignment 00166 short align = in.readShort(); 00167 switch(align) { 00168 case 1: 00169 O3dSchema::worldManager->setCentreAligned(true); 00170 break; 00171 default: 00172 O3dSchema::worldManager->setCentreAligned(false); 00173 } 00174 } 00175 break; 00176 00177 default: 00178 LogFatal("Unsupported code: " << (char)(code) << " in file " << in.name()); 00179 } 00180 } 00181 00182 if(O3dSchema::sceneManager) { 00183 Ogre::StaticGeometry* sg = O3dSchema::sceneManager->getStaticGeometry("Scenery"); 00184 //sg->setRegionDimensions(Ogre::Vector3(128, 128, 128)); 00185 sg->build(); 00186 } 00187 } 00188 00189 00190 void O3dConfigParser 00191 ::chooseSceneManager(const char* sceneManager) { 00192 // Create the SceneManager, in this case a generic one 00193 O3dSchema::sceneManager = O3dSchema::root->createSceneManager(sceneManager); 00194 LogDetail("Created scene manager: " << O3dSchema::sceneManager->getTypeName().c_str()); 00195 00196 // My laptop ATI Mobility Radeon 9200 needs this initial ambient light 00197 // even if it is changed later (or else everything goes dark) 00198 O3dSchema::sceneManager->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0)); 00199 00200 O3dSchema::sceneManager->createStaticGeometry("Scenery"); 00201 00202 //O3dSchema::sceneManager->getRootSceneNode()->createChild("Scenery"); 00203 } 00204 00205 00206 void O3dConfigParser 00207 ::createCamera(float vnear, float vfar, float vfovy) { 00208 // Create the camera 00209 if(O3dSchema::playerCamera) { 00210 O3dSchema::sceneManager->destroyCamera(O3dSchema::playerCamera); 00211 O3dSchema::playerCamera = 0; 00212 O3dSchema::window->removeAllViewports(); 00213 LogDetail("Destroyed camera"); 00214 } 00215 00216 O3dSchema::playerCamera = O3dSchema::sceneManager->createCamera("PlayerCam"); 00217 O3dSchema::playerCamera->setNearClipDistance(vnear); 00218 O3dSchema::playerCamera->setFarClipDistance(vfar); 00219 O3dSchema::playerCamera->setFOVy(Ogre::Radian(Ogre::Degree(vfovy))); 00220 LogDetail("Created player camera"); 00221 } 00222 00223 00224 void O3dConfigParser 00225 ::createViewports(void) { 00226 // Create one viewport, entire window 00227 Ogre::Viewport* vp = O3dSchema::window->addViewport(O3dSchema::playerCamera); 00228 vp->setBackgroundColour(Ogre::ColourValue(0,0,0)); 00229 00230 // Alter the camera aspect ratio to match the viewport 00231 O3dSchema::playerCamera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight())); 00232 00233 LogDetail("Created Ogre viewport"); 00234 00235 } 00236 00237 00238 00239 void O3dConfigParser 00240 ::readLight(InputStream& in) { 00241 int code; 00242 code = in.readInfoCode(); 00243 Assert(code == '{'); 00244 00245 while((code = in.readInfoCode()) != '}') { 00246 switch(code) { 00247 case 'A': 00248 { // Ambient 00249 float r = in.readFloat(); 00250 float g = in.readFloat(); 00251 float b = in.readFloat(); 00252 O3dSchema::sceneManager->setAmbientLight(Ogre::ColourValue(r, g, b)); 00253 } 00254 break; 00255 00256 case 'D': 00257 { // Directional light 00258 Ogre::Light* light; 00259 if(O3dSchema::sceneManager->hasLight("MainLight")) { 00260 light = O3dSchema::sceneManager->getLight("MainLight"); 00261 } 00262 else { 00263 light = O3dSchema::sceneManager->createLight("MainLight"); 00264 } 00265 light->setType(Ogre::Light::LT_DIRECTIONAL); 00266 light->setCastShadows(false); 00267 00268 while((code = in.readInfoCode()) != '/') { 00269 switch(code) { 00270 case 'V': // Direction vector 00271 { 00272 float x = in.readFloat(); 00273 float y = in.readFloat(); 00274 float z = in.readFloat(); 00275 light->setDirection(x, y, z); 00276 } 00277 break; 00278 00279 case 'C': // Colour 00280 { 00281 float r = in.readFloat(); 00282 float g = in.readFloat(); 00283 float b = in.readFloat(); 00284 light->setDiffuseColour(Ogre::ColourValue(r, g, b)); 00285 } 00286 break; 00287 00288 case 'S': // Colour 00289 { 00290 float r = in.readFloat(); 00291 float g = in.readFloat(); 00292 float b = in.readFloat(); 00293 light->setSpecularColour(Ogre::ColourValue(r, g, b)); 00294 } 00295 break; 00296 00297 case 'W': // Colour 00298 { 00299 light->setCastShadows(true); 00300 } 00301 break; 00302 00303 default: 00304 LogFatal("Unknown directional lighting code: " << (char)(code)); 00305 } 00306 } 00307 } 00308 break; 00309 00310 case 'P': 00311 { 00312 String name; 00313 in.readString(name); 00314 Ogre::Light* light = O3dSchema::sceneManager->createLight(name.get()); 00315 light->setType(Ogre::Light::LT_POINT); 00316 light->setCastShadows(false); 00317 00318 while((code = in.readInfoCode()) != '/') { 00319 switch(code) { 00320 case 'W': 00321 light->setCastShadows(true); 00322 break; 00323 case 'T': 00324 { // Translation 00325 float x = in.readFloat(); 00326 float y = in.readFloat(); 00327 float z = in.readFloat(); 00328 light->setPosition(x, y, z); 00329 } 00330 00331 case 'V': // Direction vector 00332 { 00333 float x = in.readFloat(); 00334 float y = in.readFloat(); 00335 float z = in.readFloat(); 00336 light->setPosition(x, y, z); 00337 } 00338 break; 00339 00340 case 'C': // Colour 00341 LogDetail("Deprecated"); 00342 case 'D': // Diffuse 00343 { 00344 float r = in.readFloat(); 00345 float g = in.readFloat(); 00346 float b = in.readFloat(); 00347 light->setDiffuseColour(Ogre::ColourValue(r, g, b)); 00348 } 00349 break; 00350 00351 case 'S': // Specular 00352 { 00353 float r = in.readFloat(); 00354 float g = in.readFloat(); 00355 float b = in.readFloat(); 00356 light->setSpecularColour(Ogre::ColourValue(r, g, b)); 00357 } 00358 break; 00359 00360 case 'A': // Attenuation 00361 { 00362 float range = in.readFloat(); 00363 float constant = in.readFloat(); 00364 float linear = in.readFloat(); 00365 float quadratic = in.readFloat(); 00366 light->setAttenuation(range, constant, linear, quadratic); 00367 } 00368 break; 00369 00370 default: 00371 LogFatal("Unknown point lighting code: " << (char)(code)); 00372 } 00373 } 00374 00375 } 00376 break; 00377 00378 case 'T': 00379 { // Texture shadows 00380 short size = in.readShort(); 00381 short count = in.readShort(); 00382 float vfar = in.readFloat(); 00383 float r = in.readFloat(); 00384 float g = in.readFloat(); 00385 float b = in.readFloat(); 00386 00387 try { 00388 AssertFatal(O3dSchema::sceneManager, 00389 "SceneManager must be created before setting shadow technique"); 00390 O3dSchema::sceneManager->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_MODULATIVE); 00391 O3dSchema::sceneManager->setShadowTextureSettings(size, count); 00392 O3dSchema::sceneManager->setShadowFarDistance(vfar); 00393 O3dSchema::sceneManager->setShadowColour(Ogre::ColourValue(r, g, b)); 00394 00395 LogDetail("Created " << count << " shadow textures of size " << size); 00396 } 00397 catch(...) { 00398 LogDetail("Couldn't create shadow texture"); 00399 } 00400 } 00401 break; 00402 00403 default: 00404 LogFatal("Unknown lighting code: " << (char)(code)); 00405 } 00406 } 00407 } 00408 00409 void O3dConfigParser 00410 ::readResources(InputStream& in) { 00411 int sectionCount = 0; 00412 const char* sections[8]; 00413 00414 int code; 00415 code = in.readInfoCode(); 00416 Assert(code == '{'); 00417 00418 while((code = in.readInfoCode()) != '}') { 00419 switch(code) { 00420 case 'S': 00421 { // Level resource section 00422 String section; 00423 in.readString(section); 00424 sections[ sectionCount++ ] = section.copyValue(); 00425 } 00426 break; 00427 } 00428 } 00429 00430 if(sectionCount > 0) { 00431 sections[ sectionCount++ ] = 0; 00432 RenderEngine::singleton()->loadLevelResources(sections); 00433 /* 00434 for(int i = 0; i < sectionCount; ++i) 00435 delete sections[i]; 00436 } 00437 */ 00438 } 00439 } 00440 00441 } 00442
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:06 2007 by Doxygen version 1.3.9.1.