source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhConstructor.cpp @ 3265

Revision 3265, 4.0 KB checked in by mattausch, 16 years ago (diff)

worked on bvh constructor

Line 
1#include "BvhConstructor.h"
2#include "Triangle3.h"
3#include "SceneEntity.h"
4#include "Geometry.h"
5#include "gzstream.h"
6
7#include <queue>
8#include <stack>
9#include <fstream>
10
11#ifdef _CRT_SET
12        #define _CRTDBG_MAP_ALLOC
13        #include <stdlib.h>
14        #include <crtdbg.h>
15
16        // redefine new operator
17        #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
18        #define new DEBUG_NEW
19#endif
20
21
22using namespace std;
23
24
25namespace CHCDemoEngine
26{
27
28BvhConstructor::BvhConstructor(SceneEntity **entities,
29                                                           int first,
30                                                           int last):
31mEntities(entities),
32mFirst(first),
33mLast(last),
34mMaxDepth(10),
35mMaxObjects(1),
36mNumNodes(0)
37{
38}
39
40
41int BvhConstructor::SortTriangles(BvhLeaf *leaf,
42                                           int axis,
43                                           float position
44                                           )
45{
46        int i = leaf->mFirst;
47        int j = leaf->mLast;
48
49    while (1)
50        {
51                //while (mEntities[i]->GetWorldCenter()[axis] < position) ++ i;
52                //while (position < mEntities[j]->GetWorldCenter()[axis]) -- j;
53
54                while ((i < leaf->mLast) && (mEntities[i]->GetWorldCenter()[axis] < position)) ++ i;
55                while ((j > leaf->mFirst) && (position < mEntities[j]->GetWorldCenter()[axis])) -- j;
56
57                // sorting finished
58                if (i >= j) break;
59
60                // swap entities
61                swap(mEntities[i], mEntities[j]);
62                       
63                ++ i;
64                -- j;
65        }
66
67        return j;
68}
69
70
71int BvhConstructor::SortTrianglesSpatialMedian(BvhLeaf *leaf,
72                                                                                           int axis)
73{
74        // spatial median
75        float m = leaf->GetBox().Center()[axis];
76        return SortTriangles(leaf, axis, m);
77}
78
79
80BvhNode *BvhConstructor::SubdivideLeaf(BvhLeaf *leaf,
81                                                                           int parentAxis
82                                                                           )
83{
84        if (TerminationCriteriaMet(leaf))
85        {
86                if (leaf->CountPrimitives() <= 0)
87                        cout << "leaf constructed:" << leaf->mBox << " " << leaf->mFirst << " " << leaf->mLast << endl;
88                return leaf;
89        }
90
91        //const int axis = (parentAxis + 1) % 3;
92        const int axis = leaf->mBox.MajorAxis();
93        const int scale = 20;
94
95        // position of the split in the partailly sorted array of triangles
96        // corresponding to this leaf
97        int split = -1;
98        float pos = -1.0f;
99       
100        // Spatial median subdivision
101        split = SortTrianglesSpatialMedian(leaf, axis);
102        pos = leaf->mBox.Center()[axis];
103       
104        if (split == leaf->mLast)
105        {
106                // no split could be achieved => just halve number of objects
107                split = (leaf->mLast + leaf->mFirst) / 2;
108                cerr << "no reduction " << leaf->CountPrimitives() << " " << leaf->mFirst << " " << leaf->mLast << endl;
109        }
110
111        // create two more nodes
112        mNumNodes += 2;
113        BvhInterior *parent = new BvhInterior(leaf->GetParent());
114        parent->mFirst = leaf->mFirst;
115        parent->mLast = leaf->mLast;
116       
117        parent->mAxis = axis;
118        parent->mBox = leaf->mBox;
119        parent->mDepth = leaf->mDepth;
120
121        BvhLeaf *front = new BvhLeaf(parent);
122
123        parent->mBack = leaf;
124        parent->mFront = front;
125               
126        // now assign the triangles to the subnodes
127        front->mFirst = split + 1;
128        front->mLast = leaf->mLast;
129        front->mDepth = leaf->mDepth + 1;
130
131        leaf->mLast = split;
132        leaf->mDepth = front->mDepth;
133        leaf->mParent = parent;
134       
135        front->mBox = SceneEntity::ComputeBoundingBox(mEntities + front->mFirst, front->CountPrimitives());
136        leaf->mBox = SceneEntity::ComputeBoundingBox(mEntities + leaf->mFirst, leaf->CountPrimitives());
137
138        // recursively continue subdivision
139        parent->mBack = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mBack), axis);
140        parent->mFront = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mFront), axis);
141       
142        return parent;
143}
144
145
146bool BvhConstructor::TerminationCriteriaMet(BvhLeaf *leaf) const
147{
148        const bool criteriaMet =
149                (leaf->mDepth > mMaxDepth) ||
150                (leaf->CountPrimitives() <= mMaxObjects);
151
152        return criteriaMet;
153}
154
155
156BvhNode *BvhConstructor::Construct(int &numNodes)
157{
158        BvhNode *root;
159
160        mNumNodes = 1;
161
162        BvhLeaf *l = new BvhLeaf(NULL);
163       
164        l->mBox = SceneEntity::ComputeBoundingBox(mEntities + mFirst, mFirst - mLast + 1);
165
166        l->mFirst = mFirst;
167        l->mLast = mLast;
168        l->mArea = l->mBox.SurfaceArea();
169       
170        cout << "constructing bvh"  << endl;
171
172        root = SubdivideLeaf(l, 0);
173
174        numNodes = mNumNodes;
175
176        return root;
177}
178
179
180}
Note: See TracBrowser for help on using the repository browser.