source: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h @ 1168

Revision 1168, 18.2 KB checked in by mattausch, 18 years ago (diff)
RevLine 
[372]1#ifndef _ViewCell_H__
2#define _ViewCell_H__
3
4#include "Mesh.h"
5#include "Containers.h"
6#include "Ray.h"
[462]7#include "Statistics.h"
[608]8#include "Material.h"
[955]9#include "gzstream.h"
[469]10
[1010]11
[860]12namespace GtpVisibilityPreprocessor {
13
[469]14struct Triangle3;
15
[372]16class BspInterior;
17class BspPvs;
18class BspLeaf;
[1008]19class VspLeaf;
[469]20class KdLeaf;
[580]21class ViewCellInterior;
22class MergeCandidate;
23class ViewCellsManager;
[881]24class ViewCellLeaf;
[1004]25//class Environment;
[372]26
[955]27
[479]28/** Statistics for a view cell partition.
29*/
30
31class ViewCellsStatistics: public StatisticsBase
32{
33public:
34
35        /// number of view cells
36        int viewCells;
37
38        /// size of the PVS
[613]39        int pvsSize;
[479]40
41        /// largest PVS of all view cells
42        int maxPvs;
43
44        /// smallest PVS of all view cells
45        int minPvs;
46
47        /// view cells with empty PVS
48        int emptyPvs;
49
50        /// number of leaves covering the view space
51        int leaves;
52
53        /// largest number of leaves covered by one view cell
54        int maxLeaves;
55
[564]56        int invalid;
57
[479]58    // Constructor
59        ViewCellsStatistics()
60        {
61                Reset();
62        }
63
64        double AvgLeaves() const {return (double)leaves / (double)viewCells;};
[613]65        double AvgPvs() const {return (double)pvsSize / (double)viewCells;};
[479]66
67        void Reset()
68        {
69                viewCells = 0;
[613]70                pvsSize = 0;
[479]71                maxPvs = 0;
72
73                minPvs = 999999;
74                emptyPvs = 0;
75                leaves = 0;
76                maxLeaves = 0;
[564]77                invalid = 0;
[479]78        }
79
80        void Print(ostream &app) const;
81
82        friend ostream &operator<<(ostream &s, const ViewCellsStatistics &stat)
83        {
84                stat.Print(s);
85                return s;
86        }
87};
88
[580]89
[372]90/**
91        View cell with an optional mesh representation
92*/
[580]93
94
[372]95class ViewCell: public MeshInstance
96{
[752]97        friend class ViewCellsTree;
98        friend class ViewCellsManager;
99
[372]100public:
101        ViewCell();
[471]102
[372]103        /** Constructor taking a mesh representing the shape of the viewcell.
104        */
105        ViewCell(Mesh *mesh);
[462]106
[469]107        /** Default destructor.
108        */
[462]109        virtual ~ViewCell() {}
[580]110
[471]111        /** Returns Pvs.
[372]112        */
[469]113        const ObjectPvs &GetPvs() const;
[752]114
[1002]115        /** Returns pvs.
116        */
[469]117        ObjectPvs &GetPvs();
[372]118
[1002]119        /** Completely substitutes the pvs.
120        */
[880]121        void SetPvs(const ObjectPvs &pvs);
122
[752]123        /** Type of view cells.
124        */
[372]125        int Type() const;
[471]126
[1002]127       
[372]128        /** Adds a passing ray to the passing ray container.
129        */
[471]130        void AddPassingRay(const Ray &ray, const int contributions);
[372]131
[469]132        /** Returns volume of the view cell.
133        */
[478]134        float GetVolume() const;
[372]135
[478]136        /** Returns area of the view cell.
[469]137        */
[478]138        float GetArea() const;
[469]139
[478]140        /** Sets the volume of the view cell.
141        */
142        void SetVolume(float volume);
143       
144        /** Sets the area of the view cell.
145        */
146        void SetArea(float area);
[503]147
[478]148
[580]149        /** if this view cell is the root of a view cell hierarchy
150        */
151        bool IsRoot() const;
[372]152
[580]153        /** Returns parent view cell.
154        */
155        ViewCellInterior *GetParent() const;
[372]156
[1002]157        /** Sets parent of this view cell.
158        */
159        void SetParent(ViewCellInterior *parent);
160
161
[503]162        /** Sets the mesh for this view cell.
163        */
164        void SetMesh(Mesh *mesh);
165
[1002]166        /** Sets this view cell to be a valid view cell according to some criteria.
167        */
[547]168        void SetValid(const bool valid);
[1002]169        /** Returns true if this view cell is considered to be valid according to
170                some criteria.
171        */
[547]172        bool GetValid() const;
173
[728]174        /** Returns estimated render cost of this view cell.
175        */
176        float GetRenderCost() const;
[580]177
[752]178        /** set color for visiualizations.
179        */
180        void SetColor(const RgbColor &color);
[580]181
[752]182        /** get color for visualuzations.
183        */
184    RgbColor GetColor() const;
[580]185
[1002]186        /** Adds a sample to the pvs.
187                @param sample the sample to be added
188                @param pdf a continuos measure of visibility
189                @param contribution returns the contribution of this sample to the pvs
190        */
191        bool AddPvsSample(Intersectable *sample, const float pdf, float &contribution);
[608]192 
[580]193
194        /// Rays piercing this view cell.
195        RayContainer mPiercingRays;
196
197
198        /** if this is a view cell correspending to a leaf in a hierarchy.
199        */
200        virtual bool IsLeaf() const = 0;
201
[752]202        static bool SmallerPvs(const ViewCell *a, const ViewCell *b)
203        {
[997]204                // HACK: take scalar value because pvs may not have been stored properly
205#if 1
206                return a->mPvsSize < b->mPvsSize;
207#else
[1168]208                return a->GetPvs().CountObjectsInPvs() < b->GetPvs().CountObjectsInPvs();
[997]209#endif
210        }
[569]211
[997]212        static bool SmallerRenderCost(const ViewCell *a, const ViewCell *b)
213        {
214                return a->GetRenderCost() < b->GetRenderCost();
215        }
[580]216
[997]217        static bool LargerRenderCost(const ViewCell *a, const ViewCell *b)
218        {
219                return a->GetRenderCost() > b->GetRenderCost();
220        }
[801]221
[1002]222        /** Sets merge cost used for merging this view cell from other cells.
223                @hack The function is available for leaves also to have a common interface,
224                but it should be less than zero for leaves.
225                */
[600]226        void SetMergeCost(const float mergeCost);
[997]227
[1002]228        /** Returns merge cost needed to merge this leaf from other cells.
229                @hack The function is available for leaves also to have a common interface,
230                but it should be less than zero for leaves.
231        */
[600]232        float GetMergeCost() const;
[997]233
[1002]234
235
236        ////////////////////////////////////////////
237        //       mailing stuff
238
239
[997]240        static void NewMail(const int reserve = 1)
241        {
[580]242                sMailId += sReservedMailboxes;
243                sReservedMailboxes = reserve;
244        }
[997]245
[580]246        void Mail() { mMailbox = sMailId; }
247        bool Mailed() const { return mMailbox == sMailId; }
248
249        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
250        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
251
[1145]252        int IncMail() { return ++ mMailbox - sMailId; }
[580]253
254
255        // last mail id -> warning not thread safe!
256        // both mailId and mailbox should be unique for each thread!!!
257        static int sMailId;
258        static int sReservedMailboxes;
259
[609]260       
[372]261protected:
262
[1002]263        /// parent view cell in the view cell hierarchy
264        ViewCellInterior *mParent;
265
[372]266        /// the potentially visible objects
[469]267        ObjectPvs mPvs;
[1160]268        /// the volume of this view cell
[469]269        float mVolume;
[478]270        float mArea;
[1160]271        /// the cost that were paid for merging this view cells from two others.
[600]272        float mMergeCost;
[1160]273        /// if the view cell is valid view space
[547]274        bool mValid;
[608]275
[881]276        /// color used for consistent visualization
[660]277        RgbColor mColor;
[752]278
[1002]279        /// store pvs size, used for evaluation purpose when pvss are stored only in the leaves
[752]280        int mPvsSize;
[1161]281        /** stores number of entries in pvs
282            this variable has the same value as mPvsSize for object pvs,
283                but usually not for kd cell based pvs
284        */
[1160]285        int mEntriesInPvs;
286
[1161]287        /// if the pvs size scalar (+ entries into pvs)
288        /// is up to date and corresponding to the real pvs size
[752]289        bool mPvsSizeValid;
[372]290};
291
[580]292
293class ViewCellInterior: public ViewCell
294{
[752]295        friend class ViewCellsManager;
[580]296public:
297        ViewCellInterior();
298        ~ViewCellInterior();
299
300        ViewCellInterior(Mesh *mesh);
301       
302
303        /** Sets pointer from parent to child and vice versa.
304        */
305        void SetupChildLink(ViewCell *l);
[586]306        void RemoveChildLink(ViewCell *l);
[580]307        bool IsLeaf() const;
308
309        ViewCellContainer mChildren;
310
[608]311  void SetCost(const float c) {
312        mCost = c;
313  }
314  float GetCost() const {
315        return mCost;
316  }
317 
318protected:
319  /** overall cost resulting from the merge */
320  float mCost;
[580]321};
322
[881]323
[469]324/**
[881]325        Leaf of the view cell.
[469]326*/
[580]327class ViewCellLeaf: public ViewCell
[366]328{
329public:
[881]330        ViewCellLeaf()  {  mActiveViewCell = this; }
331        ViewCellLeaf(Mesh *mesh):
332        ViewCell(mesh) { mActiveViewCell = this; }
[469]333
[881]334        bool IsLeaf() const
335        {
336                return true;
337        }
338
339        /** Returns if this view cell is active.
340        */
341        ViewCell *GetActiveViewCell() const
342        { return mActiveViewCell; }
343
344        /** Sets this view cell to be an active view cell.
345        */
346        void SetActiveViewCell(ViewCell *vc)
347        { mActiveViewCell = vc;}
348
[605]349       
[997]350        /** points to the currently active view cell. This is the
351                view cell representing the current brach.
352        */
[881]353        ViewCell *mActiveViewCell;
354};
[479]355
[1121]356/** Leaf of the view cell hierarchy corresponding
357        to a leaf in a spatial hierarchy.
[881]358*/
359template<typename T>
360class HierarchyLeafViewCell: public ViewCellLeaf
361{
362public:
363
364        HierarchyLeafViewCell<T>(): ViewCellLeaf() {  }
365        HierarchyLeafViewCell<T>(Mesh *mesh):
366        ViewCellLeaf(mesh) {  }
367               
368
[580]369        bool IsLeaf() const
370        {
371                return true;
372        }
373
[881]374
[580]375        /// Leaf of some hierarchy which is part of this view cell.
376        T mLeaf;
[469]377};
378
[479]379
[1010]380typedef HierarchyLeafViewCell<VspLeaf *> VspViewCell;
[881]381typedef HierarchyLeafViewCell<BspLeaf *> BspViewCell;
382typedef HierarchyLeafViewCell<KdLeaf *> KdViewCell;
[469]383
[366]384
[580]385
[1008]386
[580]387class ViewCellsTree
388{
[600]389        friend class ViewCellsManager;
[752]390
391
[580]392public:
[1004]393        /** View cells tree constructor taking a view cell mnanager as parameter
[997]394        */
[1004]395        ViewCellsTree(ViewCellsManager *vcm);
[580]396        ~ViewCellsTree();
397
398        /** Returns number of leaves this view cell consists of.
399        */
[736]400        int GetNumInitialViewCells(ViewCell *vc) const;
[580]401
402        /** Collects leaves corresponding to a view cell.
403        */
404        void CollectLeaves(ViewCell *vc, ViewCellContainer &leaves) const;
405
406        /** Merges view cells according to some cost heuristics.
407        */
408        int ConstructMergeTree(const VssRayContainer &rays, const ObjectContainer &objects);
409       
410        /** Refines view cells using shuffling, i.e., border leaves
411                of two view cells are exchanged if the resulting view cells
412                are tested to be "better" than the old ones.
413                @returns number of refined view cells
414        */
415        int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
[651]416       
417        /** Assign colors to the viewcells so that they can be renderered interactively without
[997]418            color flickering. 
419        */
[651]420        void AssignRandomColors();
[580]421
[997]422        /** Updates view cell stats for this particular view cell.
[605]423        */
424        void UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat);
[580]425
[997]426        /** Get costs resulting from each merge step.
427        */
[651]428        void GetCostFunction(vector<float> &costFunction);
[608]429 
[580]430        /** Returns optimal set of view cells for a given number of view cells.
431        */
432        void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
433
[581]434        /** Root of view cells tree.
435        */
[584]436        ViewCell *GetRoot() const;
[581]437
[584]438        /** Returns pvs of view cell.
439                @note pvs is returned per reference if tree is not compressed,
440                per copy else.
441        */
442        void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
443
[1161]444        /** Returns pvs size (i.e. the number of stored objects
[584]445        */
[1142]446        int GetPvsSize(ViewCell *vc) const;
[584]447
[1161]448        /** Returns number of entries associated with this view cell.
449                This returns the same value as the GetPvsSize function for object pvs,
450                but most likely different values for kd node based pvs.
[584]451        */
[1161]452        int GetPvsEntries(ViewCell *vc) const;
[584]453
[1161]454        /** Returns the actual number of stored entries in the view cells sub tree.
455        */
456        int GetStoredPvsEntriesNum(ViewCell *root) const;
457
[584]458        /** Returns memory cost of this view cell.
459        */
460        float GetMemoryCost(ViewCell *vc) const;
461
[752]462        /** Sets method of storage for view cells.
[584]463        */
[752]464        void SetViewCellsStorage(int type);
[584]465
[837]466        /** pvs storage methods
467        */
[752]468        enum {PVS_IN_INTERIORS, COMPRESSED, PVS_IN_LEAVES};
469
[840]470       
[584]471        /** If view cells in this tree have compressed pvs.
472        */
[752]473        int ViewCellsStorage() const;
[584]474
[660]475        /** Returns active view cell that is in the path of this view cell.
476        */
[881]477        ViewCell *GetActiveViewCell(ViewCellLeaf *vc) const;
[590]478
[660]479        /** Sets the leaves to be the currently active view cells.
480        */
481    void SetActiveSetToLeaves();
482
[651]483        /** Propagates pvs up the tree to the root and downwards the tree.
[610]484        */
[651]485        void PropagatePvs(ViewCell *vc);
[610]486
[837]487        /** Exports view cells to file.
488        */
[971]489#if ZIPPED_VIEWCELLS
490        bool Export(ogzstream &stream, const bool exportPvs = false);
491#else
[955]492        bool Export(ofstream &stream, const bool exportPvs = false);
[971]493#endif
[610]494
[649]495        /** Export statistics of this view cell tree.
496        */
[660]497        void ExportStats(const string &mergeStats);
[610]498
[650]499        /** Sets root of hierarchy.
500        */
501        void SetRoot(ViewCell *root);
502
503        //float ComputeVolume(ViewCell *vc);
504
[651]505        /** Assignes unique ids to view cells.
506        */
507        void CreateUniqueViewCellsIds();
508
[660]509        /** Resets pvs of whole tree.
510        */
511        void ResetPvs();
[651]512
[1121]513        /** Counts pvs of the view cell taking the kd cells into account.
514        */
515        int CountKdPvs(const ViewCellLeaf *vc) const;
516
[580]517protected:
518
519
[997]520        /////////////////////////////////////////////////////////////////
521        //                    merge related stuff                      //
522        /////////////////////////////////////////////////////////////////
[580]523
[729]524        /** Computes render cost of the merged pvs.
525        */
526        float ComputeMergedPvsCost(const ObjectPvs &pvs1, const ObjectPvs &pvs2) const;
527
[580]528        /** Returns cost of this leaf according to current heuristics.
529        */
530        float GetCostHeuristics(ViewCell *vc) const;
531
532        /** Returns cost of leaf.
533        */
534        float GetRenderCost(ViewCell *vc) const;
535
536        /** Evaluates the merge cost of this merge candidate pair.
537        */
538        void EvalMergeCost(MergeCandidate &mc) const;
539
540        /** Variance of leaf.
541        */
542        float GetVariance(ViewCell *vc) const;
543
544        /** Standard deviation of leaf.
545        */
546        float GetDeviation(ViewCell *vc) const;
547
[582]548        /** Tries to set this merge candidate to valid.
549                @returns false if both view cells are the same
[580]550        */
[582]551        bool ValidateMergeCandidate(MergeCandidate &mc) const;
[580]552
553        /** Merge view cells of leaves l1 and l2.
554                @returns difference in pvs size
555        */
556        ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, int &pvsDiff); //const;
557
558        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
559                to view cell 2.
560        */
[586]561        void ShuffleLeaf(ViewCell *leaf, ViewCellInterior *vc1, ViewCellInterior *vc2) const;   
[580]562               
563        /** Shuffles the leaves, i.e., tests if exchanging
564                the leaves helps in improving the view cells.
565        */
[586]566        bool ShuffleLeaves(MergeCandidate &mc) const;
[580]567
568        /** Calculates cost for merge of view cell 1 and 2.
569        */
[586]570        float EvalShuffleCost(ViewCell *leaf,
571                                                  ViewCellInterior *vc1,
572                                                  ViewCellInterior *vc2) const;
[580]573
574        /** Exports a snapshot of the merged view cells to disc.
575        */
576        void ExportMergedViewCells(ViewCellContainer &viewCells,
577                                                           const ObjectContainer &objects,
578                                                           const int numNewViewCells);
579
[997]580        /** Merge queue must be reset after some time because expected value
[580]581                may not be valid.
582        */
583        void ResetMergeQueue();
584
585        /** Updates the current top level of view cells.
[582]586                @returns number of newly merged view cells
[580]587        */
[582]588        int UpdateActiveViewCells(ViewCellContainer &viewCells);
[580]589
[997]590        /** Helper function pullling pvs as high up in the tree as possible.
591        */
[610]592        void PullUpVisibility(ViewCellInterior *interior);
[580]593
[997]594        /** Compress pvs of view cell and children.
595        */
[584]596        void CompressViewCellsPvs(ViewCell *root);
[580]597
[582]598        /** Returns memory usage of view cells.
599        */
600        float GetMemUsage() const;
[837]601
602        /**     Exports single view cell.
[610]603                NOTE: should be in exporter!!
604        */
[971]605#if ZIPPED_VIEWCELLS
606        void ExportViewCell(ViewCell *viewCell, ogzstream &stream, const bool exportPvs);
607#else
608        void ExportViewCell(ViewCell *viewCell, ofstream &stream, const bool exportPvs);       
609#endif
[581]610
[837]611        /** Exports pvs of a view cell.
612        */
[971]613#if ZIPPED_VIEWCELLS
614        void ExportPvs(ViewCell *viewCell, ogzstream &stream);
615#else
[840]616        void ExportPvs(ViewCell *viewCell, ofstream &stream);
[971]617#endif
[582]618
[1166]619        int GetEntriesInPvsForCompressedStorage(ViewCell *vc) const;
620        int GetPvsSizeForCompressedStorage(ViewCell *vc) const;
621        int GetPvsSizeForLeafStorage(ViewCell *vc) const;
622        int GetEntriesInPvsForLeafStorage(ViewCell *vc) const;
[610]623
[1166]624        void UpdateStats(
625                ofstream &stats,
626                const int pass,
627                const int viewCells,
628                const float renderCostDecrease,
629                const float totalRenderCost,
630                const int currentPvs,
631                const float expectedCost,
632                const float avgRenderCost,
633                const float deviation,
634                const int totalPvs,
635                const int entriesInPvs,
636                const int pvsSizeDecr,
637                const float volume);
638
[584]639        /// if the view cell tree hold compressed pvs
[752]640        int mViewCellsStorage;
[582]641
[580]642        ViewCellsManager *mViewCellsManager;
643        ViewCell *mRoot;
644
645        /// if merge visualization should be shown
646        bool mExportMergedViewCells;
647
648       
[837]649        /// intermediate container of merged view cells.
[582]650        ViewCellContainer mMergedViewCells;
651       
[580]652
[837]653        /// if merged view cells are refined.
[586]654        bool mRefineViewCells;
655
[580]656        /// weights between variance and render cost increase (must be between zero and one)
657        float mRenderCostWeight;
658
659        /// overall cost used to normalize cost ratio
660        float mOverallCost;
661        float mExpectedCost;
662    float mDeviation;
663        float mAvgRenderCost;
[837]664        /// the area is used for pvs heuristics
[580]665        int mUseAreaForPvs;
666
[582]667        int mNumActiveViewCells;
[580]668
669        /// minimal number of view cells
670        int mMergeMinViewCells;
671        /// maximal cost ratio for the merge
672        float mMergeMaxCostRatio;
673
674        typedef priority_queue<MergeCandidate> MergeQueue;
675
676        MergeQueue mMergeQueue;
677
[582]678        float mMaxMemory;
[580]679
[938]680        int mMaxMergesPerPass;
681        float mAvgCostMaxDeviation;
[580]682};
683
684
685/**
686        Candidate for leaf merging based on priority.
687*/
688class MergeCandidate
689
690        friend class ViewCellsTree;
691
692public:
693
694        MergeCandidate(ViewCell *l, ViewCell *r);
695
696        /** If this merge pair is still valid.
697        */
698        bool IsValid() const;
699
700       
701        friend bool operator<(const MergeCandidate &leafa, const MergeCandidate &leafb)
702        {
703                return leafb.GetMergeCost() < leafa.GetMergeCost();
704        }
705
706        void SetLeftViewCell(ViewCell *l);
707        void SetRightViewCell(ViewCell *l);
708
709        ViewCell *GetLeftViewCell() const;
710        ViewCell *GetRightViewCell() const;
711
[703]712        /** Returns leaf view cell initially associated with this merge candidate.
713        */
[580]714        ViewCell *GetInitialLeftViewCell() const;
[1133]715        /** Returns leaf view cell initially associated with this merge candidate.
716        */
[580]717        ViewCell *GetInitialRightViewCell() const;
718
719        /** Returns the increase of the standard deviation of this merge candidate.
720        */
721        float GetDeviationIncr() const;
722
723        /** Merge cost of this candidate pair.
724        */
725        float GetMergeCost() const;
726
727        /** Render cost of this candidate.
728        */
729        float GetRenderCost() const;
730       
731        static float sRenderCostWeight;
732
733protected:
734
735        /// render cost increase by this merge
736        float mRenderCost;
737        /// increase / decrease of standard deviation
738        float mDeviationIncr;
739
740        ViewCell *mLeftViewCell;
741        ViewCell *mRightViewCell;
742
743        ViewCell *mInitialLeftViewCell;
744        ViewCell *mInitialRightViewCell;
745};
746
747
748class MergeStatistics: public StatisticsBase
749{
750public:
751       
752        int merged;
753        int siblings;
754        int candidates;
755        int nodes;
756
757        int accTreeDist;
758        int maxTreeDist;
759       
760        Real collectTime;
761        Real mergeTime;
762
763        Real overallCost;
764
765        Real expectedRenderCost;
766        Real deviation;
767        Real heuristics;
768
769        // Constructor
770        MergeStatistics()
771        {
772                Reset();
773        }
774       
775        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
776
777        void Reset()
778        {
779                nodes = 0;
780                merged = 0;
781                siblings = 0;
782                candidates = 0;
783       
784                accTreeDist = 0;
785                maxTreeDist = 0;
786
787                collectTime = 0;
788                mergeTime = 0;
789                overallCost = 0;
790
791                expectedRenderCost = 0;
792                deviation = 0;
793                heuristics = 0;
794
795        }
796
797        void Print(ostream &app) const;
798
799        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
800        {
801                stat.Print(s);
802                return s;
803        }
804};
805
[860]806}
807
[372]808#endif
Note: See TracBrowser for help on using the repository browser.