source: GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h @ 610

Revision 610, 7.0 KB checked in by mattausch, 19 years ago (diff)
Line 
1#ifndef __PVS_H
2#define __PVS_H
3
4#include <map>
5#include <vector>
6
7class KdNode;
8class BspNode;
9class Ray;
10class Intersectable;
11class ViewCellKdNode;
12
13template<typename T>
14struct LtSample {
15    bool operator()(const T a, const T b) const
16    {
17                return a < b;
18        }
19};
20
21/** Information stored with a PVS entry. Consists of the number
22        the object was seen from the view cell.
23*/
24
25template<typename T>
26struct PvsData {
27  //  int mVisibleSamples;
28  // sum of probability density of visible sample rays
29  float mSumPdf;
30  PvsData<T>() {}
31  PvsData<T>(const float sumPdf):
32        mSumPdf(sumPdf) {}
33
34  // $$JB in order to return meaningfull values
35  // it assumes that the sum pdf has been normalized somehow!!!
36  float GetVisibility() { return mSumPdf; }
37};
38
39/** Template class representing the Potentially Visible Set (PVS)
40        mainly from a view cell, but also e.g., from objects.
41*/
42template<typename T>
43class Pvs
44{
45public:
46  Pvs(): /*mSamples(0), */mEntries() {}
47 
48  //int mSamples;
49 
50  /** Compresses PVS lossless or lossy.
51  */
52  int Compress() {return 0;}
53  int GetSize() const {return (int)mEntries.size();}
54  bool Empty() const {return mEntries.empty();}
55
56  /** Normalize the visibility of entries in order to get comparable
57          results */
58 
59  void NormalizeMaximum();
60 
61  /** Merges pvs of a into this pvs.
62   */
63  void Merge(const Pvs<T> &a);
64 
65  /** Difference of pvs to pvs b.
66          @returns number of different entries.
67  */
68  int Diff(const Pvs<T> &b);
69 
70  /** Finds sample in PVS.
71          @returns sample if found, NULL otherwise.
72  */
73  PvsData<T> *Find(T sample);
74
75  bool GetSampleContribution(T sample, const float pdf, float &contribution);
76 
77  /** Adds sample to PVS.
78          @contribution contribution of sample (0 or 1)
79          @returns true if sample was not already in PVS.
80  */
81  bool AddSample(T sample, const float pdf, float &contribution);
82
83  /** Adds sample to PVS.
84          @returns contribution of sample (0 or 1)
85  */
86  float AddSample(T sample, const float pdf);
87 
88  /** Adds one pvs to another one.
89          @returns new pvs size
90  */
91  int AddPvs(const Pvs<T> &pvs);
92  /** Subtracts one pvs from another one.
93          @returns new pvs size
94  */
95  int SubtractPvs(const Pvs<T> &pvs);
96  /** Returns PVS data, i.e., how often it was seen from the view cell,
97          and the object itsef.
98  */
99  void GetData(const int index, T &entry, PvsData<T> &data);
100
101  /** Collects the PVS entries and returns them in the vector.
102  */
103  void CollectEntries(std::vector<T> &entries);
104
105  /** Removes sample from PVS if reference count is zero.
106          @param visibleSampels number of references to be removed
107  */
108  bool RemoveSample(T sample, const float pdf);
109
110  /// Map of PVS entries
111  std::map<T, PvsData<T>, LtSample<T> > mEntries;
112};
113
114
115template <typename T>
116int Pvs<T>::Diff(const Pvs<T> &b)
117{
118        int dif = 0;
119
120        std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
121
122        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
123        {
124                PvsData<T> *data = Find((*it).first);           
125                if (!data) ++ dif;
126        }
127
128        return dif;
129}
130
131template <typename T>
132void Pvs<T>::Merge(const Pvs<T> &a)
133{
134        std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
135
136        for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
137        {
138                PvsData<T> *data = Find((*it).first);
139               
140                if (data)
141                        data->mSumPdf += (*it).second.mSumPdf;
142                else
143                        mEntries.insert(*it);
144        }
145}
146
147template <typename T>
148PvsData<T> *Pvs<T>::Find(T sample)
149{
150  std::map<T, PvsData<T>, LtSample<T> >::iterator i = mEntries.find(sample);
151  if (i != mEntries.end()) {
152    return &(*i).second;
153  } else
154    return NULL;
155}
156
157template <typename T>
158void Pvs<T>::GetData(const int index,
159                                         T &entry,
160                                         PvsData<T> &data)
161{
162  std::map<T, PvsData<T>, LtSample<T> >::iterator i = mEntries.begin();
163  for (int k = 0; k != index && i != mEntries.end(); i++, k++);
164
165  entry = (*i).first;
166  data = (*i).second;
167}
168
169template <typename T>
170float
171Pvs<T>::AddSample(T sample, const float pdf)
172{
173  PvsData<T> *data = Find(sample);
174 
175  if (data)  {
176        data->mSumPdf+=pdf;
177        return data->mSumPdf;
178  }
179  else {
180        mEntries[sample] = PvsData<T>(pdf);
181        return pdf;
182  }
183}
184
185template <typename T>
186bool
187Pvs<T>::AddSample(T sample,
188                                  const float pdf,
189                                  float &contribution)
190{
191  PvsData<T> *data = Find(sample);
192 
193  if (data)  {
194        data->mSumPdf+=pdf;
195        contribution = pdf/data->mSumPdf;
196        return false;
197  }
198  else {
199        mEntries[sample] = PvsData<T>(pdf);
200        contribution = 1.0f;
201        return true;
202  }
203}
204
205template <typename T>
206bool
207Pvs<T>::GetSampleContribution(T sample,
208                                                          const float pdf,
209                                                          float &contribution)
210{
211  PvsData<T> *data = Find(sample);
212 
213  if (data)  {
214        contribution = pdf/(data->mSumPdf + pdf);
215        return false;
216  }
217  else {
218        contribution = 1.0f;
219        return true;
220  }
221}
222
223template <typename T>
224bool Pvs<T>::RemoveSample(T sample,
225                                                  const float pdf)
226{
227  std::map<T, PvsData<T>, LtSample<T> >::
228        iterator it = mEntries.find(sample);
229 
230  if (it == mEntries.end())
231        return false;
232 
233  PvsData<T> *data = &(*it).second;
234 
235  data->mSumPdf -= pdf;
236  if (data->mSumPdf <= 0.0f)
237        mEntries.erase(it);
238 
239  return true;
240}
241
242template <typename T>
243int Pvs<T>::AddPvs(const Pvs<T> &pvs)
244{
245  std::map<T, PvsData<T>, LtSample<T> >::
246        const_iterator it, it_end = pvs.mEntries.end();
247 
248  float contri;
249  // output PVS of view cell
250  for (it = pvs.mEntries.begin(); it != it_end; ++ it)
251        AddSample((*it).first, (*it).second.mSumPdf, contri);
252 
253  return GetSize();
254}
255 
256template <typename T>
257int Pvs<T>::SubtractPvs(const Pvs<T> &pvs)
258{
259  std::map<T, PvsData<T>, LtSample<T> >::
260        const_iterator it, it_end = pvs.mEntries.end();
261 
262  // output PVS of view cell
263  for (it = pvs.mEntries.begin(); it != it_end; ++ it)
264        RemoveSample((*it).first, (*it).second.mSumPdf);
265 
266  return GetSize();
267}
268
269template <typename T>
270void Pvs<T>::CollectEntries(std::vector<T> &entries)
271{
272        std::map<T, PvsData<T>, LtSample<T> >::
273                const_iterator it, it_end = mEntries.end();
274
275        // output PVS of view cell
276        for (it = mEntries.begin(); it != it_end; ++ it)
277                entries.push_back((*it)->first);
278}
279
280template <typename T>
281void Pvs<T>::NormalizeMaximum()
282{
283  std::map<T, PvsData<T>, LtSample<T> >::
284        const_iterator it, it_end = mEntries.end();
285
286  float maxPdfSum = -1.0f;
287
288  // output PVS of view cell
289  for (it = mEntries.begin(); it != it_end; ++ it) {
290        float sum = (*it)->second.sumPdf;
291        if (sum > maxSum)
292          maxSum = sum;
293  }
294
295  maxSum = 1.0f/maxSum;
296
297  for (it = mEntries.begin(); it != it_end; ++ it) {
298        (*it)->second.sumPdf *= maxSum;
299  }
300 
301}
302
303
304/** Class instantiating the Pvs template for kd tree nodes.
305*/
306class KdPvs: public Pvs<KdNode *>
307{
308        int Compress();
309};
310
311typedef std::map<KdNode *, PvsData<KdNode *>, LtSample<KdNode *> > KdPvsMap;
312typedef std::map<Intersectable *, PvsData<Intersectable *>, LtSample<Intersectable *> > ObjectPvsMap;
313typedef PvsData<Intersectable *> ObjectPvsData;
314typedef PvsData<KdNode *> KdPvsData;
315
316typedef Pvs<Intersectable *> ObjectPvs;
317
318
319#endif
320
Note: See TracBrowser for help on using the repository browser.