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

Revision 971, 15.4 KB checked in by mattausch, 18 years ago (diff)

added stuff for view cell ziping (not working yet!)

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