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

Revision 1845, 19.9 KB checked in by mattausch, 18 years ago (diff)

improved object pvs

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