static void parse_planebody( BodyMap& bodies, const TiXmlElement* elem, PlaneBody* body ) { parse_elem( elem, true, STR_ID, &body->id ); parse_elem( elem, true, STR_POSITION, &body->position ); parse_elem( elem, true, STR_NORMAL, &body->normal ); bodies[body->id] = body; }
static void parse_point_light( const TiXmlElement* elem, PointLight* light ) { parse_elem( elem, false, STR_ACON, &light->attenuation.constant ); parse_elem( elem, false, STR_ALIN, &light->attenuation.linear ); parse_elem( elem, false, STR_AQUAD, &light->attenuation.quadratic ); parse_elem( elem, true, STR_POSITION, &light->position ); parse_elem( elem, true, STR_COLOR, &light->color ); }
static void parse_trianglebody( const TiXmlElement* elem, TriangleBody* body ) { parse_elem( elem, true, STR_ID, &body->id ); parse_elem( elem, false, STR_POINTA, &body->vertices[0]); parse_elem( elem, false, STR_POINTB, &body->vertices[1]); parse_elem( elem, false, STR_POINTC, &body->vertices[2]); body->position = body->vertices[0]; }
static void parse_geom_base( const MaterialMap& matmap, const TiXmlElement* elem, Geometry* geom ) { Quaternion ori = geom->orientation; parse_elem( elem, true, STR_POSITION, &geom->position ); parse_elem( elem, false, STR_ORIENT, &ori ); parse_elem( elem, false, STR_SCALE, &geom->scale ); // normalize orientation geom->orientation = normalize( ori ); }
static void parse_camera( const TiXmlElement* elem, Camera* camera ) { Quaternion ori = camera->orientation; // note: we don't load aspect, since it's set by the application parse_elem( elem, true, STR_FOV, &camera->fov ); parse_elem( elem, true, STR_NEAR, &camera->near_clip ); parse_elem( elem, true, STR_FAR, &camera->far_clip ); parse_elem( elem, true, STR_POSITION, &camera->position ); parse_elem( elem, true, STR_ORIENT, &ori ); // normalize orientation camera->orientation = normalize( ori ); }
static const char* parse_triangle_vertex( const MaterialMap& matmap, const TiXmlElement* elem, Triangle::Vertex* vertex ) { const char* name; Vector3 normal = vertex->normal; parse_elem( elem, true, STR_POSITION, &vertex->position ); parse_elem( elem, true, STR_NORMAL, &normal ); parse_elem( elem, true, STR_TCOORD, &vertex->tex_coord ); parse_lookup_data( matmap, elem, STR_MATERIAL, &vertex->material ); parse_attrib_string( elem, true, STR_NAME, &name ); // normalize normal vertex->normal = normalize( normal ); return name; }
static const char* parse_material( const TiXmlElement* elem, Material* material ) { const char* name; parse_attrib_string( elem, false, STR_TEXTURE, &material->texture_filename ); parse_attrib_string( elem, true, STR_NAME, &name ); parse_elem( elem, false, STR_REFRACT, &material->refractive_index ); parse_elem( elem, false, STR_AMBIENT, &material->ambient ); parse_elem( elem, false, STR_DIFFUSE, &material->diffuse ); parse_elem( elem, false, STR_SPECULAR, &material->specular ); parse_elem( elem, false, STR_SHININESS, &material->shininess ); return name; }
static void parse_geom_sphere( const MaterialMap& matmap, const TiXmlElement* elem, Sphere* geom ) { // parse base parse_geom_base( matmap, elem, geom ); parse_elem( elem, true, STR_RADIUS, &geom->radius ); parse_lookup_data( matmap, elem, STR_MATERIAL, &geom->material ); }
static void parse_spherebody( const TiXmlElement* elem, SphereBody* body ) { parse_elem( elem, true, STR_ID, &body->id ); parse_elem( elem, true, STR_MASS, &body->mass ); parse_elem( elem, false, STR_POSITION, &body->position ); parse_elem( elem, false, STR_RADIUS, &body->radius ); parse_elem( elem, false, STR_VELOCITY, &body->velocity ); parse_elem( elem, false, STR_ANGULARVELOCITY, &body->angular_velocity ); parse_elem( elem, false, STR_ORIENT, &body->orientation ); }
static void parse_camera( const TiXmlElement* elem, Camera* camera ) { Quaternion ori; Vector3 position; real_t fov; real_t nearClip; real_t farClip; // note: we don't load aspect, since it's set by the application parse_elem( elem, true, STR_FOV, &fov ); parse_elem( elem, true, STR_NEAR, &nearClip ); parse_elem( elem, true, STR_FAR, &farClip ); parse_elem( elem, true, STR_POSITION, &position ); parse_elem( elem, true, STR_ORIENT, &ori ); // normalize orientation camera->SetOrientation( normalize( ori ) ); camera->SetPosition(position); camera->SetFarClip(farClip); camera->SetNearClip(nearClip); camera->SetFOV(fov); }
static void parse_spring( BodyMap& bmap, const TiXmlElement* elem, Spring* spring ) { int id; parse_elem( elem, true, STR_CONSTANT, &spring->constant ); parse_elem( elem, true, STR_EQUILIBRIUM, &spring->equilibrium ); parse_elem( elem, true, STR_BODY1, &id ); spring->body1 = bmap[id]; parse_elem( elem, false, STR_OFFSET1, &spring->body1_offset ); parse_elem( elem, true, STR_BODY2, &id ); spring->body2 = bmap[id]; parse_elem( elem, false, STR_OFFSET2, &spring->body2_offset ); parse_elem( elem, false, STR_DAMPING, &spring->damping ); }
static void parse_geom_sphere( const MaterialMap& matmap, BodyMap& bodies, Physics* phys, const TiXmlElement* elem, Sphere* geom ) { // parse base parse_geom_base( matmap, elem, geom ); parse_elem( elem, true, STR_RADIUS, &geom->radius ); parse_lookup_data( matmap, elem, STR_MATERIAL, &geom->material ); const TiXmlElement* child = elem->FirstChildElement( STR_BODY ); if ( child ) { SphereBody* body = new SphereBody( geom ); check_mem( body ); parse_spherebody( child, body ); bodies[body->id] = body; phys->add_sphere(body); } }
// Parse a comma separated sequence of elements in // either a tuple or a variant. // // elem-list ::= elem | elem-list ',' elem Tree_seq* parse_elem_list(Parser& p, Token_kind close_tok) { Tree_seq* ts = new Tree_seq(); while (true) { // Try parsing the next element. if (Tree* t = parse_elem(p)) ts->push_back(t); else return nullptr; // Either break or continue. if (parse::next_token_is(p, close_tok)) break; parse::expect(p, comma_tok); } return ts; }
bool load_scene( Scene* scene, const char* filename ) { TiXmlDocument doc( filename ); const TiXmlElement* root = 0; const TiXmlElement* elem = 0; MaterialMap materials; MeshMap meshes; TriVertMap triverts; assert( scene ); // load the document if ( !doc.LoadFile() ) { std::cout << "ERROR, " << doc.ErrorRow() << ":" << doc.ErrorCol() << "; " << "parse error: " << doc.ErrorDesc() << "\n"; return false; } // check for root element root = doc.RootElement(); if ( !root ) { std::cout << "No root element.\n"; return false; } // reset the scene scene->reset(); try { // parse the camera elem = get_unique_child( root, true, STR_CAMERA ); parse_camera( elem, &scene->camera ); // parse background color parse_elem( root, true, STR_BACKGROUND, &scene->background_color ); // parse refractive index parse_elem( root, true, STR_REFRACT, &scene->refractive_index ); // parse ambient light parse_elem( root, false, STR_AMLIGHT, &scene->ambient_light ); // parse the lights elem = root->FirstChildElement( STR_PLIGHT ); while ( elem ) { PointLight pl; parse_point_light( elem, &pl ); scene->add_light( pl ); elem = elem->NextSiblingElement( STR_PLIGHT ); } // parse the materials elem = root->FirstChildElement( STR_MATERIAL ); while ( elem ) { Material* mat = new Material(); check_mem( mat ); scene->add_material( mat ); const char* name = parse_material( elem, mat ); assert( name ); // place each material in map by it's name, so we can associate geometries // with them when loading geometries // check for repeat name if ( !materials.insert( std::make_pair( name, mat ) ).second ) { print_error_header( elem ); std::cout << "Material '" << name << "' multiply defined.\n"; throw std::exception(); } elem = elem->NextSiblingElement( STR_MATERIAL ); } // parse the meshes elem = root->FirstChildElement( STR_MESH ); while ( elem ) { Mesh* mesh = new Mesh(); check_mem( mesh ); scene->add_mesh( mesh ); const char* name = parse_mesh( elem, mesh ); assert( name ); // place each mesh in map by it's name, so we can associate geometries // with them when loading geometries if ( !meshes.insert( std::make_pair( name, mesh ) ).second ) { print_error_header( elem ); std::cout << "Mesh '" << name << "' multiply defined.\n"; throw std::exception(); } elem = elem->NextSiblingElement( STR_MESH ); } // parse vertices (used by triangles) elem = root->FirstChildElement( STR_VERTEX ); while ( elem ) { Triangle::Vertex v; const char* name = parse_triangle_vertex( materials, elem, &v ); assert( name ); // place each vertex in map by it's name, so we can associate triangles // with them when loading geometries if ( !triverts.insert( std::make_pair( name, v ) ).second ) { print_error_header( elem ); std::cout << "Triangle vertex '" << name << "' multiply defined.\n"; throw std::exception(); } elem = elem->NextSiblingElement( STR_VERTEX ); } // parse the geometries // spheres elem = root->FirstChildElement( STR_SPHERE ); while ( elem ) { Sphere* geom = new Sphere(); check_mem( geom ); scene->add_geometry( geom ); parse_geom_sphere( materials, elem, geom ); elem = elem->NextSiblingElement( STR_SPHERE ); } // triangles elem = root->FirstChildElement( STR_TRIANGLE ); while ( elem ) { Triangle* geom = new Triangle(); check_mem( geom ); scene->add_geometry( geom ); parse_geom_triangle( materials, triverts, elem, geom ); elem = elem->NextSiblingElement( STR_TRIANGLE ); } // models elem = root->FirstChildElement( STR_MODEL ); while ( elem ) { Model* geom = new Model(); check_mem( geom ); scene->add_geometry( geom ); parse_geom_model( materials, meshes, elem, geom ); elem = elem->NextSiblingElement( STR_MODEL ); } // TODO add you own geometries here } catch ( std::bad_alloc const& ) { std::cout << "Out of memory error while loading scene\n."; scene->reset(); return false; } catch ( ... ) { scene->reset(); return false; } return true; }