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

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