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

Revision 2606, 3.6 KB checked in by bittner, 16 years ago (diff)

merge on nemo

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