source: GTP/trunk/Lib/Vis/Preprocessing/src/havran/testrt.cpp @ 2656

Revision 2656, 33.6 KB checked in by mattausch, 16 years ago (diff)
Line 
1#define USE_THREADS 0
2
3#ifdef UNICODE
4#undef UNICODE
5#endif
6
7#define NOMINMAX
8#ifdef __WINDOWS__
9#include <windows.h>
10#ifdef _CRT_SET
11#include <crtdbg.h>
12#endif // _CRT_SET
13#endif
14#include <cstdio>
15
16#include "Camera.h"
17#include "PreprocessorFactory.h"
18#include "Parser.h"
19#include "Environment.h"
20#include "MeshKdTree.h"
21#include "Preprocessor.h"
22#include "common.h"
23#include "PreprocessorThread.h"
24#include "ObjExporter.h"
25#include "SceneGraph.h"
26#include "GlobalLinesRenderer.h"
27#include "RayCaster.h"
28#include "Triangle3.h"
29#include "IntersectableWrapper.h"
30#include "timer.h"
31#include "raypack.h"
32
33#include "ViewCellsManager.h"
34
35#ifdef USE_QT 
36/*      #include "QtPreprocessorThread.h"
37        #include "QtGlViewer.h"
38        #include "QtGlRenderer.h"
39        */
40#else
41        #if USE_THREADS
42#include "BoostPreprocessorThread.h"
43        #endif
44#endif
45
46#include "ResourceManager.h"
47#include "GlRenderer.h"
48
49
50#define USE_EXE_PATH false
51
52
53using namespace GtpVisibilityPreprocessor;
54
55//Preprocessor *preprocessor = NULL;
56extern GlRendererWidget *rendererWidget;
57//GlobalLinesRenderer *globalLinesRenderer = NULL;
58
59// DLL function signature
60typedef GlRendererWidget *(*importFunction)(Preprocessor *);
61
62
63// Flag if the ray should be single sided (one direction)
64// or double sided (shooting ray in both directions)
65static bool castDoubleRays;
66
67extern void Cleanup();
68
69void
70_SortRays2(SimpleRayContainer &rays,
71           const int l,
72           const int r,
73           const int depth,
74           float box[12])
75{
76  // pick-up a pivot
77  int axis;
78 
79  float maxDiff = -1.0f;
80  // get the largest axis
81  int offset = 0;
82  int i;
83
84  //const int batchsize = 16384;
85  //const int batchsize = 8192;
86  //const int batchsize = 128;
87  const int batchsize = 4;
88
89  //if (r - l < 16*batchsize)
90  //    offset = 3;
91       
92  //  if (depth%2==0)
93  //    offset = 3;
94 
95  for (i=offset; i < offset + 6; i++) {
96    float diff = box[i + 6] - box[i];
97    assert(diff >= 0.f);
98    if (diff > maxDiff) {
99      // Find the maximum
100      maxDiff = diff;
101      axis = i;
102    }
103  }
104
105  //  cout<<depth<<" "<<axis<<" "<<l<<" "<<r<<endl;
106 
107  i=l;
108  int j=r;
109
110  float x = (box[axis] + box[axis+6])*0.5f;
111  //  float x = rays[(l+r)/2].GetParam(axis);
112  do {
113        while(i<j && rays[i].GetParam(axis) < x)
114          i++;
115        while(i<j && x < rays[j].GetParam(axis))
116          j--;
117       
118        if (i <= j) {
119          swap(rays[i], rays[j]);
120          i++;
121          j--;
122        }
123  } while (i<=j);
124
125 
126  if (l + batchsize < j ) {
127        // set new max
128        float save = box[axis+6];
129        box[axis+6] = x;
130        _SortRays2(rays, l, j, depth+1, box);
131        box[axis+6] = save;
132  } else {
133        //      for (int k=0; k < 6; k++)
134        //        cout<<k<<" "<<box[k]<<" - "<<box[k+6]<<endl;
135  }
136 
137  if (i + batchsize < r) {
138    // set new min
139    box[axis] = x;
140    _SortRays2(rays, i, r, depth+1, box);
141  } else {
142        //      for (int k=0; k < 6; k++)
143        //        cout<<k<<" "<<box[k]<<" - "<<box[k+6]<<endl;
144  }     
145}
146
147void
148SortRays2(SimpleRayContainer &rays, const AxisAlignedBox3 &box)
149{
150  const float sizeBox = Magnitude(box.Diagonal());
151  // This is some size of the
152  const float sizeDir = 0.1f * sizeBox;
153 
154  float b[12]={
155    box.Min().x,
156    box.Min().y,
157    box.Min().z,
158    -sizeDir,
159    -sizeDir,
160    -sizeDir,
161    box.Max().x,
162    box.Max().y,
163    box.Max().z,
164    sizeDir,
165    sizeDir,
166    sizeDir
167  };
168
169 
170  _SortRays2(rays, 0, (int)rays.size()-1, 0, b);
171
172  return;
173}                                       
174
175
176static string GetInternFilename(const string &filename, const string newSuffix)
177{
178        vector<string> filenames;
179        const int files = SplitFilenames(filename, filenames);
180
181        vector<string>::const_iterator sit, sit_end = filenames.end();
182        string kdFilename;
183
184        int i = 0;
185        for (sit = filenames.begin(); sit != sit_end; ++ sit, ++ i)
186        {
187                string currentFile = *sit;
188                string strippedFilename;
189
190                if (i == 0)
191                {       
192                        strippedFilename = currentFile;
193                }
194                else
195                {
196                        char *str = StripPath(currentFile.c_str());
197                        strippedFilename = string(str);
198
199                        delete [] str;
200                }
201               
202                string suffix("_");
203
204                if (i == (int)filenames.size() - 1)
205                {
206                        suffix = newSuffix;
207                }
208
209                if (strstr(strippedFilename.c_str(), ".x3d"))
210                {
211                        kdFilename += ReplaceSuffix(strippedFilename, ".x3d", suffix);
212                }
213        else if (strstr(strippedFilename.c_str(), ".dat"))
214                {
215                        kdFilename += ReplaceSuffix(strippedFilename, ".dat", suffix);
216                }
217                else if (strstr(strippedFilename.c_str(), ".obj"))
218                {
219                        kdFilename += ReplaceSuffix(strippedFilename, ".obj", suffix);
220                }
221                else
222                {
223                        cerr << "Error: Currently unsupported format for kd, filename " << currentFile << endl;
224                }
225        }
226
227        //cout << "kdfilename: " << kdFilename << endl;
228        return kdFilename;
229}
230
231
232// -------------------------------------------------------
233// Written by Vlastimil Havran
234
235// This is for testing RT implementation
236void
237TestRTcamera(int argc, char **argv)
238{
239  int returnCode = 0;
240
241  InitTiming();
242  Debug.open("debug.log");
243
244  Environment::GetSingleton()->Parse(argc, argv, USE_EXE_PATH);
245  MeshKdTree::ParseEnvironment();
246
247  char buff[128];
248  Environment::GetSingleton()->GetStringValue("Preprocessor.type", buff);
249  string preprocessorType(buff);
250
251  if (!(preprocessor = PreprocessorFactory::CreatePreprocessor(preprocessorType)))
252  {
253    Environment::DelSingleton();
254    cerr << "Unknown preprocessor type" << endl;
255    exit(1);
256  }
257
258
259  Environment::GetSingleton()->GetStringValue("Scene.filename", buff);
260  string filename(buff);
261
262  const string externKdTree = ReplaceSuffix(filename, ".obj", ".kdf");
263  const string internKdTree = GetInternFilename(filename, preprocessor->mLoadMeshes ?
264                                                ".kdm" : ".kdt");
265
266  if (preprocessor->InitRayCast(externKdTree, internKdTree))
267  {
268    cout << "ray casting initialized!" << endl;
269  }
270  else
271  {
272    cout << "ray casting initialization failed!" << endl;
273    Cleanup();
274    exit(1);
275  }
276 
277  //Debug << "using pvs type " << PVS_TYPE << endl;
278
279  /////////////
280  //-- load scene
281 
282  if (!preprocessor->LoadScene(filename))
283  {
284    cout << "loading file " << filename << " failed" << endl;
285    Cleanup();
286    exit(1);
287  }
288       
289  ////////////
290  //-- initialize external ray caster
291 
292  if (preprocessor->LoadInternKdTree(internKdTree))
293  {
294    cout << "intern kd tree loaded!" << endl;
295  }
296  else
297  {
298    cout << "loading intern kd tree failed!" << endl;
299    Cleanup();
300    exit(1);
301  }
302 
303  // export objects as obj
304  if (preprocessor->mExportObj)
305  {
306    if (strstr(filename.c_str(), ".obj"))
307      {
308        cerr << "already in obj format" << endl;
309        if (0)  preprocessor->ExportObj("test.obj", preprocessor->mObjects);
310      }
311    else
312      {
313       
314        const string objname = GetInternFilename(filename, ".obj");
315       
316        cout << "exporting scene to " << objname << endl;
317        bool success = preprocessor->ExportObj(objname, preprocessor->mObjects);
318       
319       
320        if (success)
321          cout << "finished exporting obj" << endl;
322        else
323          cerr << "error exporting " << objname << endl;
324      }
325  }
326
327  int width = 1000;
328  int height = 500;
329  float fieldOfView = 115.f;
330  Camera cam(width, height, fieldOfView);
331 
332  AxisAlignedBox3 bboxOrig = preprocessor->mSceneGraph->GetBox();
333  AxisAlignedBox3 bbox = bboxOrig;
334  float sizeDiag = Magnitude(bbox.Diagonal());
335  bbox.Enlarge(sizeDiag * 1.5f);
336
337  Vector3 origin, dir;
338
339#define WIEN1
340//#define WIEN2
341//#define ARENA1
342   
343#ifdef WIEN1
344  // 1099.9 183.0 -387
345  origin = Vector3(1099.9f, 183.0f, -387.0f);
346  dir = Vector3(-0.6f, 0.0001f, -0.8f);
347  //dir = -dir;
348#define DIREXISTS
349#endif 
350#ifdef WIEN2
351  // 935.6 215.8 -1012.3
352  origin = Vector3(935.6, 215.8, -1012.4);
353  dir = Vector3(0.01f, 0.01f, 1.0f);
354#define DIREXISTS
355#endif
356#ifdef ARENA1
357  origin = Vector3(22.16, 19.63, -950.44);
358  dir = Vector3(0.9, 0.001f, -0.5f);
359#define DIREXISTS
360#endif 
361
362  cam.SetPosition(origin);
363
364#ifndef DIREXISTS
365  Vector3 center = bbox.Center();
366  dir = center - origin;
367#endif
368 
369  dir.Normalize();
370  cam.SetDirection(dir);
371  cout << "Computing image\n" << endl;
372
373  int id = (int)preprocessor->mObjects.size() + 1;
374   
375  //We add here a few objects
376  ObjectContainer dynObjects;
377  Vector3 baseVec = origin + dir * 2.0f;
378  Triangle3 tr1(baseVec, baseVec + Vector3(1, 0, 0),
379                baseVec + Vector3(0, 1, 0));           
380  TriangleIntersectable ti1(tr1);
381  dynObjects.push_back(&ti1);
382  ti1.mId = id+1;
383 
384  tr1.Init(baseVec, baseVec + Vector3(1, 0, 0),
385           baseVec + Vector3(0, 0, 1));       
386  TriangleIntersectable ti2(tr1);
387  dynObjects.push_back(&ti2);
388  ti2.mId = id+2;
389
390  tr1.Init(baseVec, baseVec + Vector3(0, 1, 0),
391           baseVec + Vector3(0, 0, 1));       
392  TriangleIntersectable ti3(tr1);
393  dynObjects.push_back(&ti3);
394  ti3.mId = id+3;
395
396#if 1
397  // This is required for cam.SnapImagePacket2
398  // otherwise dynamic object cannot be identified!
399  preprocessor->mObjects.push_back(&ti1);
400  preprocessor->mObjects.push_back(&ti2);
401  preprocessor->mObjects.push_back(&ti3);
402#endif
403
404  if (0) {
405    Matrix4x4 mat;
406    mat = IdentityMatrix();
407    mat = mat * TranslationMatrix(Vector3(-1, 0, 0));
408    preprocessor->mRayCaster->AddDynamicObjecs(dynObjects, mat);
409 
410#if 1
411    // ray by ray
412    cam.SnapImage("test-rays.tga",
413                  preprocessor->mRayCaster,
414                  bboxOrig,
415                  preprocessor->mSceneGraph);
416#endif
417#if 1
418    // using ray packets
419    cam.SnapImage2("test-oneDir.tga",
420                   preprocessor->mRayCaster,
421                   bboxOrig,
422                   preprocessor->mSceneGraph);
423#endif
424   
425#if 1
426#ifdef _USE_HAVRAN_SSE
427    // using ray packets
428    cam.SnapImagePacket("test-packet.tga",
429                        preprocessor->mRayCaster,
430                        bboxOrig,
431                        preprocessor->mSceneGraph);
432#endif
433#endif   
434#if 1
435    // using ray packets
436    cam.SnapImagePacket2("test-packet4.tga",
437                         preprocessor->mRayCaster,
438                         bboxOrig,
439                         preprocessor->mSceneGraph);
440#endif
441  }
442  else {
443    cout << "Computing animation" << endl;   
444    for (int i = 0; i < 20; i++) {
445      preprocessor->mRayCaster->DeleteDynamicObjects();
446      Matrix4x4 mat;
447      mat = IdentityMatrix();
448      mat = mat * TranslationMatrix(Vector3(-0.1*(float)i, 0, 0));
449      preprocessor->mRayCaster->AddDynamicObjecs(dynObjects, mat);
450      char name[200];     
451#if 1
452    // ray by ray
453      sprintf(name, "test-rays-%03d.tga", i);
454      cam.SnapImage(name,
455                    preprocessor->mRayCaster,
456                    bboxOrig,
457                    preprocessor->mSceneGraph);
458#endif
459#if 1
460      // using ray packets
461      sprintf(name, "test-oneDir-%03d.tga", i);
462      cam.SnapImage2(name,
463                     preprocessor->mRayCaster,
464                     bboxOrig,
465                     preprocessor->mSceneGraph);
466#endif
467
468#if 1
469#ifdef _USE_HAVRAN_SSE 
470      // using ray packets
471      sprintf(name, "test-packet-%03d.tga", i);
472      cam.SnapImagePacket(name,
473                          preprocessor->mRayCaster,
474                          bboxOrig,
475                          preprocessor->mSceneGraph);
476#endif
477#endif
478#if 1
479      // using ray packets
480      sprintf(name, "test-packet4-%03d.tga", i);
481      cam.SnapImagePacket2(name,
482                           preprocessor->mRayCaster,
483                           bboxOrig,
484                           preprocessor->mSceneGraph);
485#endif
486    } // for
487  } // animation
488
489 
490  cout << "Done\n" << endl;
491  return;
492}
493
494struct RESult {
495  int hitA;
496  float hitAT;
497  int hitB;
498  float hitBT;
499  RESult(int hA, float tA, int hB, float tB):
500    hitA(hA), hitAT(tA), hitB(hB), hitBT(tB) { }
501};
502
503
504// This is for testing RT implementation
505void
506TestRTfromFile(int argc, char **argv)
507{
508  int returnCode = 0;
509
510  InitTiming();
511  Debug.open("debug.log");
512
513  Environment::GetSingleton()->Parse(argc, argv, USE_EXE_PATH);
514  MeshKdTree::ParseEnvironment();
515
516  char buff[128];
517  Environment::GetSingleton()->GetStringValue("Preprocessor.type", buff);
518  string preprocessorType(buff);
519
520  if (!(preprocessor = PreprocessorFactory::CreatePreprocessor(preprocessorType)))
521  {
522    Environment::DelSingleton();
523    cerr << "Unknown preprocessor type" << endl;
524    exit(1);
525  }
526
527
528  Environment::GetSingleton()->GetStringValue("Scene.filename", buff);
529  string filename(buff);
530
531  const string externKdTree = ReplaceSuffix(filename, ".obj", ".kdf");
532  const string internKdTree = GetInternFilename(filename, preprocessor->mLoadMeshes ?
533                                                ".kdm" : ".kdt");
534
535  if (preprocessor->InitRayCast(externKdTree, internKdTree))
536  {
537    cout << "ray casting initialized!" << endl;
538  }
539  else
540  {
541    cout << "ray casting initialization failed!" << endl;
542    Cleanup();
543    exit(1);
544  }
545 
546  //Debug << "using pvs type " << PVS_TYPE << endl;
547
548  /////////////
549  //-- load scene
550 
551  if (!preprocessor->LoadScene(filename))
552  {
553    cout << "loading file " << filename << " failed" << endl;
554    Cleanup();
555    exit(1);
556  }
557       
558  ////////////
559  //-- initialize external ray caster
560 
561  if (preprocessor->LoadInternKdTree(internKdTree))
562  {
563    cout << "intern kd tree loaded!" << endl;
564  }
565  else
566  {
567    cout << "loading intern kd tree failed!" << endl;
568    Cleanup();
569    exit(1);
570  }
571 
572  // export objects as obj
573  if (preprocessor->mExportObj)
574  {
575    if (strstr(filename.c_str(), ".obj"))
576    {
577      cerr << "already in obj format" << endl;
578      if (0)    preprocessor->ExportObj("test.obj", preprocessor->mObjects);
579    }
580    else
581    {
582      const string objname = GetInternFilename(filename, ".obj");
583       
584      cout << "exporting scene to " << objname << endl;
585      bool success = preprocessor->ExportObj(objname, preprocessor->mObjects); 
586       
587      if (success)
588        cout << "finished exporting obj" << endl;
589      else
590        cerr << "error exporting " << objname << endl;
591    }
592  }
593
594  Environment::GetSingleton()->GetStringValue("Rays.file", buff);
595  FILE *fp = fopen(buff, "rb");
596  if (!fp) {
597    cerr << "ERROR: file " << buff << " cannot be opened for reading" << endl;
598    cerr << "EXITING" << endl;
599    exit(3);
600  }
601  cout << "File " << buff << " was opened successfully" << endl;
602  int cntMaxRays = 100000;
603  Environment::GetSingleton()->GetIntValue("Rays.cnt", cntMaxRays);
604  SimpleRayContainer rays;
605  SimpleRay rayTest;
606  vector<RESult> results;
607 
608  int cntRays = 0;
609  for (int i = 0; cntRays < cntMaxRays; i++) {
610    int ch = fgetc(fp);
611    switch (ch) {
612    case 'G': { // two-sided rays of 16
613      for (int j = 0; j < 16; j++) {
614        int order;
615        float ox, oy, oz, dx, dy, dz;
616        int hitA; float hitAT;
617        int hitB; float hitBT; 
618        if (fscanf(fp, "%d %f %f %f %f %f %f %d %f %d %f\n",
619                   &order, &ox, &oy, &oz, &dx, &dy, &dz, &hitA, &hitAT, &hitB, &hitBT) != 11) {
620          cerr << "Problem parsing the ray file" << endl;
621          cerr << "EXITING for ray order" << order << endl;
622          goto FINISH;
623        }
624        Vector3 mPosition(ox, oy, oz);
625        Vector3 mDirection(dx, dy, dz);
626        rayTest.Set(mPosition, mDirection, 0, 1.0, true);
627        rays.push_back(rayTest);
628        results.push_back(RESult(hitA, hitAT, hitB, hitBT));
629        cntRays++;
630      }
631      break;
632    }
633    case 'H': // one-sided rays of 16
634      cerr << "Not yet implemented " << endl; abort();
635     
636    case 'D': // two-sided ray
637      cerr << "Not yet implemented " << endl; abort();
638     
639    case 'S': // one-sided ray
640      cerr << "Not yet implemented " << endl; abort();
641    } // switch
642  } // for i
643
644FINISH:
645  fclose(fp);
646
647  Environment::GetSingleton()->GetBoolValue("TestDoubleRays", castDoubleRays);
648
649  double mult = 1.0;
650  if (castDoubleRays)
651    mult = 2.0;
652
653  cout << "Press a key to start ray shooting" << endl;
654  getchar();
655  cout << "Ray shooting " << cntRays << " rays started - "
656       << (castDoubleRays ? " double " : " single ")
657       << " dir " << endl;
658 
659  AxisAlignedBox3 bboxOrig = preprocessor->mSceneGraph->GetBox();
660 
661  cout << "Sorting rays " << endl;
662
663  CTimer timer;
664  timer.Reset();
665  timer.Start();
666  long t1 = GetTime();
667
668  //SortRays2(rays, bboxOrig);
669
670  timer.Stop();
671  long t2 = GetTime();
672  cout<<"\n#SORTING_TIME = ";
673  cout << TimeDiff(t1, t2)<<" [mikrosec]"
674       << " userTime = " << timer.UserTime() << " realTime = "
675       << timer.RealTime() << endl;
676
677  cout << "Starting to shoot " << cntRays * mult << " rays" << endl;
678  timer.Start();
679 
680  RayCaster *raycaster = preprocessor->mRayCaster;
681  VssRayContainer vssRays;
682
683//#define DEBUGRESULTS
684
685#ifdef DEBUGRESULTS
686  int cntIntelYesWeNo = 0;
687  int cntIntelNoWeYes = 0;
688  int cntIntelOurDistMismatch = 0;
689  bool printOut = false;
690  double sumDistIntel = 0.f;
691  double sumDistOurAlg = 0.f;
692  double sumDistAbsDiff = 0.f;
693#endif
694
695  SimpleRayContainer raysToTest;
696  for (int i = 0; i < cntRays - 16; i++) {
697
698#if 0
699    int res = raycaster->CastRay(rays[i],
700                                 vssRays,
701                                 bboxOrig,
702                                 castDoubleRays, // castDoubleRay,
703                                 false); // pruneInvalidRays
704#else
705    raysToTest.erase(raysToTest.begin(), raysToTest.end());
706    for (int j = 0; j < 16; j++, i++) {
707      raysToTest.push_back(rays[i]);
708    }
709#if 0
710    for (int j = 0; j < 16; j++) {
711      cout << "orig = " << raysToTest[j].mOrigin << " dir = "
712           << raysToTest[j].mDirection << endl;
713    }
714#endif   
715       
716    raycaster->CastRays16(raysToTest,
717                          vssRays,
718                          bboxOrig,
719                          castDoubleRays,
720                          false);
721#endif
722   
723#ifdef DEBUGRESULTS
724    if (!castDoubleRays) {
725      float T = rays[i].IntersectionRes[0].tdist;
726      if ( (res != results[i].hitA) ||
727           ((res)&&(results[i].hitA)&& (fabs(T - results[i].hitAT)) > 0.1f)
728           )
729        {
730          if (printOut)
731            cout << " i = " << i << " ";
732          if ((res != 0) && (results[i].hitA == 0)) {
733            cntIntelNoWeYes++;
734            if (printOut)
735              cout << "Intel no intersection, our alg intersection at t = " << T << endl;
736          }
737          else {
738            if ((res == 0) && (results[i].hitA)) {
739              cntIntelYesWeNo++;
740              if (printOut)
741                cout << "Intel intersection at = " << results[i].hitAT
742                     << " , our alg no intersection = " << endl;
743             
744            }
745            else {
746              cntIntelOurDistMismatch++;
747              sumDistOurAlg += T;
748              sumDistIntel += results[i].hitAT;
749              sumDistAbsDiff += fabs(T - results[i].hitAT);
750              if (printOut)
751                cout << "Intel intersection at = " << results[i].hitAT
752                     << " , our alg intersection at = " << T << endl;       
753            }
754          }
755        }
756    } // double rays
757    else {
758      // checking for results of double rays - not yet implemented
759    }
760#endif   
761  }
762
763  timer.Stop();
764  t2 = GetTime();
765  cout<<"\n#SORTING + RAY_CAST_TIME = ";
766  cout << TimeDiff(t1, t2)<<" [mikrosec]"
767       << " userTime = " << timer.UserTime() << " realTime = "
768       << timer.RealTime() << endl;
769  cout << "Rays shot per milisecond [userTimer] = "
770       << ((double)cntRays * mult/(double)timer.UserTime()) / 1000.f << endl;
771
772#ifdef DEBUGRESULTS 
773  cout << "cntIntelYesWeNo = " << cntIntelYesWeNo << endl;
774  cout << "cntIntelNoWeYes = " << cntIntelNoWeYes << endl;
775  cout << "cntIntelOurDistMismatch = " << cntIntelOurDistMismatch++ << endl;
776  cout << " sumDistIntel = " << sumDistIntel/(double)cntIntelOurDistMismatch << endl;
777  cout << " sumDistOur = " << sumDistOurAlg/(double)cntIntelOurDistMismatch << endl;
778  cout << " sumAbsDiffDist = " << sumDistAbsDiff/(double)cntIntelOurDistMismatch
779       << endl;
780#endif 
781  cout << "Done\n" << endl;
782  return;
783}
784
785//-------------------------------------------------------------------------
786// This is for testing RT implementation using ray packets
787void
788TestRTfromFilePackets(int argc, char **argv)
789{
790  int returnCode = 0;
791
792  InitTiming();
793  Debug.open("debug.log");
794
795  Environment::GetSingleton()->Parse(argc, argv, USE_EXE_PATH);
796  MeshKdTree::ParseEnvironment();
797
798  char buff[128];
799  Environment::GetSingleton()->GetStringValue("Preprocessor.type", buff);
800  string preprocessorType(buff);
801
802  if (!(preprocessor = PreprocessorFactory::CreatePreprocessor(preprocessorType)))
803  {
804    Environment::DelSingleton();
805    cerr << "Unknown preprocessor type" << endl;
806    exit(1);
807  }
808
809
810  Environment::GetSingleton()->GetStringValue("Scene.filename", buff);
811  string filename(buff);
812
813  const string externKdTree = ReplaceSuffix(filename, ".obj", ".kdf");
814  const string internKdTree = GetInternFilename(filename, preprocessor->mLoadMeshes ?
815                                                ".kdm" : ".kdt");
816
817  if (preprocessor->InitRayCast(externKdTree, internKdTree))
818  {
819    cout << "ray casting initialized!" << endl;
820  }
821  else
822  {
823    cout << "ray casting initialization failed!" << endl;
824    Cleanup();
825    exit(1);
826  }
827 
828  //Debug << "using pvs type " << PVS_TYPE << endl;
829
830  /////////////
831  //-- load scene
832 
833  if (!preprocessor->LoadScene(filename))
834  {
835    cout << "loading file " << filename << " failed" << endl;
836    Cleanup();
837    exit(1);
838  }
839       
840  ////////////
841  //-- initialize external ray caster
842 
843  if (preprocessor->LoadInternKdTree(internKdTree))
844  {
845    cout << "intern kd tree loaded!" << endl;
846  }
847  else
848  {
849    cout << "loading intern kd tree failed!" << endl;
850    Cleanup();
851    exit(1);
852  }
853 
854  // export objects as obj
855  if (preprocessor->mExportObj)
856  {
857    if (strstr(filename.c_str(), ".obj"))
858    {
859      cerr << "already in obj format" << endl;
860      if (0)    preprocessor->ExportObj("test.obj", preprocessor->mObjects);
861    }
862    else
863    {
864      const string objname = GetInternFilename(filename, ".obj");
865       
866      cout << "exporting scene to " << objname << endl;
867      bool success = preprocessor->ExportObj(objname, preprocessor->mObjects); 
868       
869      if (success)
870        cout << "finished exporting obj" << endl;
871      else
872        cerr << "error exporting " << objname << endl;
873    }
874  }
875
876  Environment::GetSingleton()->GetStringValue("Rays.file", buff);
877  FILE *fp = fopen(buff, "rb");
878  if (!fp) {
879    cerr << "ERROR: file " << buff << " cannot be opened for reading" << endl;
880    cerr << "EXITING" << endl;
881    exit(3);
882  }
883  cout << "File " << buff << " was opened successfully" << endl;
884  int cntMaxRays = 100000;
885  Environment::GetSingleton()->GetIntValue("Rays.cnt", cntMaxRays);
886  SimpleRayContainer rays;
887  SimpleRay rayTest;
888  vector<RESult> results;
889 
890  int cntRays = 0;
891  for (int i = 0; cntRays < cntMaxRays; i++) {
892    int ch = fgetc(fp);
893    switch (ch) {
894    case 'G': { // two-sided rays of 16
895      for (int j = 0; j < 16; j++) {
896        int order;
897        float ox, oy, oz, dx, dy, dz;
898        int hitA; float hitAT;
899        int hitB; float hitBT; 
900        if (fscanf(fp, "%d %f %f %f %f %f %f %d %f %d %f\n",
901                   &order, &ox, &oy, &oz, &dx, &dy, &dz, &hitA, &hitAT, &hitB, &hitBT) != 11) {
902          cerr << "Problem parsing the ray file" << endl;
903          cerr << "EXITING for ray order" << order << endl;
904          goto FINISH;
905        }
906        Vector3 mPosition(ox, oy, oz);
907        Vector3 mDirection(dx, dy, dz);
908        rayTest.Set(mPosition, mDirection, 0, 1.0, true);
909        rays.push_back(rayTest);
910        results.push_back(RESult(hitA, hitAT, hitB, hitBT));
911        cntRays++;
912      }
913      break;
914    }
915    case 'H': // one-sided rays of 16
916      cerr << "Not yet implemented " << endl; abort();
917     
918    case 'D': // two-sided ray
919      cerr << "Not yet implemented " << endl; abort();
920     
921    case 'S': // one-sided ray
922      cerr << "Not yet implemented " << endl; abort();
923    } // switch
924  } // for i
925FINISH:
926  fclose(fp);
927 
928  Environment::GetSingleton()->GetBoolValue("TestDoubleRays", castDoubleRays);
929
930  double mult = 1.0;
931  if (castDoubleRays)
932    mult = 2.0;
933
934  cout << "Starting to shoot " << cntRays * mult << " rays" << endl;
935 
936  RayCaster *raycaster = preprocessor->mRayCaster;
937  VssRayContainer vssRays;
938  AxisAlignedBox3 bboxOrig = preprocessor->mSceneGraph->GetBox();
939
940#undef DEBUGRESULTS
941//#define DEBUGRESULTS
942
943#ifdef DEBUGRESULTS
944  int cntIntelYesWeNo = 0;
945  int cntIntelNoWeYes = 0;
946  int cntIntelOurDistMismatch = 0;
947  bool printOut = false;
948  double sumDistIntel = 0.;
949  double sumDistOurAlg = 0.;
950  double sumDistAbsDiff = 0.f;
951#endif
952
953  cout << "Press a key to start ray shooting" << endl;
954  getchar();
955  cout << "Ray packs shooting " << cntRays << " rays started - "
956       << (castDoubleRays ? " double " : " single ")
957       << " dir " << endl;
958
959  long t1 = GetTime();
960  CTimer timer;
961  timer.Reset();
962  timer.Start();
963
964#ifdef _USE_HAVRAN_SSE
965#ifdef __SSE__ 
966  RayPacket2x2 raysPack;
967 
968  for (int i = 0; i < cntRays - 16; i++) {
969    for (int j = 0; j < 4; j++, i++) {
970      raysPack.SetLoc(j, rays[i].mOrigin);
971      raysPack.SetDir(j, rays[i].mDirection);
972    } // for
973#if 0
974    for (int j = 0; j < 16; j++) {
975      cout << "orig = " << raysToTest[j].mOrigin << " dir = "
976           << raysToTest[j].mDirection << endl;
977    }
978#endif
979    raysPack.ComputeDirSign();
980    raycaster->CastRaysPacket2x2(raysPack, castDoubleRays);
981   
982#ifdef DEBUGRESULTS
983    if (!castDoubleRays) {
984      float T = rays[i].IntersectionRes[0].tdist;
985      if ( (res != results[i].hitA) ||
986           ((res)&&(results[i].hitA)&& (fabs(T - results[i].hitAT)) > 2.0f)
987           )
988        {
989          if (printOut)
990            cout << " i = " << i << " ";
991          if ((res != 0) && (results[i].hitA == 0)) {
992            cntIntelNoWeYes++;
993            if (printOut)
994              cout << "Intel no intersection, our alg intersection at t = " << T << endl;
995          }
996          else {
997            if ((res = 0) && (results[i].hitA)) {
998              cntIntelYesWeNo++;
999              if (printOut)
1000                cout << "Intel intersection at = " << results[i].hitAT
1001                     << " , our alg no intersection = " << endl;
1002             
1003            }
1004            else {
1005              cntIntelOurDistMismatch++;
1006              sumDistOurAlg += T;
1007              sumDistIntel += results[i].hitAT;
1008              sumDistAbsDiff += fabs(T - results[i].hitAT);
1009              if (printOut)
1010                cout << "Intel intersection at = " << results[i].hitAT
1011                     << " , our alg intersection at = " << T << endl;       
1012            }
1013          }
1014        }
1015    } // double rays
1016    else {
1017      // checking for results of double rays - not yet implemented
1018    }
1019#endif   
1020  }
1021
1022#endif // __SSE__
1023#endif // _USE_HAVRAN_SSE
1024
1025  timer.Stop();
1026  long t2 = GetTime();
1027  cout<<"\n#RAY_CAST_TIME = ";
1028  cout << TimeDiff(t1, t2)<<" [mikrosec]"
1029       << " userTime = " << timer.UserTime() << " realTime = "
1030       << timer.RealTime() << endl;
1031    ;
1032  cout << "Rays shot per milisecond [userTimer] = "
1033       << ((double)cntRays * mult/(double)timer.UserTime()) / 1000.f << endl;
1034
1035#ifdef DEBUGRESULTS 
1036  cout << "cntIntelYesWeNo = " << cntIntelYesWeNo << endl;
1037  cout << "cntIntelNoWeYes = " << cntIntelNoWeYes << endl;
1038  cout << "cntIntelOurDistMismatch = " << cntIntelOurDistMismatch++ << endl;
1039  cout << " sumDistIntel = " << sumDistIntel/(double)cntIntelOurDistMismatch << endl;
1040  cout << " sumDistOur = " << sumDistOurAlg/(double)cntIntelOurDistMismatch << endl;
1041  cout << " sumAbsDiffDist = " << sumDistAbsDiff/(double)cntIntelOurDistMismatch
1042       << endl;
1043#endif 
1044  cout << "Done\n" << endl;
1045  return;
1046}
1047
1048// This is for testing RT implementation
1049void
1050TestRT_4_fromFile(int argc, char **argv)
1051{
1052  int returnCode = 0;
1053
1054  InitTiming();
1055  Debug.open("debug.log");
1056
1057  Environment::GetSingleton()->Parse(argc, argv, USE_EXE_PATH);
1058  MeshKdTree::ParseEnvironment();
1059
1060  char buff[128];
1061  Environment::GetSingleton()->GetStringValue("Preprocessor.type", buff);
1062  string preprocessorType(buff);
1063
1064  if (!(preprocessor = PreprocessorFactory::CreatePreprocessor(preprocessorType)))
1065  {
1066    Environment::DelSingleton();
1067    cerr << "Unknown preprocessor type" << endl;
1068    exit(1);
1069  }
1070
1071
1072  Environment::GetSingleton()->GetStringValue("Scene.filename", buff);
1073  string filename(buff);
1074
1075  const string externKdTree = ReplaceSuffix(filename, ".obj", ".kdf");
1076  const string internKdTree = GetInternFilename(filename, preprocessor->mLoadMeshes ?
1077                                                ".kdm" : ".kdt");
1078
1079  if (preprocessor->InitRayCast(externKdTree, internKdTree))
1080  {
1081    cout << "ray casting initialized!" << endl;
1082  }
1083  else
1084  {
1085    cout << "ray casting initialization failed!" << endl;
1086    Cleanup();
1087    exit(1);
1088  }
1089 
1090  //Debug << "using pvs type " << PVS_TYPE << endl;
1091
1092  /////////////
1093  //-- load scene
1094 
1095  if (!preprocessor->LoadScene(filename))
1096  {
1097    cout << "loading file " << filename << " failed" << endl;
1098    Cleanup();
1099    exit(1);
1100  }
1101       
1102  ////////////
1103  //-- initialize external ray caster
1104 
1105  if (preprocessor->LoadInternKdTree(internKdTree))
1106  {
1107    cout << "intern kd tree loaded!" << endl;
1108  }
1109  else
1110  {
1111    cout << "loading intern kd tree failed!" << endl;
1112    Cleanup();
1113    exit(1);
1114  }
1115 
1116  // export objects as obj
1117  if (preprocessor->mExportObj)
1118  {
1119    if (strstr(filename.c_str(), ".obj"))
1120    {
1121      cerr << "already in obj format" << endl;
1122      if (0)    preprocessor->ExportObj("test.obj", preprocessor->mObjects);
1123    }
1124    else
1125    {
1126      const string objname = GetInternFilename(filename, ".obj");
1127       
1128      cout << "exporting scene to " << objname << endl;
1129      bool success = preprocessor->ExportObj(objname, preprocessor->mObjects); 
1130       
1131      if (success)
1132        cout << "finished exporting obj" << endl;
1133      else
1134        cerr << "error exporting " << objname << endl;
1135    }
1136  }
1137
1138  Environment::GetSingleton()->GetStringValue("Rays.file", buff);
1139  FILE *fp = fopen(buff, "rb");
1140  if (!fp) {
1141    cerr << "ERROR: file " << buff << " cannot be opened for reading" << endl;
1142    cerr << "EXITING" << endl;
1143    exit(3);
1144  }
1145  cout << "File " << buff << " was opened successfully" << endl;
1146  int cntMaxRays = 100000;
1147  Environment::GetSingleton()->GetIntValue("Rays.cnt", cntMaxRays);
1148  SimpleRayContainer rays;
1149  SimpleRay rayTest;
1150  vector<RESult> results;
1151  vector<AxisAlignedBox3> boxes;
1152
1153  int cntRays = 0;
1154  for (int i = 0; cntRays < cntMaxRays;) {
1155    int ch = fgetc(fp);
1156    switch (ch) {
1157    case 'I': { // two-sided rays of 16
1158      Vector3 minv, maxv;
1159      if (fscanf(fp, "%f %f %f %f %f %f\n",
1160                 &minv.x, &minv.y, &minv.z,
1161                 &maxv.x, &maxv.y, &maxv.z) != 6) {
1162        cerr << "Problem parsing the ray file" << endl;
1163        cerr << "EXITING for ray order" << i << endl;
1164        goto FINISH;
1165      }
1166      boxes.push_back(AxisAlignedBox3(minv, maxv));     
1167
1168      for (int j = 0; j < 4; j++) {
1169        int order;
1170        float ox, oy, oz, dx, dy, dz;
1171        int hitA; float hitAT;
1172        int hitB; float hitBT; 
1173        if (fscanf(fp, "%d %f %f %f %f %f %f %d %f\n",
1174                   &order, &ox, &oy, &oz, &dx, &dy, &dz,
1175                   &hitA, &hitAT) != 9) {
1176          cerr << "Problem parsing the ray file" << endl;
1177          cerr << "EXITING for ray order" << order << endl;
1178          goto FINISH;
1179        }
1180        Vector3 mPosition(ox, oy, oz);
1181        Vector3 mDirection(dx, dy, dz);
1182        rayTest.Set(mPosition, mDirection, 0, 1.0, true);
1183        rays.push_back(rayTest);
1184        results.push_back(RESult(hitA, hitAT, 0, -1.f));
1185        cntRays++;
1186        i++;
1187      }
1188      break;
1189    }
1190    default: {
1191      cerr << "Not yet implemented or end of file" << endl;
1192      goto FINISH;
1193    }
1194    } // switch
1195  } // for i
1196
1197FINISH:
1198 
1199  fclose(fp);
1200  cout << "Starting to shoot " << cntRays << " rays" << endl;
1201 
1202  RayCaster *raycaster = preprocessor->mRayCaster;
1203  VssRayContainer vssRays;
1204  AxisAlignedBox3 bboxOrig = preprocessor->mSceneGraph->GetBox();
1205
1206//#define DEBUGRESULTS
1207
1208#ifdef DEBUGRESULTS
1209  int cntIntelYesWeNo = 0;
1210  int cntIntelNoWeYes = 0;
1211  int cntIntelOurDistMismatch = 0;
1212  bool printOut = false;
1213  double sumDistIntel = 0.f;
1214  double sumDistOurAlg = 0.f;
1215  double sumDistAbsDiff = 0.f;
1216#endif
1217
1218  //cout << "Press a key to start ray shooting" << endl;
1219  //getchar();
1220  cout << "Ray shooting " << cntRays << " rays started - "
1221       << (castDoubleRays ? " double " : " single ")
1222       << " dir " << endl;
1223
1224  long t1 = GetTime();
1225  CTimer timer;
1226  timer.Reset();
1227  timer.Start();
1228  Vector3 boxMin, boxMax;
1229
1230  bool printOut = false;
1231 
1232  SimpleRayContainer raysToTest;
1233  int boxI = 0;
1234  for (int i = 0; i < cntRays - 4; i+= 4, boxI++) {
1235    Vector3 origin4[4];
1236    Vector3 direction4[4];
1237    int     result4[4];
1238    float   dist4[4];
1239    boxMin = boxes[boxI].Min();
1240    boxMax = boxes[boxI].Max();
1241    for (int j = 0; j < 4; j++) {
1242      int o = i+j;
1243      origin4[j] = rays[o].mOrigin;
1244      direction4[j] = rays[o].mDirection;
1245    }
1246    raycaster->CastRaysPacket4(boxMin, boxMax,
1247                               origin4, direction4,
1248                               result4, dist4);
1249    if (printOut) {
1250      printf("I %4.7f %4.7f %4.7f %4.7f %4.7f %4.7f\n",
1251             boxMin.x, boxMin.y, boxMin.z, boxMax.x, boxMax.y, boxMax.z);
1252    }
1253
1254    for (int j = 0; j < 4; j++) {
1255#if 0
1256      if (result4[j] == 0) {
1257        int res = raycaster->CastRay(rays[i+j],
1258                                     vssRays,
1259                                     bboxOrig,
1260                                     false,
1261                                     true);
1262        if (res) {
1263          float tdist = SimpleRay::IntersectionRes[0].tdist;
1264          Vector3 point = rays[i+j].Extrap(tdist);
1265          AxisAlignedBox3 testbox(boxMin, boxMax);
1266         
1267          if (testbox.IsInside(point)) {
1268            cout << "Error in the algorithm - computed not in the box, but"
1269                 << " it is later found in the box" << endl;
1270            cout << " j = " << j << endl;
1271            cout << " box = " << testbox << endl;
1272            cout << " point = " << point << endl;
1273            raycaster->CastRaysPacket4(boxMin, boxMax,
1274                               origin4, direction4,
1275                               result4, dist4);
1276          }
1277        }
1278      }
1279#endif     
1280     
1281      if (printOut) {
1282        printf("%d %4.7f %4.7f %4.7f %4.7f %4.7f %4.7f %d %4.7f\n",
1283               i+j,
1284               origin4[j].x,
1285               origin4[j].y,
1286               origin4[j].z,
1287               direction4[j].x,
1288               direction4[j].y,
1289               direction4[j].z,
1290               (result4[j] != -1) ? 1 : 0,
1291               (result4[j] != -1) ? dist4[j] : 0);
1292      }
1293    } // for j   
1294  } // for i
1295
1296  timer.Stop();
1297  long t2 = GetTime();
1298  cout<<"\n#RAY_CAST_TIME = ";
1299  cout << TimeDiff(t1, t2)<<" [mikrosec]"
1300       << " userTime = " << timer.UserTime() << " realTime = "
1301       << timer.RealTime() << endl;
1302  cout << "Rays shot per milisecond [userTimer] = "
1303       << ((double)cntRays/(double)timer.UserTime()) / 1000.f << endl;
1304
1305#ifdef DEBUGRESULTS 
1306  cout << "cntIntelYesWeNo = " << cntIntelYesWeNo << endl;
1307  cout << "cntIntelNoWeYes = " << cntIntelNoWeYes << endl;
1308  cout << "cntIntelOurDistMismatch = " << cntIntelOurDistMismatch++ << endl;
1309  cout << " sumDistIntel = " << sumDistIntel/(double)cntIntelOurDistMismatch << endl;
1310  cout << " sumDistOur = " << sumDistOurAlg/(double)cntIntelOurDistMismatch << endl;
1311  cout << " sumAbsDiffDist = " << sumDistAbsDiff/(double)cntIntelOurDistMismatch
1312       << endl;
1313#endif 
1314  cout << "Done\n" << endl;
1315  return;
1316}
Note: See TracBrowser for help on using the repository browser.