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

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