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

Revision 2530, 17.9 KB checked in by mattausch, 17 years ago (diff)
RevLine 
[2116]1#ifndef __VERBOSEPVS_H
2#define __VERBOSEPVS_H
[177]3
[469]4#include <vector>
[1189]5#include "common.h"
[2019]6#include <math.h>
[2116]7#include "PvsBase.h"
8
9
[177]10
[860]11namespace GtpVisibilityPreprocessor {
12
[177]13
[2530]14/** Iterator over the pvs.
15*/
[1740]16template<typename T, typename S>
[1742]17class PvsIterator
18{
19public:
[2116]20        PvsIterator<T, S>(){}
[1742]21        PvsIterator<T, S>(const typename vector<PvsEntry<T, S> >::const_iterator &itCurrent,
22                                          const typename vector<PvsEntry<T, S> >::const_iterator &itEnd):
23        mItCurrent(itCurrent), mItEnd(itEnd)
24        {
25        }
26
[2530]27        inline bool HasMoreEntries() const { return (mItCurrent != mItEnd);     }
[1742]28
[2530]29        inline T Next(S &pdf) {
[2117]30                pdf = (*mItCurrent).mData;
31                return (*(mItCurrent ++)).mObject;
[1742]32        }
[2116]33
[2530]34        inline T Next() { return (*(mItCurrent ++)).mObject; }
[2117]35
[2530]36
[1742]37private:
[2530]38       
[1742]39        typename vector<PvsEntry<T, S> >::const_iterator mItCurrent;
40        typename vector<PvsEntry<T, S> >::const_iterator mItEnd;
[1740]41};
42
43
[469]44/** Template class representing the Potentially Visible Set (PVS)
45        mainly from a view cell, but also e.g., from objects.
46*/
[1189]47template<typename T, typename S>
[2116]48class VerbosePvs
[310]49{
[2116]50        template<typename T, typename S> friend class PvsIterator;
[1740]51
[310]52public:
[2100]53
[2530]54        VerbosePvs(): mSamples(0), mEntries(), mLastSorted(0), mQueriesSinceSort(0)
55        {}
[1738]56
[1742]57        /** creates pvs and initializes it with the given entries.
[2529]58                Assumes that entries are sorted.
[1742]59        */
[2116]60        VerbosePvs(const vector<PvsEntry<T, S> > &samples);
61        virtual ~VerbosePvs() {};
[492]62
[1706]63        /** Compresses PVS lossless or lossy.
64        */
[2529]65        int Compress() { return 0; }
[2100]66       
[2529]67        inline int GetSize() const { return (int)mEntries.size(); }
[2100]68       
[2529]69        inline bool Empty() const { return mEntries.empty(); }
[469]70
[2529]71        inline void Reserve(const int n) { mEntries.reserve(n); }
[1740]72        /** Normalize the visibility of entries in order to get
[2529]73                comparable results.
[1706]74        */
75        void NormalizeMaximum();
76        /** Merges pvs of a into this pvs.
[2529]77                Warning: very slow!
[1706]78        */
[2116]79        void MergeInPlace(const VerbosePvs<T, S> &a);
[1706]80        /** Difference of pvs to pvs b.
[2100]81        @returns number of different entries.
[1706]82        */
[2116]83        int Diff(const VerbosePvs<T, S> &b);
[1706]84        /** Finds sample in PVS.
[1789]85                @param checkDirty if dirty part of the pvs should be checked for entry
[2100]86                (warning: linear runtime in dirty part)
[2066]87                @returns iterator on the sample if found, else the place where
[2100]88                it would be added in the sorted vector.
[1706]89        */
[1790]90        bool Find(T sample,
91                          typename vector<PvsEntry<T, S> >::iterator &it,
92                          const bool checkDirty = true);
[469]93
[1706]94        bool GetSampleContribution(T sample, const float pdf, float &contribution);
95        /** Adds sample to PVS.
96                @returns contribution of sample (0 or 1)
97        */
98        float AddSample(T sample, const float pdf);
[1789]99        /** Adds sample to PVS without checking for presence of the sample
[2066]100                warning: pvs remains unsorted!
[1789]101        */
102        void AddSampleDirty(T sample, const float pdf);
103        /** Adds sample dirty (on the end of the vector) but
104                first checks if sample is already in clean part of the pvs.
105        */
[2116]106        bool AddSampleDirtyCheck(T sample, const float pdf);
[2529]107        /** Sort pvs entries. This should always be called after a
[1789]108                sequence of AddSampleDirty calls
109        */
110        void Sort();
[2100]111        /** Sort pvs entries assume that the pvs contains unique entries
[1740]112        */
[2100]113        void SimpleSort();
[1706]114        /** Adds sample to PVS.
115                @returns PvsData
116        */
[2116]117        typename std::vector<PvsEntry<T, S> >::iterator
118                AddSample2(T sample, const float pdf);
[1706]119        /** Subtracts one pvs from another one.
120                WARNING: could contains bugs
121                @returns new pvs size
122        */
[2116]123        int SubtractPvs(const VerbosePvs<T, S> &pvs);
[1740]124
[1706]125        /** Returns PVS data, i.e., how often it was seen from the view cell,
126                and the object itsef.
127        */
128        void GetData(const int index, T &entry, S &data);
129
130        /** Collects the PVS entries and returns them in the vector.
131        */
132        void CollectEntries(std::vector<T> &entries);
133
134        /** Removes sample from PVS if reference count is zero.
[2100]135        @param visibleSamples number of references to be removed
[1706]136        */
137        bool RemoveSample(T sample, const float pdf);
138
139        /** Compute continuous PVS difference
140        */
[2116]141        void ComputeContinuousPvsDifference(VerbosePvs<T, S> &pvs,
[1740]142                                                                                float &pvsReduction,
143                                                                                float &pvsEnlargement);
[1706]144
145        /** Clears the pvs.
146        */
[1750]147        void Clear(const bool trim = true);
[2529]148        /** Trim the vector containing the pvs.
149        */
[1750]150        void Trim();
151
[1706]152        static int GetEntrySizeByte();
153        static float GetEntrySize();
154
[1740]155        /** Compute continuous PVS difference
156        */
[2116]157        float GetPvsHomogenity(VerbosePvs<T, S> &pvs);
[1706]158
[2116]159        static void Merge(VerbosePvs<T, S> &mergedPvs,
160                                          const VerbosePvs<T, S> &a,
161                                          const VerbosePvs<T, S> &b);
[1706]162
[2529]163        inline int GetSamples() const { return mSamples; }
[1738]164
[2529]165        /** If there is an unsorted part in the pvs.
166        */
167        bool IsDirty() const { return mLastSorted < mEntries.size(); }
[1789]168
[2529]169        /** If this pvs requires a resort to stay efficient.
170        */
[1789]171        bool RequiresResort() const
172        {
[2100]173                // the last part should not be more than log of the sorted part. this
174                // way we can achieve logarithmic behaviour for insertion and find
175                const int n = mEntries.size();
176                const int dirtySize = n - mLastSorted;
[2019]177
[2116]178                const double LOG2E = 1.442695040f;
[2100]179
180                const float logN = log((float)max(1, n))/LOG2E;
181                const float logS = log((float)max(1, mLastSorted))/LOG2E;
182                const float logD = log((float)max(1, dirtySize))/LOG2E;
183
184                if (8*(n + 2*dirtySize*logD) <
185                        mQueriesSinceSort*((mLastSorted*logS + dirtySize*dirtySize/2)/n - logN))
186                {
[2529]187                        // cout<<"Q="<<mQueriesSinceSort<<" N="<<n<<" D="<<dirtySize<<endl;
[2100]188                        return true;
189                }
190               
191                return false;
[1789]192        }
193
[2529]194        /** If this pvs requires a resort to stay efficient.
195        */
[2100]196        bool RequiresResortLog() const
197        {
198                // the last part should not be more than log of the sorted part. this
199                // way we can achieve logarithmic behaviour for insertion and find
200                const int dirtySize = (int)mEntries.size() - mLastSorted;
201                return dirtySize > 4 * (int)(log((double)mEntries.size()) / log(2.0));
202        }
203
[2529]204        inline int GetLastSorted() const { return mLastSorted; }
[1789]205
[1742]206        typename PvsIterator<T, S> GetIterator() const;
207
208protected:
209
[2529]210        /** Merge pvs 1 from begin iterator to end iterator with
211                pvs 2 from begin iterator to end iterator.
212        */
[2116]213        static void Merge(VerbosePvs<T, S> &mergedPvs,
[2100]214                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aBegin,
215                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aEnd,
216                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bBegin,
217                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bEnd,
218                                          const int aSamples,
219                                          const int bSamples);
220
[2529]221
[2116]222        //////////////////////////////
223
[1738]224        /// vector of PVS entries
[1740]225        vector<PvsEntry<T, S> > mEntries;
[2100]226
[1736]227        /// Number of samples used to create the PVS
228        int mSamples;
[2100]229
[1789]230        /// Last sorted entry in the pvs (important for find and merge)
[2019]231        int mLastSorted;
232
[2100]233        int mQueriesSinceSort;
[310]234};
235
[581]236
[1740]237template <typename T, typename S>
[2116]238VerbosePvs<T, S>::VerbosePvs(const vector<PvsEntry<T, S> > &samples)
[1740]239{
240        mEntries.reserve(samples.size());
241        mEntries = samples;
[1757]242        mLastSorted = 0;
[1789]243        mSamples = samples.size();
[1740]244}
[677]245
[1789]246
[1757]247template <typename T, typename S>
[2116]248void VerbosePvs<T, S>::Sort()
[1757]249{
[2116]250        vector<PvsEntry<T, S> >::iterator it = mEntries.begin() + mLastSorted;
251        vector<PvsEntry<T, S> >::iterator it_end = mEntries.end();
[1789]252
253        // throw out double entries
254        std::vector<PvsEntry<T, S> >::iterator newEnd = unique(it, it_end);
255        sort(it, newEnd);
[2019]256       
[1789]257        // now merge sorted ranges
258        ObjectPvs newPvs;
259        Merge(newPvs,
[2019]260                  mEntries.begin(),
261                  it,
262                  it,
263                  newEnd,
264                  mSamples,
265                  0);
[1789]266       
267        mEntries = newPvs.mEntries;
268        mLastSorted = (int)mEntries.size();
[2019]269        mQueriesSinceSort = 0;
[1757]270}
[1740]271
[1877]272template <typename T, typename S>
[2116]273void VerbosePvs<T, S>::SimpleSort()
[1877]274{
[2066]275        //  sort(mEntries.begin(), mEntries.end());
[2116]276        vector<PvsEntry<T, S> >::iterator it = mEntries.begin() + mLastSorted;
[2066]277
278        sort(it, mEntries.end());
279        inplace_merge(mEntries.begin(), it, mEntries.end());
[2019]280 
[2066]281        mLastSorted = (int)mEntries.size();
282        mQueriesSinceSort = 0;
[1877]283}
[1789]284
[1877]285
[695]286/**
287   Compute continuous PVS difference of 'b' with respect to the base PVS (*this).
288   Provides separatelly PVS reduction from PVS enlargement.
289
290*/
[1189]291template <typename T, typename S>
[677]292void
[2116]293VerbosePvs<T, S>::ComputeContinuousPvsDifference(VerbosePvs<T, S> &b,
[1740]294                                                                                  float &pvsReduction,
295                                                                                  float &pvsEnlargement)
[677]296{
[705]297        pvsReduction = 0.0f;
298        pvsEnlargement = 0.0f;
[1740]299
[1738]300        // Uses sum of log differences, which corresponds to entropy
[2116]301        vector<PvsEntry<T, S> >::iterator it;
[1738]302
303        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
[1189]304        {
[1740]305                float bSumPdf = (*it).mData.mSumPdf;
[1738]306                float aSumPdf = 0.0f;
[713]307
[1790]308                vector<PvsEntry<T, S> >::iterator oit;
309                const bool entryFound = Find((*it).mObject, oit);               
[1740]310
311                if (entryFound)
[1738]312                {
[1740]313                        aSumPdf = (*it).mData.mSumPdf;
314
[1738]315                        // mark this entry as processed to avoid double counting
[1740]316                        (*it).mData.mSumPdf = -aSumPdf;
[1738]317                }
318
[713]319#if 0
[1740]320                const float diff = bSumPdf - aSumPdf;
[1738]321
[2100]322                if (diff > 0.0f)
323                {
[1738]324                        pvsEnlargement += diff;
[2100]325                }
326                else
327                {
[1738]328                        pvsReduction += -diff;
329                }
[713]330#else
[1740]331                if (!entryFound)
[2100]332                {
[1738]333                        pvsEnlargement += 1.0f;
[2100]334                }
[713]335#endif
[1738]336        }
337
[1740]338        for (it = mEntries.begin(); it != mEntries.end(); ++ it)
339        {
340                float aSumPdf = (*it).mData.mSumPdf;
[1738]341                float bSumPdf = 0.0f;
[2100]342                if (aSumPdf < 0.0f)
343                {
[1738]344                        // this entry was already accounted for!
345                        // just revert it back
[1740]346                        (*it).mData.mSumPdf = -aSumPdf;
[2100]347                }
348                else
349                {
[1790]350                        vector<PvsEntry<T, S> >::iterator oit;
351               
352                        const bool entryFound = b.Find((*it).mObject, oit);
353                                               
[1740]354                        if (entryFound) {
355                                bSumPdf = (*oit).mData.mSumPdf;
[1738]356                        }
[713]357#if 0
[1740]358                        const float diff = bSumPdf - aSumPdf;
[713]359
[1738]360                        if (diff > 0.0f) {
361                                pvsEnlargement += diff;
362                        } else {
363                                pvsReduction += -diff;
364                        }
365
[713]366#else
[1740]367                        if (!entryFound)
[1738]368                                pvsReduction += 1.0f;
[713]369#endif
[1738]370                }
[695]371        }
[677]372}
373
[1738]374
[1189]375template <typename T, typename S>
[2116]376int VerbosePvs<T, S>::Diff(const VerbosePvs<T, S> &b)
[362]377{
378        int dif = 0;
379
[1740]380        std::vector<PvsEntry<T, S> >::const_iterator it;
[362]381
382        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
383        {
[1790]384                vector<PvsEntry<T, S> >::iterator bit;
385                const bool entryFound = Find((*it).first, bit);
386
387                if (!entryFound) ++ dif;
[362]388        }
389
390        return dif;
391}
392
[1740]393
394template <typename T, typename S>
[2116]395void VerbosePvs<T, S>::MergeInPlace(const VerbosePvs<T, S> &a)
[341]396{
[1786]397        // early exit
398        if (a.Empty())
399        {
400                return;
401        }
402        else if (Empty())
403        {
404                mEntries.reserve(a.GetSize());
405                mEntries = a.mEntries;
406                mSamples = a.mSamples;
407                return;
408        }
409
[1740]410        ObjectPvs interPvs;
411       
412        Merge(interPvs, *this, a);
413       
414        mEntries.reserve(interPvs.GetSize());
415        mEntries = interPvs.mEntries;
[1751]416        mSamples = interPvs.mSamples;
[1740]417}
418
419
420template <typename T, typename S>
[2116]421void VerbosePvs<T, S>::Merge(VerbosePvs<T, S> &mergedPvs,
422                                                         const VerbosePvs<T, S> &a,
423                                                         const VerbosePvs<T, S> &b)
[1740]424{
[2116]425        std::vector<PvsEntry<T, S> >::const_iterator ait =
426                a.mEntries.begin(), ait_end = a.mEntries.end();
427        std::vector<PvsEntry<T, S> >::const_iterator bit =
428                b.mEntries.begin(), bit_end = b.mEntries.end();
[1741]429       
[1789]430        Merge(mergedPvs,
431                  ait, ait_end,
432                  bit, bit_end,
433                  a.mSamples,
434                  b.mSamples);
435}
436
437
438template <typename T, typename S>
[2116]439void VerbosePvs<T, S>::Merge(VerbosePvs<T, S> &mergedPvs,
[1789]440                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aBegin,
441                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aEnd,
442                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bBegin,
443                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bEnd,
444                                          const int aSamples,
445                                          const int bSamples)
446{
447        std::vector<PvsEntry<T, S> >::const_iterator ait = aBegin;
448        std::vector<PvsEntry<T, S> >::const_iterator bit = bBegin;
449       
450        for (; (ait != aEnd); ++ ait)
[1741]451        {
452                Intersectable *aObj = (*ait).mObject;
453                Intersectable *bObj = NULL;
[1789]454                //Intersectable *bObjOld = NULL;
455       
456                const PvsEntry<T, S> &aEntry = (*ait);
[1740]457
[1789]458                for (; (bit != bEnd) && ((*bit).mObject <= (*ait).mObject); ++ bit)
[1741]459                {
460                        bObj = (*bit).mObject;
461
462                        // object found => add up probabilities
[1742]463                        if (bObj == aEntry.mObject)
[1741]464                        {
465                                PvsData newData(aEntry.mData.mSumPdf + (*bit).mData.mSumPdf);
466                                PvsEntry<T, S> entry(bObj, newData);
467                                mergedPvs.mEntries.push_back(entry);
468                        }
469                        else
470                        {
471                                mergedPvs.mEntries.push_back(*bit);
472                        }
473                }
474
475                // only push back if objects different
476                // (equal case is handled by second loop)
477                if (aObj != bObj)
478                {
479                        mergedPvs.mEntries.push_back(*ait);
480                }
481        }
482
483        // add the rest
[1789]484        for (; (bit != bEnd); ++ bit)
[1740]485        {
[1741]486                mergedPvs.mEntries.push_back(*bit);
487        }
[1789]488
489        mergedPvs.mSamples = aSamples + bSamples;
[1740]490}
491
492
[2199]493template <typename T, typename S> void VerbosePvs<T, S>::Clear(const bool trim)
[752]494{
495        mEntries.clear();
[1750]496        mSamples = 0;
[1789]497        mLastSorted = 0;
[1786]498
499        if (trim)
500        {
501                vector<PvsEntry<T,S> >().swap(mEntries);
502        }
[752]503}
504
505
[2116]506template <typename T, typename S> void VerbosePvs<T, S>::Trim()
[1750]507{
[1786]508        vector<PvsEntry<T,S> >(mEntries).swap(mEntries);
[1750]509}
510
511
[1189]512template <typename T, typename S>
[2116]513bool VerbosePvs<T, S>::Find(T sample,
[1790]514                                         typename vector<PvsEntry<T, S> >::iterator &it,
515                                         const bool checkDirty)
[310]516{
[2066]517        bool found = false;
[2077]518       
[2066]519        PvsEntry<T, S> dummy(sample, PvsData());
520
521        // only check clean part
522        vector<PvsEntry<T, S> >::iterator sorted_end = mEntries.begin() + mLastSorted;
[2077]523        mQueriesSinceSort++;
[2066]524
525        // binary search
526        it = lower_bound(mEntries.begin(), sorted_end, dummy);
527
528        if ((it != mEntries.end()) && ((*it).mObject == sample))
529                found = true;
530
531        // sample not found yet => search further in the unsorted part
532        if (!found && checkDirty)
533        {
534                vector<PvsEntry<T, S> >::iterator dit, dit_end = mEntries.end();
535
536        for (dit = sorted_end; (dit != dit_end) && ((*dit).mObject != sample); ++ dit);
[1790]537       
[2066]538                if (dit != dit_end)
539                {
540                        found = true;
541                        it = dit;
542                }
543        }
544
545        return found;
[310]546}
547
[1740]548
[1189]549template <typename T, typename S>
[2116]550void VerbosePvs<T, S>::GetData(const int index, T &entry, S &data)
[310]551{
[1740]552        std::vector<PvsEntry<T, S> >::iterator i = mEntries.begin();
[1738]553        for (int k = 0; k != index && i != mEntries.end(); ++ i, ++ k);
[310]554
[1738]555        entry = (*i).first;
556        data = (*i).second;
[310]557}
558
[1738]559
[1189]560template <typename T, typename S>
[2116]561float VerbosePvs<T, S>::AddSample(T sample, const float pdf)
[2071]562{
[1738]563        ++ mSamples;
[1790]564       
565        vector<PvsEntry<T, S> >::iterator it;
566        const bool entryFound = Find(sample, it);               
[1738]567
[1790]568        if (entryFound)
569        {       
[1740]570                S &data = (*it).mData;
571                data.mSumPdf += pdf;
572                return data.mSumPdf;
[1189]573        }
[1738]574        else
[2066]575        {
[1740]576                PvsEntry<T, S> entry(sample, pdf);
577                mEntries.insert(it, entry);
[1789]578                ++ mLastSorted;
[1738]579                return pdf;
[2066]580        }
[466]581}
[177]582
[1189]583
584template <typename T, typename S>
[2116]585void VerbosePvs<T, S>::AddSampleDirty(T sample, const float pdf)
[1757]586{
[1789]587        ++ mSamples;
588        mEntries.push_back(PvsEntry<T, S>(sample, pdf));
[1757]589}
590                                         
591
592template <typename T, typename S>
[2116]593typename vector< PvsEntry<T, S> >::iterator VerbosePvs<T, S>::AddSample2(T sample,
[1790]594                                                                                                                                  const float pdf)
[1184]595{
[1740]596        ++ mSamples;
[1789]597       
[1790]598        vector<PvsEntry<T, S> >::iterator it;
[2066]599        const bool entryFound = Find(sample, it);
[1740]600
[1790]601        if (entryFound)
[1189]602        {
[1740]603                S &data = (*it).second;
604                data->mSumPdf += pdf;
[1189]605        }
[1740]606        else
[1189]607        {
[1740]608                PvsEntry<T, S> entry(sample, pdf);
609                mEntries.insert(it, entry);
[1789]610                ++ mLastSorted;
[1189]611        }
[1740]612
613        return it;
[1184]614}
615
[1740]616
[1789]617template <typename T, typename S>
[2530]618bool VerbosePvs<T, S>::AddSampleDirtyCheck(T sample, const float pdf)
[1789]619{
620        ++ mSamples;
621
[1790]622        vector<PvsEntry<T, S> >::iterator it;
[2066]623        const bool entryFound = Find(sample, it);
[1789]624
[2066]625        if (entryFound)
626        {
627                S &data = (*it).mData;
[1877]628         
[2066]629                data.mSumPdf += pdf;
630        return false;
[1789]631        }
[2066]632        else
633        {
634                AddSampleDirty(sample, pdf);
635                return true;
[1789]636        }
[311]637}
[308]638
[492]639
[1189]640template <typename T, typename S>
[2116]641bool VerbosePvs<T, S>::GetSampleContribution(T sample,
[1740]642                                                                          const float pdf,
643                                                                          float &contribution)
[485]644{
[1790]645        vector<PvsEntry<T, S> >::iterator it;
646        const bool entryFound = Find(sample, it);
[1189]647
[1790]648        if (entryFound) 
[1740]649        {
650                S &data = (*it).mData;
651                contribution = pdf / (data.mSumPdf + pdf);
652                return false;
653        }
654        else
655        {
656                contribution = 1.0f;
657                return true;
658        }
[485]659}
660
[1740]661
[1189]662template <typename T, typename S>
[2116]663bool VerbosePvs<T, S>::RemoveSample(T sample, const float pdf)
[485]664{
[1740]665        -- mSamples;
[1789]666       
[1790]667        vector<PvsEntry<T, S> >::iterator it;
668        const bool entryFound = Find(sample, it);
[1737]669
[1790]670        if (!entryFound)
[1740]671                return false;
672
673        S &data = (*it).mData;
674
675        data.mSumPdf -= pdf;
676
677        if (data.mSumPdf <= 0.0f)
678        {
679                mEntries.erase(it);
[1789]680                -- mLastSorted; // wrong if sample was in tail!!
[1740]681        }
682
683        return true;
[485]684}
[1740]685
686
[1189]687template <typename T, typename S>
[2116]688int VerbosePvs<T, S>::SubtractPvs(const VerbosePvs<T, S> &pvs)
[485]689{
[1738]690        const int samples = mSamples - pvs.mSamples;
[1740]691
692        std::vector<PvsEntry<T, S> >::
[1738]693                const_iterator it, it_end = pvs.mEntries.end();
[1737]694
[1738]695        // output PVS of view cell
696        for (it = pvs.mEntries.begin(); it != it_end; ++ it)
[1740]697                RemoveSample((*it).mObject, (*it).mData.mSumPdf);
[1738]698
699        mSamples = samples;
[1740]700
[1738]701        return GetSize();
[485]702}
703
[1740]704
[1189]705template <typename T, typename S>
[2116]706void VerbosePvs<T, S>::CollectEntries(std::vector<T> &entries)
[469]707{
[1740]708        std::vector<PvsEntry<T, S> >::
[485]709                const_iterator it, it_end = mEntries.end();
[469]710
711        // output PVS of view cell
712        for (it = mEntries.begin(); it != it_end; ++ it)
713                entries.push_back((*it)->first);
714}
715
[1740]716
[1189]717template <typename T, typename S>
[2116]718void VerbosePvs<T, S>::NormalizeMaximum()
[556]719{
[1740]720        std::vector<PvsEntry<T, S> >::
721                const_iterator it, it_end = mEntries.end();
[556]722
[1740]723        float maxPdfSum = -1.0f;
[556]724
[1740]725        // output PVS of view cell
726        for (it = mEntries.begin(); it != it_end; ++ it) {
727                float sum = (*it)->second.sumPdf;
728                if (sum > maxSum)
729                        maxSum = sum;
730        }
[556]731
[1740]732        maxSum = 1.0f / maxSum;
[556]733
[1740]734        for (it = mEntries.begin(); it != it_end; ++ it) {
735                (*it)->second.sumPdf *= maxSum;
736        }
[556]737}
738
739
[1667]740template <typename T, typename S>
[2116]741float VerbosePvs<T, S>::GetEntrySize()
[1667]742{
[1673]743        return (float)(sizeof(T) + sizeof(S)) / float(1024 * 1024);
[1667]744}
745
746
747template <typename T, typename S>
[2116]748int VerbosePvs<T, S>::GetEntrySizeByte()
[1667]749{
750        return sizeof(T) + sizeof(S);
751}
752
753
[1740]754template <typename T, typename S>
[2116]755float VerbosePvs<T, S>::GetPvsHomogenity(VerbosePvs<T, S> &pvs)
[1740]756{
757        float pvsReduction, pvsEnlargement;
758
759        ComputeContinuousPvsDifference(pvs,     pvsReduction, pvsEnlargement);
760        return pvsReduction + pvsEnlargement;
761}
762
763
[1742]764template <typename T, typename S>
[2116]765typename PvsIterator<T, S> VerbosePvs<T, S>::GetIterator() const
[1742]766{
767        PvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
768        return pit;
769}
770
[860]771}
[469]772
[177]773#endif
774
Note: See TracBrowser for help on using the repository browser.