source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhLoader.cpp @ 3068

Revision 3068, 4.3 KB checked in by mattausch, 16 years ago (diff)

working on dynamic stuff again

Line 
1#include <queue>
2#include <stack>
3#include <fstream>
4#include <iostream>
5
6#include "BvhLoader.h"
7#include "gzstream.h"
8
9
10#ifdef _CRT_SET
11        #define _CRTDBG_MAP_ALLOC
12        #include <stdlib.h>
13        #include <crtdbg.h>
14
15        // redefine new operator
16        #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
17        #define new DEBUG_NEW
18#endif
19
20
21namespace CHCDemoEngine
22{
23
24using namespace std;
25
26
27#define TYPE_INTERIOR -2
28#define TYPE_LEAF -3
29
30
31
32BvhNode *BvhLoader::LoadNextNode(igzstream &stream, BvhInterior *parent)
33{
34        int nodeType;
35        stream.read(reinterpret_cast<char *>(&nodeType), sizeof(int));
36
37        BvhNode *node;
38
39        if (nodeType == TYPE_LEAF)
40                node = new BvhLeaf(parent);
41        else if (nodeType == TYPE_INTERIOR)
42                node = new BvhInterior(parent);
43        else
44                cerr << "error: wrong node type: " << nodeType << endl;
45               
46
47        Vector3 bMin, bMax;
48
49        stream.read(reinterpret_cast<char *>(&(node->mFirst)), sizeof(int));
50        stream.read(reinterpret_cast<char *>(&(node->mLast)), sizeof(int));
51
52        stream.read(reinterpret_cast<char *>(&bMin), sizeof(Vector3));
53        stream.read(reinterpret_cast<char *>(&bMax), sizeof(Vector3));
54
55        node->mBox = AxisAlignedBox3(bMin, bMax);
56        node->mArea = node->mBox.SurfaceArea();
57
58        //cout << "box: " << node->mBox << " area: " << node->mArea << endl;
59       
60        return node;
61}
62
63
64Bvh *BvhLoader::Load(const string &filename, 
65                                         const SceneEntityContainer &entities)
66{
67        queue<BvhNode *> tQueue;
68        igzstream stream(filename.c_str());
69
70        if (!stream.is_open()) return NULL;
71
72        cout << "loading bvh" << endl;
73
74        Bvh *bvh = new Bvh(entities);
75
76        BvhNode *root = LoadNextNode(stream, NULL);
77
78        bvh->mRoot = root;
79
80#if 0
81
82        //bvh->mRoot = bvh->mStaticRoot;
83        bvh->mNumNodes = 1;
84
85#else
86        // we are setting a new root node
87        // and adds one level of indirection to the bvh
88        // It allows us to use dynamic objects
89
90        // the new bvh has two main branches
91        // a static branch (the old root), and adynamic branch
92        // we create a 'dynamic' leaf which basically is a container
93        // for all dynamic objects underneath
94
95        // the bounding boxes of the dynamic tree must be updated
96        // once each frame in order to be able to incorporate
97        // the movements of the objects within
98
99        // create new root
100        /*BvhInterior *newRoot = new BvhInterior(NULL);
101        bvh->mRoot = newRoot;
102
103        // the separation is a purely logical one
104        // the bounding boxes of the child nodes are
105        // identical to those of the root node
106
107        newRoot->mBox = bvh->mStaticRoot->mBox;
108        newRoot->mArea = newRoot->mBox.SurfaceArea();
109
110        newRoot->mFirst = bvh->mStaticRoot->mFirst;
111        newRoot->mLast = bvh->mStaticRoot->mLast;
112
113        // add static root on left subtree
114        newRoot->mFront = bvh->mStaticRoot;
115        bvh->mStaticRoot->mParent = newRoot;
116        */
117        // create and add dynamic root
118        BvhLeaf *dynamicRoot = new BvhLeaf(NULL);
119       
120        dynamicRoot->mFirst = 0;
121        dynamicRoot->mLast = 0;
122
123        //dynamicRoot->mBox = bvh->mStaticRoot->mBox;
124        dynamicRoot->mBox = bvh->mRoot->mBox;
125        dynamicRoot->mArea = dynamicRoot->mBox.SurfaceArea();
126
127        bvh->mDynamicRoot = dynamicRoot;
128        //newRoot->mBack = dynamicRoot;
129
130        bvh->mNumNodes = 1;
131#endif
132
133        tQueue.push(bvh->mRoot);
134       
135        while(!tQueue.empty())
136        {
137                BvhNode *node = tQueue.front();
138                tQueue.pop();
139
140                if (!node->IsLeaf())
141                {
142                        bvh->mNumNodes += 2;
143
144                        BvhInterior *interior = static_cast<BvhInterior *>(node);
145
146                        BvhNode *front = LoadNextNode(stream, interior);
147                        BvhNode *back = LoadNextNode(stream, interior);
148
149                        interior->mFront = front;
150                        interior->mBack = back;
151
152                        front->mDepth = interior->mDepth + 1;
153                        back->mDepth = interior->mDepth + 1;
154
155                        tQueue.push(front);                     
156                        tQueue.push(back);
157                }
158        }
159
160
161        bvh->mBox = bvh->mRoot->GetBox();
162
163        cout << "... finished loading " << bvh->mNumNodes << " nodes" << endl;
164        cout << "scene box: " << bvh->mBox << endl;
165
166       
167        ///////////
168        //-- post process nodes
169
170        /// this function must be called once after creation
171        bvh->PostProcess();
172       
173        // set virtual leaves for specified number of triangles
174        bvh->SetVirtualLeaves(INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES);
175        /// update the numleaves parameter of the bvh nodes
176        bvh->UpdateNumLeaves(bvh->mRoot);
177        // compute unique ids
178        bvh->ComputeIds();
179        // specify bounds for occlusion tests
180        bvh->RecomputeBounds();
181
182        // compute and print stats
183        bvh->ComputeBvhStats();
184        bvh->PrintBvhStats();
185
186        return bvh;
187}
188
189
190}
Note: See TracBrowser for help on using the repository browser.