source: GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.cpp @ 2643

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

compiling under release internal

Line 
1#include <iostream>
2#include <stack>
3
4#include "Mesh.h"
5#include "ObjectPvs.h"
6#include "Intersectable.h"
7#include "IntersectableWrapper.h"
8#include "KdTree.h"
9#include "common.h"
10#include "BvHierarchy.h"
11
12// $$ switched off by JB for testing
13#define USE_MULTIPLE_OBJECTS  0
14using namespace std;
15
16namespace GtpVisibilityPreprocessor {
17
18static ObjectPvs dummyPvs;
19
20/** the pvs is the number of different objects in the node leaves
21        We eliminate already accounted kd nodes and objects using mailboxing.
22*/
23static int EvalKdNodeContribution(KdIntersectable *kdobj)
24{
25        int pvs = 0;
26        stack<KdNode *> tStack;
27
28        tStack.push(kdobj->GetItem());
29
30        while (!tStack.empty())
31        {
32                KdNode *node = tStack.top();
33                tStack.pop();
34
35                // already processed node (=> objects already in pvs)?
36                if (1)//!node->Mailed())
37                {
38                        //node->Mail();
39                        if (node->IsLeaf())
40                        {
41                                KdLeaf *leaf = static_cast<KdLeaf *>(node);
42#if USE_MULTIPLE_OBJECTS                               
43                                // add #objects exclusivly in this node
44                                pvs += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
45
46                                // Objects already accounted for can only be found among those
47                                // which are referenced in more than one leaf
48                                ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
49                                               
50                                for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
51                                {
52                                        Intersectable *obj = *oit;                                             
53                           
54                                        if (1)//!obj->Mailed())
55                                        {
56                                                //obj->Mail();
57                                                if (dummyPvs.AddSample(obj))
58                                                        ++ pvs;
59                                        }
60                                }
61#else
62
63                                // Objects already accounted for can only be found among those
64                                // which are referenced in more than one leaf
65                                ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
66                               
67                                for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
68                                  {
69                                        Intersectable *obj = *oit;                                             
70                                       
71                                        if (!obj->Mailed2())
72                                          {
73                                                  //if (dummyPvs.AddSample(obj, 1.0f))++ pvs;
74                                                  obj->Mail2();
75                                                  ++pvs;
76                                          }
77                                  }
78                               
79#endif
80                        }
81                        else // traverse tree
82                        {
83                                KdInterior *interior = static_cast<KdInterior *>(node);
84
85                                tStack.push(interior->mFront);
86                                tStack.push(interior->mBack);
87                        }
88                }
89        }
90
91        ///return dummyPvs.Size();
92        return pvs;
93}
94
95
96/** Returns the the number of new (unmailed) objects in the leaves of the node.
97        We eliminate already accounted bvh nodes and objects using mailboxing.
98*/
99static float EvalBvhNodeContribution(BvhNode *bvhObj)
100{
101        BvhNode *node;
102
103        // hack for choosing which node to account for
104        if (bvhObj->IsLeaf())
105                node = static_cast<BvhLeaf *>(bvhObj)->GetActiveNode();
106        else
107                node = bvhObj;
108
109        // early exit
110        if (node->IsLeaf())     
111        {       
112                BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
113                // objects already accounted for
114                if (leaf->Mailed())
115                        return 0;
116
117                leaf->Mail();
118                return (float)leaf->mObjects.size();
119        }                       
120
121        // compute leaf pvs
122        float pvs = 0;
123        stack<BvhNode *> tStack;
124        tStack.push(node);
125
126        while (!tStack.empty())
127        {
128                node = tStack.top();
129                tStack.pop();
130
131                // already processed node (=> objects already in pvs)?
132                if (!node->Mailed())
133                {
134                        node->Mail();
135
136                        if (node->IsLeaf())
137                        {
138                                BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
139
140                                // add #objects exclusivly in this node
141                                pvs += (float)leaf->mObjects.size();
142                        }
143                        else // traverse tree
144                        {
145                                BvhInterior *interior = static_cast<BvhInterior *>(node);
146
147                                tStack.push(interior->GetFront());
148                                tStack.push(interior->GetBack());
149                        }
150                }
151        }
152
153        return pvs;
154}
155
156
157
158float ObjectPvs::EvalPvsCost() const
159{
160        float pvs = 0;
161
162        Intersectable::NewMail2();
163        //KdNode::NewMail();
164        dummyPvs.Clear();
165
166        ObjectPvsIterator pit = GetIterator();
167
168        while (pit.HasMoreEntries())
169        {               
170                Intersectable *obj = pit.Next();
171
172                switch (obj->Type())
173                {
174                        case Intersectable::KD_INTERSECTABLE:
175                                {
176                                        // found kd node
177                                        KdIntersectable *kdObj = static_cast<KdIntersectable *>(obj);
178                                        pvs += EvalKdNodeContribution(kdObj);   
179                                        break;
180                                }
181                        case Intersectable::BVH_INTERSECTABLE:
182                                {
183                                        BvhNode *bvhObj = static_cast<BvhNode *>(obj);
184                                        pvs += EvalBvhNodeContribution(bvhObj);
185                                        break;
186                                }
187                        default:
188                                // hack: should use assigned cost here
189                                ++ pvs;
190                               
191                                break;
192                }
193        }
194
195        return pvs;
196}
197
198}
Note: See TracBrowser for help on using the repository browser.