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

Revision 2635, 4.1 KB checked in by bittner, 16 years ago (diff)

GetPvsCost? changed, APplyFilter2 collects small kdnodes

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