O3dConfigParser.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 "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.

SourceForge.net Logo