source: GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp @ 1932

Revision 1932, 7.6 KB checked in by mattausch, 18 years ago (diff)
Line 
1#include "VssRay.h"
2#include "AxisAlignedBox3.h"
3
4namespace GtpVisibilityPreprocessor {
5
6// Static variables
7int
8VssRay::mailID = 0;
9
10#define OLD_PARAM 0
11
12VssRay::VssRay(
13                 const Vector3 &origin,
14                 const Vector3 &termination,
15                 Intersectable *originObject,
16                 Intersectable *terminationObject,
17                 const int pass,
18                 const float pdf
19                 ):
20        mMailbox(-1),
21    mOrigin(origin),
22    mTermination(termination),
23        mOriginObject(originObject),
24        mTerminationObject(terminationObject),
25        mRefCount(0),
26    mFlags(0),
27        mPass(pass),
28        mViewCells(0),
29        mWeightedPvsContribution(0),
30        mPdf(pdf),
31        mTerminationNode(NULL),
32        mOriginNode(NULL),
33        mPvsContribution(0)
34{
35        Precompute();
36}
37
38
39VssRay::VssRay(const Ray &ray):
40        mRefCount(0),
41        mFlags(0),
42        mMailbox(-1),
43        mOriginObject(ray.sourceObject.mObject),
44        mPass(0),
45        mViewCells(0),
46        mPdf(1.0f),
47        mTerminationNode(NULL),
48        mOriginNode(NULL),
49        mPvsContribution(0)
50{
51        if (ray.sourceObject.mObject)
52                mOrigin = ray.Extrap(ray.sourceObject.mT);
53        else
54                mOrigin = ray.GetLoc();
55
56        //Debug << "origin: " << mOrigin << endl;
57        if (!ray.intersections.empty())
58        {
59                mTermination = ray.Extrap(ray.intersections[0].mT);
60                mTerminationObject = ray.intersections[0].mObject;
61        }
62        else
63        {
64                mTermination = ray.Extrap(1e6);//TODO: should be Limits::Infinity
65                mTerminationObject = NULL;
66        }
67
68        Precompute();
69}
70
71
72void VssRay::Precompute()
73{
74        mFlags = 0;
75        Vector3 dir = GetDir();
76//mFlags |= BorderSample;
77#define BIDIRECTIONAL_RAY 0
78#if BIDIRECTIONAL_RAY
79        if (dir.y < 0) {
80                // swap objects and poits       
81                swap(mOriginObject, mTerminationObject);
82                swap(mOrigin, mTermination);
83                dir = -dir;
84        }
85#endif
86        if (dir.x > 0.0f) mFlags |= FPosDirX;
87        if (dir.y > 0.0f) mFlags |= FPosDirY;
88        if (dir.z > 0.0f) mFlags |= FPosDirZ;
89
90        mInvSize = 1.0f/Magnitude(GetDir());
91}
92
93
94bool
95VssRay::ComputeMinMaxT(const AxisAlignedBox3 &box,
96                                           float &tmin,
97                                           float &tmax) const
98{
99       
100  float minx, maxx, miny, maxy, minz, maxz;
101  Vector3 dir = GetDir();
102 
103  if (fabs(dir.x) < 0.001) {
104    if (box.Min().x < GetOrigin().x && box.Max().x > GetOrigin().x) {
105      minx = -MAXFLOAT;
106      maxx = MAXFLOAT;
107    }
108    else
109      return false;
110  }
111  else {
112    float t1 = (box.Min().x - GetOrigin().x) / dir.x;
113    float t2 = (box.Max().x - GetOrigin().x) / dir.x;
114    if (t1 < t2) {
115      minx = t1;
116      maxx = t2;
117    }
118    else {
119      minx = t2;
120      maxx = t1;
121    }
122    if (maxx < 0)
123      return false;
124  }
125
126  if (fabs(dir.y) < 0.001) {
127    if (box.Min().y < GetOrigin().y && box.Max().y > GetOrigin().y) {
128      miny = -MAXFLOAT;
129      maxy = MAXFLOAT;
130    }
131    else
132      return false;
133  }
134  else {
135    float t1 = (box.Min().y - GetOrigin().y) / dir.y;
136    float t2 = (box.Max().y - GetOrigin().y) / dir.y;
137    if (t1 < t2) {
138      miny = t1;
139      maxy = t2;
140    }
141    else {
142      miny = t2;
143      maxy = t1;
144    }
145    if (maxy < 0.0)
146      return false;
147  }
148       
149  if (fabs(dir.z) < 0.001) {
150    if (box.Min().z < GetOrigin().z && box.Max().z > GetOrigin().z) {
151      minz = -MAXFLOAT;
152      maxz = MAXFLOAT;
153    }
154    else
155      return false;
156  }
157  else {
158    float t1 = (box.Min().z - GetOrigin().z) / dir.z;
159    float t2 = (box.Max().z - GetOrigin().z) / dir.z;
160    if (t1 < t2) {
161      minz = t1;
162      maxz = t2;
163    }
164    else {
165      minz = t2;
166      maxz = t1;
167    }
168    if (maxz < 0.0)
169      return false;
170  }
171
172  tmin = minx;
173  if (miny > tmin)
174    tmin = miny;
175  if (minz > tmin)
176    tmin = minz;
177
178  tmax = maxx;
179  if (maxy < tmax)
180    tmax = maxy;
181  if (maxz < tmax)
182    tmax = maxz;
183
184  return 1; // yes, intersection was found
185}
186
187
188
189bool
190VssRay::Intersects(const AxisAlignedBox3 &box,
191                                   float &tmin,
192                                   float &tmax) const
193{
194  if (!ComputeMinMaxT(box, tmin, tmax))
195    return false;
196       
197  if ( tmax < tmin)
198    return false; // the ray passes outside the box
199 
200  if ( tmax < 0.0f)
201    return false; // the intersection is not on the positive halfline
202 
203  return true; // ray hits the box .. origin can be outside or inside the box
204}
205
206
207bool
208VssRay::IntersectsSphere(const Vector3 &center,
209                                                 const float sqrRadius,
210                                                 Vector3 &point,
211                                                 float &t) const
212{
213  // compute ray/plane intersection
214  Vector3 dir = GetDir();
215       
216  t = -DotProd(GetOrigin() - center, dir)*sqr(GetInvSize());
217       
218  if (t < 0.0f)
219    t = 0.0f;
220  else
221    if (t > 1.0f)
222      t = 1.0f;
223 
224  point = GetOrigin() + t*dir;
225 
226  return GtpVisibilityPreprocessor::SqrDistance(point, center) < sqrRadius;
227}
228
229
230float
231VssRay::GetDirParam(const int axis, const Vector3 dir)
232{
233  Vector3 d = Normalize(dir);
234#if OLD_PARAM
235  return (axis == 0) ? atan2(dir.x, dir.z) : asin(dir.y);
236#else
237  //  x = cos(p0)sin(p1)
238  //  y = cos(p1)
239  //  z = sin(p0)sin(p1)
240  return (axis == 0) ? atan2(dir.z, dir.x) : acos(dir.y);
241#endif
242}
243
244Vector3 VssRay::GetInvDirParam(const float alpha, const float beta)
245{
246#if OLD_PARAM
247  return Normalize(Vector3(sin(alpha), sin(beta), cos(alpha)));
248
249#else
250  return Normalize(Vector3(cos(alpha)*sin(beta),
251                                                   cos(beta),
252                                                   sin(alpha)*sin(beta)));
253#endif
254}
255
256float
257VssRay::GetDirParametrization(const int axis) const
258{
259  Vector3 dir = GetNormalizedDir();
260  return GetDirParam(axis, dir);
261}
262
263float
264VssRay::GetOpositeDirParametrization(const int axis) const
265{
266  Vector3 dir = -GetNormalizedDir();
267  return GetDirParam(axis, dir);
268}
269
270
271void
272GenerateExtendedConvexCombinationWeights2(float &w1,
273                                                                                  float &w2,
274                                                                                  const float overlap
275                                                                                  )
276{
277  w1 = RandomValue(-overlap, 1.0f + overlap);
278  w2 = 1.0f - w1;
279}
280
281void
282GenerateExtendedConvexCombinationWeights(float &w1,
283                                                                                 float &w2,
284                                                                                 float &w3,
285                                                                                 const float overlap
286                                                                                 )
287{
288
289  while (1) {
290        w1 = RandomValue(-overlap, 1.0f + overlap);
291        w2 = RandomValue(-overlap, 1.0f + overlap);
292        w3 = 1.0f + overlap - w1 - w2;
293        if (w3 >= -overlap && w3 <= 1.0f + overlap)
294          break;
295        /*
296        w3 = RandomValue(0.0f, 1.0f + overlap);
297       
298        float sum = w1 + w2 + w3;
299        if (sum>0.0f) {
300          w1/=sum;
301          w2/=sum;
302          w3/=sum;
303          break;
304        }
305        */
306  }
307}
308
309
310void
311VssRayContainer::PrintStatistics(ostream &s)
312{
313
314  VssRayContainer::const_iterator it = begin(), it_end = end();
315  int sumContributions = 0;
316  float sumRelContributions = 0.0f;
317 
318  for (; it != it_end; ++it) {
319        VssRay *ray = *it;
320        sumContributions += ray->mPvsContribution;
321        sumRelContributions += ray->mRelativePvsContribution;
322  }
323 
324  s<<"##### VSS RAY STAT ##########\n";
325  s<<"#RAYS\n"<<(int)size()<<endl;
326  s<<"#AVG_RAY_PVS_CONTRIBUTION\n"<<sumContributions/(float)size()<<endl;
327  s<<"#AVG_RAY_RELATIVE_PVS_CONTRIBUTION\n"<<sumRelContributions/
328        (float)size()<<endl;
329 
330}
331
332
333int
334VssRayContainer::SelectRays(const int number,
335                                                        VssRayContainer &selected,
336                                                        const bool copy) const
337{
338  float p = number/(float)size();
339  VssRayContainer::const_iterator it = begin();
340 
341  for (; it != end(); it++)
342        if (Random(1.0f) < p) {
343          if (!copy)
344                selected.push_back(*it);
345          else
346                selected.push_back(new VssRay(**it));
347        }
348 
349  return (int)selected.size();
350}
351
352
353int
354VssRayContainer::GetContributingRays(VssRayContainer &selected,
355                                                                         const int minPass
356                                                                         ) const
357{
358  VssRayContainer::const_iterator it = begin();
359
360  // ofstream s("contrib.log");
361
362  for (; it != end(); it++)
363  {
364          VssRay *ray = *it;
365
366          // s<<"(pass="<<ray->mPass<<", c="<<ray->mPvsContribution<<")"<<endl;
367          if (ray->mPass >= minPass && ray->mPvsContribution > 0)
368                  selected.push_back(ray);
369  }
370
371  return (int)selected.size();
372}
373
374
375
376}
Note: See TracBrowser for help on using the repository browser.