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

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