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

Revision 1264, 26.0 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#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, mLoadPolygonsAsMeshes, &mFaceParents);
241                else
242                        result = parser->ParseFile(filename, &mSceneGraph->mRoot, mLoadPolygonsAsMeshes);
243
244                delete parser;
245
246        } else {
247                // root for different files
248                mSceneGraph->mRoot = new SceneGraphNode;
249                for (int i= 0; i < filenames.size(); i++) {
250                        if (strstr(filenames[i].c_str(), ".x3d"))
251                                parser = new X3dParser;
252                        else
253                                parser = new UnigraphicsParser;
254                                               
255                        SceneGraphNode *node;
256                        if (parser->ParseFile(filenames[i], &node)) {
257                                mSceneGraph->mRoot->mChildren.push_back(node);
258                                // at least one file parsed
259                                result = true;
260                        }
261                        delete parser;
262                }
263        }
264       
265
266        if (result)
267        {
268                // HACK
269                if (ADDITIONAL_GEOMETRY_HACK)
270                        AddGeometry(mSceneGraph);
271               
272                mSceneGraph->AssignObjectIds();
273       
274                int intersectables, faces;
275                mSceneGraph->GetStatistics(intersectables, faces);
276       
277                cout<<filename<<" parsed successfully."<<endl;
278                cout<<"#NUM_OBJECTS (Total numner of objects)\n"<<intersectables<<endl;
279                cout<<"#NUM_FACES (Total numner of faces)\n"<<faces<<endl;
280                mSceneGraph->CollectObjects(&mObjects);
281                mSceneGraph->mRoot->UpdateBox();
282
283                if (0)
284                {
285                        Exporter *exporter = Exporter::GetExporter("testload.x3d");
286
287                        if (exporter)
288                        {
289                                exporter->ExportGeometry(mObjects);
290                                delete exporter;
291                        }
292                }
293        }
294       
295       
296        return result;
297}
298
299bool
300Preprocessor::ExportPreprocessedData(const string filename)
301{
302 
303  mViewCellsManager->ExportViewCells(filename, true, mObjects);
304 
305  return true;
306}
307
308bool
309Preprocessor::PostProcessVisibility()
310{
311 
312  if (mApplyVisibilityFilter || mApplyVisibilitySpatialFilter) {
313        cout<<"Applying visibility filter ...";
314        cout<<"filter width = " << mVisibilityFilterWidth << endl;
315       
316        if (!mViewCellsManager)
317          return false;
318       
319        mViewCellsManager->ApplyFilter(mKdTree,
320                                                                   mApplyVisibilityFilter ? mVisibilityFilterWidth : -1.0f,
321                                                                   mApplyVisibilitySpatialFilter ? mVisibilityFilterWidth : -1.0f);
322        cout << "done." << endl;
323  }
324 
325  // export the preprocessed information to a file
326  if (mExportVisibility)
327        ExportPreprocessedData(mVisibilityFileName);
328 
329  return true;
330}
331
332
333bool
334Preprocessor::BuildKdTree()
335{
336  mKdTree = new KdTree;
337  // add mesh instances of the scene graph to the root of the tree
338  KdLeaf *root = (KdLeaf *)mKdTree->GetRoot();
339  mSceneGraph->CollectObjects(&root->mObjects);
340 
341  long startTime = GetTime();
342
343  cout << "building kd tree ... " << endl;
344  mKdTree->Construct();
345  cout << "construction finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs " << endl;
346  return true;
347}
348
349void
350Preprocessor::KdTreeStatistics(ostream &s)
351{
352  s<<mKdTree->GetStatistics();
353}
354
355void
356Preprocessor::BspTreeStatistics(ostream &s)
357{
358        s << mBspTree->GetStatistics();
359}
360
361bool
362Preprocessor::Export( const string filename,
363                                          const bool scene,
364                                          const bool kdtree,
365                                          const bool bsptree
366                                          )
367{
368  Exporter *exporter = Exporter::GetExporter(filename);
369       
370  if (exporter) {
371    if (scene)
372      exporter->ExportScene(mSceneGraph->mRoot);
373
374    if (kdtree) {
375      exporter->SetWireframe();
376      exporter->ExportKdTree(*mKdTree);
377    }
378
379        if (bsptree) {
380                //exporter->SetWireframe();
381                exporter->ExportBspTree(*mBspTree);
382        }
383
384    delete exporter;
385    return true;
386  }
387
388  return false;
389}
390
391
392bool Preprocessor::PrepareViewCells()
393{
394        //-- parse view cells construction method
395        Environment::GetSingleton()->GetBoolValue("ViewCells.loadFromFile", mLoadViewCells);
396        char buf[100];
397       
398        if (mLoadViewCells)
399        {       
400                Environment::GetSingleton()->GetStringValue("ViewCells.filename", buf);
401                cout << "loading view cells from " << buf << endl;
402                mViewCellsManager = ViewCellsManager::LoadViewCells(buf, &mObjects, true);
403        }
404        else
405        {
406                //-- parse type of view cell container
407
408                Environment::GetSingleton()->GetStringValue("ViewCells.type", buf);             
409            mViewCellsManager = CreateViewCellsManager(buf);
410
411                // default view space is the extent of the scene
412                mViewCellsManager->SetViewSpaceBox(mSceneGraph->GetBox());
413
414
415        }
416       
417        //-- parameters for render heuristics evaluation
418        float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
419
420        Environment::GetSingleton()->GetFloatValue("Simulation.objRenderCost",objRenderCost);
421        Environment::GetSingleton()->GetFloatValue("Simulation.vcOverhead", vcOverhead);
422        Environment::GetSingleton()->GetFloatValue("Simulation.moveSpeed", moveSpeed);
423       
424        mRenderSimulator =
425                new RenderSimulator(mViewCellsManager, objRenderCost, vcOverhead, moveSpeed);
426
427        mViewCellsManager->SetRenderer(mRenderSimulator);
428
429
430        if (mUseGlRenderer || mUseGlDebugger)
431        {
432                // NOTE: render texture should be power of 2 and square
433                // renderer must be initialised
434                // $$matt
435//              renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager, mKdTree);
436                //              renderer->makeCurrent();
437               
438        }
439       
440        return true;
441}
442
443
444ViewCellsManager *Preprocessor::CreateViewCellsManager(const char *name)
445{
446        ViewCellsTree *vcTree = new ViewCellsTree;
447
448        if (strcmp(name, "kdTree") == 0)
449        {
450                mViewCellsManager = new KdViewCellsManager(vcTree, mKdTree);
451        }
452        else if (strcmp(name, "bspTree") == 0)
453        {
454                Debug << "view cell type: Bsp" << endl;
455
456                mBspTree = new BspTree();
457                mViewCellsManager = new BspViewCellsManager(vcTree, mBspTree);
458        }
459        else if (strcmp(name, "vspBspTree") == 0)
460        {
461                Debug << "view cell type: VspBsp" << endl;
462
463                mVspBspTree = new VspBspTree();
464                mViewCellsManager = new VspBspViewCellsManager(vcTree, mVspBspTree);
465        }
466        else if (strcmp(name, "vspOspTree") == 0)
467        {
468                mVspTree = new VspTree();
469                //mOspTree = new OspTree();
470               
471                // HACK for testing if per kd evaluation works!!
472                mOspTree = new OspTree(*mKdTree);
473
474                mViewCellsManager = new VspOspViewCellsManager(vcTree, mVspTree, mOspTree);
475        }
476        else if (strcmp(name, "sceneDependent") == 0)
477        {
478                Debug << "view cell type: Bsp" << endl;
479
480                //TODO
481                mBspTree = new BspTree();
482                mViewCellsManager = new BspViewCellsManager(vcTree, mBspTree);
483        }
484        else
485        {
486                cerr << "Wrong view cells type " << name << "!!!" << endl;
487                exit(1);
488        }
489
490        //vcTree->SetViewCellsManager(mViewCellsManager);
491        return mViewCellsManager;
492}
493
494
495// use ascii format to store rays
496#define USE_ASCII 0
497
498
499static inline bool ilt(Intersectable *obj1, Intersectable *obj2)
500{
501        return obj1->mId < obj2->mId;
502}
503
504
505bool Preprocessor::LoadKdTree()
506{
507        return true;
508}
509
510bool Preprocessor::ExportKdTree()
511{
512        return true;
513}
514
515
516bool Preprocessor::LoadSamples(VssRayContainer &samples,
517                                                           ObjectContainer &objects) const
518{
519        std::stable_sort(objects.begin(), objects.end(), ilt);
520        char fileName[100];
521        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
522       
523    Vector3 origin, termination;
524        // HACK: needed only for lower_bound algorithm to find the
525        // intersected objects
526        MeshInstance sObj(NULL);
527        MeshInstance tObj(NULL);
528
529#if USE_ASCII
530        ifstream samplesIn(fileName);
531        if (!samplesIn.is_open())
532                return false;
533
534        string buf;
535        while (!(getline(samplesIn, buf)).eof())
536        {
537                sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d",
538                           &origin.x, &origin.y, &origin.z,
539                           &termination.x, &termination.y, &termination.z,
540                           &(sObj.mId), &(tObj.mId));
541               
542                Intersectable *sourceObj = NULL;
543                Intersectable *termObj = NULL;
544               
545                if (sObj.mId >= 0)
546                {
547                        ObjectContainer::iterator oit =
548                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
549                        sourceObj = *oit;
550                }
551               
552                if (tObj.mId >= 0)
553                {
554                        ObjectContainer::iterator oit =
555                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
556                        termObj = *oit;
557                }
558
559                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
560        }
561#else
562        ifstream samplesIn(fileName, ios::binary);
563        if (!samplesIn.is_open())
564                return false;
565
566        while (1)
567        {
568                 samplesIn.read(reinterpret_cast<char *>(&origin), sizeof(Vector3));
569                 samplesIn.read(reinterpret_cast<char *>(&termination), sizeof(Vector3));
570                 samplesIn.read(reinterpret_cast<char *>(&(sObj.mId)), sizeof(int));
571                 samplesIn.read(reinterpret_cast<char *>(&(tObj.mId)), sizeof(int));
572               
573                 if (samplesIn.eof())
574                        break;
575
576                Intersectable *sourceObj = NULL;
577                Intersectable *termObj = NULL;
578               
579                if (sObj.mId >= 0)
580                {
581                        ObjectContainer::iterator oit =
582                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
583                        sourceObj = *oit;
584                }
585               
586                if (tObj.mId >= 0)
587                {
588                        ObjectContainer::iterator oit =
589                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
590                        termObj = *oit;
591                }
592
593                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
594        }
595
596#endif
597        samplesIn.close();
598
599        return true;
600}
601
602
603bool Preprocessor::ExportSamples(const VssRayContainer &samples) const
604{
605        char fileName[100];
606        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
607       
608
609        VssRayContainer::const_iterator it, it_end = samples.end();
610       
611#if USE_ASCII
612        ofstream samplesOut(fileName);
613        if (!samplesOut.is_open())
614                return false;
615
616        for (it = samples.begin(); it != it_end; ++ it)
617        {
618                VssRay *ray = *it;
619                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
620                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;       
621
622                samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " "
623                                   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " "
624                                   << sourceid << " " << termid << "\n";
625        }
626#else
627        ofstream samplesOut(fileName, ios::binary);
628        if (!samplesOut.is_open())
629                return false;
630
631        for (it = samples.begin(); it != it_end; ++ it)
632        {       
633                VssRay *ray = *it;
634                Vector3 origin(ray->GetOrigin());
635                Vector3 termination(ray->GetTermination());
636               
637                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
638                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;               
639
640                samplesOut.write(reinterpret_cast<char *>(&origin), sizeof(Vector3));
641                samplesOut.write(reinterpret_cast<char *>(&termination), sizeof(Vector3));
642                samplesOut.write(reinterpret_cast<char *>(&sourceid), sizeof(int));
643                samplesOut.write(reinterpret_cast<char *>(&termid), sizeof(int));
644    }
645#endif
646        samplesOut.close();
647
648        return true;
649}
650
651#if 0 // matt: implemented interface samplestrategy
652bool
653Preprocessor::GenerateRays(
654                                                   const int number,
655                                                   const int sampleType,
656                                                   SimpleRayContainer &rays
657                                                   )
658{
659  Vector3 origin, direction;
660  int startSize = (int)rays.size();
661  for (int i=0; (int)rays.size() - startSize  < number; i ++) {
662        // now get the direction
663        switch (sampleType) {
664        case OBJECT_BASED_DISTRIBUTION: {
665          mViewCellsManager->GetViewPoint(origin);
666          Vector3 point;
667          Vector3 normal;
668          int i = RandomValue(0, mObjects.size() - 1);
669          Intersectable *object = mObjects[i];
670          object->GetRandomSurfacePoint(point, normal);
671          direction = point - origin;
672        }
673          break;
674        case OBJECT_DIRECTION_BASED_DISTRIBUTION: {
675          int i = RandomValue(0, mObjects.size() - 1);
676          Intersectable *object = mObjects[i];
677          Vector3 normal;
678          object->GetRandomSurfacePoint(origin, normal);
679          direction = UniformRandomVector(normal);
680          origin += 0.1f*direction;
681        }
682          break;
683        case DIRECTION_BASED_DISTRIBUTION:
684          mViewCellsManager->GetViewPoint(origin);
685          direction = UniformRandomVector();
686          break;
687        case DIRECTION_BOX_BASED_DISTRIBUTION: {
688          mViewCellsManager->GetViewPoint(origin);
689          float alpha = RandomValue(0.0f, 2*M_PI);
690          float beta = RandomValue(-M_PI/2, M_PI/2);
691          direction = VssRay::GetDirection(alpha, beta);
692          break;
693        }
694        case SPATIAL_BOX_BASED_DISTRIBUTION:
695          mViewCellsManager->GetViewPoint(origin);
696          direction = mKdTree->GetBox().GetRandomPoint() - origin;
697          break;
698        default:
699          // unsuported distribution type
700          return false;
701        }
702        // $$ jb the pdf is yet not correct for all sampling methods!
703        float pdf = 1.0f;
704        float c = Magnitude(direction);
705        if (c > Limits::Small) {
706          direction*=1.0f/c;
707          rays.AddRay(SimpleRay(origin, direction, pdf));
708        }
709  }
710  return true;
711}
712#endif
713bool Preprocessor::GenerateRays(const int number,
714                                                                const int sampleType,
715                                                                SimpleRayContainer &rays)
716{
717        Vector3 origin, direction;
718       
719        const int startSize = (int)rays.size();
720        SamplingStrategy *strategy = GenerateSamplingStrategy(sampleType);
721
722        if (!strategy)
723                return false;
724
725        for (int i=0; (int)rays.size() - startSize < number; ++ i)
726        {
727                SimpleRay newRay;
728                bool success = strategy->GenerateSample(newRay);
729
730                if (success)
731                        rays.AddRay(newRay);
732        }
733
734        delete strategy;
735
736    return true;
737}
738
739
740SamplingStrategy *Preprocessor::GenerateSamplingStrategy(const int strategyId) const
741{
742        switch (strategyId)
743        {
744        case OBJECT_BASED_DISTRIBUTION:
745                return new ObjectBasedDistribution(*this);
746        case OBJECT_DIRECTION_BASED_DISTRIBUTION:
747                return new ObjectDirectionBasedDistribution(*this);
748        case DIRECTION_BASED_DISTRIBUTION:
749                return new DirectionBasedDistribution(*this);
750        case DIRECTION_BOX_BASED_DISTRIBUTION:
751                return new DirectionBoxBasedDistribution(*this);
752        case SPATIAL_BOX_BASED_DISTRIBUTION:
753                return new SpatialBoxBasedDistribution(*this);
754        //case OBJECTS_INTERIOR_DISTRIBUTION:
755        //      return new ObjectsInteriorDistribution(*this);
756        default: // no valid strategy
757                return NULL;
758        }
759
760        // should never come here
761        return NULL;
762}
763
764
765bool Preprocessor::InitRayCast(const string externKdTree)
766{
767        switch (mRayCastMethod) // use intel ray tracing
768        {
769        case INTEL_RAYCASTER:
770#ifdef GTP_INTERNAL
771                return mlrtaLoadAS(externKdTree.c_str());
772#endif
773        case INTERNAL_RAYCASTER:
774        default:
775                break;
776        }
777
778        return true;
779}
780
781
782int Preprocessor::CastIntelDoubleRay(
783                                                                         const Vector3 &viewPoint,
784                                                                         const Vector3 &direction,
785                                                                         const float probability,
786                                                                         VssRayContainer &vssRays,
787                                                                         const AxisAlignedBox3 &box
788                                                                         )
789{
790        VssRay *vssRay  = NULL;
791        int hits = 0;
792
793        Vector3 pointA, pointB;
794       
795        Intersectable *objectA =
796                CastIntelSingleRay(viewPoint, direction, pointA, box);
797       
798        // cast ray into other direction
799        Intersectable *objectB =
800                CastIntelSingleRay(viewPoint, -direction, pointB, box);
801
802        const bool validSample = (objectA != objectB);
803       
804        if (validSample)
805        {       
806                if (objectA)
807                {
808                        vssRay = new VssRay(pointB,
809                                                                pointA,
810                                                                objectB,
811                                                                objectA,
812                                                                probability,
813                                                                mPass);
814
815                        vssRays.push_back(vssRay);
816                        hits ++;
817                }
818
819                if (objectB)
820                {
821                        vssRay = new VssRay(pointA,
822                                                                pointB,
823                                                                objectA,
824                                                                objectB,
825                                                                probability,
826                                                                mPass);
827
828                        vssRays.push_back(vssRay);
829                        hits ++;
830                }
831                //Debug << "intel ray: " << *vssRay << endl;
832        }
833        //cout << "a";
834        return hits;
835}
836
837
838Intersectable *Preprocessor::CastIntelSingleRay(const Vector3 &viewPoint,
839                                                                                                const Vector3 &direction,
840                                                                                                //const float probability,
841                                                                                                Vector3 &tPoint,
842                                                                                                const AxisAlignedBox3 &box
843                                                                                                )
844{
845        AxisAlignedBox3 sbox = box;
846        sbox.Enlarge(Vector3(-Limits::Small));
847
848        if (!sbox.IsInside(viewPoint))
849                return 0;
850       
851        float pforg[3];
852        float pfdir[3];
853        //double pfnorm[3];
854
855        pforg[0] = viewPoint[0]; pforg[1] = viewPoint[1]; pforg[2] = viewPoint[2];
856        pfdir[0] = direction[0]; pfdir[1] = direction[1]; pfdir[2] = direction[2];
857
858        float dist = 0;
859#ifdef GTP_INTERNAL
860        const int hittriangle = mlrtaIntersectAS(pforg, pfdir, pfnorm, dist);
861#else
862        const int hittriangle = -1;
863#endif
864
865        if (hittriangle == -1)
866        {
867                static Ray ray;
868                SetupRay(ray, viewPoint, direction);
869
870                float tmin = 0, tmax;
871                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
872                {
873                        tPoint = ray.Extrap(tmax);
874                }
875
876                return NULL;
877        }
878        else
879        {
880                tPoint[0] = pforg[0] + pfdir[0] * dist;
881                tPoint[1] = pforg[1] + pfdir[1] * dist;
882                tPoint[2] = pforg[2] + pfdir[2] * dist;
883
884                return mFaceParents[hittriangle];
885        }
886}
887
888
889int Preprocessor::CastInternalRay(
890                                                                  const Vector3 &viewPoint,
891                                                                  const Vector3 &direction,
892                                                                  const float probability,
893                                                                  VssRayContainer &vssRays,
894                                                                  const AxisAlignedBox3 &box
895                                                                  )
896{
897    int hits = 0;
898        static Ray ray;
899
900        AxisAlignedBox3 sbox = box;
901        sbox.Enlarge(Vector3(-Limits::Small));
902
903        if (!sbox.IsInside(viewPoint))
904                return 0;
905       
906        SetupRay(ray, viewPoint, direction);
907       
908        // cast ray to KD tree to find intersection with other objects
909        Intersectable *objectA, *objectB;
910       
911        Vector3 pointA;
912        Vector3 pointB;
913
914        //float bsize = Magnitude(box.Size());
915        if (!mDetectEmptyViewSpace)
916                ray.mFlags &= ~Ray::CULL_BACKFACES;
917        else
918                ray.mFlags |= Ray::CULL_BACKFACES;
919
920        if (mKdTree->CastRay(ray))
921        {
922                objectA = ray.intersections[0].mObject;
923                pointA = ray.Extrap(ray.intersections[0].mT);
924        }
925        else
926        {
927                objectA = NULL;
928                // compute intersection with the scene bounding box
929                float tmin, tmax;
930                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
931                        pointA = ray.Extrap(tmax);
932                else
933                        return 0;
934        }
935
936        // matt: point A could be undefined?
937
938        // cast ray into opposite direction
939        if (1 && mDetectEmptyViewSpace) {
940                SetupRay(ray, pointA, -direction);
941        } else
942                SetupRay(ray, viewPoint, -direction);
943 
944        if (!mDetectEmptyViewSpace)
945                ray.mFlags &= ~Ray::CULL_BACKFACES;
946        else
947                ray.mFlags |= Ray::CULL_BACKFACES;
948
949        if (mKdTree->CastRay(ray))
950        {
951                objectB = ray.intersections[0].mObject;
952                pointB = ray.Extrap(ray.intersections[0].mT);
953        }
954        else
955        {
956                objectB = NULL;
957                float tmin, tmax;
958               
959                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
960                        pointB = ray.Extrap(tmax);
961                else
962                        return 0;
963        }
964 
965        //bool thesame = objectA && (objectA == objectB);
966       
967        //  if (objectA == NULL && objectB != NULL) {
968        if (1 && mDetectEmptyViewSpace)
969        {
970                // cast again to ensure that there is no objectA
971                SetupRay(ray, pointB, direction);
972                ray.mFlags |= Ray::CULL_BACKFACES;
973               
974                if (mKdTree->CastRay(ray))
975                {
976                        objectA = ray.intersections[0].mObject;
977                        pointA = ray.Extrap(ray.intersections[0].mT);
978                }
979        }
980
981 
982        VssRay *vssRay  = NULL;
983
984        bool validSample = (objectA != objectB);
985       
986        //if (validSample && thesame) Debug << "warning!!" << endl;
987
988        if (0 && mDetectEmptyViewSpace)
989        {   
990                // consider all samples valid
991                // check if the viewpoint lies on the line segment AB
992                if (Distance(pointA, pointB) <
993                        Distance(viewPoint, pointA) + Distance(viewPoint, pointB) - Limits::Small)
994                {
995                        validSample = false;
996                }
997        }
998       
999        if (validSample)
1000        {       
1001                if (objectA)
1002                {
1003                        vssRay = new VssRay(pointB,
1004                                                                pointA,
1005                                                                objectB,
1006                                                                objectA,
1007                                                                probability,
1008                                                                mPass);
1009                        vssRays.push_back(vssRay);
1010                        hits ++;
1011                }
1012
1013                if (objectB)
1014                {
1015                        vssRay = new VssRay(pointA,
1016                                                                pointB,
1017                                                                objectA,
1018                                                                objectB,
1019                                                                probability,
1020                                                                mPass);
1021                        vssRays.push_back(vssRay);
1022                        hits ++;
1023                }
1024                //Debug << "internal ray: " << *vssRay << endl << endl;
1025        }
1026//cout << "b";
1027        return hits;
1028}
1029
1030
1031int Preprocessor::CastRay(
1032                                                  const Vector3 &viewPoint,
1033                                                  const Vector3 &direction,
1034                                                  const float probability,
1035                                                  VssRayContainer &vssRays,
1036                                                  const AxisAlignedBox3 &box
1037                                                  )
1038{
1039        switch (mRayCastMethod)
1040        {
1041        case INTEL_RAYCASTER:
1042                return CastIntelDoubleRay(viewPoint, direction, probability, vssRays, box);
1043        case INTERNAL_RAYCASTER:
1044        default:
1045                return CastInternalRay(viewPoint, direction, probability, vssRays, box);
1046        }
1047}
1048
1049
1050void Preprocessor::SetupRay(Ray &ray,
1051                                                        const Vector3 &point,
1052                                                        const Vector3 &direction
1053                                                        )
1054{
1055        ray.Clear();
1056        // do not store anything else then intersections at the ray
1057        ray.Init(point, direction, Ray::LOCAL_RAY);
1058}
1059
1060}
Note: See TracBrowser for help on using the repository browser.