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

Revision 2019, 21.2 KB checked in by bittner, 17 years ago (diff)

merge

Line 
1#ifndef __PVS_H
2#define __PVS_H
3
4#include <map>
5#include <vector>
6#include "common.h"
7#include <math.h>
8using namespace std;
9
10namespace GtpVisibilityPreprocessor {
11
12class KdNode;
13class BspNode;
14class Ray;
15class Intersectable;
16class ViewCell;
17
18
19/** Information stored with a PVS entry. Consists of the number
20        the object was seen from the view cell.
21*/
22template<typename T, typename S>
23struct PvsEntry
24{
25public:
26
27        PvsEntry() {}
28
29        PvsEntry(T sample, const S &data): mObject(sample), mData(data) {}
30
31        T mObject;
32        S mData;
33
34        template<typename T, typename S>
35        friend int operator< (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b);
36        template<typename T, typename S>
37        friend int operator== (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b);
38};
39
40
41template<typename T, typename S>
42int operator< (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b)
43{
44        return a.mObject < b.mObject;
45}
46
47template<typename T, typename S>
48int operator== (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b)
49{
50        return a.mObject == b.mObject;
51}
52
53
54template<typename T, typename S>
55struct LtSample
56{
57    bool operator()(const PvsEntry<T, S> &a, const PvsEntry<T, S> &b) const
58    {
59                return a.mObject < b.mObject;
60        }
61};
62
63template<typename T, typename S>
64int equalSample (const PvsEntry<T, S> &a, const PvsEntry<T, S> &b)
65{
66        return a.mObject == b.mObject;
67}
68
69/** Information stored with a PVS entry. Consists of the number
70        the object was seen from the view cell.
71*/
72struct PvsData {
73public:
74        PvsData() {}
75        PvsData(const float sumPdf):
76        mSumPdf(sumPdf) {}
77       
78        // $$JB in order to return meaningfull values
79        // it assumes that the sum pdf has been normalized somehow!!!
80        inline float GetVisibility()
81        {
82                return mSumPdf;
83        }
84
85        /// sum of probability density of visible sample rays
86        float mSumPdf;
87};
88
89
90class MailablePvsData
91{
92public:
93        // sum of probability density of visible sample rays
94        float mSumPdf;
95        int mCounter;
96
97        MailablePvsData() {}
98        MailablePvsData(const float sumPdf):
99        mSumPdf(sumPdf) {}
100
101        // $$JB in order to return meaningfull values
102        // it assumes that the sum pdf has been normalized somehow!!!
103        float GetVisibility()
104        {
105                return mSumPdf;
106        }
107
108        ////////////////////////////
109        //  Mailing stuff
110
111        // last mail id -> warning not thread safe!
112        // both mailId and mailbox should be unique for each thread!!!
113        static int sMailId;
114        static int sReservedMailboxes;
115
116        static void NewMail(const int reserve = 1) {
117                sMailId += sReservedMailboxes;
118                sReservedMailboxes = reserve;
119        }
120
121        void Mail() { mMailbox = sMailId; }
122        bool Mailed() const { return mMailbox == sMailId; }
123
124        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
125        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
126
127        int IncMail() { return ++ mMailbox - sMailId; }
128       
129        //////////////////////////////////////////
130
131protected:
132
133        int mMailbox;
134
135};
136
137
138template<typename T, typename S>
139class PvsIterator
140{
141public:
142PvsIterator<T, S>(){}
143        PvsIterator<T, S>(const typename vector<PvsEntry<T, S> >::const_iterator &itCurrent,
144                                          const typename vector<PvsEntry<T, S> >::const_iterator &itEnd):
145        mItCurrent(itCurrent), mItEnd(itEnd)
146        {
147        }
148
149        bool HasMoreEntries() const
150        {
151                return (mItCurrent != mItEnd);
152        }
153
154        const PvsEntry<T, S> &Next()
155        {
156                return *(mItCurrent ++);
157        }
158       
159private:
160        typename vector<PvsEntry<T, S> >::const_iterator mItCurrent;
161        typename vector<PvsEntry<T, S> >::const_iterator mItEnd;
162};
163
164
165/** Template class representing the Potentially Visible Set (PVS)
166        mainly from a view cell, but also e.g., from objects.
167*/
168template<typename T, typename S>
169class Pvs
170{
171        template<typename T, typename S>
172        friend class PvsIterator;
173
174public:
175 
176        Pvs(): mSamples(0), mEntries(), mLastSorted(0), mQueriesSinceSort(0) {}
177
178        /** creates pvs and initializes it with the given entries.
179                Assumes that entries are sorted-
180        */
181        Pvs(const vector<PvsEntry<T, S> > &samples);
182        virtual ~Pvs() {};
183
184        /** Compresses PVS lossless or lossy.
185        */
186        int Compress() {return 0;}
187        int GetSize() const {return (int)mEntries.size();}
188        bool Empty() const {return mEntries.empty();}
189
190        void Reserve(const int n) { mEntries.reserve(n); }
191
192        /** Normalize the visibility of entries in order to get
193                comparable results.
194        */
195        void NormalizeMaximum();
196
197        /** Merges pvs of a into this pvs.
198                Warning: very slow!
199        */
200        void MergeInPlace(const Pvs<T, S> &a);
201
202        /** Difference of pvs to pvs b.
203                @returns number of different entries.
204        */
205        int Diff(const Pvs<T, S> &b);
206
207        /** Finds sample in PVS.
208                @param checkDirty if dirty part of the pvs should be checked for entry
209                        (warning: linear runtime in dirty part)
210                @returns iterator on the sample.
211        */
212        bool Find(T sample,
213                          typename vector<PvsEntry<T, S> >::iterator &it,
214                          const bool checkDirty = true);
215
216        bool GetSampleContribution(T sample, const float pdf, float &contribution);
217
218        /** Adds sample to PVS.
219                @returns contribution of sample (0 or 1)
220        */
221        float AddSample(T sample, const float pdf);
222
223        /** Adds sample to PVS without checking for presence of the sample
224                pvs remains unsorted!
225        */
226        void AddSampleDirty(T sample, const float pdf);
227
228        /** Adds sample dirty (on the end of the vector) but
229                first checks if sample is already in clean part of the pvs.
230        */
231        bool AddSampleDirtyCheck(T sample, const float pdf);//, float &contribution);
232
233        /** Sort pvs entries - this should always be called after a
234                sequence of AddSampleDirty calls
235        */
236        void Sort();
237
238  /** Sort pvs entries assume that the pvs contains unique entries
239   */
240  void SimpleSort();
241
242        /** Adds sample to PVS. Assumes that the pvs is sorted
243                @returns contribution of sample (0 or 1)
244        */
245        //float AddSamples(const vector<PvsEntry<T, S> > &samples);
246
247        /** Adds sample to PVS.
248                @returns PvsData
249        */
250        typename std::vector<PvsEntry<T, S> >::iterator AddSample2(T sample, const float pdf);
251
252        /** Subtracts one pvs from another one.
253                WARNING: could contains bugs
254                @returns new pvs size
255        */
256        int SubtractPvs(const Pvs<T, S> &pvs);
257
258        /** Returns PVS data, i.e., how often it was seen from the view cell,
259                and the object itsef.
260        */
261        void GetData(const int index, T &entry, S &data);
262
263        /** Collects the PVS entries and returns them in the vector.
264        */
265        void CollectEntries(std::vector<T> &entries);
266
267        /** Removes sample from PVS if reference count is zero.
268                @param visibleSamples number of references to be removed
269        */
270        bool RemoveSample(T sample, const float pdf);
271
272        /** Compute continuous PVS difference
273        */
274        void ComputeContinuousPvsDifference(Pvs<T, S> &pvs,
275                                                                                float &pvsReduction,
276                                                                                float &pvsEnlargement);
277
278        /** Clears the pvs.
279        */
280        void Clear(const bool trim = true);
281
282        void Trim();
283
284        static int GetEntrySizeByte();
285        static float GetEntrySize();
286
287        /** Compute continuous PVS difference
288        */
289        float GetPvsHomogenity(Pvs<T, S> &pvs);
290
291        static void Merge(Pvs<T, S> &mergedPvs, const Pvs<T, S> &a, const Pvs<T, S> &b);
292
293        static void Merge(Pvs<T, S> &mergedPvs,
294                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aBegin,
295                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aEnd,
296                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bBegin,
297                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bEnd,
298                                          const int aSamples,
299                                          const int bSamples);
300
301        int GetSamples() const
302        {
303                return mSamples;
304        }
305
306
307        bool IsDirty() const
308        {
309                return mLastSorted < mEntries.size();
310        }
311
312        bool RequiresResort() const
313        {
314          // the last part should not be more than log of the sorted part. this
315          // way we can achieve logarithmic behaviour for insertion and find
316          const int n = mEntries.size();
317          const int dirtySize = n - mLastSorted;
318
319#define LOG2E 1.442695040f
320         
321          const float logN = log((float)max(1, n))/LOG2E;
322          const float logS = log((float)max(1, mLastSorted))/LOG2E;
323          const float logD = log((float)max(1, dirtySize))/LOG2E;
324         
325          if (8*(n + 2*dirtySize*logD) <
326                  mQueriesSinceSort*((mLastSorted*logS + dirtySize*dirtySize/2)/n - logN)) {
327                //              cout<<"Q="<<mQueriesSinceSort<<" N="<<n<<" D="<<dirtySize<<endl;
328                return true;
329          }
330          return false;
331        }
332
333  bool RequiresResortLog() const
334  {
335        // the last part should not be more than log of the sorted part. this
336        // way we can achieve logarithmic behaviour for insertion and find
337        const int dirtySize = (int)mEntries.size() - mLastSorted;
338        return dirtySize > 4*(int)(log((double)mEntries.size()) / log(2.0));
339  }
340 
341 
342        int GetLastSorted() const
343        {
344                return mLastSorted;
345        }
346
347        typename PvsIterator<T, S> GetIterator() const;
348
349protected:
350
351        /// vector of PVS entries
352        vector<PvsEntry<T, S> > mEntries;
353       
354        /// Number of samples used to create the PVS
355        int mSamples;
356 
357        /// Last sorted entry in the pvs (important for find and merge)
358        int mLastSorted;
359
360  int mQueriesSinceSort;
361};
362
363
364template <typename T, typename S>
365Pvs<T, S>::Pvs(const vector<PvsEntry<T, S> > &samples)
366{
367        mEntries.reserve(samples.size());
368        mEntries = samples;
369        mLastSorted = 0;
370        mSamples = samples.size();
371}
372
373
374template <typename T, typename S>
375void Pvs<T, S>::Sort()
376{
377        std::vector<PvsEntry<T, S> >::iterator it = mEntries.begin() + mLastSorted;
378        //std::vector<PvsEntry<T, S> >::const_iterator it = mEntries.begin() + mLastSorted;
379        std::vector<PvsEntry<T, S> >::iterator it_end = mEntries.end();
380
381        // throw out double entries
382        std::vector<PvsEntry<T, S> >::iterator newEnd = unique(it, it_end);
383        sort(it, newEnd);
384        //sort(mEntries.begin(), mEntries.end());
385       
386        // now merge sorted ranges
387        ObjectPvs newPvs;
388        Merge(newPvs,
389                  mEntries.begin(),
390                  it,
391                  it,
392                  newEnd,
393                  mSamples,
394                  0);
395       
396        mEntries = newPvs.mEntries;
397        mLastSorted = (int)mEntries.size();
398        mQueriesSinceSort = 0;
399}
400
401template <typename T, typename S>
402void Pvs<T, S>::SimpleSort()
403{
404  //  sort(mEntries.begin(), mEntries.end());
405  std::vector<PvsEntry<T, S> >::iterator it = mEntries.begin() + mLastSorted;
406 
407  sort(it, mEntries.end());
408  inplace_merge(mEntries.begin(), it, mEntries.end());
409 
410  mLastSorted = (int)mEntries.size();
411  mQueriesSinceSort = 0;
412}
413
414
415/**
416   Compute continuous PVS difference of 'b' with respect to the base PVS (*this).
417   Provides separatelly PVS reduction from PVS enlargement.
418
419*/
420template <typename T, typename S>
421void
422Pvs<T, S>::ComputeContinuousPvsDifference(Pvs<T, S> &b,
423                                                                                  float &pvsReduction,
424                                                                                  float &pvsEnlargement)
425{
426        pvsReduction = 0.0f;
427        pvsEnlargement = 0.0f;
428
429        // Uses sum of log differences, which corresponds to entropy
430        std::vector<PvsEntry<T, S> >::iterator it;
431
432        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
433        {
434                float bSumPdf = (*it).mData.mSumPdf;
435                float aSumPdf = 0.0f;
436
437                vector<PvsEntry<T, S> >::iterator oit;
438                const bool entryFound = Find((*it).mObject, oit);               
439
440                if (entryFound)
441                {
442                        aSumPdf = (*it).mData.mSumPdf;
443
444                        // mark this entry as processed to avoid double counting
445                        (*it).mData.mSumPdf = -aSumPdf;
446                }
447
448#if 0
449                const float diff = bSumPdf - aSumPdf;
450
451                if (diff > 0.0f) {
452                        pvsEnlargement += diff;
453                } else {
454                        pvsReduction += -diff;
455                }
456#else
457                if (!entryFound)
458                        pvsEnlargement += 1.0f;
459#endif
460        }
461
462        for (it = mEntries.begin(); it != mEntries.end(); ++ it)
463        {
464                float aSumPdf = (*it).mData.mSumPdf;
465                float bSumPdf = 0.0f;
466                if (aSumPdf < 0.0f) {
467               
468                        // this entry was already accounted for!
469                        // just revert it back
470                        (*it).mData.mSumPdf = -aSumPdf;
471                } else {
472                        vector<PvsEntry<T, S> >::iterator oit;
473               
474                        const bool entryFound = b.Find((*it).mObject, oit);
475                                               
476                        if (entryFound) {
477                                bSumPdf = (*oit).mData.mSumPdf;
478                        }
479#if 0
480                        const float diff = bSumPdf - aSumPdf;
481
482                        if (diff > 0.0f) {
483                                pvsEnlargement += diff;
484                        } else {
485                                pvsReduction += -diff;
486                        }
487
488#else
489                        if (!entryFound)
490                                pvsReduction += 1.0f;
491#endif
492                }
493        }
494}
495
496
497template <typename T, typename S>
498int Pvs<T, S>::Diff(const Pvs<T, S> &b)
499{
500        int dif = 0;
501
502        std::vector<PvsEntry<T, S> >::const_iterator it;
503
504        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
505        {
506                vector<PvsEntry<T, S> >::iterator bit;
507                const bool entryFound = Find((*it).first, bit);
508
509                if (!entryFound) ++ dif;
510        }
511
512        return dif;
513}
514
515
516template <typename T, typename S>
517void Pvs<T, S>::MergeInPlace(const Pvs<T, S> &a)
518{
519        // early exit
520        if (a.Empty())
521        {
522                return;
523        }
524        else if (Empty())
525        {
526                mEntries.reserve(a.GetSize());
527                mEntries = a.mEntries;
528                mSamples = a.mSamples;
529                return;
530        }
531
532        ObjectPvs interPvs;
533       
534        Merge(interPvs, *this, a);
535       
536        mEntries.reserve(interPvs.GetSize());
537        mEntries = interPvs.mEntries;
538        mSamples = interPvs.mSamples;
539}
540
541
542template <typename T, typename S>
543void Pvs<T, S>::Merge(Pvs<T, S> &mergedPvs, const Pvs<T, S> &a, const Pvs<T, S> &b)
544{
545        std::vector<PvsEntry<T, S> >::const_iterator ait = a.mEntries.begin(), ait_end = a.mEntries.end();
546        std::vector<PvsEntry<T, S> >::const_iterator bit = b.mEntries.begin(), bit_end = b.mEntries.end();
547       
548        Merge(mergedPvs,
549                  ait, ait_end,
550                  bit, bit_end,
551                  a.mSamples,
552                  b.mSamples);
553}
554
555
556template <typename T, typename S>
557void Pvs<T, S>::Merge(Pvs<T, S> &mergedPvs,
558                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aBegin,
559                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aEnd,
560                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bBegin,
561                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bEnd,
562                                          const int aSamples,
563                                          const int bSamples)
564{
565        std::vector<PvsEntry<T, S> >::const_iterator ait = aBegin;
566        std::vector<PvsEntry<T, S> >::const_iterator bit = bBegin;
567       
568        for (; (ait != aEnd); ++ ait)
569        {
570                Intersectable *aObj = (*ait).mObject;
571                Intersectable *bObj = NULL;
572                //Intersectable *bObjOld = NULL;
573       
574                const PvsEntry<T, S> &aEntry = (*ait);
575
576                for (; (bit != bEnd) && ((*bit).mObject <= (*ait).mObject); ++ bit)
577                {
578                        bObj = (*bit).mObject;
579
580                        // object found => add up probabilities
581                        if (bObj == aEntry.mObject)
582                        {
583                                PvsData newData(aEntry.mData.mSumPdf + (*bit).mData.mSumPdf);
584                                PvsEntry<T, S> entry(bObj, newData);
585                                mergedPvs.mEntries.push_back(entry);
586                        }
587                        else
588                        {
589                                mergedPvs.mEntries.push_back(*bit);
590                        }
591                       
592                        //bObjOld = bObj;
593                }
594
595                // only push back if objects different
596                // (equal case is handled by second loop)
597                if (aObj != bObj)
598                {
599                        mergedPvs.mEntries.push_back(*ait);
600                }
601        }
602
603        // add the rest
604        for (; (bit != bEnd); ++ bit)
605        {
606                mergedPvs.mEntries.push_back(*bit);
607        }
608
609        mergedPvs.mSamples = aSamples + bSamples;
610}
611
612
613template <typename T, typename S> void Pvs<T, S>::Clear(const bool trim = true)
614{
615        mEntries.clear();
616        mSamples = 0;
617        mLastSorted = 0;
618
619        if (trim)
620        {
621                vector<PvsEntry<T,S> >().swap(mEntries);
622        }
623}
624
625
626template <typename T, typename S> void Pvs<T, S>::Trim()
627{
628        vector<PvsEntry<T,S> >(mEntries).swap(mEntries);
629}
630
631
632template <typename T, typename S>
633bool Pvs<T, S>::Find(T sample,
634                                         typename vector<PvsEntry<T, S> >::iterator &it,
635                                         const bool checkDirty)
636{
637  PvsEntry<T, S> dummy(sample, PvsData());
638  mQueriesSinceSort++;
639 
640  // only check clean part
641  vector<PvsEntry<T, S> >::iterator sorted_end = mEntries.begin() + mLastSorted;
642 
643  // binary search
644  it = lower_bound(mEntries.begin(), sorted_end, dummy);
645 
646  if ((it != mEntries.end()) && ((*it).mObject == sample))
647        //  if (it != sorted_end)
648        return true;
649 
650  // sample not found yet => search further in the unsorted part
651  if (checkDirty) {
652       
653        for (it = sorted_end; (it != mEntries.end()) && ((*it).mObject != sample); ++ it) ;
654       
655        if (it != mEntries.end())
656          return true;
657  }
658 
659  return false;
660}
661
662
663template <typename T, typename S>
664void Pvs<T, S>::GetData(const int index, T &entry, S &data)
665{
666        std::vector<PvsEntry<T, S> >::iterator i = mEntries.begin();
667        for (int k = 0; k != index && i != mEntries.end(); ++ i, ++ k);
668
669        entry = (*i).first;
670        data = (*i).second;
671}
672
673
674template <typename T, typename S>
675float Pvs<T, S>::AddSample(T sample, const float pdf)
676{
677        ++ mSamples;
678       
679        vector<PvsEntry<T, S> >::iterator it;
680        const bool entryFound = Find(sample, it);               
681
682        if (entryFound)
683        {       
684                S &data = (*it).mData;
685                data.mSumPdf += pdf;
686                return data.mSumPdf;
687        }
688        else
689          {
690                PvsEntry<T, S> entry(sample, pdf);
691                mEntries.insert(it, entry);
692                ++ mLastSorted;
693                return pdf;
694          }
695}
696
697
698template <typename T, typename S>
699void Pvs<T, S>::AddSampleDirty(T sample, const float pdf)
700{
701        ++ mSamples;
702        mEntries.push_back(PvsEntry<T, S>(sample, pdf));
703}
704                                         
705
706template <typename T, typename S>
707typename vector< PvsEntry<T, S> >::iterator Pvs<T, S>::AddSample2(T sample,
708                                                                                                                                  const float pdf)
709{
710        ++ mSamples;
711       
712        vector<PvsEntry<T, S> >::iterator it;
713        const bool entryFound == Find(sample, it);
714
715        if (entryFound)
716        {
717                S &data = (*it).second;
718                data->mSumPdf += pdf;
719        }
720        else
721        {
722                PvsEntry<T, S> entry(sample, pdf);
723                mEntries.insert(it, entry);
724                ++ mLastSorted;
725        }
726
727        return it;
728}
729
730
731/** Adds sample dirty (on the end of the vector) but
732        first checks if sample is already in clean part of the pvs.
733*/
734template <typename T, typename S>
735bool Pvs<T, S>::AddSampleDirtyCheck(T sample,
736                                                                        const float pdf)
737                                                                        //,float &contribution)
738{
739        ++ mSamples;
740
741        vector<PvsEntry<T, S> >::iterator it;
742        bool entryFound = Find(sample, it);
743
744        if (entryFound) {
745          S &data = (*it).mData;
746         
747          data.mSumPdf += pdf;
748          //contribution = pdf / data.mSumPdf;
749         
750          return false;
751        }
752        else {
753          AddSampleDirty(sample, pdf);
754          //contribution = 1.0f;
755          return true;
756        }
757}
758
759
760template <typename T, typename S>
761bool Pvs<T, S>::GetSampleContribution(T sample,
762                                                                          const float pdf,
763                                                                          float &contribution)
764{
765        vector<PvsEntry<T, S> >::iterator it;
766        const bool entryFound = Find(sample, it);
767
768        if (entryFound) 
769        {
770                S &data = (*it).mData;
771                contribution = pdf / (data.mSumPdf + pdf);
772                return false;
773        }
774        else
775        {
776                contribution = 1.0f;
777                return true;
778        }
779}
780
781
782template <typename T, typename S>
783bool Pvs<T, S>::RemoveSample(T sample, const float pdf)
784{
785        -- mSamples;
786       
787        vector<PvsEntry<T, S> >::iterator it;
788        const bool entryFound = Find(sample, it);
789
790        if (!entryFound)
791                return false;
792
793        S &data = (*it).mData;
794
795        data.mSumPdf -= pdf;
796
797        if (data.mSumPdf <= 0.0f)
798        {
799                mEntries.erase(it);
800                -- mLastSorted; // wrong if sample was in tail!!
801        }
802
803        return true;
804}
805
806
807template <typename T, typename S>
808int Pvs<T, S>::SubtractPvs(const Pvs<T, S> &pvs)
809{
810        const int samples = mSamples - pvs.mSamples;
811
812        std::vector<PvsEntry<T, S> >::
813                const_iterator it, it_end = pvs.mEntries.end();
814
815        // output PVS of view cell
816        for (it = pvs.mEntries.begin(); it != it_end; ++ it)
817                RemoveSample((*it).mObject, (*it).mData.mSumPdf);
818
819        mSamples = samples;
820
821        return GetSize();
822}
823
824
825template <typename T, typename S>
826void Pvs<T, S>::CollectEntries(std::vector<T> &entries)
827{
828        std::vector<PvsEntry<T, S> >::
829                const_iterator it, it_end = mEntries.end();
830
831        // output PVS of view cell
832        for (it = mEntries.begin(); it != it_end; ++ it)
833                entries.push_back((*it)->first);
834}
835
836
837template <typename T, typename S>
838void Pvs<T, S>::NormalizeMaximum()
839{
840        std::vector<PvsEntry<T, S> >::
841                const_iterator it, it_end = mEntries.end();
842
843        float maxPdfSum = -1.0f;
844
845        // output PVS of view cell
846        for (it = mEntries.begin(); it != it_end; ++ it) {
847                float sum = (*it)->second.sumPdf;
848                if (sum > maxSum)
849                        maxSum = sum;
850        }
851
852        maxSum = 1.0f / maxSum;
853
854        for (it = mEntries.begin(); it != it_end; ++ it) {
855                (*it)->second.sumPdf *= maxSum;
856        }
857
858}
859
860
861template <typename T, typename S>
862float Pvs<T, S>::GetEntrySize()
863{
864        return (float)(sizeof(T) + sizeof(S)) / float(1024 * 1024);
865}
866
867
868template <typename T, typename S>
869int Pvs<T, S>::GetEntrySizeByte()
870{
871        return sizeof(T) + sizeof(S);
872}
873
874
875template <typename T, typename S>
876float Pvs<T, S>::GetPvsHomogenity(Pvs<T, S> &pvs)
877{
878        float pvsReduction, pvsEnlargement;
879
880        ComputeContinuousPvsDifference(pvs,     pvsReduction, pvsEnlargement);
881
882        return pvsReduction + pvsEnlargement;
883}
884
885
886template <typename T, typename S>
887typename PvsIterator<T, S> Pvs<T, S>::GetIterator() const
888{
889        PvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
890
891        return pit;
892}
893
894
895///////////////////////////////////////
896
897/** Class instantiating the Pvs template for kd tree nodes.
898*/
899class KdPvs: public Pvs<KdNode *, PvsData>
900{
901public:
902        int Compress();
903};
904
905
906////////////
907//-- typedefs
908
909typedef PvsEntry<Intersectable *, PvsData> ObjectPvsEntry;
910typedef std::vector<ObjectPvsEntry> ObjectPvsEntries;
911typedef Pvs<ViewCell *, MailablePvsData> ViewCellPvs;
912typedef PvsIterator<Intersectable *, PvsData> ObjectPvsIterator;
913
914
915class ObjectPvs: public Pvs<Intersectable *, PvsData>
916{
917public:
918        /** Counts object int the pvs. Different to method "GetSize", not
919                only the raw container size is returned,
920                but the individual contributions of the entries are summed up.
921        */
922        float EvalPvsCost() const;
923
924        friend ostream &operator<<(ostream &s, const ObjectPvs &p)
925        {
926                ObjectPvsIterator pit = p.GetIterator();
927
928                while (pit.HasMoreEntries())
929                {               
930                        const ObjectPvsEntry &entry = pit.Next();
931                        Intersectable *obj = entry.mObject;
932
933                        cout << obj << " ";
934                }
935               
936                return s;
937        }
938};
939
940
941
942}
943
944#endif
945
Note: See TracBrowser for help on using the repository browser.