source: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h @ 573

Revision 573, 7.2 KB checked in by mattausch, 18 years ago (diff)

implemented functtion for view cell construction

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 and pvs of b into this pvs.
62   */
63  void Merge(const Pvs<T> &a, const Pvs<T> &b);
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
114template <typename T>
115int Pvs<T>::Diff(const Pvs<T> &b)
116{
117        int dif = 0;
118
119        std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
120
121        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
122        {
123                PvsData<T> *data = Find((*it).first);           
124                if (!data) ++ dif;
125        }
126
127        return dif;
128}
129
130template <typename T>
131void Pvs<T>::Merge(const Pvs<T> &a, const Pvs<T> &b)
132{
133        std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
134
135        mEntries = a.mEntries;
136        // todo: copy all elements instead of inserting
137        //for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
138        //      mEntries.insert(*it);
139       
140        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
141        {
142                PvsData<T> *data = Find((*it).first);
143               
144                if (data)
145                        data->mSumPdf += (*it).second.mSumPdf;
146                else
147                        mEntries.insert(*it);
148        }
149}
150
151template <typename T>
152PvsData<T> *Pvs<T>::Find(T sample)
153{
154  std::map<T, PvsData<T>, LtSample<T> >::iterator i = mEntries.find(sample);
155  if (i != mEntries.end()) {
156    return &(*i).second;
157  } else
158    return NULL;
159}
160
161template <typename T>
162void Pvs<T>::GetData(const int index,
163                                         T &entry,
164                                         PvsData<T> &data)
165{
166  std::map<T, PvsData<T>, LtSample<T> >::iterator i = mEntries.begin();
167  for (int k = 0; k != index && i != mEntries.end(); i++, k++);
168
169  entry = (*i).first;
170  data = (*i).second;
171}
172
173template <typename T>
174float
175Pvs<T>::AddSample(T sample, const float pdf)
176{
177  PvsData<T> *data = Find(sample);
178 
179  if (data)  {
180        data->mSumPdf+=pdf;
181        return data->mSumPdf;
182  }
183  else {
184        mEntries[sample] = PvsData<T>(pdf);
185        return pdf;
186  }
187}
188
189template <typename T>
190bool
191Pvs<T>::AddSample(T sample,
192                                  const float pdf,
193                                  float &contribution)
194{
195  PvsData<T> *data = Find(sample);
196 
197  if (data)  {
198        data->mSumPdf+=pdf;
199        contribution = pdf/data->mSumPdf;
200        return false;
201  }
202  else {
203        mEntries[sample] = PvsData<T>(pdf);
204        contribution = 1.0f;
205        return true;
206  }
207}
208
209template <typename T>
210bool
211Pvs<T>::GetSampleContribution(T sample,
212                                                          const float pdf,
213                                                          float &contribution)
214{
215  PvsData<T> *data = Find(sample);
216 
217  if (data)  {
218        contribution = pdf/(data->mSumPdf + pdf);
219        return false;
220  }
221  else {
222        contribution = 1.0f;
223        return true;
224  }
225}
226
227template <typename T>
228bool Pvs<T>::RemoveSample(T sample,
229                                                  const float pdf)
230{
231  std::map<T, PvsData<T>, LtSample<T> >::
232        iterator it = mEntries.find(sample);
233 
234  if (it == mEntries.end())
235        return false;
236 
237  PvsData<T> *data = &(*it).second;
238 
239  data->mSumPdf -= pdf;
240  if (data->mSumPdf <= 0.0f)
241        mEntries.erase(it);
242 
243  return true;
244}
245
246template <typename T>
247int Pvs<T>::AddPvs(const Pvs<T> &pvs)
248{
249  std::map<T, PvsData<T>, LtSample<T> >::
250        const_iterator it, it_end = pvs.mEntries.end();
251 
252  float contri;
253  // output PVS of view cell
254  for (it = pvs.mEntries.begin(); it != it_end; ++ it)
255        AddSample((*it).first, (*it).second.mSumPdf, contri);
256 
257  return GetSize();
258}
259 
260template <typename T>
261int Pvs<T>::SubtractPvs(const Pvs<T> &pvs)
262{
263  std::map<T, PvsData<T>, LtSample<T> >::
264        const_iterator it, it_end = pvs.mEntries.end();
265 
266  // output PVS of view cell
267  for (it = pvs.mEntries.begin(); it != it_end; ++ it)
268        RemoveSample((*it).first, (*it).second.mSumPdf);
269 
270  return GetSize();
271}
272
273template <typename T>
274void Pvs<T>::CollectEntries(std::vector<T> &entries)
275{
276        std::map<T, PvsData<T>, LtSample<T> >::
277                const_iterator it, it_end = mEntries.end();
278
279        // output PVS of view cell
280        for (it = mEntries.begin(); it != it_end; ++ it)
281                entries.push_back((*it)->first);
282}
283
284template <typename T>
285void Pvs<T>::NormalizeMaximum()
286{
287  std::map<T, PvsData<T>, LtSample<T> >::
288        const_iterator it, it_end = mEntries.end();
289
290  float maxPdfSum = -1.0f;
291
292  // output PVS of view cell
293  for (it = mEntries.begin(); it != it_end; ++ it) {
294        float sum = (*it)->second.sumPdf;
295        if (sum > maxSum)
296          maxSum = sum;
297  }
298
299  maxSum = 1.0f/maxSum;
300
301  for (it = mEntries.begin(); it != it_end; ++ it) {
302        (*it)->second.sumPdf *= maxSum;
303  }
304 
305}
306
307
308/** Class instantiating the Pvs template for kd tree nodes.
309*/
310class KdPvs: public Pvs<KdNode *>
311{
312        int Compress();
313};
314
315typedef std::map<KdNode *, PvsData<KdNode *>, LtSample<KdNode *> > KdPvsMap;
316typedef std::map<Intersectable *, PvsData<Intersectable *>, LtSample<Intersectable *> > ObjectPvsMap;
317typedef PvsData<Intersectable *> ObjectPvsData;
318typedef PvsData<KdNode *> KdPvsData;
319
320typedef Pvs<Intersectable *> ObjectPvs;
321
322
323#endif
324
Note: See TracBrowser for help on using the repository browser.