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

Revision 2727, 3.5 KB checked in by mattausch, 16 years ago (diff)
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
16
17namespace GtpVisibilityPreprocessor {
18
19static ObjectPvs dummyPvs;
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)?
37                //node->Mail();
38                if (node->IsLeaf())
39                {
40                        KdLeaf *leaf = static_cast<KdLeaf *>(node);
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->mObjects.end();
45
46                        for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
47                        {
48                                Intersectable *obj = *oit;                                             
49
50                                if (!obj->Mailed2())
51                                {
52                                        //if (dummyPvs.AddSample(obj, 1.0f))++ pvs;
53                                        obj->Mail2();
54                                        ++ pvs;
55                                }
56                        }
57                }
58                else // traverse tree
59                {
60                        KdInterior *interior = static_cast<KdInterior *>(node);
61
62                        tStack.push(interior->mFront);
63                        tStack.push(interior->mBack);
64                }
65        }
66
67        ///return dummyPvs.Size();
68        return pvs;
69}
70
71
72/** Returns the the number of new (unmailed) objects in the leaves of the node.
73        We eliminate already accounted bvh nodes and objects using mailboxing.
74*/
75static float EvalBvhNodeContribution(BvhNode *bvhObj)
76{
77        BvhNode *node;
78
79        // hack for choosing which node to account for
80        if (bvhObj->IsLeaf())
81                node = static_cast<BvhLeaf *>(bvhObj)->GetActiveNode();
82        else
83                node = bvhObj;
84
85        // early exit
86        if (node->IsLeaf())     
87        {       
88                BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
89                // objects already accounted for
90                if (leaf->Mailed())
91                        return 0;
92
93                leaf->Mail();
94                return (float)leaf->mObjects.size();
95        }                       
96
97        // compute leaf pvs
98        float pvs = 0;
99        stack<BvhNode *> tStack;
100        tStack.push(node);
101
102        while (!tStack.empty())
103        {
104                node = tStack.top();
105                tStack.pop();
106
107                // already processed node (=> objects already in pvs)?
108                if (!node->Mailed())
109                {
110                        node->Mail();
111
112                        if (node->IsLeaf())
113                        {
114                                BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
115
116                                // add #objects exclusivly in this node
117                                pvs += (float)leaf->mObjects.size();
118                        }
119                        else // traverse tree
120                        {
121                                BvhInterior *interior = static_cast<BvhInterior *>(node);
122
123                                tStack.push(interior->GetFront());
124                                tStack.push(interior->GetBack());
125                        }
126                }
127        }
128
129        return pvs;
130}
131
132
133float ObjectPvs::EvalPvsCost() const
134{
135        float pvs = 0;
136
137        Intersectable::NewMail2();
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
172}
Note: See TracBrowser for help on using the repository browser.