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

Revision 1166, 18.2 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 volume of this view cell
269        float mVolume;
270        float mArea;
271        /// the cost that were paid for merging this view cells from two others.
272        float mMergeCost;
273        /// if the view cell is valid view space
274        bool mValid;
275
276        /// color used for consistent visualization
277        RgbColor mColor;
278
279        /// store pvs size, used for evaluation purpose when pvss are stored only in the leaves
280        int mPvsSize;
281        /** stores number of entries in pvs
282            this variable has the same value as mPvsSize for object pvs,
283                but usually not for kd cell based pvs
284        */
285        int mEntriesInPvs;
286
287        /// if the pvs size scalar (+ entries into pvs)
288        /// is up to date and corresponding to the real pvs size
289        bool mPvsSizeValid;
290       
291
292};
293
294
295class ViewCellInterior: public ViewCell
296{
297        friend class ViewCellsManager;
298public:
299        ViewCellInterior();
300        ~ViewCellInterior();
301
302        ViewCellInterior(Mesh *mesh);
303       
304
305        /** Sets pointer from parent to child and vice versa.
306        */
307        void SetupChildLink(ViewCell *l);
308        void RemoveChildLink(ViewCell *l);
309        bool IsLeaf() const;
310
311        ViewCellContainer mChildren;
312
313  void SetCost(const float c) {
314        mCost = c;
315  }
316  float GetCost() const {
317        return mCost;
318  }
319 
320protected:
321  /** overall cost resulting from the merge */
322  float mCost;
323};
324
325
326/**
327        Leaf of the view cell.
328*/
329class ViewCellLeaf: public ViewCell
330{
331public:
332        ViewCellLeaf()  {  mActiveViewCell = this; }
333        ViewCellLeaf(Mesh *mesh):
334        ViewCell(mesh) { mActiveViewCell = this; }
335
336        bool IsLeaf() const
337        {
338                return true;
339        }
340
341        /** Returns if this view cell is active.
342        */
343        ViewCell *GetActiveViewCell() const
344        { return mActiveViewCell; }
345
346        /** Sets this view cell to be an active view cell.
347        */
348        void SetActiveViewCell(ViewCell *vc)
349        { mActiveViewCell = vc;}
350
351       
352        /** points to the currently active view cell. This is the
353                view cell representing the current brach.
354        */
355        ViewCell *mActiveViewCell;
356};
357
358/** Leaf of the view cell hierarchy corresponding
359        to a leaf in a spatial hierarchy.
360*/
361template<typename T>
362class HierarchyLeafViewCell: public ViewCellLeaf
363{
364public:
365
366        HierarchyLeafViewCell<T>(): ViewCellLeaf() {  }
367        HierarchyLeafViewCell<T>(Mesh *mesh):
368        ViewCellLeaf(mesh) {  }
369               
370
371        bool IsLeaf() const
372        {
373                return true;
374        }
375
376
377        /// Leaf of some hierarchy which is part of this view cell.
378        T mLeaf;
379};
380
381
382typedef HierarchyLeafViewCell<VspLeaf *> VspViewCell;
383typedef HierarchyLeafViewCell<BspLeaf *> BspViewCell;
384typedef HierarchyLeafViewCell<KdLeaf *> KdViewCell;
385
386
387
388
389class ViewCellsTree
390{
391        friend class ViewCellsManager;
392
393
394public:
395        /** View cells tree constructor taking a view cell mnanager as parameter
396        */
397        ViewCellsTree(ViewCellsManager *vcm);
398        ~ViewCellsTree();
399
400        /** Returns number of leaves this view cell consists of.
401        */
402        int GetNumInitialViewCells(ViewCell *vc) const;
403
404        /** Collects leaves corresponding to a view cell.
405        */
406        void CollectLeaves(ViewCell *vc, ViewCellContainer &leaves) const;
407
408        /** Merges view cells according to some cost heuristics.
409        */
410        int ConstructMergeTree(const VssRayContainer &rays, const ObjectContainer &objects);
411       
412        /** Refines view cells using shuffling, i.e., border leaves
413                of two view cells are exchanged if the resulting view cells
414                are tested to be "better" than the old ones.
415                @returns number of refined view cells
416        */
417        int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
418       
419        /** Assign colors to the viewcells so that they can be renderered interactively without
420            color flickering. 
421        */
422        void AssignRandomColors();
423
424        /** Updates view cell stats for this particular view cell.
425        */
426        void UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat);
427
428        /** Get costs resulting from each merge step.
429        */
430        void GetCostFunction(vector<float> &costFunction);
431 
432        /** Returns optimal set of view cells for a given number of view cells.
433        */
434        void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
435
436        /** Root of view cells tree.
437        */
438        ViewCell *GetRoot() const;
439
440        /** Returns pvs of view cell.
441                @note pvs is returned per reference if tree is not compressed,
442                per copy else.
443        */
444        void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
445
446        /** Returns pvs size (i.e. the number of stored objects
447        */
448        int GetPvsSize(ViewCell *vc) const;
449
450        /** Returns number of entries associated with this view cell.
451                This returns the same value as the GetPvsSize function for object pvs,
452                but most likely different values for kd node based pvs.
453        */
454        int GetPvsEntries(ViewCell *vc) const;
455
456        /** Returns the actual number of stored entries in the view cells sub tree.
457        */
458        int GetStoredPvsEntriesNum(ViewCell *root) const;
459
460        /** Returns memory cost of this view cell.
461        */
462        float GetMemoryCost(ViewCell *vc) const;
463
464        /** Sets method of storage for view cells.
465        */
466        void SetViewCellsStorage(int type);
467
468        /** pvs storage methods
469        */
470        enum {PVS_IN_INTERIORS, COMPRESSED, PVS_IN_LEAVES};
471
472       
473        /** If view cells in this tree have compressed pvs.
474        */
475        int ViewCellsStorage() const;
476
477        /** Returns active view cell that is in the path of this view cell.
478        */
479        ViewCell *GetActiveViewCell(ViewCellLeaf *vc) const;
480
481        /** Sets the leaves to be the currently active view cells.
482        */
483    void SetActiveSetToLeaves();
484
485        /** Propagates pvs up the tree to the root and downwards the tree.
486        */
487        void PropagatePvs(ViewCell *vc);
488
489        /** Exports view cells to file.
490        */
491#if ZIPPED_VIEWCELLS
492        bool Export(ogzstream &stream, const bool exportPvs = false);
493#else
494        bool Export(ofstream &stream, const bool exportPvs = false);
495#endif
496
497        /** Export statistics of this view cell tree.
498        */
499        void ExportStats(const string &mergeStats);
500
501        /** Sets root of hierarchy.
502        */
503        void SetRoot(ViewCell *root);
504
505        //float ComputeVolume(ViewCell *vc);
506
507        /** Assignes unique ids to view cells.
508        */
509        void CreateUniqueViewCellsIds();
510
511        /** Resets pvs of whole tree.
512        */
513        void ResetPvs();
514
515        /** Counts pvs of the view cell taking the kd cells into account.
516        */
517        int CountKdPvs(const ViewCellLeaf *vc) const;
518
519protected:
520
521
522        /////////////////////////////////////////////////////////////////
523        //                    merge related stuff                      //
524        /////////////////////////////////////////////////////////////////
525
526        /** Computes render cost of the merged pvs.
527        */
528        float ComputeMergedPvsCost(const ObjectPvs &pvs1, const ObjectPvs &pvs2) const;
529
530        /** Returns cost of this leaf according to current heuristics.
531        */
532        float GetCostHeuristics(ViewCell *vc) const;
533
534        /** Returns cost of leaf.
535        */
536        float GetRenderCost(ViewCell *vc) const;
537
538        /** Evaluates the merge cost of this merge candidate pair.
539        */
540        void EvalMergeCost(MergeCandidate &mc) const;
541
542        /** Variance of leaf.
543        */
544        float GetVariance(ViewCell *vc) const;
545
546        /** Standard deviation of leaf.
547        */
548        float GetDeviation(ViewCell *vc) const;
549
550        /** Tries to set this merge candidate to valid.
551                @returns false if both view cells are the same
552        */
553        bool ValidateMergeCandidate(MergeCandidate &mc) const;
554
555        /** Merge view cells of leaves l1 and l2.
556                @returns difference in pvs size
557        */
558        ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, int &pvsDiff); //const;
559
560        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
561                to view cell 2.
562        */
563        void ShuffleLeaf(ViewCell *leaf, ViewCellInterior *vc1, ViewCellInterior *vc2) const;   
564               
565        /** Shuffles the leaves, i.e., tests if exchanging
566                the leaves helps in improving the view cells.
567        */
568        bool ShuffleLeaves(MergeCandidate &mc) const;
569
570        /** Calculates cost for merge of view cell 1 and 2.
571        */
572        float EvalShuffleCost(ViewCell *leaf,
573                                                  ViewCellInterior *vc1,
574                                                  ViewCellInterior *vc2) const;
575
576        /** Exports a snapshot of the merged view cells to disc.
577        */
578        void ExportMergedViewCells(ViewCellContainer &viewCells,
579                                                           const ObjectContainer &objects,
580                                                           const int numNewViewCells);
581
582        /** Merge queue must be reset after some time because expected value
583                may not be valid.
584        */
585        void ResetMergeQueue();
586
587        /** Updates the current top level of view cells.
588                @returns number of newly merged view cells
589        */
590        int UpdateActiveViewCells(ViewCellContainer &viewCells);
591
592        /** Helper function pullling pvs as high up in the tree as possible.
593        */
594        void PullUpVisibility(ViewCellInterior *interior);
595
596        /** Compress pvs of view cell and children.
597        */
598        void CompressViewCellsPvs(ViewCell *root);
599
600        /** Returns memory usage of view cells.
601        */
602        float GetMemUsage() const;
603
604        /**     Exports single view cell.
605                NOTE: should be in exporter!!
606        */
607#if ZIPPED_VIEWCELLS
608        void ExportViewCell(ViewCell *viewCell, ogzstream &stream, const bool exportPvs);
609#else
610        void ExportViewCell(ViewCell *viewCell, ofstream &stream, const bool exportPvs);       
611#endif
612
613        /** Exports pvs of a view cell.
614        */
615#if ZIPPED_VIEWCELLS
616        void ExportPvs(ViewCell *viewCell, ogzstream &stream);
617#else
618        void ExportPvs(ViewCell *viewCell, ofstream &stream);
619#endif
620
621        int GetEntriesInPvsForCompressedStorage(ViewCell *vc) const;
622        int GetPvsSizeForCompressedStorage(ViewCell *vc) const;
623        int GetPvsSizeForLeafStorage(ViewCell *vc) const;
624        int GetEntriesInPvsForLeafStorage(ViewCell *vc) const;
625
626        void UpdateStats(
627                ofstream &stats,
628                const int pass,
629                const int viewCells,
630                const float renderCostDecrease,
631                const float totalRenderCost,
632                const int currentPvs,
633                const float expectedCost,
634                const float avgRenderCost,
635                const float deviation,
636                const int totalPvs,
637                const int entriesInPvs,
638                const int pvsSizeDecr,
639                const float volume);
640
641        /// if the view cell tree hold compressed pvs
642        int mViewCellsStorage;
643
644        ViewCellsManager *mViewCellsManager;
645        ViewCell *mRoot;
646
647        /// if merge visualization should be shown
648        bool mExportMergedViewCells;
649
650       
651        /// intermediate container of merged view cells.
652        ViewCellContainer mMergedViewCells;
653       
654
655        /// if merged view cells are refined.
656        bool mRefineViewCells;
657
658        /// weights between variance and render cost increase (must be between zero and one)
659        float mRenderCostWeight;
660
661        /// overall cost used to normalize cost ratio
662        float mOverallCost;
663        float mExpectedCost;
664    float mDeviation;
665        float mAvgRenderCost;
666        /// the area is used for pvs heuristics
667        int mUseAreaForPvs;
668
669        int mNumActiveViewCells;
670
671        /// minimal number of view cells
672        int mMergeMinViewCells;
673        /// maximal cost ratio for the merge
674        float mMergeMaxCostRatio;
675
676        typedef priority_queue<MergeCandidate> MergeQueue;
677
678        MergeQueue mMergeQueue;
679
680        float mMaxMemory;
681
682        int mMaxMergesPerPass;
683        float mAvgCostMaxDeviation;
684};
685
686
687/**
688        Candidate for leaf merging based on priority.
689*/
690class MergeCandidate
691
692        friend class ViewCellsTree;
693
694public:
695
696        MergeCandidate(ViewCell *l, ViewCell *r);
697
698        /** If this merge pair is still valid.
699        */
700        bool IsValid() const;
701
702       
703        friend bool operator<(const MergeCandidate &leafa, const MergeCandidate &leafb)
704        {
705                return leafb.GetMergeCost() < leafa.GetMergeCost();
706        }
707
708        void SetLeftViewCell(ViewCell *l);
709        void SetRightViewCell(ViewCell *l);
710
711        ViewCell *GetLeftViewCell() const;
712        ViewCell *GetRightViewCell() const;
713
714        /** Returns leaf view cell initially associated with this merge candidate.
715        */
716        ViewCell *GetInitialLeftViewCell() const;
717        /** Returns leaf view cell initially associated with this merge candidate.
718        */
719        ViewCell *GetInitialRightViewCell() const;
720
721        /** Returns the increase of the standard deviation of this merge candidate.
722        */
723        float GetDeviationIncr() const;
724
725        /** Merge cost of this candidate pair.
726        */
727        float GetMergeCost() const;
728
729        /** Render cost of this candidate.
730        */
731        float GetRenderCost() const;
732       
733        static float sRenderCostWeight;
734
735protected:
736
737        /// render cost increase by this merge
738        float mRenderCost;
739        /// increase / decrease of standard deviation
740        float mDeviationIncr;
741
742        ViewCell *mLeftViewCell;
743        ViewCell *mRightViewCell;
744
745        ViewCell *mInitialLeftViewCell;
746        ViewCell *mInitialRightViewCell;
747};
748
749
750class MergeStatistics: public StatisticsBase
751{
752public:
753       
754        int merged;
755        int siblings;
756        int candidates;
757        int nodes;
758
759        int accTreeDist;
760        int maxTreeDist;
761       
762        Real collectTime;
763        Real mergeTime;
764
765        Real overallCost;
766
767        Real expectedRenderCost;
768        Real deviation;
769        Real heuristics;
770
771        // Constructor
772        MergeStatistics()
773        {
774                Reset();
775        }
776       
777        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
778
779        void Reset()
780        {
781                nodes = 0;
782                merged = 0;
783                siblings = 0;
784                candidates = 0;
785       
786                accTreeDist = 0;
787                maxTreeDist = 0;
788
789                collectTime = 0;
790                mergeTime = 0;
791                overallCost = 0;
792
793                expectedRenderCost = 0;
794                deviation = 0;
795                heuristics = 0;
796
797        }
798
799        void Print(ostream &app) const;
800
801        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
802        {
803                stat.Print(s);
804                return s;
805        }
806};
807
808}
809
810#endif
Note: See TracBrowser for help on using the repository browser.