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

Revision 1551, 18.2 KB checked in by mattausch, 18 years ago (diff)

updated view cells loading. probably no optimal for performance

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