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

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