SceneGraph.cpp
Go to the documentation of this file.00001 /**<!--------------------------------------------------------------------> 00002 @file SceneGraph.cpp 00003 @author Travis Fischer (fisch0920@gmail.com) 00004 @author Matthew Jacobs (jacobs.mh@gmail.com) 00005 @date Fall 2008 00006 00007 @brief 00008 Bare-bones scene graph used during scene parsing 00009 <!-------------------------------------------------------------------->**/ 00010 00011 #include "SceneGraph.h" 00012 #include "MiltonJSONSceneLoader.h" 00013 #include <milton.h> 00014 00015 #include <QtCore> 00016 #include <boost/any.hpp> 00017 #include <typeinfo> 00018 #include <iostream> 00019 #include <fstream> 00020 00021 00022 bool SceneGraph::flatten(JSONParseData &data) { 00023 data << "flattening scenegraph" << endl; 00024 00025 ASSERT(data.sceneGraph.size() == 1); 00026 ASSERT(data.instance == 0); 00027 00028 { // initialize default material 00029 Material *defaultMaterial = new Material(); 00030 defaultMaterial->init(); 00031 data.activeMaterial = defaultMaterial; 00032 data.materials.push_back(defaultMaterial); 00033 } 00034 00035 { // traverse scenegraph 00036 SceneNode *root = data.sceneGraph.pop(); 00037 00038 bool retVal = 00039 flatten(root, Matrix4x4::identity(), Matrix4x4::identity(), data); 00040 00041 ASSERT(data.instance == 0); 00042 safeDelete(root); 00043 00044 return retVal; 00045 } 00046 } 00047 00048 bool SceneGraph::flatten(SceneNode *node, 00049 Matrix4x4 transform, 00050 Matrix4x4 transformInv, 00051 JSONParseData &data) 00052 { 00053 ASSERT(node); 00054 00055 // pre-order traversal (visit current node before children) 00056 if (!node->flatten(transform, transformInv, data)) 00057 return false; 00058 00059 Material *activeMaterial = data.activeMaterial; 00060 ShapeSet *activeShapeSet = data.primitives; 00061 00062 // traverse all children 00063 FOREACH(SceneNodeListIter, node->children, iter) { 00064 SceneNode *child = *iter; 00065 ASSERT(child); 00066 00067 // recursively flatten current child 00068 if (!flatten(child, transform, transformInv, data)) 00069 return false; 00070 00071 // ensure active material is restored to current level 00072 data.activeMaterial = activeMaterial; 00073 data.primitives = activeShapeSet; 00074 } 00075 00076 return true; 00077 } 00078 00079 00080 bool SceneNodeTransform::flatten(Matrix4x4 &trans, 00081 Matrix4x4 &transInv, 00082 JSONParseData &data) 00083 { 00084 trans *= getTransform(); 00085 // TODO: deal with inverses 00086 00087 return true; 00088 } 00089 00090 bool SceneNodeMaterial::flatten(Matrix4x4 &trans, 00091 Matrix4x4 &transInv, 00092 JSONParseData &data) 00093 { 00094 ASSERT(material); 00095 00096 data.activeMaterial = material; 00097 data.materials.push_back(material); 00098 00099 return true; 00100 } 00101 00102 bool SceneNodeShape::flatten(Matrix4x4 &trans, 00103 Matrix4x4 &transInv, 00104 JSONParseData &data) 00105 { 00106 Shape *current = shape; 00107 00108 if (data.instance > 0) 00109 current = new InstancedShape(current); 00110 00111 current->setMaterial(data.activeMaterial); 00112 00113 Transformable *t = NULL; 00114 try { 00115 t = dynamic_cast<Transformable*>(current); 00116 } catch(std::bad_cast&) { } 00117 00118 // if the current shape is transformable 00119 if (t) { 00120 const Matrix4x4 &newTrans = trans * t->getTransToWorld(); 00121 t->setTransToWorld(newTrans); 00122 // TODO: use transInv instead of trans.getInverse() 00123 } 00124 00125 ShapeSet *shapeSet = NULL; 00126 try { 00127 shapeSet = dynamic_cast<ShapeSet*>(current); 00128 } catch(std::bad_cast&) { } 00129 00130 if (shapeSet) 00131 data.primitives = shapeSet; 00132 else 00133 data.primitives->push_back(current); 00134 00135 return true; 00136 } 00137 00138 bool SceneNodeInstance::flatten(Matrix4x4 &trans, 00139 Matrix4x4 &transInv, 00140 JSONParseData &data) 00141 { 00142 InstancedNodeMapIter instanceeIter = data.instancedNodes.find(instancee); 00143 if (instanceeIter == data.instancedNodes.end()) { 00144 data << "error: instanced node '" << instancee << "' not found" << endl; 00145 00146 return false; 00147 } 00148 00149 SceneNode *node = instanceeIter->second; 00150 00151 if (NULL == node) { 00152 data << "error: instanced node '" << instancee << "' not found" << endl; 00153 00154 return false; 00155 } 00156 00157 if (node->type != instanceeType) { 00158 data << "error: instanced node '" << instancee 00159 << "' type mismatch with expected type" << endl; 00160 00161 return false; 00162 } 00163 00164 Material *activeMaterial = data.activeMaterial; 00165 ShapeSet *activeShapeSet = data.primitives; 00166 00167 // record the fact that we're instanced 00168 ++data.instance; 00169 00170 data.sceneGraph.flatten(node, trans, transInv, data); 00171 00172 // pop this instance off of the implicit instance stack 00173 --data.instance; 00174 00175 // ensure active material is restored to current level 00176 data.activeMaterial = activeMaterial; 00177 data.primitives = activeShapeSet; 00178 00179 return true; 00180 } 00181
Generated on 28 Feb 2009 for Milton by
1.5.6