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

Revision 1706, 11.2 KB checked in by mattausch, 18 years ago (diff)

worked on full evaluation framework

Line 
1#ifndef __PVS_H
2#define __PVS_H
3
4#include <map>
5#include <vector>
6#include "common.h"
7
8namespace GtpVisibilityPreprocessor {
9
10class KdNode;
11class BspNode;
12class Ray;
13class Intersectable;
14class ViewCell;
15
16
17template<typename T>
18struct LtSample
19{
20    bool operator()(const T a, const T b) const
21    {
22                return a < b;
23        }
24};
25
26/** Information stored with a PVS entry. Consists of the number
27        the object was seen from the view cell.
28*/
29class PvsData {
30public:
31        /// sum of probability density of visible sample rays
32        float mSumPdf;
33
34        PvsData() {}
35        PvsData(const float sumPdf):
36        mSumPdf(sumPdf) {}
37
38        // $$JB in order to return meaningfull values
39        // it assumes that the sum pdf has been normalized somehow!!!
40        float GetVisibility()
41        {
42                return mSumPdf;
43        }
44};
45
46
47class MailablePvsData
48{
49        ////////////////////////////
50        //  Mailing stuff
51protected:
52        int mMailbox;
53
54public:
55        // last mail id -> warning not thread safe!
56        // both mailId and mailbox should be unique for each thread!!!
57        static int sMailId;
58        static int sReservedMailboxes;
59
60
61        static void NewMail(const int reserve = 1) {
62                sMailId += sReservedMailboxes;
63                sReservedMailboxes = reserve;
64        }
65
66        void Mail() { mMailbox = sMailId; }
67        bool Mailed() const { return mMailbox == sMailId; }
68
69        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
70        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
71
72        int IncMail() { return ++ mMailbox - sMailId; }
73        //////////////////////////////////////////
74
75        // sum of probability density of visible sample rays
76        float mSumPdf;
77        int mCounter;
78
79        MailablePvsData() {}
80        MailablePvsData(const float sumPdf):
81        mSumPdf(sumPdf) {}
82
83        // $$JB in order to return meaningfull values
84        // it assumes that the sum pdf has been normalized somehow!!!
85        float GetVisibility()
86        {
87                return mSumPdf;
88        }
89};
90
91
92/** Template class representing the Potentially Visible Set (PVS)
93        mainly from a view cell, but also e.g., from objects.
94*/
95template<typename T, typename S>
96class Pvs
97{
98public:
99        Pvs(): /*mSamples(0), */mEntries() {}
100
101        //virtual ~Pvs();
102
103        /** Compresses PVS lossless or lossy.
104        */
105        int Compress() {return 0;}
106        int GetSize() const {return (int)mEntries.size();}
107        bool Empty() const {return mEntries.empty();}
108
109        /** Normalize the visibility of entries in order to get comparable
110                results
111        */
112        void NormalizeMaximum();
113
114        /** Merges pvs of a into this pvs.
115        */
116        void Merge(const Pvs<T, S> &a);
117
118        /** Difference of pvs to pvs b.
119                @returns number of different entries.
120        */
121        int Diff(const Pvs<T, S> &b);
122
123        /** Finds sample in PVS.
124                @returns sample if found, NULL otherwise.
125        */
126        S *Find(T sample);
127
128        bool GetSampleContribution(T sample, const float pdf, float &contribution);
129
130        /** Adds sample to PVS.
131                @contribution contribution of sample (0 or 1)
132                @returns true if sample was not already in PVS.
133        */
134        bool AddSample(T sample, const float pdf, float &contribution);
135
136        /** Adds sample to PVS.
137                @returns contribution of sample (0 or 1)
138        */
139        float AddSample(T sample, const float pdf);
140
141        /** Adds sample to PVS.
142                @returns PvsData
143        */
144        S *AddSample2(T sample, const float pdf);
145
146        /** Adds one pvs to another one.
147                @returns new pvs size
148        */
149        int AddPvs(const Pvs<T, S> &pvs);
150
151        /** Subtracts one pvs from another one.
152                WARNING: could contains bugs
153                @returns new pvs size
154        */
155        int SubtractPvs(const Pvs<T, S> &pvs);
156        /** Returns PVS data, i.e., how often it was seen from the view cell,
157                and the object itsef.
158        */
159        void GetData(const int index, T &entry, S &data);
160
161        /** Collects the PVS entries and returns them in the vector.
162        */
163        void CollectEntries(std::vector<T> &entries);
164
165        /** Removes sample from PVS if reference count is zero.
166                @param visibleSamples number of references to be removed
167        */
168        bool RemoveSample(T sample, const float pdf);
169
170        /** Compute continuous PVS difference
171        */
172        void ComputeContinuousPvsDifference(Pvs<T, S> &pvs,
173                float &pvsReduction,
174                float &pvsEnlargement);
175
176
177        /** Clears the pvs.
178        */
179        void Clear();
180
181        static int GetEntrySizeByte();
182        static float GetEntrySize();
183
184        /** Compute continuous PVS difference */
185        float GetPvsHomogenity(Pvs<T, S> &pvs) {
186                float
187                        pvsReduction,
188                        pvsEnlargement;
189
190                ComputeContinuousPvsDifference(pvs,
191                        pvsReduction,
192                        pvsEnlargement);
193
194                return pvsReduction + pvsEnlargement;
195        }
196
197        int Size() { return mEntries.size(); }
198
199        /// Map of PVS entries
200        std::map<T, S, LtSample<T> > mEntries;
201};
202
203
204
205/**
206   Compute continuous PVS difference of 'b' with respect to the base PVS (*this).
207   Provides separatelly PVS reduction from PVS enlargement.
208
209*/
210template <typename T, typename S>
211void
212Pvs<T, S>::ComputeContinuousPvsDifference(Pvs<T, S> &b,
213                                                                           float &pvsReduction,
214                                                                           float &pvsEnlargement)
215{
216        pvsReduction = 0.0f;
217        pvsEnlargement = 0.0f;
218  // Uses sum of log differences, which corresponds to entropy
219  std::map<T, S, LtSample<T> >::iterator it;
220 
221  for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
222  {
223        float bSumPdf = (*it).second.mSumPdf;
224        float aSumPdf = 0.0f;
225        S *data = Find((*it).first);           
226       
227        if (data)
228        {
229                aSumPdf = data->mSumPdf;
230                // mark this entry as processed to avoid double counting
231                data->mSumPdf = -aSumPdf;
232        }
233
234#if 0
235        float diff = bSumPdf - aSumPdf;
236       
237        if (diff > 0.0f) {
238          pvsEnlargement += diff;
239        } else {
240          pvsReduction += -diff;
241        }
242#else
243        if (!data)
244          pvsEnlargement += 1.0f;
245#endif
246  }
247 
248  for (it = mEntries.begin(); it != mEntries.end(); ++ it) {
249        float aSumPdf = (*it).second.mSumPdf;
250        float bSumPdf = 0.0f;
251        if (aSumPdf < 0.0f) {
252          // this entry was already accounted for!
253          // just revert it back
254          (*it).second.mSumPdf = -aSumPdf;
255        } else {
256          S *data = b.Find((*it).first);
257          if (data) {
258                bSumPdf = data->mSumPdf;
259          }
260#if 0
261          float diff = bSumPdf - aSumPdf;
262         
263          if (diff > 0.0f) {
264                pvsEnlargement += diff;
265          } else {
266                pvsReduction += -diff;
267          }
268
269#else
270          if (!data)
271                pvsReduction += 1.0f;
272#endif
273        }
274  }
275}
276
277template <typename T, typename S>
278int Pvs<T, S>::Diff(const Pvs<T, S> &b)
279{
280        int dif = 0;
281
282        std::map<T, S, LtSample<T> >::const_iterator it;
283
284        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
285        {
286                S data = Find((*it).first);             
287                if (!data) ++ dif;
288        }
289
290        return dif;
291}
292
293template <typename T, typename S> void Pvs<T, S>::Merge(const Pvs<T, S> &a)
294{
295        std::map<T, S, LtSample<T> >::const_iterator it;
296
297        for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
298        {
299                AddSample((*it).first, (*it).second.mSumPdf);
300        }
301}
302
303
304template <typename T, typename S> void Pvs<T, S>::Clear()
305{
306        mEntries.clear();
307}
308
309
310template <typename T, typename S>
311S *Pvs<T, S>::Find(T sample)
312{
313  std::map<T, S, LtSample<T> >::iterator i = mEntries.find(sample);
314
315  if (i != mEntries.end())
316  {
317          return &(*i).second;
318  }
319  else
320  {
321          return NULL;
322  }
323}
324
325template <typename T, typename S>
326void Pvs<T, S>::GetData(const int index,
327                                         T &entry,
328                                         S &data)
329{
330  std::map<T, S, LtSample<T> >::iterator i = mEntries.begin();
331  for (int k = 0; k != index && i != mEntries.end(); i++, k++);
332
333  entry = (*i).first;
334  data = (*i).second;
335 
336}
337
338template <typename T, typename S>
339float
340Pvs<T, S>::AddSample(T sample, const float pdf)
341{
342        S *data = Find(sample);
343 
344        if (data) 
345        {
346                data->mSumPdf += pdf;
347                return data->mSumPdf;
348        }
349        else
350        {
351                mEntries[sample] = S(pdf);
352                return pdf;
353        }
354}
355
356
357template <typename T, typename S>
358S * Pvs<T, S>::AddSample2(T sample, const float pdf)
359{
360        S *data = Find(sample);
361 
362        if (data) 
363        {
364                data->mSumPdf += pdf;
365        }
366        else
367        {
368                mEntries[sample] = S(pdf);
369                data = Find(sample);
370        }
371
372        return data;
373}
374
375template <typename T, typename S>
376bool Pvs<T, S>::AddSample(T sample,
377                                  const float pdf,
378                                  float &contribution)
379{
380  S *data = Find(sample);
381 
382  if (data) 
383  {
384        data->mSumPdf += pdf;
385        contribution = pdf / data->mSumPdf;
386        return false;
387  }
388  else {
389        mEntries[sample] = S(pdf);
390        contribution = 1.0f;
391        return true;
392  }
393}
394
395template <typename T, typename S>
396bool
397Pvs<T, S>::GetSampleContribution(T sample,
398                                                                 const float pdf,
399                                                                 float &contribution)
400{
401  S *data = Find(sample);
402 
403  if (data)  {
404        contribution = pdf / (data->mSumPdf + pdf);
405        return false;
406  }
407  else {
408        contribution = 1.0f;
409        return true;
410  }
411}
412
413template <typename T, typename S>
414bool Pvs<T, S>::RemoveSample(T sample,
415                                                  const float pdf)
416{
417  std::map<T, S, LtSample<T> >::
418        iterator it = mEntries.find(sample);
419 
420  if (it == mEntries.end())
421        return false;
422 
423  S *data = &(*it).second;
424 
425  data->mSumPdf -= pdf;
426
427  if (data->mSumPdf <= 0.0f)
428  {
429          mEntries.erase(it);
430  }
431
432  return true;
433}
434
435template <typename T, typename S>
436int Pvs<T, S>::AddPvs(const Pvs<T, S> &pvs)
437{
438  std::map<T, S, LtSample<T> >::
439        const_iterator it, it_end = pvs.mEntries.end();
440 
441  float contri;
442  // output PVS of view cell
443  for (it = pvs.mEntries.begin(); it != it_end; ++ it)
444  {     
445          AddSample((*it).first, (*it).second.mSumPdf, contri);
446  }
447 
448  return GetSize();
449}
450 
451template <typename T, typename S>
452int Pvs<T, S>::SubtractPvs(const Pvs<T, S> &pvs)
453{
454  std::map<T, S, LtSample<T> >::
455        const_iterator it, it_end = pvs.mEntries.end();
456 
457  // output PVS of view cell
458  for (it = pvs.mEntries.begin(); it != it_end; ++ it)
459        RemoveSample((*it).first, (*it).second.mSumPdf);
460 
461  return GetSize();
462}
463
464template <typename T, typename S>
465void Pvs<T, S>::CollectEntries(std::vector<T> &entries)
466{
467        std::map<T, S, LtSample<T> >::
468                const_iterator it, it_end = mEntries.end();
469
470        // output PVS of view cell
471        for (it = mEntries.begin(); it != it_end; ++ it)
472                entries.push_back((*it)->first);
473}
474
475template <typename T, typename S>
476void Pvs<T, S>::NormalizeMaximum()
477{
478  std::map<T, S, LtSample<T> >::
479        const_iterator it, it_end = mEntries.end();
480
481  float maxPdfSum = -1.0f;
482
483  // output PVS of view cell
484  for (it = mEntries.begin(); it != it_end; ++ it) {
485        float sum = (*it)->second.sumPdf;
486        if (sum > maxSum)
487          maxSum = sum;
488  }
489
490  maxSum = 1.0f / maxSum;
491
492  for (it = mEntries.begin(); it != it_end; ++ it) {
493        (*it)->second.sumPdf *= maxSum;
494  }
495 
496}
497
498
499template <typename T, typename S>
500float Pvs<T, S>::GetEntrySize()
501{
502        return (float)(sizeof(T) + sizeof(S)) / float(1024 * 1024);
503}
504
505
506template <typename T, typename S>
507int Pvs<T, S>::GetEntrySizeByte()
508{
509        return sizeof(T) + sizeof(S);
510}
511
512
513///////////////////////////////////////
514
515/** Class instantiating the Pvs template for kd tree nodes.
516*/
517class KdPvs: public Pvs<KdNode *, PvsData>
518{
519public:
520        int Compress();
521};
522
523
524class ObjectPvs: public Pvs<Intersectable *, PvsData>
525{
526public:
527        /** Counts object int the pvs. Different to method "GetSize", not
528                only the raw container size is returned,
529                but the individual contributions of the entries are summed up.
530        */
531        int CountObjectsInPvs() const;
532};
533
534
535////////////
536//-- typedefs
537
538typedef std::map<KdNode *, PvsData, LtSample<KdNode *> > KdPvsMap;
539typedef std::map<Intersectable *, PvsData, LtSample<Intersectable *> > ObjectPvsMap;
540typedef std::map<ViewCell *, MailablePvsData, LtSample<ViewCell *> > ViewCellPvsMap;
541
542
543typedef Pvs<ViewCell *, MailablePvsData> ViewCellPvs;
544
545}
546
547#endif
548
Note: See TracBrowser for help on using the repository browser.