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

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