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

Revision 1842, 20.1 KB checked in by mattausch, 18 years ago (diff)

fixed compress

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                @contribution contribution of sample (0 or 1)
216                @returns true if sample was not already in PVS.
217        */
[1789]218        //bool AddSample(T sample, const float pdf, float &contribution);
[677]219
[1706]220        /** Adds sample to PVS.
221                @returns contribution of sample (0 or 1)
222        */
223        float AddSample(T sample, const float pdf);
[1757]224
[1789]225        /** Adds sample to PVS without checking for presence of the sample
226                pvs remains unsorted!
227        */
228        void AddSampleDirty(T sample, const float pdf);
[1757]229
[1789]230        /** Adds sample dirty (on the end of the vector) but
231                first checks if sample is already in clean part of the pvs.
232        */
233        bool AddSampleDirtyCheck(T sample, const float pdf);//, float &contribution);
234
235        /** Sort pvs entries - this should always be called after a
236                sequence of AddSampleDirty calls
237        */
238        void Sort();
239
[1742]240        /** Adds sample to PVS. Assumes that the pvs is sorted
[1740]241                @returns contribution of sample (0 or 1)
242        */
243        float AddSamples(const vector<PvsEntry<T, S> > &samples);
[752]244
[1706]245        /** Adds sample to PVS.
246                @returns PvsData
247        */
[1740]248        typename std::vector<PvsEntry<T, S> >::iterator AddSample2(T sample, const float pdf);
[1667]249
[1706]250        /** Subtracts one pvs from another one.
251                WARNING: could contains bugs
252                @returns new pvs size
253        */
254        int SubtractPvs(const Pvs<T, S> &pvs);
[1740]255
[1706]256        /** Returns PVS data, i.e., how often it was seen from the view cell,
257                and the object itsef.
258        */
259        void GetData(const int index, T &entry, S &data);
260
261        /** Collects the PVS entries and returns them in the vector.
262        */
263        void CollectEntries(std::vector<T> &entries);
264
265        /** Removes sample from PVS if reference count is zero.
266                @param visibleSamples number of references to be removed
267        */
268        bool RemoveSample(T sample, const float pdf);
269
270        /** Compute continuous PVS difference
271        */
[1740]272        void ComputeContinuousPvsDifference(Pvs<T, S> &pvs,
273                                                                                float &pvsReduction,
274                                                                                float &pvsEnlargement);
[1706]275
276        /** Clears the pvs.
277        */
[1750]278        void Clear(const bool trim = true);
[1706]279
[1750]280        void Trim();
281
[1706]282        static int GetEntrySizeByte();
283        static float GetEntrySize();
284
[1740]285        /** Compute continuous PVS difference
286        */
287        float GetPvsHomogenity(Pvs<T, S> &pvs);
[1706]288
[1740]289        static void Merge(Pvs<T, S> &mergedPvs, const Pvs<T, S> &a, const Pvs<T, S> &b);
[1706]290
[1789]291        static void Merge(Pvs<T, S> &mergedPvs,
292                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aBegin,
293                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aEnd,
294                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bBegin,
295                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bEnd,
296                                          const int aSamples,
297                                          const int bSamples);
298
[1742]299        int GetSamples() const
300        {
301                return mSamples;
302        }
[1738]303
[1789]304
305        bool IsDirty() const
306        {
307                return mLastSorted < mEntries.size();
308        }
309
310        bool RequiresResort() const
311        {
312                // the last part should not be more than log of the sorted part. this
313                // way we can achieve logarithmic behaviour for insertion and find
314                const int dirtySize = (int)mEntries.size() - mLastSorted;
315                return dirtySize > (int)(log((double)mEntries.size()) / log(2.0));
316        }
317
318
319        int GetLastSorted() const
320        {
321                return mLastSorted;
322        }
323
[1742]324        typename PvsIterator<T, S> GetIterator() const;
325
326protected:
327
[1738]328        /// vector of PVS entries
[1740]329        vector<PvsEntry<T, S> > mEntries;
[1736]330       
331        /// Number of samples used to create the PVS
332        int mSamples;
[1757]333 
[1789]334        /// Last sorted entry in the pvs (important for find and merge)
335        int mLastSorted; 
[310]336};
337
[581]338
[1740]339template <typename T, typename S>
340Pvs<T, S>::Pvs(const vector<PvsEntry<T, S> > &samples)
341{
342        mEntries.reserve(samples.size());
343        mEntries = samples;
[1757]344        mLastSorted = 0;
[1789]345        mSamples = samples.size();
[1740]346}
[677]347
[1789]348
[1757]349template <typename T, typename S>
350void Pvs<T, S>::Sort()
351{
[1789]352        std::vector<PvsEntry<T, S> >::iterator it = mEntries.begin() + mLastSorted;
353        //std::vector<PvsEntry<T, S> >::const_iterator it = mEntries.begin() + mLastSorted;
354        std::vector<PvsEntry<T, S> >::iterator it_end = mEntries.end();
355
356        // throw out double entries
357        std::vector<PvsEntry<T, S> >::iterator newEnd = unique(it, it_end);
358        sort(it, newEnd);
359        //sort(mEntries.begin(), mEntries.end());
360
361        // now merge sorted ranges
362        ObjectPvs newPvs;
363        Merge(newPvs,
364                  mEntries.begin(), it,
365                  it, newEnd,
366                  mSamples, 0);
367       
368        mEntries = newPvs.mEntries;
369        mLastSorted = (int)mEntries.size();
[1757]370}
[1740]371
[1789]372
[695]373/**
374   Compute continuous PVS difference of 'b' with respect to the base PVS (*this).
375   Provides separatelly PVS reduction from PVS enlargement.
376
377*/
[1189]378template <typename T, typename S>
[677]379void
[1189]380Pvs<T, S>::ComputeContinuousPvsDifference(Pvs<T, S> &b,
[1740]381                                                                                  float &pvsReduction,
382                                                                                  float &pvsEnlargement)
[677]383{
[705]384        pvsReduction = 0.0f;
385        pvsEnlargement = 0.0f;
[1740]386
[1738]387        // Uses sum of log differences, which corresponds to entropy
[1740]388        std::vector<PvsEntry<T, S> >::iterator it;
[1738]389
390        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
[1189]391        {
[1740]392                float bSumPdf = (*it).mData.mSumPdf;
[1738]393                float aSumPdf = 0.0f;
[713]394
[1790]395                vector<PvsEntry<T, S> >::iterator oit;
396                const bool entryFound = Find((*it).mObject, oit);               
[1740]397
398                if (entryFound)
[1738]399                {
[1740]400                        aSumPdf = (*it).mData.mSumPdf;
401
[1738]402                        // mark this entry as processed to avoid double counting
[1740]403                        (*it).mData.mSumPdf = -aSumPdf;
[1738]404                }
405
[713]406#if 0
[1740]407                const float diff = bSumPdf - aSumPdf;
[1738]408
409                if (diff > 0.0f) {
410                        pvsEnlargement += diff;
411                } else {
412                        pvsReduction += -diff;
413                }
[713]414#else
[1740]415                if (!entryFound)
[1738]416                        pvsEnlargement += 1.0f;
[713]417#endif
[1738]418        }
419
[1740]420        for (it = mEntries.begin(); it != mEntries.end(); ++ it)
421        {
422                float aSumPdf = (*it).mData.mSumPdf;
[1738]423                float bSumPdf = 0.0f;
424                if (aSumPdf < 0.0f) {
[1740]425               
[1738]426                        // this entry was already accounted for!
427                        // just revert it back
[1740]428                        (*it).mData.mSumPdf = -aSumPdf;
[1738]429                } else {
[1790]430                        vector<PvsEntry<T, S> >::iterator oit;
431               
432                        const bool entryFound = b.Find((*it).mObject, oit);
433                                               
[1740]434                        if (entryFound) {
435                                bSumPdf = (*oit).mData.mSumPdf;
[1738]436                        }
[713]437#if 0
[1740]438                        const float diff = bSumPdf - aSumPdf;
[713]439
[1738]440                        if (diff > 0.0f) {
441                                pvsEnlargement += diff;
442                        } else {
443                                pvsReduction += -diff;
444                        }
445
[713]446#else
[1740]447                        if (!entryFound)
[1738]448                                pvsReduction += 1.0f;
[713]449#endif
[1738]450                }
[695]451        }
[677]452}
453
[1738]454
[1189]455template <typename T, typename S>
456int Pvs<T, S>::Diff(const Pvs<T, S> &b)
[362]457{
458        int dif = 0;
459
[1740]460        std::vector<PvsEntry<T, S> >::const_iterator it;
[362]461
462        for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
463        {
[1790]464                vector<PvsEntry<T, S> >::iterator bit;
465                const bool entryFound = Find((*it).first, bit);
466
467                if (!entryFound) ++ dif;
[362]468        }
469
470        return dif;
471}
472
[1740]473
474template <typename T, typename S>
475void Pvs<T, S>::MergeInPlace(const Pvs<T, S> &a)
[341]476{
[1786]477        // early exit
478        if (a.Empty())
479        {
480                return;
481        }
482        else if (Empty())
483        {
484                mEntries.reserve(a.GetSize());
485                mEntries = a.mEntries;
486                mSamples = a.mSamples;
487                return;
488        }
489
[1740]490        ObjectPvs interPvs;
491       
492        Merge(interPvs, *this, a);
493       
494        mEntries.reserve(interPvs.GetSize());
495        mEntries = interPvs.mEntries;
[1751]496        mSamples = interPvs.mSamples;
[1740]497}
498
499
500template <typename T, typename S>
501void Pvs<T, S>::Merge(Pvs<T, S> &mergedPvs, const Pvs<T, S> &a, const Pvs<T, S> &b)
502{
503        std::vector<PvsEntry<T, S> >::const_iterator ait = a.mEntries.begin(), ait_end = a.mEntries.end();
504        std::vector<PvsEntry<T, S> >::const_iterator bit = b.mEntries.begin(), bit_end = b.mEntries.end();
[1741]505       
[1789]506        Merge(mergedPvs,
507                  ait, ait_end,
508                  bit, bit_end,
509                  a.mSamples,
510                  b.mSamples);
511}
512
513
514template <typename T, typename S>
515void Pvs<T, S>::Merge(Pvs<T, S> &mergedPvs,
516                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aBegin,
517                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &aEnd,
518                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bBegin,
519                                          const typename std::vector<PvsEntry<T, S> >::const_iterator &bEnd,
520                                          const int aSamples,
521                                          const int bSamples)
522{
523        std::vector<PvsEntry<T, S> >::const_iterator ait = aBegin;
524        std::vector<PvsEntry<T, S> >::const_iterator bit = bBegin;
525       
526        for (; (ait != aEnd); ++ ait)
[1741]527        {
528                Intersectable *aObj = (*ait).mObject;
529                Intersectable *bObj = NULL;
[1789]530                //Intersectable *bObjOld = NULL;
531       
532                const PvsEntry<T, S> &aEntry = (*ait);
[1740]533
[1789]534                for (; (bit != bEnd) && ((*bit).mObject <= (*ait).mObject); ++ bit)
[1741]535                {
536                        bObj = (*bit).mObject;
537
538                        // object found => add up probabilities
[1742]539                        if (bObj == aEntry.mObject)
[1741]540                        {
541                                PvsData newData(aEntry.mData.mSumPdf + (*bit).mData.mSumPdf);
542                                PvsEntry<T, S> entry(bObj, newData);
543                                mergedPvs.mEntries.push_back(entry);
544                        }
545                        else
546                        {
547                                mergedPvs.mEntries.push_back(*bit);
548                        }
[1789]549                       
550                        //bObjOld = bObj;
[1741]551                }
552
553                // only push back if objects different
554                // (equal case is handled by second loop)
555                if (aObj != bObj)
556                {
557                        mergedPvs.mEntries.push_back(*ait);
558                }
559        }
560
561        // add the rest
[1789]562        for (; (bit != bEnd); ++ bit)
[1740]563        {
[1741]564                mergedPvs.mEntries.push_back(*bit);
565        }
[1789]566
567        mergedPvs.mSamples = aSamples + bSamples;
[1740]568}
569
570
[1750]571template <typename T, typename S> void Pvs<T, S>::Clear(const bool trim = true)
[752]572{
573        mEntries.clear();
[1750]574        mSamples = 0;
[1789]575        mLastSorted = 0;
[1786]576
577        if (trim)
578        {
579                vector<PvsEntry<T,S> >().swap(mEntries);
580        }
[752]581}
582
583
[1750]584template <typename T, typename S> void Pvs<T, S>::Trim()
585{
[1786]586        vector<PvsEntry<T,S> >(mEntries).swap(mEntries);
[1750]587}
588
589
[1189]590template <typename T, typename S>
[1790]591bool Pvs<T, S>::Find(T sample,
592                                         typename vector<PvsEntry<T, S> >::iterator &it,
593                                         const bool checkDirty)
[310]594{
[1790]595        bool found = false;
596
[1740]597        PvsEntry<T, S> dummy(sample, PvsData());
[1789]598
599        // only check clean part
600        //mLastSorted = 0;
601        vector<PvsEntry<T, S> >::iterator sorted_end = mEntries.begin() + mLastSorted;
[1790]602
[1789]603        // binary search
[1790]604        it = lower_bound(mEntries.begin(), sorted_end, dummy);
[1789]605
[1790]606        if ((it != mEntries.end()) && ((*it).mObject == sample))
607                found = true;
608
[1789]609        // sample not found yet => search further in the unsorted part
[1790]610        if (!found && checkDirty)
[1789]611        {
[1790]612                vector<PvsEntry<T, S> >::const_iterator dit, dit_end = mEntries.end();
613
614                for (dit = sorted_end; (dit != dit_end) && ((*dit).mObject != sample); ++ dit);
615
616                if ((dit != mEntries.end()) && ((*dit).mObject == sample))
617                        found = true;
[1789]618        }
[1790]619       
620        return found;
[310]621}
622
[1740]623
[1189]624template <typename T, typename S>
[1740]625void Pvs<T, S>::GetData(const int index, T &entry, S &data)
[310]626{
[1740]627        std::vector<PvsEntry<T, S> >::iterator i = mEntries.begin();
[1738]628        for (int k = 0; k != index && i != mEntries.end(); ++ i, ++ k);
[310]629
[1738]630        entry = (*i).first;
631        data = (*i).second;
[310]632}
633
[1738]634
[1189]635template <typename T, typename S>
[1740]636float Pvs<T, S>::AddSample(T sample, const float pdf)
[177]637{
[1738]638        ++ mSamples;
[1790]639       
640        vector<PvsEntry<T, S> >::iterator it;
641        const bool entryFound = Find(sample, it);               
[1738]642
[1790]643        if (entryFound)
644        {       
[1740]645                S &data = (*it).mData;
646                data.mSumPdf += pdf;
647                return data.mSumPdf;
[1189]648        }
[1738]649        else
[1790]650        {
[1740]651                PvsEntry<T, S> entry(sample, pdf);
652                mEntries.insert(it, entry);
[1789]653                ++ mLastSorted;
[1738]654                return pdf;
[1189]655        }
[466]656}
[177]657
[1189]658
659template <typename T, typename S>
[1757]660void Pvs<T, S>::AddSampleDirty(T sample, const float pdf)
661{
[1789]662        ++ mSamples;
663        mEntries.push_back(PvsEntry<T, S>(sample, pdf));
[1757]664}
665                                         
666
667template <typename T, typename S>
[1790]668typename vector< PvsEntry<T, S> >::iterator Pvs<T, S>::AddSample2(T sample,
669                                                                                                                                  const float pdf)
[1184]670{
[1740]671        ++ mSamples;
[1789]672       
[1790]673        vector<PvsEntry<T, S> >::iterator it;
674        const bool entryFound == Find(sample, it);
[1740]675
[1790]676        if (entryFound)
[1189]677        {
[1740]678                S &data = (*it).second;
679                data->mSumPdf += pdf;
[1189]680        }
[1740]681        else
[1189]682        {
[1740]683                PvsEntry<T, S> entry(sample, pdf);
684                mEntries.insert(it, entry);
[1789]685                ++ mLastSorted;
[1189]686        }
[1740]687
688        return it;
[1184]689}
690
[1740]691
[1789]692/** Adds sample dirty (on the end of the vector) but
693        first checks if sample is already in clean part of the pvs.
694*/
695template <typename T, typename S>
696bool Pvs<T, S>::AddSampleDirtyCheck(T sample,
697                                                                        const float pdf)
698                                                                        //,float &contribution)
699{
700        ++ mSamples;
701
[1790]702        vector<PvsEntry<T, S> >::iterator it;
703        const bool entryFound = Find(sample, it);
[1789]704
[1790]705        if (entryFound)
[1789]706        {
707                S &data = (*it).mData;
708
709                data.mSumPdf += pdf;
710                //contribution = pdf / data.mSumPdf;
711
712                return false;
713        }
714        else
715        {
716                AddSampleDirty(sample, pdf);
717                //contribution = 1.0f;
718
719                return true;
720        }
[311]721}
[308]722
[492]723
[1189]724template <typename T, typename S>
[1740]725bool Pvs<T, S>::GetSampleContribution(T sample,
726                                                                          const float pdf,
727                                                                          float &contribution)
[485]728{
[1790]729        vector<PvsEntry<T, S> >::iterator it;
730        const bool entryFound = Find(sample, it);
[1189]731
[1790]732        if (entryFound) 
[1740]733        {
734                S &data = (*it).mData;
735                contribution = pdf / (data.mSumPdf + pdf);
736                return false;
737        }
738        else
739        {
740                contribution = 1.0f;
741                return true;
742        }
[485]743}
744
[1740]745
[1189]746template <typename T, typename S>
[1740]747bool Pvs<T, S>::RemoveSample(T sample, const float pdf)
[485]748{
[1740]749        -- mSamples;
[1789]750       
[1790]751        vector<PvsEntry<T, S> >::iterator it;
752        const bool entryFound = Find(sample, it);
[1737]753
[1790]754        if (!entryFound)
[1740]755                return false;
756
757        S &data = (*it).mData;
758
759        data.mSumPdf -= pdf;
760
761        if (data.mSumPdf <= 0.0f)
762        {
763                mEntries.erase(it);
[1789]764                -- mLastSorted; // wrong if sample was in tail!!
[1740]765        }
766
767        return true;
[485]768}
[1740]769
770
[1189]771template <typename T, typename S>
772int Pvs<T, S>::SubtractPvs(const Pvs<T, S> &pvs)
[485]773{
[1738]774        const int samples = mSamples - pvs.mSamples;
[1740]775
776        std::vector<PvsEntry<T, S> >::
[1738]777                const_iterator it, it_end = pvs.mEntries.end();
[1737]778
[1738]779        // output PVS of view cell
780        for (it = pvs.mEntries.begin(); it != it_end; ++ it)
[1740]781                RemoveSample((*it).mObject, (*it).mData.mSumPdf);
[1738]782
783        mSamples = samples;
[1740]784
[1738]785        return GetSize();
[485]786}
787
[1740]788
[1189]789template <typename T, typename S>
790void Pvs<T, S>::CollectEntries(std::vector<T> &entries)
[469]791{
[1740]792        std::vector<PvsEntry<T, S> >::
[485]793                const_iterator it, it_end = mEntries.end();
[469]794
795        // output PVS of view cell
796        for (it = mEntries.begin(); it != it_end; ++ it)
797                entries.push_back((*it)->first);
798}
799
[1740]800
[1189]801template <typename T, typename S>
802void Pvs<T, S>::NormalizeMaximum()
[556]803{
[1740]804        std::vector<PvsEntry<T, S> >::
805                const_iterator it, it_end = mEntries.end();
[556]806
[1740]807        float maxPdfSum = -1.0f;
[556]808
[1740]809        // output PVS of view cell
810        for (it = mEntries.begin(); it != it_end; ++ it) {
811                float sum = (*it)->second.sumPdf;
812                if (sum > maxSum)
813                        maxSum = sum;
814        }
[556]815
[1740]816        maxSum = 1.0f / maxSum;
[556]817
[1740]818        for (it = mEntries.begin(); it != it_end; ++ it) {
819                (*it)->second.sumPdf *= maxSum;
820        }
821
[556]822}
823
824
[1667]825template <typename T, typename S>
826float Pvs<T, S>::GetEntrySize()
827{
[1673]828        return (float)(sizeof(T) + sizeof(S)) / float(1024 * 1024);
[1667]829}
830
831
832template <typename T, typename S>
833int Pvs<T, S>::GetEntrySizeByte()
834{
835        return sizeof(T) + sizeof(S);
836}
837
838
[1740]839template <typename T, typename S>
840float Pvs<T, S>::GetPvsHomogenity(Pvs<T, S> &pvs)
841{
842        float pvsReduction, pvsEnlargement;
843
844        ComputeContinuousPvsDifference(pvs,     pvsReduction, pvsEnlargement);
845
846        return pvsReduction + pvsEnlargement;
847}
848
849
[1742]850template <typename T, typename S>
851typename PvsIterator<T, S> Pvs<T, S>::GetIterator() const
852{
853        PvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
854
855        return pit;
856}
857
858
[1667]859///////////////////////////////////////
860
[311]861/** Class instantiating the Pvs template for kd tree nodes.
862*/
[1189]863class KdPvs: public Pvs<KdNode *, PvsData>
[308]864{
[1141]865public:
[311]866        int Compress();
[308]867};
868
[1077]869
[1842]870////////////
871//-- typedefs
872
873typedef PvsEntry<Intersectable *, PvsData> ObjectPvsEntry;
874typedef std::vector<ObjectPvsEntry> ObjectPvsEntries;
875typedef Pvs<ViewCell *, MailablePvsData> ViewCellPvs;
876typedef PvsIterator<Intersectable *, PvsData> ObjectPvsIterator;
877
878
[1189]879class ObjectPvs: public Pvs<Intersectable *, PvsData>
[1141]880{
881public:
[1586]882        /** Counts object int the pvs. Different to method "GetSize", not
[1141]883                only the raw container size is returned,
884                but the individual contributions of the entries are summed up.
885        */
[1707]886        float EvalPvsCost() const;
[1842]887
888        friend ostream &operator<<(ostream &s, const ObjectPvs &p)
889        {
890                ObjectPvsIterator pit = p.GetIterator();
891
892                while (pit.HasMoreEntries())
893                {               
894                        const ObjectPvsEntry &entry = pit.Next();
895                        Intersectable *obj = entry.mObject;
896
897                        cout << (int)obj << " ";
898                }
899               
900                return s;
901        }
902
[1141]903};
904
[1586]905
[1077]906
[860]907}
[469]908
[177]909#endif
910
Note: See TracBrowser for help on using the repository browser.