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

Revision 2670, 4.3 KB checked in by mattausch, 17 years ago (diff)
RevLine 
[2123]1#include <iostream>
2#include <stack>
[2575]3
4#include "Mesh.h"
[2123]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
[2635]12// $$ switched off by JB for testing
13#define USE_MULTIPLE_OBJECTS  0
[2176]14using namespace std;
[2123]15
[2670]16
[2123]17namespace GtpVisibilityPreprocessor {
18
[2643]19static ObjectPvs dummyPvs;
[2123]20
21/** the pvs is the number of different objects in the node leaves
22        We eliminate already accounted kd nodes and objects using mailboxing.
23*/
24static int EvalKdNodeContribution(KdIntersectable *kdobj)
25{
26        int pvs = 0;
27        stack<KdNode *> tStack;
28
29        tStack.push(kdobj->GetItem());
30
31        while (!tStack.empty())
32        {
33                KdNode *node = tStack.top();
34                tStack.pop();
35
36                // already processed node (=> objects already in pvs)?
[2643]37                if (1)//!node->Mailed())
[2123]38                {
[2643]39                        //node->Mail();
[2123]40                        if (node->IsLeaf())
41                        {
42                                KdLeaf *leaf = static_cast<KdLeaf *>(node);
[2635]43#if USE_MULTIPLE_OBJECTS                               
[2123]44                                // add #objects exclusivly in this node
45                                pvs += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
46
47                                // Objects already accounted for can only be found among those
48                                // which are referenced in more than one leaf
49                                ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
50                                               
51                                for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
52                                {
[2643]53                                        Intersectable *obj = *oit;                                             
[2123]54                           
[2643]55                                        if (1)//!obj->Mailed())
[2123]56                                        {
[2643]57                                                //obj->Mail();
58                                                if (dummyPvs.AddSample(obj))
59                                                        ++ pvs;
[2123]60                                        }
61                                }
[2635]62#else
63
64                                // Objects already accounted for can only be found among those
65                                // which are referenced in more than one leaf
66                                ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
67                               
68                                for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
69                                  {
[2643]70                                        Intersectable *obj = *oit;                                             
[2635]71                                       
[2643]72                                        if (!obj->Mailed2())
[2635]73                                          {
[2643]74                                                  //if (dummyPvs.AddSample(obj, 1.0f))++ pvs;
75                                                  obj->Mail2();
76                                                  ++pvs;
[2635]77                                          }
78                                  }
79                               
80#endif
[2123]81                        }
82                        else // traverse tree
[2643]83                        {
[2123]84                                KdInterior *interior = static_cast<KdInterior *>(node);
85
86                                tStack.push(interior->mFront);
87                                tStack.push(interior->mBack);
88                        }
89                }
90        }
91
[2643]92        ///return dummyPvs.Size();
[2123]93        return pvs;
94}
95
96
97/** Returns the the number of new (unmailed) objects in the leaves of the node.
98        We eliminate already accounted bvh nodes and objects using mailboxing.
99*/
100static float EvalBvhNodeContribution(BvhNode *bvhObj)
101{
102        BvhNode *node;
103
104        // hack for choosing which node to account for
105        if (bvhObj->IsLeaf())
106                node = static_cast<BvhLeaf *>(bvhObj)->GetActiveNode();
107        else
108                node = bvhObj;
109
110        // early exit
111        if (node->IsLeaf())     
112        {       
113                BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
114                // objects already accounted for
115                if (leaf->Mailed())
116                        return 0;
117
118                leaf->Mail();
[2332]119                return (float)leaf->mObjects.size();
[2123]120        }                       
121
122        // compute leaf pvs
123        float pvs = 0;
124        stack<BvhNode *> tStack;
125        tStack.push(node);
126
127        while (!tStack.empty())
128        {
129                node = tStack.top();
130                tStack.pop();
131
132                // already processed node (=> objects already in pvs)?
133                if (!node->Mailed())
134                {
135                        node->Mail();
136
137                        if (node->IsLeaf())
138                        {
139                                BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
140
141                                // add #objects exclusivly in this node
[2332]142                                pvs += (float)leaf->mObjects.size();
[2123]143                        }
144                        else // traverse tree
145                        {
146                                BvhInterior *interior = static_cast<BvhInterior *>(node);
147
148                                tStack.push(interior->GetFront());
149                                tStack.push(interior->GetBack());
150                        }
151                }
152        }
153
154        return pvs;
155}
156
157
158float ObjectPvs::EvalPvsCost() const
159{
160        float pvs = 0;
161
[2643]162        Intersectable::NewMail2();
163        //KdNode::NewMail();
164        dummyPvs.Clear();
[2123]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.