source: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp @ 1251

Revision 1251, 25.7 KB checked in by mattausch, 18 years ago (diff)
Line 
1#include "SceneGraph.h"
2#include "Exporter.h"
3#include "UnigraphicsParser.h"
4#include "X3dParser.h"
5#include "Preprocessor.h"
6#include "ViewCell.h"
7#include "Environment.h"
8#include "ViewCellsManager.h"
9#include "ViewCellBsp.h"
10#include "VspBspTree.h"
11#include "RenderSimulator.h"
12#include "GlRenderer.h"
13#include "PlyParser.h"
14#include "SamplingStrategy.h"
15#include "VspTree.h"
16#include "OspTree.h"
17#include "ObjParser.h"
18#ifdef GTP_INTERNAL
19#include "ArchModeler2MLRT.hxx"
20#endif
21
22namespace GtpVisibilityPreprocessor {
23
24const static bool ADDITIONAL_GEOMETRY_HACK = false;
25
26//Preprocessor *preprocessor;
27
28
29// HACK: Artificially modify scene to watch rendercost changes
30static void AddGeometry(SceneGraph *scene)
31{
32        scene->mRoot->UpdateBox();
33
34        AxisAlignedBox3 sceneBox = scene->GetBox();
35
36        int n = 200;
37
38        if (0){
39        // form grid of boxes
40        for (int i = 0; i < n; ++ i)
41        {
42                for (int j = 0; j < n; ++ j)
43                {
44                        const Vector3 scale2((float)j * 0.8f / n + 0.1f,  0.05f, (float)i * 0.8f  / (float)n + 0.1f);
45               
46                        const Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
47               
48                        const Vector3 boxSize = sceneBox.Size() * Vector3(0.0025f, 0.01f, 0.0025f);
49                        AxisAlignedBox3 box(pt2, pt2 + boxSize);
50                        Mesh *mesh = CreateMeshFromBox(box);
51
52                        mesh->Preprocess();
53               
54                        MeshInstance *mi = new MeshInstance(mesh);
55                        scene->mRoot->mGeometry.push_back(mi);
56                }
57        }
58
59        for (int i = 0; i < n; ++ i)
60        {
61                for (int j = 0; j < n; ++ j)
62                {
63                        const Vector3 scale2(0.15f, (float)j * 0.8f / n + 0.1f, (float)i * 0.8f  / (float)n + 0.1f);
64               
65                        Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
66               
67                        Vector3 boxSize = sceneBox.Size() * Vector3(0.0025f, 0.01f, 0.0025f);
68                        AxisAlignedBox3 box(pt2, pt2 + boxSize);
69                        Mesh *mesh = CreateMeshFromBox(box);
70
71                        mesh->Preprocess();
72               
73                        MeshInstance *mi = new MeshInstance(mesh);
74                        scene->mRoot->mGeometry.push_back(mi);
75                }
76        }
77
78        for (int i = 0; i < n; ++ i)
79        {
80                const Vector3 scale2(2, 0.2f, (float)i * 0.8f  / (float)n + 0.1f);
81               
82                Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
83               
84                //Vector3 boxSize = sceneBox.Size() * Vector3(0.0025, 0.01, 0.0025);
85                Vector3 boxSize = sceneBox.Size() * Vector3(0.005f, 0.02f, 0.005f);
86
87                AxisAlignedBox3 box(pt2 + 0.1f, pt2 + boxSize);
88                Mesh *mesh = CreateMeshFromBox(box);
89
90                mesh->Preprocess();
91               
92                MeshInstance *mi = new MeshInstance(mesh);
93                scene->mRoot->mGeometry.push_back(mi);
94        }
95       
96        scene->mRoot->UpdateBox();
97        }
98               
99        if (1)
100        {
101                // plane separating view space regions
102                const Vector3 scale(1.0f, 0.0, 0);
103
104                Vector3 pt = sceneBox.Min() + scale * (sceneBox.Max() - sceneBox.Min());
105
106                Plane3 cuttingPlane(Vector3(1, 0, 0), pt);
107                Mesh *planeMesh = new Mesh();
108               
109                Polygon3 *poly = sceneBox.CrossSection(cuttingPlane);
110                IncludePolyInMesh(*poly, *planeMesh);
111               
112                planeMesh->Preprocess();
113               
114                MeshInstance *planeMi = new MeshInstance(planeMesh);
115                scene->mRoot->mGeometry.push_back(planeMi);
116        }       
117}
118
119
120Preprocessor::Preprocessor():
121mKdTree(NULL),
122mBspTree(NULL),
123mVspBspTree(NULL),
124mViewCellsManager(NULL),
125mRenderSimulator(NULL),
126mPass(0)
127{
128        Environment::GetSingleton()->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
129 
130        // renderer will be constructed when the scene graph and viewcell manager will be known
131        renderer = NULL;
132 
133        Environment::GetSingleton()->GetBoolValue("Preprocessor.useGlDebugger", mUseGlDebugger);
134        Environment::GetSingleton()->GetBoolValue("Preprocessor.loadPolygonsAsMeshes", mLoadPolygonsAsMeshes);
135        Environment::GetSingleton()->GetBoolValue("Preprocessor.quitOnFinish", mQuitOnFinish);
136        Environment::GetSingleton()->GetBoolValue("Preprocessor.computeVisibility", mComputeVisibility);
137        Environment::GetSingleton()->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
138        Environment::GetSingleton()->GetBoolValue("Preprocessor.exportVisibility", mExportVisibility );
139        Environment::GetSingleton()->GetIntValue("Preprocessor.rayCastMethod", mRayCastMethod);
140
141        char buffer[256];
142        Environment::GetSingleton()->GetStringValue("Preprocessor.visibilityFile",  buffer);
143        mVisibilityFileName = buffer;
144        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", mApplyVisibilityFilter );
145        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter",
146                                                          mApplyVisibilitySpatialFilter );
147        Environment::GetSingleton()->GetFloatValue("Preprocessor.visibilityFilterWidth", mVisibilityFilterWidth);
148
149        Debug << "detect empty view space=" << mDetectEmptyViewSpace << endl;
150        Debug << "load polygons as meshes: " << mLoadPolygonsAsMeshes << endl;
151}
152
153
154Preprocessor::~Preprocessor()
155{
156  cout << "cleaning up" << endl;
157
158  cout << "Deleting view cells manager ... \n";
159  DEL_PTR(mViewCellsManager);
160  cout << "done.\n";
161
162  cout << "Deleting bsp tree ... \n";
163  DEL_PTR(mBspTree);
164  cout << "done.\n";
165
166  cout << "Deleting kd tree...\n";
167  DEL_PTR(mKdTree);
168  cout << "done.\n";
169 
170  cout << "Deleting vsp tree...\n";
171  DEL_PTR(mVspTree);
172  cout << "done.\n";
173
174  cout << "Deleting osp tree...\n";
175  DEL_PTR(mOspTree);
176  cout << "done.\n";
177
178  cout << "Deleting vspbsp tree...\n";
179  DEL_PTR(mVspBspTree);
180  cout << "done.\n";
181
182   cout << "Deleting scene graph...\n";
183  DEL_PTR(mSceneGraph);
184  cout << "done.\n";
185
186  DEL_PTR(mRenderSimulator);
187  DEL_PTR(renderer);
188}
189
190int
191SplitFilenames(const string str, vector<string> &filenames)
192{
193        int pos = 0;
194
195        while(1) {
196                int npos = (int)str.find(';', pos);
197               
198                if (npos < 0 || npos - pos < 1)
199                        break;
200                filenames.push_back(string(str, pos, npos - pos));
201                pos = npos + 1;
202        }
203       
204        filenames.push_back(string(str, pos, str.size() - pos));
205        return (int)filenames.size();
206}
207
208
209bool
210Preprocessor::LoadScene(const string filename)
211{
212        // use leaf nodes of the original spatial hierarchy as occludees
213        mSceneGraph = new SceneGraph;
214 
215        Parser *parser;
216        vector<string> filenames;
217        int files = SplitFilenames(filename, filenames);
218        cout << "number of input files: " << files << endl;
219        bool result = false;
220        if (files == 1) {
221               
222                if (strstr(filename.c_str(), ".x3d"))
223                  parser = new X3dParser;
224                else
225                  if (strstr(filename.c_str(), ".ply") || strstr(filename.c_str(), ".plb"))
226                        parser = new PlyParser;
227                  else if (strstr(filename.c_str(), ".obj"))
228                          parser = new ObjParser;
229                  else
230                          parser = new UnigraphicsParser;
231
232                cout<<filename<<endl;
233
234                if (mRayCastMethod == Preprocessor::INTEL_RAYCASTER)
235                        result = parser->ParseFile(filename, &mSceneGraph->mRoot, mLoadPolygonsAsMeshes, &mFaceParents);
236                else
237                        result = parser->ParseFile(filename, &mSceneGraph->mRoot, mLoadPolygonsAsMeshes);
238
239                delete parser;
240
241        } else {
242                // root for different files
243                mSceneGraph->mRoot = new SceneGraphNode;
244                for (int i= 0; i < filenames.size(); i++) {
245                        if (strstr(filenames[i].c_str(), ".x3d"))
246                                parser = new X3dParser;
247                        else
248                                parser = new UnigraphicsParser;
249                                               
250                        SceneGraphNode *node;
251                        if (parser->ParseFile(filenames[i], &node)) {
252                                mSceneGraph->mRoot->mChildren.push_back(node);
253                                // at least one file parsed
254                                result = true;
255                        }
256                        delete parser;
257                }
258        }
259       
260
261        if (result)
262        {
263                // HACK
264                if (ADDITIONAL_GEOMETRY_HACK)
265                        AddGeometry(mSceneGraph);
266               
267                mSceneGraph->AssignObjectIds();
268       
269                int intersectables, faces;
270                mSceneGraph->GetStatistics(intersectables, faces);
271       
272                cout<<filename<<" parsed successfully."<<endl;
273                cout<<"#NUM_OBJECTS (Total numner of objects)\n"<<intersectables<<endl;
274                cout<<"#NUM_FACES (Total numner of faces)\n"<<faces<<endl;
275                mSceneGraph->CollectObjects(&mObjects);
276                mSceneGraph->mRoot->UpdateBox();
277
278                if (0)
279                {
280                        Exporter *exporter = Exporter::GetExporter("testload.x3d");
281
282                        if (exporter)
283                        {
284                                exporter->ExportGeometry(mObjects);
285                                delete exporter;
286                        }
287                }
288        }
289       
290       
291        return result;
292}
293
294bool
295Preprocessor::ExportPreprocessedData(const string filename)
296{
297 
298  mViewCellsManager->ExportViewCells(filename, true, mObjects);
299 
300  return true;
301}
302
303bool
304Preprocessor::PostProcessVisibility()
305{
306 
307  if (mApplyVisibilityFilter || mApplyVisibilitySpatialFilter) {
308        cout<<"Applying visibility filter ...";
309        cout<<"filter width = " << mVisibilityFilterWidth << endl;
310       
311        if (!mViewCellsManager)
312          return false;
313       
314        mViewCellsManager->ApplyFilter(mKdTree,
315                                                                   mApplyVisibilityFilter ? mVisibilityFilterWidth : -1.0f,
316                                                                   mApplyVisibilitySpatialFilter ? mVisibilityFilterWidth : -1.0f);
317        cout << "done." << endl;
318  }
319 
320  // export the preprocessed information to a file
321  if (mExportVisibility)
322        ExportPreprocessedData(mVisibilityFileName);
323 
324  return true;
325}
326
327
328bool
329Preprocessor::BuildKdTree()
330{
331  mKdTree = new KdTree;
332  // add mesh instances of the scene graph to the root of the tree
333  KdLeaf *root = (KdLeaf *)mKdTree->GetRoot();
334  mSceneGraph->CollectObjects(&root->mObjects);
335 
336  long startTime = GetTime();
337
338  cout << "building kd tree ... " << endl;
339  mKdTree->Construct();
340  cout << "construction finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs " << endl;
341  return true;
342}
343
344void
345Preprocessor::KdTreeStatistics(ostream &s)
346{
347  s<<mKdTree->GetStatistics();
348}
349
350void
351Preprocessor::BspTreeStatistics(ostream &s)
352{
353        s << mBspTree->GetStatistics();
354}
355
356bool
357Preprocessor::Export( const string filename,
358                                          const bool scene,
359                                          const bool kdtree,
360                                          const bool bsptree
361                                          )
362{
363  Exporter *exporter = Exporter::GetExporter(filename);
364       
365  if (exporter) {
366    if (scene)
367      exporter->ExportScene(mSceneGraph->mRoot);
368
369    if (kdtree) {
370      exporter->SetWireframe();
371      exporter->ExportKdTree(*mKdTree);
372    }
373
374        if (bsptree) {
375                //exporter->SetWireframe();
376                exporter->ExportBspTree(*mBspTree);
377        }
378
379    delete exporter;
380    return true;
381  }
382
383  return false;
384}
385
386
387bool Preprocessor::PrepareViewCells()
388{
389        //-- parse view cells construction method
390        Environment::GetSingleton()->GetBoolValue("ViewCells.loadFromFile", mLoadViewCells);
391        char buf[100];
392       
393        if (mLoadViewCells)
394        {       
395                Environment::GetSingleton()->GetStringValue("ViewCells.filename", buf);
396                mViewCellsManager = ViewCellsManager::LoadViewCells(buf, &mObjects, true);
397        }
398        else
399        {
400                //-- parse type of view cell container
401                Environment::GetSingleton()->GetStringValue("ViewCells.type", buf);             
402            mViewCellsManager = CreateViewCellsManager(buf);
403
404                // default view space is the extent of the scene
405                mViewCellsManager->SetViewSpaceBox(mSceneGraph->GetBox());
406
407
408        }
409       
410        //-- parameters for render heuristics evaluation
411        float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
412
413        Environment::GetSingleton()->GetFloatValue("Simulation.objRenderCost",objRenderCost);
414        Environment::GetSingleton()->GetFloatValue("Simulation.vcOverhead", vcOverhead);
415        Environment::GetSingleton()->GetFloatValue("Simulation.moveSpeed", moveSpeed);
416       
417        mRenderSimulator =
418                new RenderSimulator(mViewCellsManager, objRenderCost, vcOverhead, moveSpeed);
419
420        mViewCellsManager->SetRenderer(mRenderSimulator);
421
422
423        if (mUseGlRenderer || mUseGlDebugger)
424        {
425                // NOTE: render texture should be power of 2 and square
426                // renderer must be initialised
427                // $$matt
428//              renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager, mKdTree);
429                //              renderer->makeCurrent();
430               
431        }
432       
433        return true;
434}
435
436
437ViewCellsManager *Preprocessor::CreateViewCellsManager(const char *name)
438{
439        if (strcmp(name, "kdTree") == 0)
440        {
441                mViewCellsManager = new KdViewCellsManager(mKdTree);
442        }
443        else if (strcmp(name, "bspTree") == 0)
444        {
445                Debug << "view cell type: Bsp" << endl;
446
447                mBspTree = new BspTree();
448                mViewCellsManager = new BspViewCellsManager(mBspTree);
449        }
450        else if (strcmp(name, "vspBspTree") == 0)
451        {
452                Debug << "view cell type: VspBsp" << endl;
453
454                mVspBspTree = new VspBspTree();
455                mViewCellsManager = new VspBspViewCellsManager(mVspBspTree);
456        }
457        else if (strcmp(name, "vspOspTree") == 0)
458        {
459                mVspTree = new VspTree();
460                mOspTree = new OspTree();
461               
462                // HACK for testing if per kd evaluation works!!
463                mOspTree = new OspTree(*mKdTree);
464
465                mViewCellsManager = new VspOspViewCellsManager(mVspTree, mOspTree);
466        }
467        else if (strcmp(name, "sceneDependent") == 0)
468        {
469                Debug << "view cell type: Bsp" << endl;
470
471                //TODO
472                mBspTree = new BspTree();
473                mViewCellsManager = new BspViewCellsManager(mBspTree);
474        }
475        else
476        {
477                cerr << "Wrong view cells type " << name << "!!!" << endl;
478                exit(1);
479        }
480
481        return mViewCellsManager;
482}
483
484
485// use ascii format to store rays
486#define USE_ASCII 0
487
488
489static inline bool ilt(Intersectable *obj1, Intersectable *obj2)
490{
491        return obj1->mId < obj2->mId;
492}
493
494
495bool Preprocessor::LoadKdTree()
496{
497        return true;
498}
499
500bool Preprocessor::ExportKdTree()
501{
502        return true;
503}
504
505
506bool Preprocessor::LoadSamples(VssRayContainer &samples,
507                                                           ObjectContainer &objects) const
508{
509        std::stable_sort(objects.begin(), objects.end(), ilt);
510        char fileName[100];
511        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
512       
513    Vector3 origin, termination;
514        // HACK: needed only for lower_bound algorithm to find the
515        // intersected objects
516        MeshInstance sObj(NULL);
517        MeshInstance tObj(NULL);
518
519#if USE_ASCII
520        ifstream samplesIn(fileName);
521        if (!samplesIn.is_open())
522                return false;
523
524        string buf;
525        while (!(getline(samplesIn, buf)).eof())
526        {
527                sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d",
528                           &origin.x, &origin.y, &origin.z,
529                           &termination.x, &termination.y, &termination.z,
530                           &(sObj.mId), &(tObj.mId));
531               
532                Intersectable *sourceObj = NULL;
533                Intersectable *termObj = NULL;
534               
535                if (sObj.mId >= 0)
536                {
537                        ObjectContainer::iterator oit =
538                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
539                        sourceObj = *oit;
540                }
541               
542                if (tObj.mId >= 0)
543                {
544                        ObjectContainer::iterator oit =
545                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
546                        termObj = *oit;
547                }
548
549                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
550        }
551#else
552        ifstream samplesIn(fileName, ios::binary);
553        if (!samplesIn.is_open())
554                return false;
555
556        while (1)
557        {
558                 samplesIn.read(reinterpret_cast<char *>(&origin), sizeof(Vector3));
559                 samplesIn.read(reinterpret_cast<char *>(&termination), sizeof(Vector3));
560                 samplesIn.read(reinterpret_cast<char *>(&(sObj.mId)), sizeof(int));
561                 samplesIn.read(reinterpret_cast<char *>(&(tObj.mId)), sizeof(int));
562               
563                 if (samplesIn.eof())
564                        break;
565
566                Intersectable *sourceObj = NULL;
567                Intersectable *termObj = NULL;
568               
569                if (sObj.mId >= 0)
570                {
571                        ObjectContainer::iterator oit =
572                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
573                        sourceObj = *oit;
574                }
575               
576                if (tObj.mId >= 0)
577                {
578                        ObjectContainer::iterator oit =
579                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
580                        termObj = *oit;
581                }
582
583                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
584        }
585
586#endif
587        samplesIn.close();
588
589        return true;
590}
591
592
593bool Preprocessor::ExportSamples(const VssRayContainer &samples) const
594{
595        char fileName[100];
596        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
597       
598
599        VssRayContainer::const_iterator it, it_end = samples.end();
600       
601#if USE_ASCII
602        ofstream samplesOut(fileName);
603        if (!samplesOut.is_open())
604                return false;
605
606        for (it = samples.begin(); it != it_end; ++ it)
607        {
608                VssRay *ray = *it;
609                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
610                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;       
611
612                samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " "
613                                   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " "
614                                   << sourceid << " " << termid << "\n";
615        }
616#else
617        ofstream samplesOut(fileName, ios::binary);
618        if (!samplesOut.is_open())
619                return false;
620
621        for (it = samples.begin(); it != it_end; ++ it)
622        {       
623                VssRay *ray = *it;
624                Vector3 origin(ray->GetOrigin());
625                Vector3 termination(ray->GetTermination());
626               
627                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
628                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;               
629
630                samplesOut.write(reinterpret_cast<char *>(&origin), sizeof(Vector3));
631                samplesOut.write(reinterpret_cast<char *>(&termination), sizeof(Vector3));
632                samplesOut.write(reinterpret_cast<char *>(&sourceid), sizeof(int));
633                samplesOut.write(reinterpret_cast<char *>(&termid), sizeof(int));
634    }
635#endif
636        samplesOut.close();
637
638        return true;
639}
640
641#if 0 // matt: implemented interface samplestrategy
642bool
643Preprocessor::GenerateRays(
644                                                   const int number,
645                                                   const int sampleType,
646                                                   SimpleRayContainer &rays
647                                                   )
648{
649  Vector3 origin, direction;
650  int startSize = (int)rays.size();
651  for (int i=0; (int)rays.size() - startSize  < number; i ++) {
652        // now get the direction
653        switch (sampleType) {
654        case OBJECT_BASED_DISTRIBUTION: {
655          mViewCellsManager->GetViewPoint(origin);
656          Vector3 point;
657          Vector3 normal;
658          int i = RandomValue(0, mObjects.size() - 1);
659          Intersectable *object = mObjects[i];
660          object->GetRandomSurfacePoint(point, normal);
661          direction = point - origin;
662        }
663          break;
664        case OBJECT_DIRECTION_BASED_DISTRIBUTION: {
665          int i = RandomValue(0, mObjects.size() - 1);
666          Intersectable *object = mObjects[i];
667          Vector3 normal;
668          object->GetRandomSurfacePoint(origin, normal);
669          direction = UniformRandomVector(normal);
670          origin += 0.1f*direction;
671        }
672          break;
673        case DIRECTION_BASED_DISTRIBUTION:
674          mViewCellsManager->GetViewPoint(origin);
675          direction = UniformRandomVector();
676          break;
677        case DIRECTION_BOX_BASED_DISTRIBUTION: {
678          mViewCellsManager->GetViewPoint(origin);
679          float alpha = RandomValue(0.0f, 2*M_PI);
680          float beta = RandomValue(-M_PI/2, M_PI/2);
681          direction = VssRay::GetDirection(alpha, beta);
682          break;
683        }
684        case SPATIAL_BOX_BASED_DISTRIBUTION:
685          mViewCellsManager->GetViewPoint(origin);
686          direction = mKdTree->GetBox().GetRandomPoint() - origin;
687          break;
688        default:
689          // unsuported distribution type
690          return false;
691        }
692        // $$ jb the pdf is yet not correct for all sampling methods!
693        float pdf = 1.0f;
694        float c = Magnitude(direction);
695        if (c > Limits::Small) {
696          direction*=1.0f/c;
697          rays.AddRay(SimpleRay(origin, direction, pdf));
698        }
699  }
700  return true;
701}
702#endif
703bool Preprocessor::GenerateRays(const int number,
704                                                                const int sampleType,
705                                                                SimpleRayContainer &rays)
706{
707        Vector3 origin, direction;
708       
709        const int startSize = (int)rays.size();
710        SamplingStrategy *strategy = GenerateSamplingStrategy(sampleType);
711
712        if (!strategy)
713                return false;
714
715        for (int i=0; (int)rays.size() - startSize < number; ++ i)
716        {
717                SimpleRay newRay;
718                bool success = strategy->GenerateSample(newRay);
719
720                if (success)
721                        rays.AddRay(newRay);
722        }
723
724        delete strategy;
725
726    return true;
727}
728
729
730SamplingStrategy *Preprocessor::GenerateSamplingStrategy(const int strategyId) const
731{
732        switch (strategyId)
733        {
734        case OBJECT_BASED_DISTRIBUTION:
735                return new ObjectBasedDistribution(*this);
736        case OBJECT_DIRECTION_BASED_DISTRIBUTION:
737                return new ObjectDirectionBasedDistribution(*this);
738        case DIRECTION_BASED_DISTRIBUTION:
739                return new DirectionBasedDistribution(*this);
740        case DIRECTION_BOX_BASED_DISTRIBUTION:
741                return new DirectionBoxBasedDistribution(*this);
742        case SPATIAL_BOX_BASED_DISTRIBUTION:
743                return new SpatialBoxBasedDistribution(*this);
744        //case OBJECTS_INTERIOR_DISTRIBUTION:
745        //      return new ObjectsInteriorDistribution(*this);
746        default: // no valid strategy
747                return NULL;
748        }
749
750        // should never come here
751        return NULL;
752}
753
754
755bool Preprocessor::InitRayCast(const string externKdTree)
756{
757        switch (mRayCastMethod) // use intel ray tracing
758        {
759        case INTEL_RAYCASTER:
760#ifdef GTP_INTERNAL
761                return mlrtaLoadAS(externKdTree.c_str());
762#endif
763        case INTERNAL_RAYCASTER:
764        default:
765                break;
766        }
767
768        return true;
769}
770
771
772int Preprocessor::CastIntelDoubleRay(
773                                                                         const Vector3 &viewPoint,
774                                                                         const Vector3 &direction,
775                                                                         const float probability,
776                                                                         VssRayContainer &vssRays,
777                                                                         const AxisAlignedBox3 &box
778                                                                         )
779{
780        VssRay *vssRay  = NULL;
781        int hits = 0;
782
783        Vector3 pointA, pointB;
784       
785        Intersectable *objectA =
786                CastIntelSingleRay(viewPoint, direction, pointA, box);
787       
788        // cast ray into other direction
789        Intersectable *objectB =
790                CastIntelSingleRay(viewPoint, -direction, pointB, box);
791
792        const bool validSample = (objectA != objectB);
793       
794        if (validSample)
795        {       
796                if (objectA)
797                {
798                        vssRay = new VssRay(pointB,
799                                                                pointA,
800                                                                objectB,
801                                                                objectA,
802                                                                probability,
803                                                                mPass);
804
805                        vssRays.push_back(vssRay);
806                        hits ++;
807                }
808
809                if (objectB)
810                {
811                        vssRay = new VssRay(pointA,
812                                                                pointB,
813                                                                objectA,
814                                                                objectB,
815                                                                probability,
816                                                                mPass);
817
818                        vssRays.push_back(vssRay);
819                        hits ++;
820                }
821                //Debug << "intel ray: " << *vssRay << endl;
822        }
823        //cout << "a";
824        return hits;
825}
826
827
828Intersectable *Preprocessor::CastIntelSingleRay(const Vector3 &viewPoint,
829                                                                                                const Vector3 &direction,
830                                                                                                //const float probability,
831                                                                                                Vector3 &tPoint,
832                                                                                                const AxisAlignedBox3 &box
833                                                                                                )
834{
835        AxisAlignedBox3 sbox = box;
836        sbox.Enlarge(Vector3(-Limits::Small));
837
838        if (!sbox.IsInside(viewPoint))
839                return 0;
840       
841        float pforg[3];
842        float pfdir[3];
843        double pfnorm[3];
844
845        pforg[0] = viewPoint[0]; pforg[1] = viewPoint[1]; pforg[2] = viewPoint[2];
846        pfdir[0] = direction[0]; pfdir[1] = direction[1]; pfdir[2] = direction[2];
847
848        float dist = 0;
849#ifdef GTP_INTERNAL
850        const int hittriangle = mlrtaIntersectAS(pforg, pfdir, pfnorm, dist);
851#else
852        const int hittriangle = -1;
853#endif
854
855        if (hittriangle == -1)
856        {
857                static Ray ray;
858                SetupRay(ray, viewPoint, direction);
859
860                float tmin = 0, tmax;
861                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
862                {
863                        tPoint = ray.Extrap(tmax);
864                }
865
866                return NULL;
867        }
868        else
869        {
870                tPoint[0] = pforg[0] + pfdir[0] * dist;
871                tPoint[1] = pforg[1] + pfdir[1] * dist;
872                tPoint[2] = pforg[2] + pfdir[2] * dist;
873
874                return mFaceParents[hittriangle];
875        }
876}
877
878
879int Preprocessor::CastInternalRay(
880                                                                  const Vector3 &viewPoint,
881                                                                  const Vector3 &direction,
882                                                                  const float probability,
883                                                                  VssRayContainer &vssRays,
884                                                                  const AxisAlignedBox3 &box
885                                                                  )
886{
887    int hits = 0;
888        static Ray ray;
889
890        AxisAlignedBox3 sbox = box;
891        sbox.Enlarge(Vector3(-Limits::Small));
892
893        if (!sbox.IsInside(viewPoint))
894                return 0;
895       
896        SetupRay(ray, viewPoint, direction);
897       
898        // cast ray to KD tree to find intersection with other objects
899        Intersectable *objectA, *objectB;
900       
901        Vector3 pointA;
902        Vector3 pointB;
903
904        //float bsize = Magnitude(box.Size());
905        if (!mDetectEmptyViewSpace)
906                ray.mFlags &= ~Ray::CULL_BACKFACES;
907        else
908                ray.mFlags |= Ray::CULL_BACKFACES;
909
910        if (mKdTree->CastRay(ray))
911        {
912                objectA = ray.intersections[0].mObject;
913                pointA = ray.Extrap(ray.intersections[0].mT);
914        }
915        else
916        {
917                objectA = NULL;
918                // compute intersection with the scene bounding box
919                float tmin, tmax;
920                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
921                        pointA = ray.Extrap(tmax);
922                else
923                        return 0;
924        }
925
926        // matt: point A could be undefined?
927
928        // cast ray into opposite direction
929        if (1 && mDetectEmptyViewSpace) {
930                SetupRay(ray, pointA, -direction);
931        } else
932                SetupRay(ray, viewPoint, -direction);
933 
934        if (!mDetectEmptyViewSpace)
935                ray.mFlags &= ~Ray::CULL_BACKFACES;
936        else
937                ray.mFlags |= Ray::CULL_BACKFACES;
938
939        if (mKdTree->CastRay(ray))
940        {
941                objectB = ray.intersections[0].mObject;
942                pointB = ray.Extrap(ray.intersections[0].mT);
943        }
944        else
945        {
946                objectB = NULL;
947                float tmin, tmax;
948               
949                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
950                        pointB = ray.Extrap(tmax);
951                else
952                        return 0;
953        }
954 
955        //bool thesame = objectA && (objectA == objectB);
956       
957        //  if (objectA == NULL && objectB != NULL) {
958        if (1 && mDetectEmptyViewSpace)
959        {
960                // cast again to ensure that there is no objectA
961                SetupRay(ray, pointB, direction);
962                ray.mFlags |= Ray::CULL_BACKFACES;
963               
964                if (mKdTree->CastRay(ray))
965                {
966                        objectA = ray.intersections[0].mObject;
967                        pointA = ray.Extrap(ray.intersections[0].mT);
968                }
969        }
970
971 
972        VssRay *vssRay  = NULL;
973
974        bool validSample = (objectA != objectB);
975       
976        //if (validSample && thesame) Debug << "warning!!" << endl;
977
978        if (0 && mDetectEmptyViewSpace)
979        {   
980                // consider all samples valid
981                // check if the viewpoint lies on the line segment AB
982                if (Distance(pointA, pointB) <
983                        Distance(viewPoint, pointA) + Distance(viewPoint, pointB) - Limits::Small)
984                {
985                        validSample = false;
986                }
987        }
988       
989        if (validSample)
990        {       
991                if (objectA)
992                {
993                        vssRay = new VssRay(pointB,
994                                                                pointA,
995                                                                objectB,
996                                                                objectA,
997                                                                probability,
998                                                                mPass);
999                        vssRays.push_back(vssRay);
1000                        hits ++;
1001                }
1002
1003                if (objectB)
1004                {
1005                        vssRay = new VssRay(pointA,
1006                                                                pointB,
1007                                                                objectA,
1008                                                                objectB,
1009                                                                probability,
1010                                                                mPass);
1011                        vssRays.push_back(vssRay);
1012                        hits ++;
1013                }
1014                //Debug << "internal ray: " << *vssRay << endl << endl;
1015        }
1016//cout << "b";
1017        return hits;
1018}
1019
1020
1021int Preprocessor::CastRay(
1022                                                  const Vector3 &viewPoint,
1023                                                  const Vector3 &direction,
1024                                                  const float probability,
1025                                                  VssRayContainer &vssRays,
1026                                                  const AxisAlignedBox3 &box
1027                                                  )
1028{
1029        switch (mRayCastMethod)
1030        {
1031        case INTEL_RAYCASTER:
1032                return CastIntelDoubleRay(viewPoint, direction, probability, vssRays, box);
1033        case INTERNAL_RAYCASTER:
1034        default:
1035                return CastInternalRay(viewPoint, direction, probability, vssRays, box);
1036        }
1037}
1038
1039
1040void Preprocessor::SetupRay(Ray &ray,
1041                                                        const Vector3 &point,
1042                                                        const Vector3 &direction
1043                                                        )
1044{
1045        ray.Clear();
1046        // do not store anything else then intersections at the ray
1047        ray.Init(point, direction, Ray::LOCAL_RAY);
1048}
1049
1050}
Note: See TracBrowser for help on using the repository browser.