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

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