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

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