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

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

worded on obj loading in Ogre

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