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

Revision 2100, 21.1 KB checked in by mattausch, 17 years ago (diff)

worked on pvs

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