source: GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h @ 1259

Revision 1259, 8.4 KB checked in by mattausch, 18 years ago (diff)
Line 
1#ifndef __VSS_RAY_H
2#define __VSS_RAY_H
3
4#include <vector>
5using namespace std;
6#include "Vector3.h"
7#include "Ray.h"
8#include "Containers.h"
9
10namespace GtpVisibilityPreprocessor {
11
12class AxisAlignedBox3;
13class Intersectable;
14class KdNode;
15
16class VssRay {
17public:
18  // various flags
19  enum {
20    FPosDirX = 1,  // the direction of ray in X-axis is positive
21    FPosDirY = 2,  // the direction of ray in Y-axis is positive
22    FPosDirZ = 4   // the direction of ray in Z-axis is positive
23  };
24
25  static int mailID;
26  int mMailbox;
27       
28  // side of the ray - used for the ray classification
29  //  char mSide;
30       
31  // computed t
32  //  float mT;
33
34  // inverse of the ray size
35  float mInvSize;
36 
37  // counter of references to this ray
38  short mRefCount;
39 
40  // various flags
41  char mFlags;
42       
43  Vector3 mOrigin;
44  Vector3 mTermination;
45       
46  /// Termination object for the ray
47  /// only the termination object is actually used
48  Intersectable *mOriginObject;
49  Intersectable *mTerminationObject;
50
51  ViewCellContainer mViewCells;
52 
53
54  ////////////////////////
55  // members related to importance sampling
56  // sampling pass in which this ray was generated
57  short mPass;
58
59  // number of cells where this ray made a contribution to the PVS
60  short mPvsContribution;
61 
62  // sum of relative ray contributions per object
63  float mRelativePvsContribution;
64
65
66  // weighted contribution to the pvs (based on the pass the ray was casted at)
67  // computed by the prperocessor
68  float mWeightedPvsContribution;
69
70  // probability of this ray
71  float mPdf;
72 
73  //////////////////////////////
74
75 
76  /// the kd node holding the termination point
77  KdNode *mTerminationNode;
78  /// the kd node holding the origin point
79  KdNode *mOriginNode;
80
81
82  VssRay(
83                 const Vector3 &origin,
84                 const Vector3 &termination,
85                 Intersectable *originObject,
86                 Intersectable *terminationObject,
87                 const int pass = 0,
88                 const float pdf = 1.0f
89                 ):
90        mMailbox(-1),
91    mOrigin(origin),
92    mTermination(termination),
93        mOriginObject(originObject),
94        mTerminationObject(terminationObject),
95        mRefCount(0),
96    mFlags(0),
97        mPass(pass),
98        mViewCells(0),
99        mWeightedPvsContribution(0),
100        mPdf(pdf),
101        mTerminationNode(NULL),
102        mOriginNode(NULL)
103        {
104                Precompute();
105        }
106       
107  VssRay(const Ray &ray):
108        mRefCount(0),
109        mFlags(0),
110        mMailbox(-1),
111        mOriginObject(ray.sourceObject.mObject),
112        mPass(0),
113        mViewCells(0),
114        mPdf(1.0f),
115        mTerminationNode(NULL),
116        mOriginNode(NULL)
117  {
118        if (ray.sourceObject.mObject)
119          mOrigin = ray.Extrap(ray.sourceObject.mT);
120        else
121          mOrigin = ray.GetLoc();
122       
123        //Debug << "origin: " << mOrigin << endl;
124        if (!ray.intersections.empty())
125          {
126                mTermination = ray.Extrap(ray.intersections[0].mT);
127                mTerminationObject = ray.intersections[0].mObject;
128          }
129        else
130          {
131                mTermination = ray.Extrap(1e6);//TODO: should be Limits::Infinity
132                mTerminationObject = NULL;
133          }
134       
135        Precompute();
136  }
137 
138  void Precompute() {
139    mFlags = 0;
140        Vector3 dir = GetDir();
141
142#define BIDIRECTIONAL_RAY 0
143#if BIDIRECTIONAL_RAY
144        if (dir.y < 0) {
145          // swap objects and poits     
146          swap(mOriginObject, mTerminationObject);
147          swap(mOrigin, mTermination);
148          dir = -dir;
149        }
150#endif
151        if (dir.x > 0.0f) mFlags |= FPosDirX;
152    if (dir.y > 0.0f) mFlags |= FPosDirY;
153    if (dir.z > 0.0f) mFlags |= FPosDirZ;
154
155    mInvSize = 1.0f/Magnitude(GetDir());
156  }
157
158  void Mail() { mMailbox = mailID; }
159  static void NewMail() { mailID++; }
160  bool Mailed() const { return mMailbox == mailID; }
161
162  bool Mailed(const int mail) {
163    return mMailbox >= mailID + mail;
164  }
165
166  int HitCount() const {
167#if BIDIRECTIONAL_RAY
168        if (mOriginObject && mTerminationObject)
169          return 2;
170        if (mOriginObject || mTerminationObject)
171          return 1;
172        return 0;
173#else
174        return (mTerminationObject) ? 1 : 0;
175#endif
176  }
177       
178  Vector3 GetOrigin() const { return mOrigin; }
179  Vector3 GetTermination() const { return mTermination; }
180  Vector3 GetDir() const { return mTermination - mOrigin; }
181  //  Vector3 GetNormalizedDir() const { return Normalize(termination - mOrigin); }
182  Vector3 GetNormalizedDir() const { return (mTermination - mOrigin)*mInvSize; }
183
184  float Length() const { return Distance(mOrigin, mTermination); }
185
186  Vector3 Extrap(const float t) const {
187        return GetOrigin() + t * GetDir();
188  }
189       
190  float GetDirParametrization(const int axis) const;
191  float GetOpositeDirParametrization(const int axis) const;
192
193  static float VssRay::GetDirParam(const int axis, const Vector3 dir);
194
195  float GetSize() const { return  1.0f/mInvSize; }
196  float GetInvSize() const { return  mInvSize; }
197  float GetOrigin(const int axis) const { return mOrigin[axis]; }
198  float GetTermination(const int axis) const { return mTermination[axis]; }
199  float GetDir(const int axis) const { return mTermination[axis] - mOrigin[axis]; }
200  float GetNormalizedDir(const int axis) const {
201    return (mTermination[axis] - mOrigin[axis])*mInvSize;
202  }
203       
204  bool
205  ComputeMinMaxT(const AxisAlignedBox3 &box,
206                                 float &tmin,
207                                 float &tmax) const;
208       
209  bool
210  Intersects(const AxisAlignedBox3 &box,
211                         float &tmin,
212                         float &tmax) const;
213       
214  bool
215  IntersectsSphere(const Vector3 &center,
216                                   const float sqrRadius,
217                                   Vector3 &point,
218                                   float &t) const;
219       
220  void
221  Translate(const Vector3 &translation) {
222    mOrigin += translation;
223    mTermination += translation;
224  }
225
226  void SetupEndPoints(const Vector3 &origin,
227                                          const Vector3 &termination)
228  {
229        mOrigin = origin;
230        mTermination = termination;
231        Precompute();
232  }
233                                                                                       
234  bool HasPosDir(const int axis) const { return mFlags & (1<<axis); }
235
236  char Flags() const { return mFlags;}  void SetFlags(char orFlag) { mFlags |= orFlag;}
237 
238  bool IsActive() const { return mRefCount>0; }
239       
240  // reference counting for leaf nodes
241  int RefCount() const { return mRefCount; }
242  int Ref() { return mRefCount++; }
243       
244  void ScheduleForRemoval() { if (mRefCount>0) mRefCount = -mRefCount; }
245  bool ScheduledForRemoval() const { return mRefCount<0; }
246  void Unref() {
247    if (mRefCount > 0)
248      mRefCount--;
249    else
250      if (mRefCount < 0)
251                mRefCount++;
252      else {
253                cerr<<"Trying to unref already deleted ray!"<<endl;
254                exit(1);
255      }
256  }
257
258  static Vector3
259  GetDirection(const float a, const float b) {
260        return Vector3(sin(a), sin(b), cos(a));
261  }
262
263  friend bool GreaterWeightedPvsContribution(const VssRay * a,
264                                                                                         const VssRay *b) {
265        return a->mWeightedPvsContribution > b->mWeightedPvsContribution;
266  }
267
268  float SqrDistance(const Vector3 &point) const {
269        Vector3 diff = point - mOrigin;
270        float t = DotProd(diff, GetDir());
271       
272    if ( t <= 0.0f ) {
273          t = 0.0f;
274    } else {
275          if (t >= 1.0f) {
276                t = 1.0f;
277          } else {
278        t /= SqrMagnitude(GetDir());
279          }
280          diff -= t*GetDir();
281        }
282    return SqrMagnitude(diff);
283  }
284
285  void GetSampleData(
286          const bool isTerminaton,
287          Vector3 &pt,
288          Intersectable **obj,
289          KdNode **node) const;
290
291  friend ostream& operator<< (ostream &s, const VssRay &vssRay);
292   
293};
294
295void
296GenerateExtendedConvexCombinationWeights(float &w1,
297                                                                                 float &w2,
298                                                                                 float &w3,
299                                                                                 const float overlap
300                                                                                 );
301
302void
303GenerateExtendedConvexCombinationWeights2(float &w1,
304                                                                                  float &w2,
305                                                                                  const float overlap
306                                                                                  );
307
308// Overload << operator for C++-style output
309inline ostream&
310operator<< (ostream &s, const VssRay &vssRay)
311{
312        return s
313                << "(" << vssRay.mPass << ", " << vssRay.mOrigin << ", " << vssRay.mTermination
314                << ", " << vssRay.mOriginObject << ", " << vssRay.mTerminationObject << ", " << vssRay.mPdf << ")";
315}
316
317// --------------------------------------------------------------
318// For sorting rays
319// --------------------------------------------------------------
320struct  SortableEntry
321{
322  enum EType {
323    ERayMin,
324    ERayMax
325  };
326
327  int type;
328  float value;
329  void *data;
330 
331  SortableEntry() {}
332  SortableEntry(const int t, const float v, void *d):type(t),
333                                                                                                         value(v),
334                                                                                                         data(d) {}
335       
336  friend bool operator<(const SortableEntry &a, const SortableEntry &b) {
337    return a.value < b.value;
338  }
339};
340
341struct VssRayContainer : public vector<VssRay *>
342{
343  void PrintStatistics(ostream &s);
344  int SelectRays(const int number, VssRayContainer &selected, const bool copy=false) const;
345  int
346  GetContributingRays(VssRayContainer &selected,
347                                          const int minPass
348                                          ) const;
349 
350};
351
352};
353
354#endif
Note: See TracBrowser for help on using the repository browser.