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

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