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

Revision 938, 15.1 KB checked in by mattausch, 18 years ago (diff)
Line 
1#ifndef _ViewCell_H__
2#define _ViewCell_H__
3
4#include "Mesh.h"
5#include "Containers.h"
6#include "Ray.h"
7#include "Statistics.h"
8#include "Material.h"
9//namespace GtpVisibilityPreprocessor {
10
11namespace GtpVisibilityPreprocessor {
12
13struct Triangle3;
14
15class BspInterior;
16class BspPvs;
17class BspLeaf;
18class VspKdTree;
19class VspKdLeaf;
20class KdLeaf;
21class ViewCellInterior;
22class MergeCandidate;
23class ViewCellsManager;
24class ViewCellLeaf;
25class Environment;
26
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
38        int pvsSize;
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
55        int invalid;
56
57    // Constructor
58        ViewCellsStatistics()
59        {
60                Reset();
61        }
62
63        double AvgLeaves() const {return (double)leaves / (double)viewCells;};
64        double AvgPvs() const {return (double)pvsSize / (double)viewCells;};
65
66        void Reset()
67        {
68                viewCells = 0;
69                pvsSize = 0;
70                maxPvs = 0;
71
72                minPvs = 999999;
73                emptyPvs = 0;
74                leaves = 0;
75                maxLeaves = 0;
76                invalid = 0;
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
88
89/**
90        View cell with an optional mesh representation
91*/
92
93
94class ViewCell: public MeshInstance
95{
96        friend class ViewCellsTree;
97        friend class ViewCellsManager;
98        friend class VspBspViewCellsManager;
99        friend class BspViewCellsManager;
100        friend class VspBspTree;
101        friend class FromPointVisibilityTree;
102        friend class BspTree;
103
104
105public:
106        ViewCell();
107
108        /** Constructor taking a mesh representing the shape of the viewcell.
109        */
110        ViewCell(Mesh *mesh);
111
112        /** Default destructor.
113        */
114        virtual ~ViewCell() {}
115
116        /** Returns Pvs.
117        */
118        const ObjectPvs &GetPvs() const;
119
120        ObjectPvs &GetPvs();
121
122        void SetPvs(const ObjectPvs &pvs);
123
124        /** Type of view cells.
125        */
126        int Type() const;
127
128        void SetParent(ViewCellInterior *parent);
129
130        /** Adds a passing ray to the passing ray container.
131        */
132        void AddPassingRay(const Ray &ray, const int contributions);
133
134        /** Returns volume of the view cell.
135        */
136        float GetVolume() const;
137
138        /** Returns area of the view cell.
139        */
140        float GetArea() const;
141
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);
149
150
151        /** if this view cell is the root of a view cell hierarchy
152        */
153        bool IsRoot() const;
154
155        /** Returns parent view cell.
156        */
157        ViewCellInterior *GetParent() const;
158
159       
160        /** Sets the mesh for this view cell.
161        */
162        void SetMesh(Mesh *mesh);
163
164        void SetValid(const bool valid);
165        bool GetValid() const;
166
167        /** Returns estimated render cost of this view cell.
168        */
169        float GetRenderCost() const;
170
171        /** set color for visiualizations.
172        */
173        void SetColor(const RgbColor &color);
174
175        /** get color for visualuzations.
176        */
177    RgbColor GetColor() const;
178
179 
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
191        static bool SmallerPvs(const ViewCell *a, const ViewCell *b)
192        {
193        return a->GetPvs().GetSize() < b->GetPvs().GetSize();
194  }
195
196 static bool SmallerRenderCost(const ViewCell *a, const ViewCell *b)
197 {
198         return a->GetRenderCost() < b->GetRenderCost();
199 }
200
201 static bool LargerRenderCost(const ViewCell *a, const ViewCell *b)
202 {
203         return a->GetRenderCost() > b->GetRenderCost();
204 }
205
206        void SetMergeCost(const float mergeCost);
207        float GetMergeCost() const;
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
221
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
227       
228protected:
229
230        /// the potentially visible objects
231        ObjectPvs mPvs;
232
233        float mVolume;
234        float mArea;
235
236        float mMergeCost;
237
238        bool mValid;
239
240        /// color used for consistent visualization
241        RgbColor mColor;
242
243       
244        /// pvs size, used for lazy pvs computation
245        int mPvsSize;
246        /// if the given pvs size is the real pvs size
247        bool mPvsSizeValid;
248
249};
250
251
252class ViewCellInterior: public ViewCell
253{
254        friend class ViewCellsManager;
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);
265        void RemoveChildLink(ViewCell *l);
266        bool IsLeaf() const;
267
268        ViewCellContainer mChildren;
269
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;
280};
281
282
283/**
284        Leaf of the view cell.
285*/
286class ViewCellLeaf: public ViewCell
287{
288public:
289        ViewCellLeaf()  {  mActiveViewCell = this; }
290        ViewCellLeaf(Mesh *mesh):
291        ViewCell(mesh) { mActiveViewCell = this; }
292
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
308       
309        /// points to the currently active view cell.
310        ViewCell *mActiveViewCell;
311};
312
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
326        bool IsLeaf() const
327        {
328                return true;
329        }
330
331
332        /// Leaf of some hierarchy which is part of this view cell.
333        T mLeaf;
334};
335
336
337typedef HierarchyLeafViewCell<BspLeaf *> BspViewCell;
338typedef HierarchyLeafViewCell<KdLeaf *> KdViewCell;
339typedef HierarchyLeafViewCell<VspKdLeaf *> VspKdViewCell;
340
341
342
343class ViewCellsTree
344{
345        friend class ViewCellsManager;
346
347
348public:
349        ViewCellsTree(ViewCellsManager *vcm, Environment *env);
350        ~ViewCellsTree();
351
352        /** Returns number of leaves this view cell consists of.
353        */
354        int GetNumInitialViewCells(ViewCell *vc) const;
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);
370       
371        /** Assign colors to the viewcells so that they can be renderered interactively without
372          color flickering.
373          */
374        void AssignRandomColors();
375
376        /** Updates view cell stats for this particular view cell
377        */
378        void UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat);
379
380
381        /** Get costs resulting from each merge step. */
382        void GetCostFunction(vector<float> &costFunction);
383
384 
385        /** Returns optimal set of view cells for a given number of view cells.
386        */
387        void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
388
389        /** Root of view cells tree.
390        */
391        ViewCell *GetRoot() const;
392
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
411        /** Sets method of storage for view cells.
412        */
413        void SetViewCellsStorage(int type);
414
415        /** pvs storage methods
416        */
417        enum {PVS_IN_INTERIORS, COMPRESSED, PVS_IN_LEAVES};
418
419       
420        /** If view cells in this tree have compressed pvs.
421        */
422        int ViewCellsStorage() const;
423
424        /** Returns active view cell that is in the path of this view cell.
425        */
426        ViewCell *GetActiveViewCell(ViewCellLeaf *vc) const;
427
428        /** Sets the leaves to be the currently active view cells.
429        */
430    void SetActiveSetToLeaves();
431
432        /** Propagates pvs up the tree to the root and downwards the tree.
433        */
434        void PropagatePvs(ViewCell *vc);
435
436        /** Exports view cells to file.
437        */
438    bool Export(ofstream &stream, const bool exportPvs = false);
439
440        /** Export statistics of this view cell tree.
441        */
442        void ExportStats(const string &mergeStats);
443
444        /** Sets root of hierarchy.
445        */
446        void SetRoot(ViewCell *root);
447
448        //float ComputeVolume(ViewCell *vc);
449
450        /** Assignes unique ids to view cells.
451        */
452        void CreateUniqueViewCellsIds();
453
454        /** Resets pvs of whole tree.
455        */
456        void ResetPvs();
457
458protected:
459
460
461        //////////////////////////////////////////////////////////////
462        //                 merge related stuff                      //
463        //////////////////////////////////////////////////////////////
464
465        /** Computes render cost of the merged pvs.
466        */
467        float ComputeMergedPvsCost(const ObjectPvs &pvs1, const ObjectPvs &pvs2) const;
468
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
489        /** Tries to set this merge candidate to valid.
490                @returns false if both view cells are the same
491        */
492        bool ValidateMergeCandidate(MergeCandidate &mc) const;
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        */
502        void ShuffleLeaf(ViewCell *leaf, ViewCellInterior *vc1, ViewCellInterior *vc2) const;   
503               
504        /** Shuffles the leaves, i.e., tests if exchanging
505                the leaves helps in improving the view cells.
506        */
507        bool ShuffleLeaves(MergeCandidate &mc) const;
508
509        /** Calculates cost for merge of view cell 1 and 2.
510        */
511        float EvalShuffleCost(ViewCell *leaf,
512                                                  ViewCellInterior *vc1,
513                                                  ViewCellInterior *vc2) const;
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.
527                @returns number of newly merged view cells
528        */
529        int UpdateActiveViewCells(ViewCellContainer &viewCells);
530
531        void PullUpVisibility(ViewCellInterior *interior);
532
533        void CompressViewCellsPvs(ViewCell *root);
534
535        /** Returns memory usage of view cells.
536        */
537        float GetMemUsage() const;
538
539        /**     Exports single view cell.
540                NOTE: should be in exporter!!
541        */
542        void ExportViewCell(ViewCell *viewCell, ofstream &stream, const bool exportPvs);
543
544        /** Exports pvs of a view cell.
545        */
546        void ExportPvs(ViewCell *viewCell, ofstream &stream);
547
548
549
550        /// if the view cell tree hold compressed pvs
551        int mViewCellsStorage;
552
553        ViewCellsManager *mViewCellsManager;
554        ViewCell *mRoot;
555
556        /// if merge visualization should be shown
557        bool mExportMergedViewCells;
558
559       
560        /// intermediate container of merged view cells.
561        ViewCellContainer mMergedViewCells;
562       
563
564        /// if merged view cells are refined.
565        bool mRefineViewCells;
566
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;
575        /// the area is used for pvs heuristics
576        int mUseAreaForPvs;
577
578        int mNumActiveViewCells;
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
589        float mMaxMemory;
590
591        int mMaxMergesPerPass;
592        float mAvgCostMaxDeviation;
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
623        /** Returns leaf view cell initially associated with this merge candidate.
624        */
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
715}
716
717#endif
Note: See TracBrowser for help on using the repository browser.