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

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