source: GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp @ 2743

Revision 2743, 11.6 KB checked in by mattausch, 16 years ago (diff)
RevLine 
[1520]1#include "IntelRayCaster.h"
2#include "VssRay.h"
3#include "Preprocessor.h"
[1942]4#include "SceneGraph.h"
[1520]5
6#ifdef GTP_INTERNAL
7#include "ArchModeler2MLRT.hxx"
8
[1952]9#define DEBUG_RAYCAST 0
[1520]10
11
12namespace GtpVisibilityPreprocessor {
13
14
[2572]15FILE *fileOut = 0;
[2575]16bool saveRays = false;
[2606]17bool saveMutationRays = false;
[2575]18const int saveRaysStart = 3000000;
[2572]19int cntSavedRaysFLUSH = 0;
20unsigned long int cntSavedRays = 0;
[2574]21const int intSavedLIMIT = 1024;
[2575]22
[2572]23void
24InitSaving()
25{
26  fileOut = fopen("fileRays.txt", "wb");
27  if (!fileOut) {
28    cout << "ERROR: file fileRays.txt cannot be opened .. exiting" << endl;
29    exit(3);
30  }
31}
32void
33FinishSaving()
34{
35  fclose(fileOut);
36}
37
[1960]38IntelRayCaster::IntelRayCaster(const Preprocessor &preprocessor,
[2572]39                               const string externKdTree):
[1520]40RayCaster(preprocessor)
41{
[2572]42  if (!InitRayCast(externKdTree))
43    cout << "warning: intel ray tracer could not be initialized!" << endl;
[2606]44  if (saveRays || saveMutationRays)
[2572]45    InitSaving();
[1520]46}
47
48
49IntelRayCaster::~IntelRayCaster()
50{
[2572]51  if (saveRays)
52    FinishSaving();
[1520]53}
54
55
56bool IntelRayCaster::InitRayCast(const string externKdTree)
57{
[2572]58  cout<<"Intel ray cast file: " << externKdTree << endl;
[2003]59       
[2572]60  return mlrtaLoadAS(externKdTree.c_str());
[1520]61}
62
[2606]63
[2582]64// Using packet of 4 rays supposing that these are coherent
65// We give a box to which each ray is clipped to before the
66// ray shooting is computed !
[2606]67
68// Using packet of 4 rays supposing that these are coherent
69// We give a box to which each ray is clipped to before the
70// ray shooting is computed !
[2582]71void IntelRayCaster::CastRaysPacket4(const Vector3 &minBox,
72                                                                         const Vector3 &maxBox,
73                                                                         const Vector3 origin4[],
74                                                                         const Vector3 dirs4[],
75                                                                         int     result4[],
76                                                                         float   dist4[])
77{
78  for (int i = 0; i < 4; i++) {
79    mlrtaStoreRayASEye4(&origin4[i].x, &dirs4[i].x, i);
80  }
81 
[2729]82  rawCastTimer.Entry();
[2582]83  mlrtaTraverseGroupASEye4(&minBox.x, &maxBox.x, result4, dist4);
[2729]84  rawCastTimer.Exit();
[2606]85
86  if (saveMutationRays) {
87    fprintf(fileOut, "I %4.7f %4.7f %4.7f %4.7f %4.7f %4.7f\n",
88                        minBox.x, minBox.y, minBox.z, maxBox.x, maxBox.y, maxBox.z);
89    for (int i = 0; i < 4; i++) {
90      fprintf(fileOut, "%d %4.7f %4.7f %4.7f %4.7f %4.7f %4.7f %d %4.7f\n",
91                          cntSavedRays,
92                          origin4[i].x,
93                          origin4[i].y,
94                          origin4[i].z,
95                          dirs4[i].x,
96                          dirs4[i].y,
97                          dirs4[i].z,
98                          (result4[i] != -1) ? 1 : 0,
99                          (result4[i] != -1) ? dist4[i] : 0);
100      cntSavedRays ++;
101      cntSavedRaysFLUSH++;
102    }
103    if (cntSavedRaysFLUSH > intSavedLIMIT) {
104      fflush(fileOut);
105      cntSavedRaysFLUSH = 0;
106    }
107  } // if we are saving rays
108
[2582]109  return;
110}
[1520]111
[2582]112
113 
114int IntelRayCaster::CastRay(const SimpleRay &simpleRay,
115                                                        VssRayContainer &vssRays,
116                                                        const AxisAlignedBox3 &box,
117                                                        const bool castDoubleRay,
118                                                        const bool pruneInvalidRays
119                                                        )
[2572]120
121  //cout << "intel ray" << endl;
[2743]122  VssRay *vssRay = NULL;
[2572]123  int hits = 0;
124  int hittriangle;
125  Intersection hitA(simpleRay.mOrigin), hitB(simpleRay.mOrigin);
126 
127  float dist;
128  double normal[3];
[2729]129
130  rawCastTimer.Entry();
[2572]131 
132  hittriangle = mlrtaIntersectAS(
133                                 &simpleRay.mOrigin.x,
134                                 &simpleRay.mDirection.x,
135                                 normal,
136                                 dist);
[2729]137
138  rawCastTimer.Exit();
[2572]139 
[2743]140 
[2572]141  if (hittriangle != -1 ) {
142    Intersectable *intersect = mPreprocessor.GetParentObject(hittriangle);
143   
144    if (intersect)
145    {
[2743]146                hitA.mObject = intersect;
147                hitA.mNormal = Vector3(normal[0], normal[1], normal[2]);
148
149                // Get the normal of that face
150                // Mesh *mesh = ((MeshInstance *)objectA)->GetMesh();
151                // normalA = mesh->GetFacePlane(mFaceParents[forward_hit_triangles[i]].mFaceIndex).mNormal;
152                // -rays[index+i].mDirection; // $$ temporary
153                hitA.mPoint = simpleRay.Extrap(dist);
[2572]154    }
155  }
156 
157  if (castDoubleRay)
158  {
159    Vector3 dir = -simpleRay.mDirection;
[2729]160
161        rawCastTimer.Entry();
162
163        hittriangle = mlrtaIntersectAS(
[2572]164                                   &simpleRay.mOrigin.x,
165                                   &dir.x,
166                                   normal,
167                                   dist);
[2729]168       
169        rawCastTimer.Exit();
170
[2743]171        Intersectable *intersect = mPreprocessor.GetParentObject(hittriangle);
[1786]172               
[2572]173    if (intersect)
174    {
[2743]175                hitB.mObject = intersect;
176                hitB.mNormal = Vector3(normal[0], normal[1], normal[2]);
177                // Get the normal of that face
178                // Mesh *mesh = ((MeshInstance *)objectB)->GetMesh();
179        //  normalA = mesh->GetFacePlane(mFaceParents[forward_hit_triangles[i]].mFaceIndex).mNormal;
180                //-rays[index+i].mDirection; // $$ temporary
181                hitB.mPoint = simpleRay.Extrap(dist);
[2572]182    }
183  }
[2743]184/*
[2574]185  if (saveRays && preprocessor->mTotalRaysCast > saveRaysStart) {   
[2572]186    if (castDoubleRay)
[1520]187        {
[2572]188      fprintf(fileOut, "D %d %4.7f %4.7f %4.7f %4.7f %4.7f %4.7f %d %4.7f %d %4.7f\n",
189              cntSavedRays,
190              simpleRay.mOrigin.x,
191              simpleRay.mOrigin.y,
192              simpleRay.mOrigin.z,
193              simpleRay.mDirection.x,
194              simpleRay.mDirection.y,
195              simpleRay.mDirection.z,
196              hitA.mObject ? 1 : 0,
197              hitA.mObject ? dist1 : 0,
198              hitB.mObject ? 1 : 0,
199              hitB.mObject ? dist2 : 0
200              );
[1520]201        }
[2572]202    else
203      fprintf(fileOut, "S %d %4.7f %4.7f %4.7f %4.7f %4.7f %4.7f %d %4.7f\n",
204              cntSavedRays,
205              simpleRay.mOrigin.x,
206              simpleRay.mOrigin.y,
207              simpleRay.mOrigin.z,
208              simpleRay.mDirection.x,
209              simpleRay.mDirection.y,
210              simpleRay.mDirection.z,
211              hitA.mObject ? 1 : 0,
212              hitA.mObject ? dist1 : 0
213              );
214    cntSavedRays++;
215    cntSavedRaysFLUSH++;
216    if (cntSavedRaysFLUSH > intSavedLIMIT) {
217      fflush(fileOut);
218      cntSavedRaysFLUSH = 0;
219    }
220  }     
[2743]221  */
[2572]222  return ProcessRay(
223                    simpleRay,
224                    hitA,
225                    hitB,
226                    vssRays,
227                    box,
228                    castDoubleRay,
229                    pruneInvalidRays
230                    );
[1520]231}
[2572]232 
[1520]233
234void IntelRayCaster::CastRays16(
[2572]235                                SimpleRayContainer &rays,
236                                VssRayContainer &vssRays,
237                                const AxisAlignedBox3 &sbox,
238                                const bool castDoubleRay,
239                                const bool pruneInvalidRays)
[1520]240{
[2572]241  CastRays16(rays, 0, vssRays, sbox, castDoubleRay, pruneInvalidRays);
[2076]242}
[2572]243 
[2076]244void IntelRayCaster::CastRays16(
[2572]245                                SimpleRayContainer &rays,
246                                const int offset,
247                                VssRayContainer &vssRays,
248                                const AxisAlignedBox3 &sbox,
249                                const bool castDoubleRay,
250                                const bool pruneInvalidRays)
251
[2076]252  int i, k;
253  const int num = 16;
254 
[1520]255#if DEBUG_RAYCAST
[2076]256  Debug<<"C16 "<<flush;
257  static int counter=0;
258  Debug<<counter++<<endl;
[1520]259#endif
[2076]260 
261  static int forward_hit_triangles[16];
262  static float forward_dist[16];
263 
264  static int backward_hit_triangles[16];
265  static float backward_dist[16];
266 
267 
268  Vector3 min = mPreprocessor.mSceneGraph->GetBox().Min();
269  Vector3 max = mPreprocessor.mSceneGraph->GetBox().Max();
[1520]270
[2076]271  for (k=offset, i=0; i < num; i++, k++) {
[1983]272#if DEBUG_RAYCAST
[2572]273    if (counter == 43964) {
274      Debug<<rays[k].mOrigin<<" "<<rays[k].mDirection<<endl;
275    }
[1983]276#endif
[2729]277
[2572]278    mlrtaStoreRayAS16(&rays[k].mOrigin.x,
279                      &rays[k].mDirection.x,
280                      i);
[2076]281  }
282 
[1757]283#if DEBUG_RAYCAST
[2076]284  Debug<<"TA\n"<<flush;
[1757]285#endif
[2729]286  rawCastTimer.Entry();
287
[2076]288  mlrtaTraverseGroupAS16(&min.x,
[2572]289                         &max.x,
290                         forward_hit_triangles,
291                         forward_dist);
[2076]292 
[2729]293  rawCastTimer.Exit();
294 
[1757]295#if DEBUG_RAYCAST
[2076]296  Debug<<"TAB\n"<<flush;
[1757]297#endif
298
[2076]299  if (castDoubleRay) {
[2572]300    for (k=offset, i=0; i < num; i++, k++)  {
301      Vector3 dir = -rays[k].mDirection;
302      mlrtaStoreRayAS16(&rays[k].mOrigin.x,
303                        &dir.x,
304                        i);
305    }
306   
[1757]307#if DEBUG_RAYCAST
[2572]308    Debug<<"TB\n"<<flush;
[1983]309#endif
[2729]310    rawCastTimer.Entry();
[2572]311    mlrtaTraverseGroupAS16(&min.x,
312                           &max.x,
313                           backward_hit_triangles,
314                           backward_dist);
[2729]315
316        rawCastTimer.Exit();
[2572]317  }
[1983]318       
319#if DEBUG_RAYCAST
[2572]320  Debug<<"BBB\n"<<flush;
[1757]321#endif
322
[2574]323  if (saveRays && preprocessor->mTotalRaysCast > saveRaysStart) {
[2572]324    if (castDoubleRay)
325      fprintf(fileOut, "G\n");
326    else
327      fprintf(fileOut, "H\n");
328  }
329 
330  for (i=0, k=offset; i < num; i++, k++)
331  {
332    Intersection hitA(rays[k].mOrigin), hitB(rays[k].mOrigin);
333
[1757]334#if DEBUG_RAYCAST
[2572]335    Debug<<"FH\n"<<flush;
[1757]336#endif
[1984]337
[2572]338    Intersectable *intersect =
339      mPreprocessor.GetParentObject(forward_hit_triangles[i]);
[1786]340
[2572]341    if (intersect)
342    {
343      hitA.mObject = intersect;
344      // Get the normal of that face
345      hitA.mNormal = mPreprocessor.GetParentNormal(forward_hit_triangles[i]);
346     
347      //-rays[index+i].mDirection; // $$ temporary
348      hitA.mPoint = rays[k].Extrap(forward_dist[i]);
349    }
350   
[1757]351#if DEBUG_RAYCAST
[2572]352    Debug<<"BH\n"<<flush;
[1757]353#endif
[1786]354
[2572]355    if (castDoubleRay)
356    {
357      Intersectable *intersect =
[2710]358                  mPreprocessor.GetParentObject(backward_hit_triangles[i]);
[2572]359     
360      if (intersect)
361      {
[2710]362                  hitB.mObject = intersect;
363                  hitB.mNormal = mPreprocessor.GetParentNormal(backward_hit_triangles[i]);
364                 
365                  // normalB = rays[i].mDirection; // $$ temporary
366                  hitB.mPoint = rays[k].Extrap(-backward_dist[i]);
[2572]367      }
368    }
[1786]369
370
[2574]371    if (saveRays && preprocessor->mTotalRaysCast > saveRaysStart) {
[2572]372      if (castDoubleRay)     
373        fprintf(fileOut, "%d %4.7f %4.7f %4.7f %4.7f %4.7f %4.7f %d %4.7f %d %4.7f\n",
374                cntSavedRays,
375                rays[k].mOrigin.x,
376                rays[k].mOrigin.y,
377                rays[k].mOrigin.z,
378                rays[k].mDirection.x,
379                rays[k].mDirection.y,
380                rays[k].mDirection.z,
381                hitA.mObject ? 1 : 0,
382                hitA.mObject ? forward_dist[i] : 0,
383                hitB.mObject ? 1 : 0,
384                hitB.mObject ? -backward_dist[i] : 0
385                );
386      else
387        fprintf(fileOut, "%d %4.7f %4.7f %4.7f %4.7f %4.7f %4.7f %d %4.7f\n",
388                cntSavedRays,
389                rays[k].mOrigin.x,
390                rays[k].mOrigin.y,
391                rays[k].mOrigin.z,
392                rays[k].mDirection.x,
393                rays[k].mDirection.y,
394                rays[k].mDirection.z,
395                hitA.mObject ? 1 : 0,
396                hitA.mObject ? forward_dist[i] : 0
397                );
398      cntSavedRays++;
399      cntSavedRaysFLUSH++;
400    }
[1786]401
[2572]402   
[1757]403#if DEBUG_RAYCAST
[2572]404    Debug<<"PR\n"<<flush;
[1757]405#endif
[1786]406
[2076]407#if 1
[2572]408    ProcessRay(rays[k],
409               hitA,
410               hitB,
411               vssRays,
412               sbox,
413               castDoubleRay,
414               pruneInvalidRays
415               );
[2076]416#endif
[2572]417  } // for
[1786]418
[2572]419  if (saveRays) {
420    if (cntSavedRaysFLUSH > intSavedLIMIT) {
421      fflush(fileOut);
422      cntSavedRaysFLUSH = 0;
423    }
424  }
425
[1520]426#if DEBUG_RAYCAST
[2572]427  Debug<<"C16F\n"<<flush;
[1520]428#endif
429}
430
[2076]431
432
[2105]433
434
[2076]435void
[2105]436IntelRayCaster::CastSimpleForwardRays(
[2572]437                                      SimpleRayContainer &rays,
438                                      const AxisAlignedBox3 &sbox
439                                      )
[2105]440{
441  int hit_triangles[16];
442  float dist[16];
443  Vector3 normals[16];
444  Vector3 min = sbox.Min();
445  Vector3 max = sbox.Max();
446 
[2705]447  int packets = (int)rays.size() / 16;
[2105]448 
449  int i, j, k = 0;
450  Vector3 dir;
451 
452  for (i=0; i < packets; i++) {
[2572]453    for (j=0; j < 16; j++, k++)
454      mlrtaStoreRayAS16(&rays[k].mOrigin.x,
455                        &rays[k].mDirection.x,
456                        j);
[2729]457    rawCastTimer.Entry();
458
[2572]459    mlrtaTraverseGroupAS16(&min.x,
460                           &max.x,
461                           hit_triangles,
462                           dist);       
[2729]463        rawCastTimer.Exit();
[2572]464  } // for
[2105]465
466
467  for (; k < rays.size(); k++) {
468        double normal[3];
[2729]469        rawCastTimer.Entry();
[2105]470        hit_triangles[0] = mlrtaIntersectAS(
[2572]471                                            &rays[k].mOrigin.x,
472                                            &rays[k].mDirection.x,
473                                            normal,
474                                            dist[0]);
[2729]475        rawCastTimer.Exit();
[2105]476  }
477 
478}
479
480
481void
[2705]482IntelRayCaster::CastRays(SimpleRayContainer &rays,
483                                                 VssRayContainer &vssRays,
484                                                 const AxisAlignedBox3 &sbox,
485                                                 bool castDoubleRay,
486                                                 bool pruneInvalidRays)
[2076]487{
488
[2705]489  int buckets = (int)rays.size() / 16;
[2076]490  int offset = 0;
[2105]491
492#if 0
493  int time = GetTime();
494  CastSimpleForwardRays(rays, sbox);
495  cout<<1e-3*2*rays.size()/TimeDiff(time, GetTime())<<" Mrays/sec"<<endl;
496#endif
[2076]497 
498  for (int i=0; i < buckets; i++, offset+=16) {
499        CastRays16(rays, offset, vssRays, sbox, castDoubleRay, pruneInvalidRays);
500
501        if ((int)rays.size() > 100000 && i % (100000/16) == 0)
502          cout<<"\r"<<offset<<"/"<<(int)rays.size()<<"\r";
503  }
504
[2187]505  for (; offset < (int)rays.size(); offset++)
[2076]506        CastRay(rays[offset], vssRays, sbox, castDoubleRay, pruneInvalidRays);
507
[1520]508}
509
[2076]510}
511
[1520]512#endif
Note: See TracBrowser for help on using the repository browser.