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

Revision 1966, 7.6 KB checked in by bittner, 17 years ago (diff)

samplign preprocessor updates, merge

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