[162] | 1 | //#include <boost/algorithm/string.hpp>
|
---|
| 2 |
|
---|
| 3 | #include <stack>
|
---|
| 4 | #include "SceneGraph.h"
|
---|
| 5 | #include "X3dExporter.h"
|
---|
[339] | 6 | #include "Intersectable.h"
|
---|
[2615] | 7 | #include "IntersectableWrapper.h"
|
---|
[2643] | 8 | //#include "ktball.h"
|
---|
[162] | 9 |
|
---|
| 10 |
|
---|
[2176] | 11 | using namespace std;
|
---|
| 12 |
|
---|
[863] | 13 | namespace GtpVisibilityPreprocessor {
|
---|
[860] | 14 |
|
---|
| 15 |
|
---|
[162] | 16 | bool
|
---|
| 17 | SceneGraph::Export( const string filename )
|
---|
| 18 | {
|
---|
| 19 | if (strstr(filename.c_str(), ".x3d")) {
|
---|
| 20 | X3dExporter exporter(filename);
|
---|
| 21 | exporter.ExportScene(mRoot);
|
---|
| 22 | return true;
|
---|
| 23 | } else {
|
---|
| 24 | cerr<<"Error: Currently unsuported export format, filename "<<filename<<endl;
|
---|
| 25 |
|
---|
| 26 | }
|
---|
| 27 |
|
---|
| 28 |
|
---|
| 29 | return false;
|
---|
| 30 |
|
---|
| 31 | }
|
---|
| 32 |
|
---|
| 33 |
|
---|
[1328] | 34 | SceneGraphNode::~SceneGraphNode()
|
---|
| 35 | {
|
---|
[2600] | 36 | }
|
---|
| 37 |
|
---|
| 38 |
|
---|
| 39 | SceneGraphLeaf::~SceneGraphLeaf()
|
---|
| 40 | {
|
---|
[2715] | 41 | if (mDeleteGeometry)
|
---|
| 42 | CLEAR_CONTAINER(mGeometry);
|
---|
[2600] | 43 | }
|
---|
| 44 |
|
---|
| 45 |
|
---|
| 46 | SceneGraphInterior::~SceneGraphInterior()
|
---|
| 47 | {
|
---|
[1328] | 48 | // recursivly delete all children
|
---|
| 49 | CLEAR_CONTAINER(mChildren);
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 |
|
---|
[2600] | 53 |
|
---|
[1328] | 54 | /************************************************************/
|
---|
| 55 | /* SceneGraph implementation */
|
---|
| 56 | /************************************************************/
|
---|
| 57 |
|
---|
| 58 |
|
---|
| 59 | SceneGraph::SceneGraph():
|
---|
| 60 | mRoot(NULL)
|
---|
| 61 | {
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 |
|
---|
[1002] | 65 | SceneGraph::~SceneGraph()
|
---|
| 66 | {
|
---|
| 67 | DEL_PTR(mRoot);
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 |
|
---|
[2601] | 71 | SceneGraphInterior *SceneGraph::GetRoot()
|
---|
[1002] | 72 | {
|
---|
[1328] | 73 | return mRoot;
|
---|
| 74 | }
|
---|
[1002] | 75 |
|
---|
[1328] | 76 |
|
---|
[2601] | 77 | void SceneGraph::SetRoot(SceneGraphInterior *root)
|
---|
[1328] | 78 | {
|
---|
| 79 | mRoot = root;
|
---|
[1002] | 80 | }
|
---|
| 81 |
|
---|
| 82 |
|
---|
[2600] | 83 | int SceneGraph::CollectObjects(ObjectContainer &instances)
|
---|
[162] | 84 | {
|
---|
[2601] | 85 | instances.clear();
|
---|
[1328] | 86 | int number = 0;
|
---|
[162] | 87 |
|
---|
[1328] | 88 | stack<SceneGraphNode *> nodeStack;
|
---|
| 89 | nodeStack.push(mRoot);
|
---|
| 90 |
|
---|
[2600] | 91 | while (!nodeStack.empty())
|
---|
| 92 | {
|
---|
[1328] | 93 | SceneGraphNode *node = nodeStack.top();
|
---|
| 94 | nodeStack.pop();
|
---|
[2600] | 95 |
|
---|
| 96 | if (node->IsLeaf())
|
---|
[1328] | 97 | {
|
---|
[2601] | 98 | SceneGraphLeaf *leaf = static_cast<SceneGraphLeaf *>(node);
|
---|
[2600] | 99 |
|
---|
| 100 | ObjectContainer::const_iterator mi = leaf->mGeometry.begin();
|
---|
| 101 |
|
---|
| 102 | for (; mi != leaf->mGeometry.end(); mi++)
|
---|
| 103 | {
|
---|
[2601] | 104 | instances.push_back(*mi);
|
---|
[2600] | 105 | }
|
---|
[1328] | 106 | }
|
---|
[2600] | 107 | else
|
---|
| 108 | {
|
---|
[2601] | 109 | SceneGraphInterior *interior = static_cast<SceneGraphInterior *>(node);
|
---|
[2600] | 110 | SceneGraphNodeContainer::iterator ni = interior->mChildren.begin();
|
---|
| 111 |
|
---|
| 112 | for (; ni != interior->mChildren.end(); ++ ni)
|
---|
| 113 | {
|
---|
| 114 | nodeStack.push(*ni);
|
---|
| 115 | number++;
|
---|
| 116 | }
|
---|
[1328] | 117 | }
|
---|
| 118 | }
|
---|
[1344] | 119 |
|
---|
[1328] | 120 | return number;
|
---|
[162] | 121 | }
|
---|
[339] | 122 |
|
---|
| 123 |
|
---|
| 124 | int
|
---|
| 125 | SceneGraph::AssignObjectIds()
|
---|
| 126 | {
|
---|
[2544] | 127 | // matt: rather start with id zero
|
---|
| 128 | int id = 0;
|
---|
| 129 | stack<SceneGraphNode *> nodeStack;
|
---|
[1344] | 130 |
|
---|
[2544] | 131 | nodeStack.push(mRoot);
|
---|
| 132 |
|
---|
| 133 | while (!nodeStack.empty())
|
---|
| 134 | {
|
---|
| 135 | SceneGraphNode *node = nodeStack.top();
|
---|
| 136 | nodeStack.pop();
|
---|
| 137 |
|
---|
[2601] | 138 | if (node->IsLeaf())
|
---|
[2600] | 139 | {
|
---|
| 140 | SceneGraphLeaf *leaf = static_cast<SceneGraphLeaf *>(node);
|
---|
| 141 | ObjectContainer::iterator mi = leaf->mGeometry.begin();
|
---|
[2544] | 142 |
|
---|
[2600] | 143 | for (; mi != leaf->mGeometry.end(); mi ++)
|
---|
| 144 | {
|
---|
| 145 | (*mi)->SetId(id ++);
|
---|
| 146 | }
|
---|
[2544] | 147 | }
|
---|
[2600] | 148 | else
|
---|
[2544] | 149 | {
|
---|
[2600] | 150 | SceneGraphInterior *interior = static_cast<SceneGraphInterior *>(node);
|
---|
[2601] | 151 |
|
---|
[2600] | 152 | SceneGraphNodeContainer::iterator ni = interior->mChildren.begin();
|
---|
[2601] | 153 |
|
---|
| 154 | for (; ni != interior->mChildren.end(); ni ++)
|
---|
[2600] | 155 | {
|
---|
| 156 | nodeStack.push(*ni);
|
---|
| 157 | }
|
---|
[2544] | 158 | }
|
---|
[576] | 159 | }
|
---|
[2544] | 160 |
|
---|
| 161 | // return max id
|
---|
| 162 | return id;
|
---|
[339] | 163 | }
|
---|
[387] | 164 |
|
---|
| 165 | void
|
---|
| 166 | SceneGraph::GetStatistics(int &intersectables, int &faces) const
|
---|
| 167 | {
|
---|
[2600] | 168 | stack<SceneGraphNode *> nodeStack;
|
---|
| 169 |
|
---|
| 170 | nodeStack.push(mRoot);
|
---|
| 171 | faces = 0;
|
---|
[387] | 172 | intersectables = 0;
|
---|
[2601] | 173 |
|
---|
| 174 | while (!nodeStack.empty())
|
---|
| 175 | {
|
---|
[2600] | 176 | SceneGraphNode *node = nodeStack.top();
|
---|
| 177 | nodeStack.pop();
|
---|
| 178 |
|
---|
[2601] | 179 | if (node->IsLeaf())
|
---|
| 180 | {
|
---|
| 181 | SceneGraphLeaf *leaf = static_cast<SceneGraphLeaf *>(node);
|
---|
| 182 |
|
---|
| 183 | ObjectContainer::const_iterator mi = leaf->mGeometry.begin();
|
---|
| 184 | for (; mi != leaf->mGeometry.end(); mi++)
|
---|
| 185 | {
|
---|
| 186 | intersectables++;
|
---|
| 187 | faces += (*mi)->NumberOfFaces();
|
---|
| 188 | }
|
---|
[387] | 189 | }
|
---|
[2601] | 190 | else
|
---|
| 191 | {
|
---|
| 192 | SceneGraphInterior *interior = static_cast<SceneGraphInterior *>(node);
|
---|
[2600] | 193 |
|
---|
[2601] | 194 | SceneGraphNodeContainer::iterator ni = interior->mChildren.begin();
|
---|
| 195 | for (; ni != interior->mChildren.end(); ni++)
|
---|
| 196 | {
|
---|
| 197 | nodeStack.push(*ni);
|
---|
| 198 | }
|
---|
[2600] | 199 | }
|
---|
| 200 | }
|
---|
[387] | 201 | }
|
---|
[492] | 202 |
|
---|
| 203 |
|
---|
[2601] | 204 | void SceneGraphLeaf::UpdateBox()
|
---|
[492] | 205 | {
|
---|
[2600] | 206 | AxisAlignedBox3 box;
|
---|
| 207 | box.Initialize();
|
---|
| 208 |
|
---|
| 209 | ObjectContainer::const_iterator mi = mGeometry.begin();
|
---|
| 210 | for (; mi != mGeometry.end(); mi++)
|
---|
| 211 | box.Include((*mi)->GetBox());
|
---|
| 212 |
|
---|
| 213 | mBox = box;
|
---|
[492] | 214 | }
|
---|
[860] | 215 |
|
---|
[1166] | 216 |
|
---|
[2601] | 217 | void SceneGraphInterior::UpdateBox()
|
---|
[2600] | 218 | {
|
---|
| 219 | AxisAlignedBox3 box;
|
---|
| 220 |
|
---|
| 221 | box.Initialize();
|
---|
| 222 |
|
---|
| 223 | SceneGraphNodeContainer::iterator ni = mChildren.begin();
|
---|
| 224 |
|
---|
| 225 | for (; ni != mChildren.end(); ++ ni)
|
---|
| 226 | {
|
---|
| 227 | (*ni)->UpdateBox();
|
---|
[2615] | 228 | box.Include((*ni)->GetBox());
|
---|
[2600] | 229 | }
|
---|
| 230 |
|
---|
| 231 | mBox = box;
|
---|
| 232 | }
|
---|
| 233 |
|
---|
| 234 |
|
---|
| 235 |
|
---|
[1166] | 236 | void SceneGraph::ExportScene(const string filename)
|
---|
| 237 | {
|
---|
| 238 | }
|
---|
| 239 |
|
---|
[1194] | 240 |
|
---|
[1166] | 241 | void SceneGraph::LoadScene(const string filename)
|
---|
| 242 | {
|
---|
| 243 | // load binary version of mesh
|
---|
| 244 | }
|
---|
| 245 |
|
---|
[1958] | 246 |
|
---|
[2601] | 247 | int SceneGraph::GetSize() const
|
---|
| 248 | {
|
---|
| 249 | stack<SceneGraphNode *> nodeStack;
|
---|
| 250 |
|
---|
| 251 | nodeStack.push(mRoot);
|
---|
| 252 | int size = 0;
|
---|
| 253 |
|
---|
| 254 | while (!nodeStack.empty())
|
---|
| 255 | {
|
---|
| 256 | SceneGraphNode *node = nodeStack.top();
|
---|
| 257 | nodeStack.pop();
|
---|
| 258 |
|
---|
| 259 | if (node->IsLeaf())
|
---|
| 260 | {
|
---|
| 261 | SceneGraphLeaf *leaf = static_cast<SceneGraphLeaf *>(node);
|
---|
| 262 |
|
---|
[2694] | 263 | size += (int)leaf->mGeometry.size();
|
---|
[2601] | 264 | }
|
---|
| 265 | else
|
---|
| 266 | {
|
---|
| 267 | SceneGraphInterior *interior = static_cast<SceneGraphInterior *>(node);
|
---|
| 268 |
|
---|
| 269 | SceneGraphNodeContainer::iterator ni = interior->mChildren.begin();
|
---|
| 270 | for (; ni != interior->mChildren.end(); ni++)
|
---|
| 271 | {
|
---|
| 272 | nodeStack.push(*ni);
|
---|
| 273 | }
|
---|
| 274 | }
|
---|
| 275 | }
|
---|
| 276 |
|
---|
| 277 | return size;
|
---|
| 278 | }
|
---|
| 279 |
|
---|
[2609] | 280 |
|
---|
[2715] | 281 | SceneGraphLeaf::SceneGraphLeaf():
|
---|
| 282 | mIsDynamic(false), mHasChanged(true), mDeleteGeometry(true)
|
---|
[2615] | 283 | {
|
---|
| 284 | mTrafo = IdentityMatrix();
|
---|
| 285 | mIntersectable = new SceneGraphLeafIntersectable(this, mBox);
|
---|
| 286 | }
|
---|
| 287 |
|
---|
| 288 |
|
---|
[2715] | 289 | SceneGraphLeaf::SceneGraphLeaf(bool isDynamic):
|
---|
| 290 | mIsDynamic(isDynamic), mHasChanged(true), mDeleteGeometry(true)
|
---|
[2615] | 291 | {
|
---|
[2621] | 292 | mTrafo = IdentityMatrix();
|
---|
[2710] | 293 | mIntersectable = new SceneGraphLeafIntersectable(this, mBox);
|
---|
[2662] | 294 | }
|
---|
[2615] | 295 |
|
---|
[2609] | 296 |
|
---|
[2662] | 297 | void SceneGraphLeaf::ApplyTransform(const Matrix4x4 &trafo)
|
---|
| 298 | {
|
---|
[2709] | 299 | mHasChanged = true;
|
---|
[2662] | 300 | mTrafo = trafo * mTrafo;
|
---|
| 301 | }
|
---|
| 302 |
|
---|
| 303 |
|
---|
[2615] | 304 | void SceneGraphLeaf::LoadTransform(const Matrix4x4 &m)
|
---|
| 305 | {
|
---|
[2709] | 306 | mHasChanged = true;
|
---|
[2615] | 307 | mTrafo = m;
|
---|
| 308 | }
|
---|
| 309 |
|
---|
| 310 |
|
---|
| 311 | void SceneGraphLeaf::GetTransform(Matrix4x4 &m) const
|
---|
| 312 | {
|
---|
| 313 | m = mTrafo;
|
---|
| 314 | }
|
---|
| 315 |
|
---|
| 316 |
|
---|
| 317 | AxisAlignedBox3 SceneGraphLeaf::GetBox() const
|
---|
| 318 | {
|
---|
| 319 | return Transform(mBox, mTrafo);
|
---|
| 320 | }
|
---|
[2621] | 321 |
|
---|
| 322 |
|
---|
[2694] | 323 | AxisAlignedBox3 SceneGraphLeaf::GetOriginalBox() const
|
---|
| 324 | {
|
---|
| 325 | return mBox;
|
---|
| 326 | }
|
---|
[2662] | 327 |
|
---|
[2702] | 328 |
|
---|
| 329 | SceneGraphLeaf::SceneGraphLeaf(SceneGraphLeaf const& copy)
|
---|
| 330 | {
|
---|
| 331 | // hack: should just pass a IntersectableGroup as a whole
|
---|
[2715] | 332 | // instead we duplicate the geometry vector
|
---|
[2702] | 333 | mGeometry = copy.mGeometry;
|
---|
| 334 |
|
---|
| 335 | mBox = copy.mBox;
|
---|
| 336 | mTrafo = copy.mTrafo;
|
---|
| 337 | mIsDynamic = copy.mIsDynamic;
|
---|
[2710] | 338 |
|
---|
| 339 | mIntersectable = new SceneGraphLeafIntersectable(this, mBox);
|
---|
[2709] | 340 | mHasChanged = true;
|
---|
[2715] | 341 |
|
---|
| 342 | // hack: the geometry should not be deleted here because this
|
---|
| 343 | // is just a copy
|
---|
| 344 | mDeleteGeometry = false;
|
---|
[2702] | 345 | }
|
---|
| 346 |
|
---|
[2615] | 347 | } |
---|