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

Revision 1738, 12.4 KB checked in by mattausch, 18 years ago (diff)
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/** Template class representing the Potentially Visible Set (PVS)
92        mainly from a view cell, but also e.g., from objects.
93*/
94template<typename T, typename S>
95class Pvs
96{
97public:
98//vector<pair<T, S> >::iterator mItEnd;
99        template<typename T, typename S>
100        class Iterator
101        {
102                //template<typename T, typename S> friend Pvs<T, S>;
103        private:
104                //std::vector<std::pair<T, S> >::iterator mIt;
105                //vector<pair<T, S> >::iterator mItEnd;
106        };
107
108        template<typename T, typename S>
109        class ConstIterator
110        {
111        //      template<typename T, typename S> friend Pvs<T, S>;
112        private:
113                //vector<pair<T, S> >::const_iterator mIt;
114                //vector<pair<T, S> >::const_iteator mItEnd;
115        };
116
117  Pvs(): mSamples(0), mEntries() {}
118 
119
120        //virtual ~Pvs();
121
122        /** Compresses PVS lossless or lossy.
123        */
124        int Compress() {return 0;}
125        int GetSize() const {return (int)mEntries.size();}
126        bool Empty() const {return mEntries.empty();}
127
128        /** Normalize the visibility of entries in order to get comparable
129                results
130        */
131        void NormalizeMaximum();
132
133        /** Merges pvs of a into this pvs.
134        */
135        void Merge(const Pvs<T, S> &a);
136
137        /** Difference of pvs to pvs b.
138                @returns number of different entries.
139        */
140        int Diff(const Pvs<T, S> &b);
141
142        /** Finds sample in PVS.
143                @returns sample if found, NULL otherwise.
144        */
145        S *Find(T sample);
146
147        bool GetSampleContribution(T sample, const float pdf, float &contribution);
148
149        /** Adds sample to PVS.
150                @contribution contribution of sample (0 or 1)
151                @returns true if sample was not already in PVS.
152        */
153        bool AddSample(T sample, const float pdf, float &contribution);
154
155        /** Adds sample to PVS.
156                @returns contribution of sample (0 or 1)
157        */
158        float AddSample(T sample, const float pdf);
159
160        /** Adds sample to PVS.
161                @returns PvsData
162        */
163        S *AddSample2(T sample, const float pdf);
164
165        /** Adds one pvs to another one.
166                @returns new pvs size
167        */
168        int AddPvs(const Pvs<T, S> &pvs);
169
170        /** Subtracts one pvs from another one.
171                WARNING: could contains bugs
172                @returns new pvs size
173        */
174        int SubtractPvs(const Pvs<T, S> &pvs);
175        /** Returns PVS data, i.e., how often it was seen from the view cell,
176                and the object itsef.
177        */
178        void GetData(const int index, T &entry, S &data);
179
180        /** Collects the PVS entries and returns them in the vector.
181        */
182        void CollectEntries(std::vector<T> &entries);
183
184        /** Removes sample from PVS if reference count is zero.
185                @param visibleSamples number of references to be removed
186        */
187        bool RemoveSample(T sample, const float pdf);
188
189        /** Compute continuous PVS difference
190        */
191        void ComputeContinuousPvsDifference(Pvs<T, S> &pvs,
192                float &pvsReduction,
193                float &pvsEnlargement);
194
195
196        /** Clears the pvs.
197        */
198        void Clear();
199
200        static int GetEntrySizeByte();
201        static float GetEntrySize();
202
203        /** Compute continuous PVS difference */
204        float GetPvsHomogenity(Pvs<T, S> &pvs) {
205                float pvsReduction, pvsEnlargement;
206
207                ComputeContinuousPvsDifference(pvs,
208                        pvsReduction,
209                        pvsEnlargement);
210
211                return pvsReduction + pvsEnlargement;
212        }
213
214        int Size() { return mEntries.size(); }
215
216        //vector<pair<T, S> >::const_iterator &GetConstIterator() const { return mEntries.begin(); }
217        //vector<pair<T, S> >::iterator &GetIterator() { return mEntries.begin(); }
218
219//protected:
220
221        /// vector of PVS entries
222        vector<pair<T, S> > mEntries;
223       
224        /// Number of samples used to create the PVS
225        int mSamples;
226};
227
228
229
230/**
231   Compute continuous PVS difference of 'b' with respect to the base PVS (*this).
232   Provides separatelly PVS reduction from PVS enlargement.
233
234*/
235template <typename T, typename S>
236void
237Pvs<T, S>::ComputeContinuousPvsDifference(Pvs<T, S> &b,
238                                                                           float &pvsReduction,
239                                                                           float &pvsEnlargement)
240{
241        pvsReduction = 0.0f;
242        pvsEnlargement = 0.0f;
243        // Uses sum of log differences, which corresponds to entropy
244        std::vector<pair<T, S> >::iterator it;
245
246        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
247        {
248                float bSumPdf = (*it).second.mSumPdf;
249                float aSumPdf = 0.0f;
250                S *data = Find((*it).first);           
251
252                if (data)
253                {
254                        aSumPdf = data->mSumPdf;
255                        // mark this entry as processed to avoid double counting
256                        data->mSumPdf = -aSumPdf;
257                }
258
259#if 0
260                float diff = bSumPdf - aSumPdf;
261
262                if (diff > 0.0f) {
263                        pvsEnlargement += diff;
264                } else {
265                        pvsReduction += -diff;
266                }
267#else
268                if (!data)
269                        pvsEnlargement += 1.0f;
270#endif
271        }
272
273        for (it = mEntries.begin(); it != mEntries.end(); ++ it) {
274                float aSumPdf = (*it).second.mSumPdf;
275                float bSumPdf = 0.0f;
276                if (aSumPdf < 0.0f) {
277                        // this entry was already accounted for!
278                        // just revert it back
279                        (*it).second.mSumPdf = -aSumPdf;
280                } else {
281                        S *data = b.Find((*it).first);
282                        if (data) {
283                                bSumPdf = data->mSumPdf;
284                        }
285#if 0
286                        float diff = bSumPdf - aSumPdf;
287
288                        if (diff > 0.0f) {
289                                pvsEnlargement += diff;
290                        } else {
291                                pvsReduction += -diff;
292                        }
293
294#else
295                        if (!data)
296                                pvsReduction += 1.0f;
297#endif
298                }
299        }
300}
301
302
303template <typename T, typename S>
304int Pvs<T, S>::Diff(const Pvs<T, S> &b)
305{
306        int dif = 0;
307
308        std::vector<pair<T, S> >::const_iterator it;
309
310        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
311        {
312                S data = Find((*it).first);             
313                if (!data) ++ dif;
314        }
315
316        return dif;
317}
318
319template <typename T, typename S> void Pvs<T, S>::Merge(const Pvs<T, S> &a)
320{
321#if TODO
322        const int samples = mSamples + a.mSamples;
323
324        std::vector<pair<T, S>> >::const_iterator it;
325
326        for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
327        {
328                AddSample((*it).first, (*it).second.mSumPdf);
329        }
330
331        mSamples = samples;
332#endif
333}
334
335
336template <typename T, typename S> void Pvs<T, S>::Clear()
337{
338        mEntries.clear();
339}
340
341
342template <typename T, typename S>
343S *Pvs<T, S>::Find(T sample)
344{
345#if TODO
346  std::vector<pair<T, S>, LtSample<T> >::iterator i = mEntries.find(sample);
347
348  if (i != mEntries.end())
349  {
350          return &(*i).second;
351  }
352  else
353  {
354          return NULL;
355  }
356#else
357return NULL;
358#endif
359}
360
361template <typename T, typename S>
362void Pvs<T, S>::GetData(const int index,
363                                         T &entry,
364                                         S &data)
365{
366        std::vector<pair<T, S> >::iterator i = mEntries.begin();
367        for (int k = 0; k != index && i != mEntries.end(); ++ i, ++ k);
368
369        entry = (*i).first;
370        data = (*i).second;
371}
372
373
374template <typename T, typename S>
375float
376Pvs<T, S>::AddSample(T sample, const float pdf)
377{
378#if TODO
379        ++ mSamples;
380        S *data = Find(sample);
381
382        if (data) 
383        {
384                data->mSumPdf += pdf;
385                return data->mSumPdf;
386        }
387        else
388        {
389                mEntries[sample] = S(pdf);
390                return pdf;
391        }
392#else
393return 0;
394#endif
395}
396
397
398template <typename T, typename S>
399S * Pvs<T, S>::AddSample2(T sample, const float pdf)
400{
401  mSamples++;
402  S *data = Find(sample);
403 
404  if (data) 
405        {
406          data->mSumPdf += pdf;
407        }
408  else
409        {
410          mEntries[sample] = S(pdf);
411          data = Find(sample);
412        }
413 
414  return data;
415}
416
417template <typename T, typename S>
418bool Pvs<T, S>::AddSample(T sample,
419                                  const float pdf,
420                                  float &contribution)
421{
422        ++ mSamples;
423    S *data = Find(sample);
424#if TODO
425        if (data) 
426        {
427                data->mSumPdf += pdf;
428                contribution = pdf / data->mSumPdf;
429                return false;
430        }
431        else {
432                mEntries[sample] = S(pdf);
433                contribution = 1.0f;
434                return true;
435        }
436#else
437        return true;
438#endif
439}
440
441template <typename T, typename S>
442bool
443Pvs<T, S>::GetSampleContribution(T sample,
444                                                                 const float pdf,
445                                                                 float &contribution)
446{
447  S *data = Find(sample);
448 
449  if (data)  {
450        contribution = pdf / (data->mSumPdf + pdf);
451        return false;
452  }
453  else {
454        contribution = 1.0f;
455        return true;
456  }
457}
458
459template <typename T, typename S>
460bool Pvs<T, S>::RemoveSample(T sample,
461                                                         const float pdf)
462{
463  -- mSamples;
464#if TODO
465  std::vector<pair<T, S> >::iterator it = mEntries.find(sample);
466 
467  if (it == mEntries.end())
468        return false;
469 
470  S *data = &(*it).second;
471 
472  data->mSumPdf -= pdf;
473
474  if (data->mSumPdf <= 0.0f)
475  {
476          mEntries.erase(it);
477  }
478#endif
479  return true;
480}
481
482template <typename T, typename S>
483int Pvs<T, S>::AddPvs(const Pvs<T, S> &pvs)
484{
485  int samples = mSamples + pvs.mSamples;
486  std::vector<pair<T, S> >::
487        const_iterator it, it_end = pvs.mEntries.end();
488 
489  float contri;
490  // output PVS of view cell
491  for (it = pvs.mEntries.begin(); it != it_end; ++ it)
492  {     
493          AddSample((*it).first, (*it).second.mSumPdf, contri);
494  }
495
496  mSamples = samples;
497
498  return GetSize();
499}
500 
501template <typename T, typename S>
502int Pvs<T, S>::SubtractPvs(const Pvs<T, S> &pvs)
503{
504        const int samples = mSamples - pvs.mSamples;
505#if TODO
506        std::vector<pair<T, S> >::
507                const_iterator it, it_end = pvs.mEntries.end();
508
509        // output PVS of view cell
510        for (it = pvs.mEntries.begin(); it != it_end; ++ it)
511                RemoveSample((*it).first, (*it).second.mSumPdf);
512
513        mSamples = samples;
514#endif
515        return GetSize();
516}
517
518template <typename T, typename S>
519void Pvs<T, S>::CollectEntries(std::vector<T> &entries)
520{
521        std::vector<pair<T, S> >::
522                const_iterator it, it_end = mEntries.end();
523
524        // output PVS of view cell
525        for (it = mEntries.begin(); it != it_end; ++ it)
526                entries.push_back((*it)->first);
527}
528
529template <typename T, typename S>
530void Pvs<T, S>::NormalizeMaximum()
531{
532  std::vector<pair<T, S> >::
533        const_iterator it, it_end = mEntries.end();
534
535  float maxPdfSum = -1.0f;
536
537  // output PVS of view cell
538  for (it = mEntries.begin(); it != it_end; ++ it) {
539        float sum = (*it)->second.sumPdf;
540        if (sum > maxSum)
541          maxSum = sum;
542  }
543
544  maxSum = 1.0f / maxSum;
545
546  for (it = mEntries.begin(); it != it_end; ++ it) {
547        (*it)->second.sumPdf *= maxSum;
548  }
549 
550}
551
552
553template <typename T, typename S>
554float Pvs<T, S>::GetEntrySize()
555{
556        return (float)(sizeof(T) + sizeof(S)) / float(1024 * 1024);
557}
558
559
560template <typename T, typename S>
561int Pvs<T, S>::GetEntrySizeByte()
562{
563        return sizeof(T) + sizeof(S);
564}
565
566
567///////////////////////////////////////
568
569/** Class instantiating the Pvs template for kd tree nodes.
570*/
571class KdPvs: public Pvs<KdNode *, PvsData>
572{
573public:
574        int Compress();
575};
576
577
578class ObjectPvs: public Pvs<Intersectable *, PvsData>
579{
580public:
581        /** Counts object int the pvs. Different to method "GetSize", not
582                only the raw container size is returned,
583                but the individual contributions of the entries are summed up.
584        */
585        float EvalPvsCost() const;
586};
587
588
589////////////
590//-- typedefs
591
592//typedef std::map<KdNode *, PvsData, LtSample<KdNode *> > KdPvsMap;
593//typedef std::map<Intersectable *, PvsData, LtSample<Intersectable *> > ObjectPvsEntries;
594//typedef std::map<ViewCell *, MailablePvsData, LtSample<ViewCell *> > ViewCellPvsEntries;
595
596
597typedef std::vector<pair<Intersectable *, PvsData> > ObjectPvsEntries;
598
599typedef Pvs<ViewCell *, MailablePvsData> ViewCellPvs;
600
601}
602
603#endif
604
Note: See TracBrowser for help on using the repository browser.