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

Revision 810, 14.2 KB checked in by mattausch, 19 years ago (diff)

added from point visibility tree:
this tree is constructed using from point visibility information

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