src/rcrt/loaders/ObjectLoader.cpp

Go to the documentation of this file.
00001 #include "ObjectLoader.h"
00002 #include "../objects/DynamicObject.h"
00003 #include "../objects/AffineObject.h"
00004 #include "../materials/DebugMaterial.h"
00005 
00006 using namespace std;
00007 
00008 namespace rcrt
00009 {
00010 
00011 ObjectLoader::ObjectLoader(string path, MaterialLoader* mats):
00012         XMLLoader(path),materials(mats),material("debug"),initialised(false)
00013 {
00014 }
00015 
00016 ObjectLoader::~ObjectLoader()
00017 {
00018         delete object;
00019 }
00020 
00021 void ObjectLoader::init()
00022 {
00023         initialised = true;
00024         
00025         nextStartTag("object");
00026         name = parser.getAttributeValue("","name");
00027         string animT = parser.getAttributeValue("","type");
00028         if(animT == "static")
00029                 aType = STATIC;
00030         else if (animT == "affine")
00031                 aType = AFFINE;
00032         else if (animT == "dynamic")
00033                 aType = DYNAMIC;
00034         else{
00035                 cout << "[ObjectLoader]: Object " << name <<" does not have a valid(static|affine|other) type: " << animT << endl;
00036                 throw exception();
00037         }
00038         
00039         initMaterials();
00040         
00041         //sould now be on first frame tag
00042         switch(aType){
00043         case STATIC: initAffine(); break;
00044         case AFFINE: initAffine(); break;
00045         default://other
00046                 initDynamic();
00047         }
00048         
00049         if(material == "debug" || materials == 0)
00050                 object->setMaterial(new DebugMaterial());
00051         else{
00052                 Material* mat = materials->getMaterial(material);
00053                 if(mat)
00054                         object->setMaterial(mat);
00055                 else
00056                         throw runtime_error(
00057                                 "[ObjectLoader]: Not a valid object file, material does not exist: "
00058                                         + material);
00059         }
00060                 
00061 }
00062 
00063 void ObjectLoader::initMaterials()
00064 {
00065         //Assume that we're on the <object> start tag
00066         //cout << "[ObjectLoader]: Reading materials" << endl;
00067         string tagName = parser.getName();
00068         if(tagName != "object"){
00069                 cout << "[ObjectLoader]: Logic error somewhere in ObjectLoader," <<
00070                                 " could not initialize materials: not on <object> tag" << endl;
00071                 throw exception();
00072         }
00073         nextStartTag("");
00074         tagName = parser.getName();
00075         while(tagName == "mat"){//TODO support material list
00076                 material = parser.getAttributeValue("","name");
00077                 
00078                 nextStartTag("");
00079                 tagName = parser.getName();
00080         }
00081 }
00082 
00083 void ObjectLoader::updateMesh()
00084 {
00085         //Assume that we're on a <frame> tag
00086         string tagName = parser.getName();
00087         if(tagName != "frame"){
00088                 cout << "[ObjectLoader]: Either a logic error somewhere in ObjectLoader," <<
00089                                 " or not a valid object file: could not parse mesh: " <<
00090                                 "not on <frame> tag: " << tagName << endl;
00091                 throw exception();
00092         }
00093         
00094         nextStartTag("mesh");
00095         string mType = parser.getAttributeValue("","type");
00096         if(mType == "sphere"){
00097                 nextStartTag("sph");
00098                 float radius = convertTo<float>(parser.getAttributeValue("","r"));
00099                 Point3D loc(convertTo<float>(parser.getAttributeValue("","x")),
00100                                         convertTo<float>(parser.getAttributeValue("","y")),
00101                                         convertTo<float>(parser.getAttributeValue("","z")));
00102                 primitives.push_back(new Sphere(loc, radius, object));
00103                 nextStartTag("");//TODO animated spheres and stuff
00104         } else {        
00105                 nextStartTag("verts");
00106                 nextStartTag("v");
00107                 tagName = parser.getName();
00108                 unsigned int i = 0;
00109                 while(tagName == "v"){
00110                         Point3D loc(convertTo<float>(parser.getAttributeValue("","x")),
00111                                         convertTo<float>(parser.getAttributeValue("","y")),
00112                                         convertTo<float>(parser.getAttributeValue("","z")));
00113                         if(i < vertices.size())//update vertex
00114                                 vertices.at(i).setPos(loc);
00115                         else//new vertex
00116                                 vertices.push_back(Vertex(loc));
00117                         nextStartTag("");
00118                         tagName = parser.getName();
00119                         if(tagName == "no"){
00120                                 Vec3D vec(convertTo<float>(parser.getAttributeValue("","x")),
00121                                                 convertTo<float>(parser.getAttributeValue("","y")),
00122                                                 convertTo<float>(parser.getAttributeValue("","z")));
00123                                 vertices.at(i).setNormal(vec);
00124                                 nextStartTag("");
00125                                 tagName = parser.getName();
00126                         }
00127                         if(tagName == "uv"){
00128                                 Point2D uv(convertTo<float>(parser.getAttributeValue("","u")),
00129                                                 convertTo<float>(parser.getAttributeValue("","v")));
00130                                 vertices.at(i).setUV(uv);
00131                                 nextStartTag("");
00132                                 tagName = parser.getName();
00133                         }
00134                         i++;
00135                 }
00136                 if(tagName != "faces"){
00137                         cout << "[ObjectLoader]: Either a logic error somewhere in ObjectLoader," <<
00138                                         " or not a valid object file: could not parse mesh: " <<
00139                                         "no <faces> tag in frame: "<< currentFrame << endl;
00140                         throw exception();
00141                 }
00142                 nextStartTag("tri");
00143                 tagName = parser.getName();
00144                 i = 0;
00145                 while(tagName == "tri" && !eof){
00146                         bool smooth = true;
00147                         int sm = convertTo<int>(parser.getAttributeValue("","s"));
00148                         if(sm == 0)
00149                                 smooth = false;
00150                         
00151                         //cout << "[ObjectLoader]: Reading triangle" << endl;
00152                         int verts[3];
00153                         nextStartTag("");
00154                         tagName = parser.getName();
00155                         for(int vertex = 0; vertex < 3; vertex++){
00156                                 if(tagName != "v"){
00157                                         cout << "[ObjectLoader]: Not a valid object file: could not parse mesh: " <<
00158                                                         "not enough <v> tags in a tri in frame: "<< currentFrame << endl;
00159                                         throw exception();
00160                                 }
00161                                 int index = convertTo<int>(parser.getAttributeValue("","i"));
00162                                 if(i < tris.size())
00163                                         (*tris.at(i))[vertex] = &vertices.at(index);
00164                                 else
00165                                         verts[vertex] = index;
00166                                 
00167                                 eof = !nextStartTag("");
00168                                 if(!eof) tagName = parser.getName();
00169                                 else break;
00170                                 
00171                                 if(tagName == "uv"){
00172                                         Point2D uv(convertTo<float>(parser.getAttributeValue("","u")),
00173                                                         convertTo<float>(parser.getAttributeValue("","v")));
00174                                         vertices.at(index).setUV(uv);
00175                                         
00176                                         eof = !nextStartTag("");
00177                                         if(!eof) tagName = parser.getName();
00178                                         else break;
00179                                         
00180                                 }       
00181                         }
00182                         if(i >= tris.size()){
00183                                 tris.push_back(new Triangle(&vertices.at(verts[0]),
00184                                                 &vertices.at(verts[1]),
00185                                                 &vertices.at(verts[2]),object,smooth));
00186                                 primitives.push_back(tris.at(i));
00187                         }
00188                         i++;
00189                 }
00190         }
00191         
00192         //set mesh of the object
00193         object->setPrimitives(&primitives);
00194 }
00195 
00196 void ObjectLoader::updateMatrix()
00197 {
00198         //getting worldmatrix in case of STATIC/AFFINE objects
00199         string tagName = parser.getName();
00200         if(tagName != "worldmatrix"){
00201                 throw runtime_error(
00202                                 "[ObjectLoader]: Not a valid object file "+name+" : could not parse mesh: " +
00203                                 ("no <worldmatrix> tag in line: " + toString(parser.getLineNumber()) +
00204                                                 " current tag: " + tagName));
00205         }
00206         float matrix[4][4];
00207         nextStartTag("");
00208         tagName = parser.getName();
00209         for(int r = 0; r < 4; r++){
00210                 if(tagName != "matrow"){
00211                         throw runtime_error(
00212                                         "[ObjectLoader]: Not a valid object file: could not parse mesh: " +
00213                                         ("not enough <matrow> tags in line: " + toString(parser.getLineNumber())));
00214                 }
00215                 nextStartTag("");
00216                 tagName = parser.getName();
00217                 for(int c = 0; c < 4; c++){
00218                         if(tagName != "entry"){
00219                                 throw runtime_error(
00220                                         "[ObjectLoader]: Not a valid object file: could not parse mesh: " +
00221                                         ("not enough <entry> tags in line: " + toString(parser.getLineNumber())));
00222                         }
00223                         matrix[r][c] = convertTo<float>(parser.getAttributeValue("","val"));
00224                         
00225                         eof = !nextStartTag("");
00226                         if(!eof) tagName = parser.getName();
00227                         else break;
00228                 }
00229         }
00230         Matrix4D m;
00231         m = matrix;
00232         object->setWorldMatrix(m);
00233 }
00234 
00235 void ObjectLoader::initAffine()
00236 {
00237         object = new AffineObject(name);
00238         updateMesh();
00239         updateMatrix();
00240 }
00241 
00242 void ObjectLoader::initDynamic()
00243 {
00244         object = new DynamicObject(name);
00245 }
00246 
00247 bool ObjectLoader::nextFrame()
00248 {
00249         if(!initialised)
00250                 init();
00251         
00252         int eventType = parser.getEventType();
00253         string tagName = parser.getName();
00254         if(eventType != XmlPullParser::START_TAG ||
00255                         tagName != "frame"){
00256                 eof = !nextStartTag("frame");
00257         }
00258         if(!eof) {
00259                 currentFrame = convertTo<int>(parser.getAttributeValue("","no"));
00260                 updateMesh();
00261                 return true;
00262         } else {
00263                 return false;
00264         }
00265         
00266 }
00267 
00268 bool ObjectLoader::goToFrame(const int& n)
00269 {
00270         if(!initialised)
00271                 init();
00272         
00273         switch(aType){
00274         case STATIC: currentFrame = n; return true;
00275         default:        
00276                 if(n < currentFrame)
00277                         return false;//TODO error handling?
00278                 if(n == currentFrame){
00279                         return true;
00280                 }
00281                 string tagName = parser.getName();
00282                 if(tagName == "frame")
00283                         currentFrame = convertTo<int>(parser.getAttributeValue("","no"));
00284                 while(currentFrame < n && !eof){
00285                         eof = !nextStartTag("frame");
00286                         currentFrame = convertTo<int>(parser.getAttributeValue("","no"));
00287                 }
00288                 if(!eof) {
00289                         switch(aType){
00290                         case DYNAMIC: updateMesh(); break;
00291                         case AFFINE: nextStartTag("worldmatrix"); updateMatrix(); break;
00292                         case STATIC: return true;
00293                         }
00294                         return true;
00295                 } else {
00296                         return false;
00297                 }
00298         }
00299 }
00300 
00301 Object* ObjectLoader::getObject()
00302 {
00303         return object;
00304 }
00305 
00306 vector<Triangle*>* ObjectLoader::getTriangles()
00307 {
00308         return &tris;
00309 }
00310 
00311 }

Generated on Thu Jan 31 19:26:19 2008 for RenderingCompetitionRayTracer by  doxygen 1.5.3