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

Revision 752, 14.0 KB checked in by mattausch, 19 years ago (diff)

after rendering workshop submissioin
x3dparser can use def - use constructs
implemented improved evaluation (samples are only stored in leaves, only propagate pvs size)

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