/******************************************************************/ /* This file is part of the homework assignments for CSCI-427/527 */ /* at The College of William & Mary and authored by Pieter Peers. */ /* No part of this file, whether altered or in original form, can */ /* be distributed or used outside the context of CSCI-427/527 */ /* without consent of either the College of William & Mary or */ /* Pieter Peers. */ /******************************************************************/ #include "util.h" #include "scene.h" #include "raycasting.h" #include "sceneGraphNode.h" #include "linear_intersector.h" #include "sceneIO_xml.h" #include "sceneIO_core.h" #include "sceneIO_cache.h" #include "sceneIO_basis.h" #include "sceneIO_light.h" #include "sceneIO_texture.h" #include "sceneIO_geometry.h" #include "sceneIO_material.h" void importScene(const std::string& filename, scene& s) { // get root std::string rootDir = getDirectory(filename); // open xml XMLNode sceneNode(filename); // check if valid scene node if(!sceneNode.isValid()) errorMessage("Failed to find 'scene' in %s.", filename.c_str()); // create sceneGraphNode, texture, and shader cache nodeCache shape_cache; nodeCache texture_cache; nodeCache shader_cache; // init scene data bool autoTuneCamera = false; std::unique_ptr intersector(new linear_intersector_factory()); s._renderEngine = std::unique_ptr(new raycasting()); // process sceneNode for(XMLNode node = sceneNode.firstChild(); node.isValid(); node++) { // check for general node-types if(importTexture(node, texture_cache, rootDir)) continue; if(importMaterial(node, shader_cache, texture_cache, rootDir)) continue; if(importGeometry(node, shape_cache, shader_cache, texture_cache, rootDir)) continue; // check for scene-root specific nodes std::string nodeName = node.name(); if(nodeName == "camera") autoTuneCamera = importCamera(node, s._camera); else if(nodeName == "light") s._lightsources.push_back( importLight(node, shape_cache, shader_cache, texture_cache, rootDir) ); else if(nodeName == "environmentMap") importEnvironmentMap(node, texture_cache, rootDir, s._environmentMap); else if(nodeName == "intersector") importIntersector(node, intersector); else if(nodeName == "renderer") importRenderEngine(node, s._renderEngine); else errorMessage("Unknown node in scene xml: '%s'", nodeName.c_str()); } // initialize all node's intersectors auto nodeList = shape_cache.allNodes(); for(auto itr=nodeList.begin(); itr != nodeList.end(); itr++) static_cast(itr->get())->initialize(*intersector); nodeList.clear(); // add all unreferences nodes to the _sceneGraphRoot. // Note: remove any node without a shader decltype(nodeList) unusedNodes; nodeList = shape_cache.unusedNodes(); while(!nodeList.empty()) { auto bck = nodeList.back(); if(bck->hasShader()) unusedNodes.push_back(bck); nodeList.pop_back(); } // -> init + add std::unique_ptr root(new sceneGraphNode( *(reinterpret_cast< std::vector>* >(&unusedNodes)) )); root->initialize(*intersector); s._sceneGraphRoot = std::unique_ptr(root.release()); // Auto Tune Camera is requested if(autoTuneCamera) s._camera.frameBoundingBox( s._sceneGraphRoot->boundingbox() ); // Done. }