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

Revision 1121, 16.9 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
195        /// Rays piercing this view cell.
196        RayContainer mPiercingRays;
197
198
199        /** if this is a view cell correspending to a leaf in a hierarchy.
200        */
201        virtual bool IsLeaf() const = 0;
202
203        static bool SmallerPvs(const ViewCell *a, const ViewCell *b)
204        {
205                // HACK: take scalar value because pvs may not have been stored properly
206#if 1
207                return a->mPvsSize < b->mPvsSize;
208#else
209                return a->GetPvs().GetSize() < b->GetPvs().GetSize();
210#endif
211        }
212
213        static bool SmallerRenderCost(const ViewCell *a, const ViewCell *b)
214        {
215                return a->GetRenderCost() < b->GetRenderCost();
216        }
217
218        static bool LargerRenderCost(const ViewCell *a, const ViewCell *b)
219        {
220                return a->GetRenderCost() > b->GetRenderCost();
221        }
222
223        /** Sets merge cost used for merging this view cell from other cells.
224                @hack The function is available for leaves also to have a common interface,
225                but it should be less than zero for leaves.
226                */
227        void SetMergeCost(const float mergeCost);
228
229        /** Returns merge cost needed to merge this leaf from other cells.
230                @hack The function is available for leaves also to have a common interface,
231                but it should be less than zero for leaves.
232        */
233        float GetMergeCost() const;
234
235
236
237        ////////////////////////////////////////////
238        //       mailing stuff
239
240
241        static void NewMail(const int reserve = 1)
242        {
243                sMailId += sReservedMailboxes;
244                sReservedMailboxes = reserve;
245        }
246
247        void Mail() { mMailbox = sMailId; }
248        bool Mailed() const { return mMailbox == sMailId; }
249
250        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
251        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
252
253        int IncMail() { return ++mMailbox - sMailId; }
254
255
256        // last mail id -> warning not thread safe!
257        // both mailId and mailbox should be unique for each thread!!!
258        static int sMailId;
259        static int sReservedMailboxes;
260
261       
262protected:
263
264        /// parent view cell in the view cell hierarchy
265        ViewCellInterior *mParent;
266
267        /// the potentially visible objects
268        ObjectPvs mPvs;
269
270        float mVolume;
271        float mArea;
272
273        float mMergeCost;
274
275        bool mValid;
276
277        /// color used for consistent visualization
278        RgbColor mColor;
279
280       
281        /// store pvs size, used for evaluation purpose when pvss are stored only in the leaves
282        int mPvsSize;
283        /// if the pvs size scalar is up to date and corresponding to the real pvs size
284        bool mPvsSizeValid;
285
286};
287
288
289class ViewCellInterior: public ViewCell
290{
291        friend class ViewCellsManager;
292public:
293        ViewCellInterior();
294        ~ViewCellInterior();
295
296        ViewCellInterior(Mesh *mesh);
297       
298
299        /** Sets pointer from parent to child and vice versa.
300        */
301        void SetupChildLink(ViewCell *l);
302        void RemoveChildLink(ViewCell *l);
303        bool IsLeaf() const;
304
305        ViewCellContainer mChildren;
306
307  void SetCost(const float c) {
308        mCost = c;
309  }
310  float GetCost() const {
311        return mCost;
312  }
313 
314protected:
315  /** overall cost resulting from the merge */
316  float mCost;
317};
318
319
320/**
321        Leaf of the view cell.
322*/
323class ViewCellLeaf: public ViewCell
324{
325public:
326        ViewCellLeaf()  {  mActiveViewCell = this; }
327        ViewCellLeaf(Mesh *mesh):
328        ViewCell(mesh) { mActiveViewCell = this; }
329
330        bool IsLeaf() const
331        {
332                return true;
333        }
334
335        /** Returns if this view cell is active.
336        */
337        ViewCell *GetActiveViewCell() const
338        { return mActiveViewCell; }
339
340        /** Sets this view cell to be an active view cell.
341        */
342        void SetActiveViewCell(ViewCell *vc)
343        { mActiveViewCell = vc;}
344
345       
346        /** points to the currently active view cell. This is the
347                view cell representing the current brach.
348        */
349        ViewCell *mActiveViewCell;
350};
351
352/** Leaf of the view cell hierarchy corresponding
353        to a leaf in a spatial hierarchy.
354*/
355template<typename T>
356class HierarchyLeafViewCell: public ViewCellLeaf
357{
358public:
359
360        HierarchyLeafViewCell<T>(): ViewCellLeaf() {  }
361        HierarchyLeafViewCell<T>(Mesh *mesh):
362        ViewCellLeaf(mesh) {  }
363               
364
365        bool IsLeaf() const
366        {
367                return true;
368        }
369
370
371        /// Leaf of some hierarchy which is part of this view cell.
372        T mLeaf;
373};
374
375
376typedef HierarchyLeafViewCell<VspLeaf *> VspViewCell;
377typedef HierarchyLeafViewCell<BspLeaf *> BspViewCell;
378typedef HierarchyLeafViewCell<KdLeaf *> KdViewCell;
379
380
381
382
383class ViewCellsTree
384{
385        friend class ViewCellsManager;
386
387
388public:
389        /** View cells tree constructor taking a view cell mnanager as parameter
390        */
391        ViewCellsTree(ViewCellsManager *vcm);
392        ~ViewCellsTree();
393
394        /** Returns number of leaves this view cell consists of.
395        */
396        int GetNumInitialViewCells(ViewCell *vc) const;
397
398        /** Collects leaves corresponding to a view cell.
399        */
400        void CollectLeaves(ViewCell *vc, ViewCellContainer &leaves) const;
401
402        /** Merges view cells according to some cost heuristics.
403        */
404        int ConstructMergeTree(const VssRayContainer &rays, const ObjectContainer &objects);
405       
406        /** Refines view cells using shuffling, i.e., border leaves
407                of two view cells are exchanged if the resulting view cells
408                are tested to be "better" than the old ones.
409                @returns number of refined view cells
410        */
411        int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
412       
413        /** Assign colors to the viewcells so that they can be renderered interactively without
414            color flickering. 
415        */
416        void AssignRandomColors();
417
418        /** Updates view cell stats for this particular view cell.
419        */
420        void UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat);
421
422        /** Get costs resulting from each merge step.
423        */
424        void GetCostFunction(vector<float> &costFunction);
425 
426        /** Returns optimal set of view cells for a given number of view cells.
427        */
428        void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
429
430        /** Root of view cells tree.
431        */
432        ViewCell *GetRoot() const;
433
434        /** Returns pvs of view cell.
435                @note pvs is returned per reference if tree is not compressed,
436                per copy else.
437        */
438        void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
439
440        /** Returns pvs size of view cell.
441        */
442        //int GetPvsSize(ViewCell *vc) const;
443        int GetPvsSize(ViewCell *vc, const bool countKdPvs = false) 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        ViewCell *GetInitialRightViewCell() const;
688
689        /** Returns the increase of the standard deviation of this merge candidate.
690        */
691        float GetDeviationIncr() const;
692
693        /** Merge cost of this candidate pair.
694        */
695        float GetMergeCost() const;
696
697        /** Render cost of this candidate.
698        */
699        float GetRenderCost() const;
700       
701        static float sRenderCostWeight;
702
703protected:
704
705        /// render cost increase by this merge
706        float mRenderCost;
707        /// increase / decrease of standard deviation
708        float mDeviationIncr;
709
710        ViewCell *mLeftViewCell;
711        ViewCell *mRightViewCell;
712
713        ViewCell *mInitialLeftViewCell;
714        ViewCell *mInitialRightViewCell;
715};
716
717
718class MergeStatistics: public StatisticsBase
719{
720public:
721       
722        int merged;
723        int siblings;
724        int candidates;
725        int nodes;
726
727        int accTreeDist;
728        int maxTreeDist;
729       
730        Real collectTime;
731        Real mergeTime;
732
733        Real overallCost;
734
735        Real expectedRenderCost;
736        Real deviation;
737        Real heuristics;
738
739        // Constructor
740        MergeStatistics()
741        {
742                Reset();
743        }
744       
745        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
746
747        void Reset()
748        {
749                nodes = 0;
750                merged = 0;
751                siblings = 0;
752                candidates = 0;
753       
754                accTreeDist = 0;
755                maxTreeDist = 0;
756
757                collectTime = 0;
758                mergeTime = 0;
759                overallCost = 0;
760
761                expectedRenderCost = 0;
762                deviation = 0;
763                heuristics = 0;
764
765        }
766
767        void Print(ostream &app) const;
768
769        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
770        {
771                stat.Print(s);
772                return s;
773        }
774};
775
776}
777
778#endif
Note: See TracBrowser for help on using the repository browser.