00001 #include "SceneLoader.h"
00002
00003 using namespace std;
00004
00005 namespace rcrt
00006 {
00007
00008 SceneLoader::SceneLoader(string scenePath, MaterialLoader* mats):
00009 XMLLoader(scenePath),materials(mats),initialised(false),addedTraceables(false)
00010 {
00011 }
00012
00013 SceneLoader::~SceneLoader()
00014 {
00015 }
00016
00017 void SceneLoader::init()
00018 {
00019 initialised = true;
00020
00021 nextStartTag("scene");
00022 scene.setName(parser.getAttributeValue("","name"));
00023
00024 initCameras();
00025
00026 initObjects();
00027
00028 initLights();
00029 }
00030
00031 void SceneLoader::initCameras()
00032 {
00033 string tagName = parser.getName();
00034 if(tagName != "scene"){
00035 throw runtime_error("[SceneLoader]: Not a valid scene file," +
00036 string(" could not initialize scene: no <scene> tag"));
00037 }
00038 nextStartTag("");
00039 tagName = parser.getName();
00040 while(tagName == "cam"){
00041
00042 string camName = parser.getAttributeValue("","name");
00043 cout << "[SceneLoader]: loading camera " << camName << endl;
00044 cameras.push_back(new CameraLoader(parser.getAttributeValue("","file")));
00045 nextStartTag("");
00046 tagName = parser.getName();
00047 }
00048 }
00049
00050 void SceneLoader::initObjects()
00051 {
00052 string tagName = parser.getName();
00053 bool notEOF = true;
00054 while(tagName == "obj" && notEOF){
00055
00056 string objName = parser.getAttributeValue("","name");
00057 cout << "[SceneLoader]: loading object " << objName << endl;
00058 objects.push_back(new ObjectLoader(parser.getAttributeValue("","file"),materials));
00059
00060 notEOF = nextStartTag("");
00061 if(notEOF) tagName = parser.getName();
00062 }
00063
00064 }
00065
00066 void SceneLoader::initLights()
00067 {
00068 string tagName = parser.getName();
00069 bool notEOF = true;
00070 while(tagName == "light" && notEOF){
00071 string lName = parser.getAttributeValue("","name");
00072 cout << "[SceneLoader]: loading light " << lName << endl;
00073 lights.push_back(new LightLoader(parser.getAttributeValue("","file")));
00074
00075 notEOF = nextStartTag("");
00076 if(notEOF) tagName = parser.getName();
00077 }
00078
00079 }
00080
00081 Scene* SceneLoader::getScene()
00082 {
00083 return &scene;
00084 }
00085
00086 Camera* SceneLoader::getCamera()
00087 {
00088 return cameras.back()->getCamera();
00089 }
00090
00091 const vector<ObjectLoader*>& SceneLoader::getObjectLoaders()
00092 {
00093 return objects;
00094 }
00095
00096 bool SceneLoader::nextFrame()
00097 {
00098 if(!initialised)
00099 init();
00100 currentFrame++;
00101
00102 for(unsigned int i = 0; i < objects.size(); i++){
00103 objects[i]->nextFrame();
00104
00105 if(!addedTraceables)
00106 traceables.push_back(objects.back()->getObject());
00107 }
00108 for(unsigned int i = 0; i < lights.size(); i++){
00109 lights[i]->nextFrame();
00110
00111 if(!addedTraceables){
00112 Light* l = lights.back()->getLight();
00113 scene.addLight(l);
00114 if(l->getObject() != 0)
00115 traceables.push_back(l->getObject());
00116 }
00117 }
00118 for(unsigned int i = 0; i < cameras.size(); i++)
00119 cameras[i]->nextFrame();
00120
00121 if(!addedTraceables)
00122 addedTraceables = true;
00123
00124 scene.setTraceables(&traceables);
00125
00126 return true;
00127 }
00128
00129 bool SceneLoader::goToFrame(const int& n)
00130 {
00131 if(!initialised){
00132 init();
00133 }
00134 currentFrame = n;
00135
00136 for(unsigned int i = 0; i < objects.size(); i++){
00137 objects[i]->goToFrame(n);
00138
00139 if(!addedTraceables){
00140 traceables.push_back(objects[i]->getObject());
00141 }
00142 }
00143 for(unsigned int i = 0; i < lights.size(); i++){
00144 lights[i]->goToFrame(n);
00145
00146 if(!addedTraceables){
00147 Light* l = lights[i]->getLight();
00148
00149 scene.addLight(l);
00150 if(l->getObject() != 0)
00151 traceables.push_back(l->getObject());
00152 }
00153 }
00154 for(unsigned int i = 0; i < cameras.size(); i++)
00155 cameras[i]->goToFrame(n);
00156
00157 if(!addedTraceables)
00158 addedTraceables = true;
00159
00160 scene.setTraceables(&traceables);
00161
00162 return true;
00163 }
00164
00165
00166 }