source: GTP/trunk/Lib/Vis/Preprocessing/src/HavranDynRayCaster.cpp @ 2710

Revision 2710, 26.4 KB checked in by mattausch, 17 years ago (diff)
Line 
1
2// Written by Vlastimil Havran, December 2007
3
4// This macro allows to use the ray shooting written by
5// Vlastimil Havran, 2007-2008
6
7
8#include "VssRay.h"
9#include "KdTree.h"
10#include "Preprocessor.h"
11#include "IntersectableWrapper.h"
12
13#ifdef USE_HAVRAN_RAYCASTER
14#include "ktbconf.h"
15#include "timer.h"
16#include "ktball.h"
17#include "ktb.h"
18#ifdef _USE_HAVRAN_SSE
19
20#include "raypack.h"
21#endif // _USE_HAVRAN_SSE
22#endif // _USE_HAVRAN_RAYCASTER
23
24#include "HavranRayCaster.h"
25
26#define DEBUG_RAYCAST 0
27
28namespace GtpVisibilityPreprocessor {
29
30#ifdef _USE_HAVRAN_SSE
31// static rays
32GALIGN16 RayPacket2x2
33HavranDynRayCaster::raypack_t;
34#endif // _USE_HAVRAN_SSE
35 
36HavranDynRayCaster::HavranDynRayCaster(const Preprocessor &preprocessor):
37  HavranRayCaster(preprocessor), mDynKtbtree(0),
38  dynobjects(0), dynamicFlag(false)
39{
40#ifdef USE_HAVRAN_RAYCASTER
41#ifdef _USE_HAVRAN_SSE
42  if ( ((int)(&raypack_t)) & 0xf != 0) {
43    cerr << "The ray pack data type not aligned on 16 Bytes boundary" << endl;
44    cerr << "Address is " << (void*)(&raypack_t) << endl;
45    cerr << "Reorganize your data structure to make it aligned" << endl;
46    abort();
47  }
48#endif
49#endif
50}
51 
52
53HavranDynRayCaster::~HavranDynRayCaster()
54{
55#ifdef USE_HAVRAN_RAYCASTER
56  DeleteDynamicObjects();
57#endif // USE_HAVRAN_RAYCASTER
58}
59
60void
61HavranDynRayCaster::DeleteDynamicObjects()
62{
63#ifdef USE_HAVRAN_RAYCASTER
64  delete mDynKtbtree; mDynKtbtree = 0;
65  delete dynobjects; dynobjects = 0;
66  dynamicFlag = false;
67#endif // USE_HAVRAN_RAYCASTER
68}
69
70void
71HavranDynRayCaster::AddDynamicObjecs(const ObjectContainer &objects, const Matrix4x4 &m)
72{
73#ifdef USE_HAVRAN_RAYCASTER
74  if (dynobjects)
75    DeleteDynamicObjects();
76
77  dynamicFlag = false;
78
79  if (objects.size()) {
80    dynamicFlag = true;
81    dynobjects = new ObjectContainer(objects);
82    assert(dynobjects);
83    // kd-tree built over the objects
84    mDynKtbtree = new CKTB;
85    mDynKtbtree->BuildUp(*dynobjects);
86
87    // The matrix to transform the objects
88    UpdateDynamicObjects(m);
89  }
90#endif // USE_HAVRAN_RAYCASTER 
91}
92
93void
94HavranDynRayCaster::UpdateDynamicObjects(const Matrix4x4 &m)
95{
96#ifdef USE_HAVRAN_RAYCASTER
97  matTr = m;
98  matTr_inv = Invert(matTr);
99#endif // USE_HAVRAN_RAYCASTER
100}
101
102// Using packet of 4 rays supposing that these are coherent
103// We give a box to which each ray is clipped to before the
104// ray shooting is computed !
105void HavranDynRayCaster::CastRaysPacket4(const Vector3 &minBox,
106                                         const Vector3 &maxBox,
107                                         const Vector3 origin4[],
108                                         const Vector3 direction4[],
109                                         int     result4[],
110                                         float   dist4[])
111{
112#ifdef USE_HAVRAN_RAYCASTER
113#ifdef _USE_HAVRAN_SSE 
114  for (int i = 0; i < 4; i++) {
115    result4[i] = -1;
116    result4_t[4] = -1;
117    raypack.SetLoc(i, origin4[i]);
118    raypack.SetDir(i, direction4[i]);
119  }
120 
121  // The same operations for packets of rays, if implemented by
122  // a particular ASDS, otherwise it is emulated by decomposition
123  // of a packet to individual rays and traced individually.
124  mKtbtree->FindNearestI(raypack, minBox, maxBox);
125 
126  for (int i = 0; i < 4; i++) {
127    // if ray intersects an object, we set the pointer to
128    // this object
129    Intersectable* intersectable = raypack.GetObject(i);
130    if (intersectable) {
131      result4[i] = intersectable->mId;
132      dist4[i] = raypack.GetT(i);
133    }
134  }
135
136  if (dynamicFlag) {
137    // The ray pack to be transformed
138    raypack_t = raypack;
139    raypack_t.ApplyTransform(matTr_inv);
140   
141    mDynKtbtree->FindNearestI(raypack_t, minBox, maxBox);
142   
143    for (int i = 0; i < 4; i++) {
144      // if ray intersects an object, we set the pointer to
145      // this object
146      Intersectable* intersectable = raypack_t.GetObject(i);
147      if (intersectable) {
148        float t = raypack_t.GetT(i);
149        if ( ( (result4[i] != -1) && (t < dist4[i]) ) ||
150             (result4[i] == -1) ) {
151          // update, dynamic object is closer
152          dist4[i] = t;
153          result4[i] = intersectable->mId;
154        }
155      }
156    } // for i
157  } // dynamic flag
158   
159  return;
160#else // _USE_HAVRAN_SSE
161  // Compute the result ray by ray
162  SimpleRay sray;
163  for (int i = 0; i < 4; i++) {
164    result4[i] = -1; // no intersection
165    sray.mOrigin = origin4[i];
166    sray.mDirection = direction4[i];
167    mKtbtree->FindNearestI(sray, minBox, maxBox);
168    if (SimpleRay::IntersectionRes[0].intersectable) {
169      // This is object ID - is this the triangle index ???
170      result4[i] = SimpleRay::IntersectionRes[0].intersectable->mId;
171      dist4[i] = SimpleRay::IntersectionRes[0].tdist;
172    }
173
174    if (dynamicFlag) {
175      // Now apply transform
176      ApplyTransform(sray);
177      mDynKtbtree->FindNearestI(sray, minBox, maxBox);
178      Intersectable *objdyn = SimpleRay::IntersectionRes[0].intersectable;
179      if (objdyn) {
180        float t = SimpleRay::IntersectionRes[0].tdist;
181        if ( ((result4[i] != -1) && (t < dist4[i])) ||
182             (result4[i] == -1) ) {
183          // = update, dynamic object is closer
184          dist4[i] = t;
185          result4[i] = objdyn->mId;
186        }
187      }
188    } // dynamic flag
189  } // for i;
190 
191#endif // _USE_HAVRAN_SSE 
192#endif // USE_HAVRAN_RAYCASTER
193}
194
195
196int HavranDynRayCaster::CastRay(const SimpleRay &simpleRay,
197                                VssRayContainer &vssRays,
198                                const AxisAlignedBox3 &box,
199                                const bool castDoubleRay,
200                                const bool pruneInvalidRays)
201{
202#ifdef USE_HAVRAN_RAYCASTER
203
204  // rays forwards - TESTED 21/1/2008 VH (only for forward rays)
205
206  int hits = 0;
207  Intersection hitA(simpleRay.mOrigin), hitB(simpleRay.mOrigin);
208   
209  // ray.mFlags &= ~Ray::CULL_BACKFACES;
210  bool result;
211  hitA.mObject = 0;
212  if ((result = mKtbtree->FindNearestI(simpleRay)))  {
213    hitA.mObject = SimpleRay::IntersectionRes[0].intersectable;
214    tdist[0] = SimpleRay::IntersectionRes[0].tdist;
215    hitA.mPoint = simpleRay.Extrap(tdist[0]);
216    hitA.mNormal = SimpleRay::IntersectionRes[0].intersectable->GetNormal(0);
217    //hitA.mNormal = (dynamic_cast< TriangleIntersectable *>
218    //              (hitA.mObject))->GetNormal(0);
219  }
220
221  if (dynamicFlag) {
222    bool result2 = false;
223    // For a dynamic object
224    sray_t = simpleRay;
225    // Now apply transform
226    ApplyTransform(sray_t);
227    if (mDynKtbtree->FindNearestI(sray_t)) {
228      float t = SimpleRay::IntersectionRes[0].tdist;
229      if  ( ((hitA.mObject) && (t < tdist[0])) ||
230          (!hitA.mObject) ) {
231        result = result2 = true; // dynamic object hit
232        // There is an intersection closer than the previous one
233        hitA.mObject = SimpleRay::IntersectionRes[0].intersectable;
234        tdist[0] = SimpleRay::IntersectionRes[0].tdist;
235        hitA.mPoint = simpleRay.Extrap(tdist[0]);
236        hitA.mNormal = hitA.mObject->GetNormal(0);
237        // We have to transform the normal
238        hitA.mNormal = TransformNormal(matTr_inv, hitA.mNormal);     
239      }
240    }
241    if (result && (!result2)) {
242      // We put back the result from hitA.mObject for ray tracing
243      SimpleRay::IntersectionRes[0].intersectable = hitA.mObject;
244      SimpleRay::IntersectionRes[0].tdist = tdist[0];
245    }
246  }
247 
248  bool resultB = false;
249  if (castDoubleRay) {
250    bool result2 = false;
251    // casting rays backward
252    Vector3 *v = (Vector3*)(&simpleRay.mDirection);
253    *v = -(*v);
254    // ray.mFlags &= ~Ray::CULL_BACKFACES;
255    if (mKtbtree->FindNearestI(simpleRay))  {
256      resultB = true;
257      hitB.mObject = SimpleRay::IntersectionRes[0].intersectable;
258      assert(hitB.mObject);
259      float tdist = SimpleRay::IntersectionRes[0].tdist;
260      hitB.mPoint = simpleRay.Extrap(tdist);
261      hitB.mNormal = hitB.mObject->GetNormal(0);
262    }
263   
264    if (dynamicFlag) {
265      // For a dynamic object
266      sray_t = simpleRay;
267      // Now apply transform
268      ApplyTransform(sray_t);
269      bool result2;
270      if ( mDynKtbtree->FindNearestI(sray_t)) {
271        assert(SimpleRay::IntersectionRes[0].intersectable);
272        float t = SimpleRay::IntersectionRes[0].tdist;
273        if ( ((hitB.mObject) && (t < tdist[0])) ||
274             (!hitB.mObject) ) {
275          // There is an intersection closer than the previous one
276          resultB = result2 = true; // dynamic object hit
277          hitB.mObject = SimpleRay::IntersectionRes[0].intersectable;
278          tdist[0] = SimpleRay::IntersectionRes[0].tdist;
279          hitB.mPoint = simpleRay.Extrap(tdist[0]);
280          hitB.mNormal = hitB.mObject->GetNormal(0);
281          // We have to transform the normal
282          hitB.mNormal = TransformNormal(matTr_inv, hitB.mNormal);     
283        }
284      }
285      if ((resultB) && (!result2)) {
286          // For visualization
287          SimpleRay::IntersectionRes[0].intersectable = hitB.mObject;
288          SimpleRay::IntersectionRes[0].tdist = tdist[0];
289        }     
290    } // dynamicFlag
291   
292    // restore the direction to the original
293    *v = -simpleRay.mDirection;
294  } // castDoubleRay
295
296#ifdef _PROCESS_RAY 
297  // This code is also in IntelRayCaster.cpp
298  return ProcessRay(
299                    simpleRay,
300                    hitA,
301                    hitB,
302                    vssRays,
303                    box,
304                    castDoubleRay,
305                    pruneInvalidRays
306                    );
307#else // _PROCESS_RAY
308  if (castDoubleRay)
309    return resultB;
310  return result;
311#endif // _PROCESS_RAY 
312
313#else
314  return 0;
315#endif // USE_HAVRAN_RAYCASTER   
316}
317
318void HavranDynRayCaster::CastRays16(SimpleRayContainer &rays,
319                                 VssRayContainer &vssRays,
320                                 const AxisAlignedBox3 &sbox,
321                                 const bool castDoubleRay,
322                                 const bool pruneInvalidRays)
323{
324  CastRays16(rays, 0, vssRays, sbox, castDoubleRay, pruneInvalidRays);
325}
326
327
328void HavranDynRayCaster::CastRays16(SimpleRayContainer &rays,
329                                 int offset,
330                                 VssRayContainer &vssRays,
331                                 const AxisAlignedBox3 &sbox,
332                                 const bool castDoubleRays,
333                                 const bool pruneInvalidRays)
334{
335#ifdef USE_HAVRAN_RAYCASTER
336 
337#if DEBUG_RAYCAST
338  Debug << "C16 " << flush;
339#endif
340
341  // Use special algorithm for 16 rays at once
342  if (castDoubleRays) {
343    // Here we decompose shooting into two phases
344
345    // First we delete the results from casting dynamic objects
346    if (dynamicFlag) {
347      for (int i = 0; i < 32; i++)
348        objI[i] = 0;
349    }
350    // Here we shoot first backward rays and forward ones
351    SimpleRayContainer::iterator sit = rays.begin() + offset;
352    SimpleRayContainer::const_iterator sit_end = rays.begin() + offset + 16;
353    for ( ; sit != sit_end; ++ sit)
354    {
355      (*sit).mDirection = - (*sit).mDirection;
356    }
357    // backward rays to be shot - saving with offset 16
358
359#ifdef _USE_HAVRAN_SSE 
360    mKtbtree->SetOffset(0);
361    mKtbtree->FindNearestI_16oneDir(rays, offset, 16);
362#else
363    mKtbtree->SetOffset(16);
364    mKtbtree->FindNearestI_16oneDirNoSSE(rays, offset);
365#endif // _USE_HAVRAN_SSE
366
367    if (dynamicFlag) {
368      for (int i = 0; i < 16; i++) {
369        // store the origin and direction of the ray
370        orig[i] = rays[offset+i].mOrigin;
371        dirs[i] = rays[offset+i].mDirection;
372
373        objI[i+16] = SimpleRay::IntersectionRes[i+16].intersectable;
374        if (objI[i+16])
375          normal[i+16] = objI[i+16]->GetNormal(0);
376        tdist[i+16] = SimpleRay::IntersectionRes[i+16].tdist;
377        ApplyTransform(rays[offset+i]);
378      } // for
379      // Now shoot the ray with dynamic object
380#ifdef _USE_HAVRAN_SSE 
381      mDynKtbtree->SetOffset(0);
382      mDynKtbtree->FindNearestI_16oneDir(rays, offset, 16);
383#else
384      mDynKtbtree->SetOffset(16);
385      mDynKtbtree->FindNearestI_16oneDirNoSSE(rays, offset);
386#endif // _USE_HAVRAN_SSE
387      for (int i = 0; i < 16; i++) {
388        Intersectable *intersectable =
389          SimpleRay::IntersectionRes[i+16].intersectable;
390        if (intersectable) {
391          float t = SimpleRay::IntersectionRes[i+16].tdist;
392          if  ( ((objI[i+16]) && (t < tdist[i+16])) ||
393                (!objI[i+16]) ) {
394            // There is an intersection closer than the previous one
395            objI[i+16] = intersectable;
396            tdist[i+16] = SimpleRay::IntersectionRes[i+16].tdist;
397            normal[i+16] = intersectable->GetNormal(0);
398            // We have to transform the normal
399            normal[i+16] = TransformNormal(matTr_inv, normal[i+16]);     
400          } // if update
401        } // if intersected dynamic object
402        else {
403          // we copy back the static object - only for visualization
404          SimpleRay::IntersectionRes[i+16].intersectable = objI[i+16];
405          SimpleRay::IntersectionRes[i+16].tdist = tdist[i+16];   
406        }
407      } // for
408    } // dynamic flag
409   
410    // set the ray direction to original direction
411    if (dynamicFlag) {
412      sit = rays.begin() + offset;
413      int i = 0;
414      for ( ; sit != sit_end; ++sit, ++i)
415      {
416        rays[offset+i].mOrigin = orig[i];
417        rays[offset+i].mDirection = -dirs[i];
418      }
419    }
420    else {
421      // no dynamic objects
422      sit = rays.begin() + offset;
423      for ( ; sit != sit_end; ++ sit)
424      {
425        (*sit).mDirection = - (*sit).mDirection;
426      }
427    }
428    // forward rays to be shot
429#ifdef _USE_HAVRAN_SSE
430    mKtbtree->SetOffset(0);
431    mKtbtree->FindNearestI_16oneDir(rays, offset, 0);
432#else
433    mKtbtree->SetOffset(0);
434    mKtbtree->FindNearestI_16oneDirNoSSE(rays, offset);
435#endif // _USE_HAVRAN_SSE
436
437    if (dynamicFlag) {
438      for (int i = 0; i < 16; i++) {
439        objI[i] = SimpleRay::IntersectionRes[i].intersectable;
440        if (objI[i])
441          normal[i] = objI[i]->GetNormal(0);
442        tdist[i] = SimpleRay::IntersectionRes[i].tdist;
443        ApplyTransform(rays[offset+i]);
444      } // for
445      // Now shoot the ray with dynamic object
446#ifdef _USE_HAVRAN_SSE 
447      mDynKtbtree->SetOffset(0);
448      mDynKtbtree->FindNearestI_16oneDir(rays, offset, 0);
449#else
450      mDynKtbtree->SetOffset(0);
451      mDynKtbtree->FindNearestI_16oneDirNoSSE(rays, offset);
452#endif // _USE_HAVRAN_SSE
453      for (int i = 0; i < 16; i++) {
454        Intersectable *intersectable
455          = SimpleRay::IntersectionRes[i].intersectable;
456        if (intersectable) {
457          float t = SimpleRay::IntersectionRes[i].tdist;
458          if  ( ((objI[i]) && (t < tdist[i])) ||
459                (!objI[i]) ) {
460            // There is an intersection closer than the previous one
461            objI[i] = intersectable;
462            tdist[i] = SimpleRay::IntersectionRes[i].tdist;
463            normal[i] = objI[i]->GetNormal(0);
464            // We have to transform the normal
465            normal[i] = TransformNormal(matTr_inv, normal[i]);
466          } // update
467        } // intersection
468        // we have to recover the ray
469        rays[offset+i].mOrigin = orig[i];
470        rays[offset+i].mDirection = -dirs[i];   
471      } // for i
472    } // dynamic flag
473  } // cast double rays
474  else {
475    // ONLY forward rays - TESTED 21/1/2007 VH
476
477    // First we delete the results from casting dynamic objects
478    if (dynamicFlag) {
479      for (int i = 0; i < 16; i++) {
480        objI[i] = 0;
481        orig[i] = rays[offset+i].mOrigin;
482        dirs[i] = rays[offset+i].mDirection;   
483      }
484    }
485
486    // Shoot all 16 rays  at the same time using a special algorithm
487    mKtbtree->SetOffset(0);
488#ifdef _USE_HAVRAN_SSE 
489    mKtbtree->FindNearestI_16oneDir(rays, offset, 0);   
490#else
491    mKtbtree->FindNearestI_16oneDirNoSSE(rays, offset);   
492#endif // _USE_HAVRAN_SSE
493
494    // Here we must add dynamic objects
495    if (dynamicFlag) {
496      for (int i = 0; i < 16; i++) {
497        objI[i] = SimpleRay::IntersectionRes[i].intersectable;
498        if (objI[i])
499          normal[i] = objI[i]->GetNormal(0);
500        tdist[i] = SimpleRay::IntersectionRes[i].tdist;
501        ApplyTransform(rays[offset+i]);
502      } // for
503      // Now shoot the ray with dynamic object
504#ifdef _USE_HAVRAN_SSE 
505      mDynKtbtree->SetOffset(0);
506      mDynKtbtree->FindNearestI_16oneDir(rays, offset, 0);
507#else
508      mDynKtbtree->SetOffset(0);
509      mDynKtbtree->FindNearestI_16oneDirNoSSE(rays, offset);
510#endif // _USE_HAVRAN_SSE
511      for (int i = 0; i < 16; i++) {
512        Intersectable *intersectable
513          = SimpleRay::IntersectionRes[i].intersectable;
514        if (intersectable) {
515          float t = SimpleRay::IntersectionRes[i].tdist;
516          if  ( ((objI[i]) && (t < tdist[i])) ||
517                (!objI[i]) ) {     
518            // There is an intersection closer than the previous one
519            objI[i] = intersectable;
520            tdist[i] = SimpleRay::IntersectionRes[i].tdist;
521            normal[i] = objI[i]->GetNormal(0);
522            // We have to transform the normal
523            normal[i] = TransformNormal(matTr_inv, normal[i]);
524          } // update
525        } // intersection
526        // we have to recover the rays back
527        rays[offset+i].mOrigin = orig[i];
528        rays[offset+i].mDirection = dirs[i];   
529      } // for i
530    } // dynamic flag
531  }
532 
533  if (dynamicFlag) {
534    for (int i=0, k=offset; i < 16; i++, k++)
535    {
536      Intersection hitA(rays[k].mOrigin), hitB(rays[k].mOrigin);
537
538#if DEBUG_RAYCAST
539      Debug<<"FH\n"<<flush;
540#endif
541
542      Intersectable *intersectable = objI[i];
543      // For visualization needs only - forward rays
544      SimpleRay::IntersectionRes[i].intersectable = objI[i];
545      SimpleRay::IntersectionRes[i].tdist = tdist[i];
546      if (intersectable)
547      {
548        hitA.mObject = intersectable;
549        // Get the normal of that face
550        hitA.mNormal = normal[i];
551       
552        //-rays[index+i].mDirection; // $$ temporary
553        hitA.mPoint = rays[k].Extrap(tdist[i]);
554      }
555   
556#if DEBUG_RAYCAST
557      Debug<<"BH\n"<<flush;
558#endif
559
560      if (castDoubleRays)
561      {
562        Intersectable *intersectable = objI[i+16];
563
564        if (intersectable)
565        {
566          hitB.mObject = intersectable;
567          hitB.mNormal = normal[i+16];
568          hitB.mPoint = rays[k].Extrap(-tdist[i+16]);
569        }
570      }
571   
572#if DEBUG_RAYCAST
573      Debug<<"PR\n"<<flush;
574#endif
575
576#ifdef _PROCESS_RAY 
577      ProcessRay(rays[k],
578                 hitA,
579                 hitB,
580                 vssRays,
581                 sbox,
582                 castDoubleRays,
583                 pruneInvalidRays
584                 );
585#endif
586    } // for
587  }
588  else {
589    // no dynamic objects
590    for (int i=0, k=offset; i < 16; i++, k++)
591    {
592      Intersection hitA(rays[k].mOrigin), hitB(rays[k].mOrigin);
593
594#if DEBUG_RAYCAST
595      Debug<<"FH\n"<<flush;
596#endif
597
598      Intersectable *intersectable
599        = SimpleRay::IntersectionRes[i].intersectable;
600
601      if (intersectable)
602      {
603        hitA.mObject = intersectable;
604        // Get the normal of that face
605        hitA.mNormal = intersectable->GetNormal(0);
606       
607        //-rays[index+i].mDirection; // $$ temporary
608        float tdist = SimpleRay::IntersectionRes[i].tdist;
609        hitA.mPoint = rays[k].Extrap(tdist);
610      }
611     
612#if DEBUG_RAYCAST
613      Debug<<"BH\n"<<flush;
614#endif
615
616      if (castDoubleRays)
617      {
618        Intersectable *intersectable =
619          SimpleRay::IntersectionRes[i+16].intersectable;
620       
621        if (intersectable)
622        {
623          hitB.mObject = intersectable;
624          hitB.mNormal = intersectable->GetNormal(0);;
625          float tdist = SimpleRay::IntersectionRes[16+i].tdist;
626          hitB.mPoint = rays[k].Extrap(-tdist);
627        }
628      }
629   
630#if DEBUG_RAYCAST
631      Debug<<"PR\n"<<flush;
632#endif
633
634#ifdef _PROCESS_RAY 
635      ProcessRay(rays[k],
636                 hitA,
637                 hitB,
638                 vssRays,
639                 sbox,
640                 castDoubleRays,
641                 pruneInvalidRays
642                 );
643#endif
644    } // for
645  } // dynamic objects
646
647 
648#if DEBUG_RAYCAST
649  Debug<<"C16F\n"<<flush;
650#endif
651
652#endif // USE_HAVRAN_RAYCASTER
653}
654
655
656
657void
658HavranDynRayCaster::CastSimpleForwardRays(
659                                          SimpleRayContainer &rays,
660                                          const AxisAlignedBox3 &sbox
661                                         )
662{
663#ifdef USE_HAVRAN_RAYCASTER
664
665  //int hit_triangles[16];
666  //float dist[16];
667  Vector3 normals[16];
668  Vector3 min = sbox.Min();
669  Vector3 max = sbox.Max();
670 
671  int packets = (int)rays.size() / 16;
672 
673  int i, k = 0;
674  Vector3 dir;
675 
676  // By groups of rays
677  for (i=0; i < packets; i++) {
678    int offset = i * 16;
679    mKtbtree->FindNearestI_16oneDir(rays, offset, 0);
680
681    if (dynamicFlag) {
682      for (int i = 0; i < 16; i++) {
683        orig[i] = rays[i].mOrigin;
684        dirs[i] = rays[i].mDirection;
685       
686        tdist[i] = SimpleRay::IntersectionRes[i].tdist;
687        objI[i] = SimpleRay::IntersectionRes[i].intersectable;
688        // for dynamic objects
689        ApplyTransform(rays[i]);
690      } // for
691
692      // shoot the rays against dynamic objects
693      mDynKtbtree->FindNearestI_16oneDir(rays, offset, 0);
694      // and combine the results
695      for (int i = 0; i < 16; i++) {
696        float t = SimpleRay::IntersectionRes[i].tdist;
697        if (SimpleRay::IntersectionRes[i].intersectable) {
698          if  ( ((objI[i]) && (t < tdist[i])) ||
699                (!objI[i]) ) {
700            // There is an intersection closer than the previous one
701            objI[i] = SimpleRay::IntersectionRes[i].intersectable;
702            tdist[i] = SimpleRay::IntersectionRes[i].tdist;
703          } // update
704        } // intersection
705        else {
706          // Only for visualization
707          SimpleRay::IntersectionRes[i].intersectable = objI[i];
708          SimpleRay::IntersectionRes[i].tdist = tdist[i];
709        }
710        // recover ray origin and direction
711        rays[i].mOrigin = orig[i];
712        rays[i].mDirection = dirs[i];   
713      } // for
714
715    } // dynamic objects
716   
717    // ??? What to do with the results ? These are
718    // not used at the moment also in IntelRayCaster.cpp
719  } // for
720
721
722  i = 0;
723  int k2 = k;
724  for (; k < rays.size(); k++, i++) {
725    //double normal[3];
726    // Intersect with the static scene
727    bool result = mKtbtree->FindNearestI(rays[k]);
728    tdist[i] = SimpleRay::IntersectionRes[0].tdist;
729    objI[i] = SimpleRay::IntersectionRes[0].intersectable;
730   
731    if (dynamicFlag) {
732      orig[i] = rays[k].mOrigin;
733      dirs[i] = rays[k].mDirection;
734
735      // Intersect with the dynamic object
736      ApplyTransform(rays[k]);
737      bool result2 = false;
738      if (mDynKtbtree->FindNearestI(rays[k])) {
739        float t = SimpleRay::IntersectionRes[0].tdist;
740        if  ( ((objI[i]) && (t < tdist[i])) ||
741              (!objI[i]) ) {
742          // There is an intersection closer than the previous one
743          result2 = true;
744          objI[i] = SimpleRay::IntersectionRes[0].intersectable;
745          tdist[i] = t;
746        }
747      }
748     
749      // recover ray origin and direction
750      rays[k].mOrigin = orig[i];
751      rays[k].mDirection = dirs[i];     
752    } // dynamic objects
753   
754    // ??? What to do with the results ? These are
755    // not used at the moment also in IntelRayCaster.cpp
756  }
757  // The result will be in the array
758  i = 0;
759  for (; k2 < rays.size(); k2++, i++) {
760    SimpleRay::IntersectionRes[i].intersectable = objI[i];
761    SimpleRay::IntersectionRes[i].tdist = tdist[i];
762  }
763#endif // USE_HAVRAN_RAYCASTER
764
765  return;
766}
767
768void HavranDynRayCaster::CastRays(
769                               SimpleRayContainer &rays,
770                               VssRayContainer &vssRays,
771                               const AxisAlignedBox3 &sbox,
772                               const bool castDoubleRay,
773                               const bool pruneInvalidRays )
774{
775  int buckets = (int)rays.size()/16;
776  int offset = 0;
777
778#if 0
779  int time = GetTime();
780  CastSimpleForwardRays(rays, sbox);
781  cout<<1e-3*2*rays.size()/TimeDiff(time, GetTime())<<" Mrays/sec"<<endl;
782#endif
783
784  // Cast only by 16 rays at once
785  for (int i=0; i < buckets; i++, offset+=16) {
786    CastRays16(rays, offset, vssRays, sbox,
787               castDoubleRay, pruneInvalidRays);
788
789    if ((int)rays.size() > 100000 && i % (100000/16) == 0)
790      cout<<"\r"<<offset<<"/"<<(int)rays.size()<<"\r";
791  }
792
793  // Cast the rest of the rays
794  for (; offset < (int)rays.size(); offset++)
795    CastRay(rays[offset], vssRays, sbox, castDoubleRay, pruneInvalidRays);
796
797  return;
798}
799
800#ifdef _USE_HAVRAN_SSE
801// BUG1 41579  196948 1064111
802// BUG2 254    1672   10869
803 
804// Just for testing concept
805void
806HavranDynRayCaster::CastRaysPacket2x2(RayPacket2x2 &raysPack,
807                                                                          bool castDoubleRay,
808                                                                          const bool pruneInvalidRays)
809{
810#ifdef USE_HAVRAN_RAYCASTER
811
812  if (castDoubleRay) {
813    // cast forward rays
814    mKtbtree->FindNearestI(raysPack);
815
816    if (dynamicFlag) {
817      // The ray pack to be transformed
818      raypack_t = raysPack;
819      raypack.ApplyTransform(matTr_inv);
820   
821      mDynKtbtree->FindNearestI(raypack_t);
822   
823      for (int i = 0; i < 4; i++) {
824        // if ray intersects an object, we set the pointer to
825        // this object
826        Intersectable* intersectable = raypack_t.GetObject(i);
827        if (intersectable) {
828          Intersectable *o = raysPack.GetObject(i);
829          if ( ((o) && (raypack_t.GetT(i) < tdist[i])) ||
830               (!o) ) {
831            // update, dynamic object is closer
832            raysPack.SetT(i, raypack_t.GetT(i));
833            raysPack.SetObject(i, raypack_t.GetObject(i));
834          } // if update is required
835        } // if intersectable
836      } // for i
837    } // dynamic object   
838
839    // Double (=opposite) direction
840    for (int i = 0; i < 4; i++)
841      raysPack.SetDir(i, -raysPack.GetDir(i));
842    // cast backward rays
843    mKtbtree->FindNearestI(raysPack);
844
845    if (dynamicFlag) {
846
847      // The ray pack to be transformed
848      raypack_t = raysPack;
849      raypack_t.ApplyTransform(matTr_inv);
850   
851      mDynKtbtree->FindNearestI(raypack_t);
852   
853      for (int i = 0; i < 4; i++) {
854        // if ray intersects an object, we set the pointer to
855        // this object
856        Intersectable* intersectable = raypack_t.GetObject(i);
857        if (intersectable) {
858          Intersectable *o = raysPack.GetObject(i);
859          if ( ((o) && (raypack_t.GetT(i) < tdist[i])) ||
860               (!o) ) {
861            // update, dynamic object is closer
862            raysPack.SetT(i, raypack_t.GetT(i));
863            raysPack.SetObject(i, raypack_t.GetObject(i));
864          } // if update is required
865        } // if intersectable
866      } // for i
867    } // dynamic object   
868   
869    // reverse the rays back
870    for (int i = 0; i < 4; i++)
871      raysPack.SetDir(i, -raysPack.GetDir(i));
872  }
873  else {
874    // ONLY forward rays - TESTED 21/1/2007 VH
875
876    mKtbtree->FindNearestI(raysPack);
877
878    if (dynamicFlag) {
879      // The ray pack to be transformed
880      raypack_t = raysPack;
881      raypack_t.ApplyTransform(matTr_inv);
882   
883      mDynKtbtree->FindNearestI(raypack_t);
884   
885      for (int i = 0; i < 4; i++) {
886        // if ray intersects an object, we set the pointer to
887        // this object
888        Intersectable* intersectable = raypack_t.GetObject(i);
889        if (intersectable) {
890          Intersectable *o = raysPack.GetObject(i);
891          if ( ((o) && (raypack_t.GetT(i) < tdist[i])) ||
892               (!o) ) {
893            // update, dynamic object is closer
894            raysPack.SetT(i, raypack_t.GetT(i));
895            raysPack.SetObject(i, raypack_t.GetObject(i));
896          } // if update is required
897        } // if intersectable
898      } // for i
899    } // dynamic object   
900   
901#if 0
902    // Only verification of correctness by casting single rays
903    static int cntBugs = 0;
904    SimpleRay ray;
905    int cntErrors = 0, cntDistErrors = 0;
906    bool newBug = false;
907    for (int i = 0; i < 4; i++) {
908      ray.mOrigin = raysPack.GetLoc(i);
909      ray.mDirection = raysPack.GetDir(i);
910      mKtbtree->FindNearestI(ray);
911      if (raysPack.GetObject(i) != SimpleRay::IntersectionRes[0].intersectable) {
912        float dist = (raysPack.GetT(i) - SimpleRay::IntersectionRes[0].tdist);
913        if (fabs(dist) > 0.001f) {
914          cntErrors++; newBug = true;
915          cntBugs++;
916          cout << " BUG1 d= " << dist;
917        }
918      }
919      else {
920        float dist = 0.f;
921        if (raysPack.GetObject(i) && SimpleRay::IntersectionRes[0].intersectable)
922          if (fabs((dist=(fabs (raysPack.GetT(i) - SimpleRay::IntersectionRes[0].tdist)))) > 1.f) {
923            cntDistErrors++; newBug = true; cntBugs++;
924            cout << " BUG2 distdf= " << dist ;     
925          }
926      }
927    } // for
928    if (newBug) cout << " CB= " << cntBugs << "\n";
929#endif
930  }
931
932  return;
933
934#endif // USE_HAVRAN_RAYCASTER
935
936}
937#endif // _USE_HAVRAN_SSE
938
939 
940} // the namespace
941
Note: See TracBrowser for help on using the repository browser.