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

Revision 2116, 7.6 KB checked in by mattausch, 17 years ago (diff)

implemented hashpvs

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