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

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