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

Revision 1272, 25.5 KB checked in by bittner, 18 years ago (diff)

mlrta configuration changes

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