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

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
16namespace GtpVisibilityPreprocessor {
17
[2643]18static ObjectPvs dummyPvs;
[2123]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)?
[2643]36                if (1)//!node->Mailed())
[2123]37                {
[2643]38                        //node->Mail();
[2123]39                        if (node->IsLeaf())
40                        {
41                                KdLeaf *leaf = static_cast<KdLeaf *>(node);
[2635]42#if USE_MULTIPLE_OBJECTS                               
[2123]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                                {
[2643]52                                        Intersectable *obj = *oit;                                             
[2123]53                           
[2643]54                                        if (1)//!obj->Mailed())
[2123]55                                        {
[2643]56                                                //obj->Mail();
57                                                if (dummyPvs.AddSample(obj))
58                                                        ++ pvs;
[2123]59                                        }
60                                }
[2635]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                                  {
[2643]69                                        Intersectable *obj = *oit;                                             
[2635]70                                       
[2643]71                                        if (!obj->Mailed2())
[2635]72                                          {
[2643]73                                                  //if (dummyPvs.AddSample(obj, 1.0f))++ pvs;
74                                                  obj->Mail2();
75                                                  ++pvs;
[2635]76                                          }
77                                  }
78                               
79#endif
[2123]80                        }
81                        else // traverse tree
[2643]82                        {
[2123]83                                KdInterior *interior = static_cast<KdInterior *>(node);
84
85                                tStack.push(interior->mFront);
86                                tStack.push(interior->mBack);
87                        }
88                }
89        }
90
[2643]91        ///return dummyPvs.Size();
[2123]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();
[2332]118                return (float)leaf->mObjects.size();
[2123]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
[2332]141                                pvs += (float)leaf->mObjects.size();
[2123]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
[2643]157
[2123]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.