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

Revision 2176, 3.6 KB checked in by mattausch, 17 years ago (diff)

removed using namespace std from .h

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