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

Revision 1297, 18.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
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        /// Rays piercing this view cell.
194        //RayContainer mPiercingRays;
195
196        /** if this is a view cell correspending to a leaf in a hierarchy.
197        */
198        virtual bool IsLeaf() const = 0;
199
200        static bool SmallerPvs(const ViewCell *a, const ViewCell *b)
201        {
202                // HACK: take scalar value because pvs may not have been stored properly
203#if 1
204                return a->mPvsSize < b->mPvsSize;
205#else
206                return a->GetPvs().CountObjectsInPvs() < b->GetPvs().CountObjectsInPvs();
207#endif
208        }
209
210        static bool SmallerRenderCost(const ViewCell *a, const ViewCell *b)
211        {
212                return a->GetRenderCost() < b->GetRenderCost();
213        }
214
215        static bool LargerRenderCost(const ViewCell *a, const ViewCell *b)
216        {
217                return a->GetRenderCost() > b->GetRenderCost();
218        }
219
220        /** Sets merge cost used for merging this view cell from other cells.
221                @hack The function is available for leaves also to have a common interface,
222                but it should be less than zero for leaves.
223                */
224        void SetMergeCost(const float mergeCost);
225
226        /** Returns merge cost needed to merge this leaf from other cells.
227                @hack The function is available for leaves also to have a common interface,
228                but it should be less than zero for leaves.
229        */
230        float GetMergeCost() const;
231
232
233
234        ////////////////////////////////////////////
235        //-- mailing stuff
236
237
238        static void NewMail(const int reserve = 1)
239        {
240                sMailId += sReservedMailboxes;
241                sReservedMailboxes = reserve;
242        }
243
244        void Mail() { mMailbox = sMailId; }
245        bool Mailed() const { return mMailbox == sMailId; }
246
247        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
248        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
249
250        int IncMail() { return ++ mMailbox - sMailId; }
251
252
253        // last mail id -> warning not thread safe!
254        // both mailId and mailbox should be unique for each thread!!!
255        static int sMailId;
256        static int sReservedMailboxes;
257        //int mMailbox;
258       
259protected:
260
261        /// parent view cell in the view cell hierarchy
262        ViewCellInterior *mParent;
263        /// the potentially visible objects
264        ObjectPvs mPvs;
265        /// the volume of this view cell
266        float mVolume;
267       
268        float mArea;
269        /// the cost that were paid for merging this view cells from two others.
270        float mMergeCost;
271        /// if the view cell is valid view space
272        bool mValid;
273        /// color used for consistent visualization
274        RgbColor mColor;
275        /// store pvs size, used for evaluation purpose when pvss are stored only in the leaves
276        int mPvsSize;
277
278        /** stores number of entries in pvs
279            this variable has the same value as mPvsSize for object pvs,
280                but usually not for kd cell based pvs
281        */
282        int mEntriesInPvs;
283
284        /** if the pvs size scalar (+ entries into pvs)
285                is up to date and corresponding to the real pvs size
286        */
287        bool mPvsSizeValid;
288
289};
290
291
292class ViewCellInterior: public ViewCell
293{
294        friend class ViewCellsManager;
295
296public:
297        ViewCellInterior();
298        ~ViewCellInterior();
299
300        ViewCellInterior(Mesh *mesh);
301       
302        /** Sets pointer from parent to child and vice versa.
303        */
304        void SetupChildLink(ViewCell *l);
305        void ReplaceChildLink(ViewCell *prev, ViewCell *cur);
306
307        void RemoveChildLink(ViewCell *l);
308        bool IsLeaf() const;
309
310        void SetCost(const float c) {
311                mCost = c;
312        }
313       
314        float GetCost() const {
315                return mCost;
316        }
317 
318  ViewCellContainer mChildren;
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        friend class ViewCellsParseHandlers;
393
394public:
395        ViewCellsTree();
396        /** View cells tree constructor taking a view cell mnanager as parameter
397        */
398        ViewCellsTree(ViewCellsManager *vcm);
399        ~ViewCellsTree();
400
401        /** Returns number of leaves this view cell consists of.
402        */
403        int GetNumInitialViewCells(ViewCell *vc) const;
404
405        /** Collects leaves corresponding to a view cell.
406        */
407        void CollectLeaves(ViewCell *vc, ViewCellContainer &leaves) const;
408
409        /** Merges view cells according to some cost heuristics.
410        */
411        int ConstructMergeTree(const VssRayContainer &rays, const ObjectContainer &objects);
412       
413        /** Refines view cells using shuffling, i.e., border leaves
414                of two view cells are exchanged if the resulting view cells
415                are tested to be "better" than the old ones.
416                @returns number of refined view cells
417        */
418        int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
419       
420        /** Assign colors to the viewcells so that they can be renderered interactively without
421            color flickering. 
422        */
423        void AssignRandomColors();
424
425        /** Updates view cell stats for this particular view cell.
426        */
427        void UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat);
428
429        /** Get costs resulting from each merge step.
430        */
431        void GetCostFunction(vector<float> &costFunction);
432 
433        /** Returns optimal set of view cells for a given number of view cells.
434        */
435        void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
436
437        /** Root of view cells tree.
438        */
439        ViewCell *GetRoot() const;
440
441        /** Returns pvs of view cell.
442                @note pvs is returned per reference if tree is not compressed,
443                per copy else.
444        */
445        void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
446
447        /** Returns pvs size (i.e. the number of stored objects
448        */
449        int GetPvsSize(ViewCell *vc) const;
450
451        /** Returns number of entries associated with this view cell.
452                This returns the same value as the GetPvsSize function for object pvs,
453                but most likely different values for kd node based pvs.
454        */
455        int GetPvsEntries(ViewCell *vc) const;
456
457        /** Returns the actual number of stored entries in the view cells sub tree.
458        */
459        int GetStoredPvsEntriesNum(ViewCell *root) const;
460
461        /** Returns memory cost of this view cell.
462        */
463        float GetMemoryCost(ViewCell *vc) const;
464
465        /** Sets method of storage for view cells.
466        */
467        void SetViewCellsStorage(int type);
468
469        /** pvs storage methods
470        */
471        enum {PVS_IN_INTERIORS, COMPRESSED, PVS_IN_LEAVES};
472
473       
474        /** If view cells in this tree have compressed pvs.
475        */
476        int ViewCellsStorage() const;
477
478        /** Returns active view cell that is in the path of this view cell.
479        */
480        ViewCell *GetActiveViewCell(ViewCellLeaf *vc) const;
481
482        /** Sets the leaves to be the currently active view cells.
483        */
484    void SetActiveSetToLeaves();
485
486        /** Propagates pvs up the tree to the root and downwards the tree.
487        */
488        void PropagatePvs(ViewCell *vc);
489
490        /** Exports view cells to file.
491        */
492        bool Export(OUT_STREAM &stream, const bool exportPvs = false);
493
494        /** Export statistics of this view cell tree.
495        */
496        void ExportStats(const string &mergeStats);
497
498        /** Sets root of hierarchy.
499        */
500        void SetRoot(ViewCell *root);
501
502        //float ComputeVolume(ViewCell *vc);
503
504        /** Assignes unique ids to view cells.
505        */
506        void CreateUniqueViewCellsIds();
507
508        /** Resets pvs of whole tree.
509        */
510        void ResetPvs();
511
512        /** Counts pvs of the view cell taking the kd cells into account.
513        */
514        int CountKdPvs(const ViewCellLeaf *vc) const;
515
516        void SetViewCellsManager(ViewCellsManager *vcm)
517        {
518                mViewCellsManager = vcm;
519        }
520
521protected:
522
523        void ReadEnvironment();
524
525        /////////////////////////////////////////////////////////////////
526        //                    merge related stuff                      //
527        /////////////////////////////////////////////////////////////////
528
529        /** Computes render cost of the merged pvs.
530        */
531        float ComputeMergedPvsCost(const ObjectPvs &pvs1, const ObjectPvs &pvs2) const;
532
533        /** Returns cost of this leaf according to current heuristics.
534        */
535        float GetCostHeuristics(ViewCell *vc) const;
536
537        /** Returns cost of leaf.
538        */
539        float GetRenderCost(ViewCell *vc) const;
540
541        /** Evaluates the merge cost of this merge candidate pair.
542        */
543        void EvalMergeCost(MergeCandidate &mc) const;
544
545        /** Variance of leaf.
546        */
547        float GetVariance(ViewCell *vc) const;
548
549        /** Standard deviation of leaf.
550        */
551        float GetDeviation(ViewCell *vc) const;
552
553        /** Tries to set this merge candidate to valid.
554                @returns false if both view cells are the same
555        */
556        bool ValidateMergeCandidate(MergeCandidate &mc) const;
557
558        /** Merge view cells of leaves l1 and l2.
559                @returns difference in pvs size
560        */
561        ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, int &pvsDiff); //const;
562
563        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
564                to view cell 2.
565        */
566        void ShuffleLeaf(ViewCell *leaf, ViewCellInterior *vc1, ViewCellInterior *vc2) const;   
567               
568        /** Shuffles the leaves, i.e., tests if exchanging
569                the leaves helps in improving the view cells.
570        */
571        bool ShuffleLeaves(MergeCandidate &mc) const;
572
573        /** Calculates cost for merge of view cell 1 and 2.
574        */
575        float EvalShuffleCost(ViewCell *leaf,
576                                                  ViewCellInterior *vc1,
577                                                  ViewCellInterior *vc2) const;
578
579        /** Exports a snapshot of the merged view cells to disc.
580        */
581        void ExportMergedViewCells(ViewCellContainer &viewCells,
582                                                           const ObjectContainer &objects,
583                                                           const int numNewViewCells);
584
585        /** Merge queue must be reset after some time because expected value
586                may not be valid.
587        */
588        void ResetMergeQueue();
589
590        /** Updates the current top level of view cells.
591                @returns number of newly merged view cells
592        */
593        int UpdateActiveViewCells(ViewCellContainer &viewCells);
594
595        /** Helper function pullling pvs as high up in the tree as possible.
596        */
597        void PullUpVisibility(ViewCellInterior *interior);
598
599        /** Compress pvs of view cell and children.
600        */
601        void CompressViewCellsPvs(ViewCell *root);
602
603        /** Returns memory usage of view cells.
604        */
605        float GetMemUsage() const;
606
607        /**     Exports single view cell.
608                NOTE: should be in exporter!!
609        */
610        void ExportViewCell(ViewCell *viewCell, OUT_STREAM &stream, const bool exportPvs);     
611
612        /** Exports pvs of a view cell.
613        */
614        void ExportPvs(ViewCell *viewCell, OUT_STREAM &stream);
615
616        int GetEntriesInPvsForCompressedStorage(ViewCell *vc) const;
617        int GetPvsSizeForCompressedStorage(ViewCell *vc) const;
618        int GetPvsSizeForLeafStorage(ViewCell *vc) const;
619        int GetEntriesInPvsForLeafStorage(ViewCell *vc) const;
620
621        void UpdateStats(
622                ofstream &stats,
623                const int pass,
624                const int viewCells,
625                const float renderCostDecrease,
626                const float totalRenderCost,
627                const int currentPvs,
628                const float expectedCost,
629                const float avgRenderCost,
630                const float deviation,
631                const int totalPvs,
632                const int entriesInPvs,
633                const int pvsSizeDecr,
634                const float volume);
635
636        /// if the view cell tree hold compressed pvs
637        int mViewCellsStorage;
638
639        ViewCellsManager *mViewCellsManager;
640        ViewCell *mRoot;
641
642        /// if merge visualization should be shown
643        bool mExportMergedViewCells;
644
645       
646        /// intermediate container of merged view cells.
647        ViewCellContainer mMergedViewCells;
648       
649
650        /// if merged view cells are refined.
651        bool mRefineViewCells;
652
653        /// weights between variance and render cost increase (must be between zero and one)
654        float mRenderCostWeight;
655
656        /// overall cost used to normalize cost ratio
657        float mOverallCost;
658        float mExpectedCost;
659    float mDeviation;
660        float mAvgRenderCost;
661        /// the area is used for pvs heuristics
662        int mUseAreaForPvs;
663
664        int mNumActiveViewCells;
665
666        /// minimal number of view cells
667        int mMergeMinViewCells;
668        /// maximal cost ratio for the merge
669        float mMergeMaxCostRatio;
670
671        typedef priority_queue<MergeCandidate> MergeQueue;
672
673        MergeQueue mMergeQueue;
674
675        float mMaxMemory;
676
677        int mMaxMergesPerPass;
678        float mAvgCostMaxDeviation;
679};
680
681
682/**
683        Candidate for leaf merging based on priority.
684*/
685class MergeCandidate
686
687        friend class ViewCellsTree;
688
689public:
690
691        MergeCandidate(ViewCell *l, ViewCell *r);
692
693        /** If this merge pair is still valid.
694        */
695        bool IsValid() const;
696
697       
698        friend bool operator<(const MergeCandidate &leafa, const MergeCandidate &leafb)
699        {
700                return leafb.GetMergeCost() < leafa.GetMergeCost();
701        }
702
703        void SetLeftViewCell(ViewCell *l);
704        void SetRightViewCell(ViewCell *l);
705
706        ViewCell *GetLeftViewCell() const;
707        ViewCell *GetRightViewCell() const;
708
709        /** Returns leaf view cell initially associated with this merge candidate.
710        */
711        ViewCell *GetInitialLeftViewCell() const;
712        /** Returns leaf view cell initially associated with this merge candidate.
713        */
714        ViewCell *GetInitialRightViewCell() const;
715
716        /** Returns the increase of the standard deviation of this merge candidate.
717        */
718        float GetDeviationIncr() const;
719
720        /** Merge cost of this candidate pair.
721        */
722        float GetMergeCost() const;
723
724        /** Render cost of this candidate.
725        */
726        float GetRenderCost() const;
727       
728        static float sRenderCostWeight;
729
730protected:
731
732        /// render cost increase by this merge
733        float mRenderCost;
734        /// increase / decrease of standard deviation
735        float mDeviationIncr;
736
737        ViewCell *mLeftViewCell;
738        ViewCell *mRightViewCell;
739
740        ViewCell *mInitialLeftViewCell;
741        ViewCell *mInitialRightViewCell;
742};
743
744
745class MergeStatistics: public StatisticsBase
746{
747public:
748       
749        int merged;
750        int siblings;
751        int candidates;
752        int nodes;
753
754        int accTreeDist;
755        int maxTreeDist;
756       
757        Real collectTime;
758        Real mergeTime;
759
760        Real overallCost;
761
762        Real expectedRenderCost;
763        Real deviation;
764        Real heuristics;
765
766        // Constructor
767        MergeStatistics()
768        {
769                Reset();
770        }
771       
772        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
773
774        void Reset()
775        {
776                nodes = 0;
777                merged = 0;
778                siblings = 0;
779                candidates = 0;
780       
781                accTreeDist = 0;
782                maxTreeDist = 0;
783
784                collectTime = 0;
785                mergeTime = 0;
786                overallCost = 0;
787
788                expectedRenderCost = 0;
789                deviation = 0;
790                heuristics = 0;
791
792        }
793
794        void Print(ostream &app) const;
795
796        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
797        {
798                stat.Print(s);
799                return s;
800        }
801};
802
803}
804
805#endif
Note: See TracBrowser for help on using the repository browser.