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

Revision 677, 7.4 KB checked in by bittner, 18 years ago (diff)

changes for visualization of distant view space sampling

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