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

Revision 2629, 33.6 KB checked in by bittner, 16 years ago (diff)

commit after merge with vlastimil

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