//------------------------------------------------------------------------------- /// /// \file xmlload.cpp /// \author Cem Yuksel (www.cemyuksel.com) /// \version 1.0 /// \date August 21, 2019 /// /// \brief Example source for CS 6620 - University of Utah. /// //------------------------------------------------------------------------------- #include "scene.h" #include "objects.h" #include "tinyxml/tinyxml.h" //------------------------------------------------------------------------------- extern Node rootNode; extern Camera camera; extern RenderImage renderImage; //------------------------------------------------------------------------------- #ifdef WIN32 #define COMPARE(a,b) (_stricmp(a,b)==0) #else #define COMPARE(a,b) (strcasecmp(a,b)==0) #endif //------------------------------------------------------------------------------- void LoadScene ( TiXmlElement *element ); void LoadNode ( Node *node, TiXmlElement *element, int level=0 ); void LoadTransform( Transformation *trans, TiXmlElement *element, int level ); void ReadVector ( TiXmlElement *element, Vec3f &v ); void ReadFloat ( TiXmlElement *element, float &f, char const *name="value" ); //------------------------------------------------------------------------------- int LoadScene( char const *filename ) { TiXmlDocument doc(filename); if ( ! doc.LoadFile() ) { printf("Failed to load the file \"%s\"\n", filename); return 0; } TiXmlElement *xml = doc.FirstChildElement("xml"); if ( ! xml ) { printf("No \"xml\" tag found.\n"); return 0; } TiXmlElement *scene = xml->FirstChildElement("scene"); if ( ! scene ) { printf("No \"scene\" tag found.\n"); return 0; } TiXmlElement *cam = xml->FirstChildElement("camera"); if ( ! cam ) { printf("No \"camera\" tag found.\n"); return 0; } rootNode.Init(); LoadScene( scene ); // Load Camera camera.Init(); camera.dir += camera.pos; TiXmlElement *camChild = cam->FirstChildElement(); while ( camChild ) { if ( COMPARE( camChild->Value(), "position" ) ) ReadVector(camChild,camera.pos); else if ( COMPARE( camChild->Value(), "target" ) ) ReadVector(camChild,camera.dir); else if ( COMPARE( camChild->Value(), "up" ) ) ReadVector(camChild,camera.up); else if ( COMPARE( camChild->Value(), "fov" ) ) ReadFloat (camChild,camera.fov); else if ( COMPARE( camChild->Value(), "width" ) ) camChild->QueryIntAttribute("value", &camera.imgWidth); else if ( COMPARE( camChild->Value(), "height" ) ) camChild->QueryIntAttribute("value", &camera.imgHeight); camChild = camChild->NextSiblingElement(); } camera.dir -= camera.pos; camera.dir.Normalize(); Vec3f x = camera.dir ^ camera.up; camera.up = (x ^ camera.dir).GetNormalized(); renderImage.Init( camera.imgWidth, camera.imgHeight ); return 1; } //------------------------------------------------------------------------------- void PrintIndent( int level ) { for ( int i=0; iFirstChildElement(); child!=nullptr; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "object" ) ) { LoadNode( &rootNode, child ); } } } //------------------------------------------------------------------------------- void LoadNode( Node *parent, TiXmlElement *element, int level ) { Node *node = new Node; parent->AppendChild(node); // name char const *name = element->Attribute("name"); node->SetName(name); PrintIndent(level); printf("object ["); if ( name ) printf("%s",name); printf("]"); // type char const *type = element->Attribute("type"); if ( type ) { if ( COMPARE(type,"sphere") ) { node->SetNodeObj( &theSphere ); printf(" - Sphere"); } else { printf(" - UNKNOWN TYPE"); } } printf("\n"); for ( TiXmlElement *child = element->FirstChildElement(); child!=nullptr; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "object" ) ) { LoadNode(node,child,level+1); } } LoadTransform( node, element, level ); } //------------------------------------------------------------------------------- void LoadTransform( Transformation *trans, TiXmlElement *element, int level ) { for ( TiXmlElement *child = element->FirstChildElement(); child!=nullptr; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "scale" ) ) { Vec3f s(1,1,1); ReadVector( child, s ); trans->Scale(s.x,s.y,s.z); PrintIndent(level); printf(" scale %f %f %f\n",s.x,s.y,s.z); } else if ( COMPARE( child->Value(), "rotate" ) ) { Vec3f s(0,0,0); ReadVector( child, s ); s.Normalize(); float a; ReadFloat(child,a,"angle"); trans->Rotate(s,a); PrintIndent(level); printf(" rotate %f degrees around %f %f %f\n", a, s.x, s.y, s.z); } else if ( COMPARE( child->Value(), "translate" ) ) { Vec3f t(0,0,0); ReadVector(child,t); trans->Translate(t); PrintIndent(level); printf(" translate %f %f %f\n",t.x,t.y,t.z); } } } //------------------------------------------------------------------------------- void ReadVector( TiXmlElement *element, Vec3f &v ) { double x = (double) v.x; double y = (double) v.y; double z = (double) v.z; element->QueryDoubleAttribute( "x", &x ); element->QueryDoubleAttribute( "y", &y ); element->QueryDoubleAttribute( "z", &z ); v.x = (float) x; v.y = (float) y; v.z = (float) z; float f=1; ReadFloat( element, f ); v *= f; } //------------------------------------------------------------------------------- void ReadFloat ( TiXmlElement *element, float &f, char const *name ) { double d = (double) f; element->QueryDoubleAttribute( name, &d ); f = (float) d; } //-------------------------------------------------------------------------------