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

RevLine 
[372]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"
[439]8#include "ViewCellsManager.h"
[445]9#include "ViewCellBsp.h"
10#include "VspBspTree.h"
[469]11#include "RenderSimulator.h"
[496]12#include "GlRenderer.h"
[749]13#include "PlyParser.h"
[1020]14#include "SamplingStrategy.h"
[1233]15#include "VspTree.h"
16#include "OspTree.h"
[1221]17#include "ObjParser.h"
[1264]18#include "BvHierarchy.h"
19
[1251]20#ifdef GTP_INTERNAL
[1221]21#include "ArchModeler2MLRT.hxx"
[1232]22#endif
[372]23
[863]24namespace GtpVisibilityPreprocessor {
[860]25
[1020]26const static bool ADDITIONAL_GEOMETRY_HACK = false;
[860]27
[1145]28//Preprocessor *preprocessor;
[492]29
[750]30
[1001]31// HACK: Artificially modify scene to watch rendercost changes
[750]32static void AddGeometry(SceneGraph *scene)
33{
[752]34        scene->mRoot->UpdateBox();
35
[750]36        AxisAlignedBox3 sceneBox = scene->GetBox();
37
38        int n = 200;
39
40        if (0){
[840]41        // form grid of boxes
[750]42        for (int i = 0; i < n; ++ i)
43        {
44                for (int j = 0; j < n; ++ j)
45                {
[1135]46                        const Vector3 scale2((float)j * 0.8f / n + 0.1f,  0.05f, (float)i * 0.8f  / (float)n + 0.1f);
[750]47               
[840]48                        const Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
[750]49               
[840]50                        const Vector3 boxSize = sceneBox.Size() * Vector3(0.0025f, 0.01f, 0.0025f);
[750]51                        AxisAlignedBox3 box(pt2, pt2 + boxSize);
[991]52                        Mesh *mesh = CreateMeshFromBox(box);
[750]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                {
[1135]65                        const Vector3 scale2(0.15f, (float)j * 0.8f / n + 0.1f, (float)i * 0.8f  / (float)n + 0.1f);
[750]66               
67                        Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
68               
[1135]69                        Vector3 boxSize = sceneBox.Size() * Vector3(0.0025f, 0.01f, 0.0025f);
[750]70                        AxisAlignedBox3 box(pt2, pt2 + boxSize);
[991]71                        Mesh *mesh = CreateMeshFromBox(box);
[750]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        {
[1135]82                const Vector3 scale2(2, 0.2f, (float)i * 0.8f  / (float)n + 0.1f);
[750]83               
84                Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
85               
86                //Vector3 boxSize = sceneBox.Size() * Vector3(0.0025, 0.01, 0.0025);
[1135]87                Vector3 boxSize = sceneBox.Size() * Vector3(0.005f, 0.02f, 0.005f);
[1020]88
[1135]89                AxisAlignedBox3 box(pt2 + 0.1f, pt2 + boxSize);
[991]90                Mesh *mesh = CreateMeshFromBox(box);
[750]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        }
[1221]100               
[840]101        if (1)
102        {
[1221]103                // plane separating view space regions
[1135]104                const Vector3 scale(1.0f, 0.0, 0);
[750]105
[840]106                Vector3 pt = sceneBox.Min() + scale * (sceneBox.Max() - sceneBox.Min());
[750]107
[840]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        }       
[750]119}
120
121
[372]122Preprocessor::Preprocessor():
123mKdTree(NULL),
[409]124mBspTree(NULL),
[445]125mVspBspTree(NULL),
[1264]126mVspTree(NULL),
127mOspTree(NULL),
128mBvHierarchy(NULL),
[1002]129mViewCellsManager(NULL),
[1251]130mRenderSimulator(NULL),
131mPass(0)
[308]132{
[1004]133        Environment::GetSingleton()->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
[538]134 
[840]135        // renderer will be constructed when the scene graph and viewcell manager will be known
136        renderer = NULL;
[496]137 
[1004]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 );
[1221]144        Environment::GetSingleton()->GetIntValue("Preprocessor.rayCastMethod", mRayCastMethod);
[599]145
[871]146        char buffer[256];
[1004]147        Environment::GetSingleton()->GetStringValue("Preprocessor.visibilityFile",  buffer);
[871]148        mVisibilityFileName = buffer;
[1004]149        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", mApplyVisibilityFilter );
150        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter",
[904]151                                                          mApplyVisibilitySpatialFilter );
[1004]152        Environment::GetSingleton()->GetFloatValue("Preprocessor.visibilityFilterWidth", mVisibilityFilterWidth);
[878]153
[840]154        Debug << "detect empty view space=" << mDetectEmptyViewSpace << endl;
155        Debug << "load polygons as meshes: " << mLoadPolygonsAsMeshes << endl;
[372]156}
157
158
159Preprocessor::~Preprocessor()
160{
[752]161  cout << "cleaning up" << endl;
162
163  cout << "Deleting view cells manager ... \n";
[496]164  DEL_PTR(mViewCellsManager);
[752]165  cout << "done.\n";
166
167  cout << "Deleting bsp tree ... \n";
[496]168  DEL_PTR(mBspTree);
[752]169  cout << "done.\n";
170
[840]171  cout << "Deleting kd tree...\n";
[496]172  DEL_PTR(mKdTree);
[840]173  cout << "done.\n";
[1006]174 
[1145]175  cout << "Deleting vsp tree...\n";
176  DEL_PTR(mVspTree);
[840]177  cout << "done.\n";
[752]178
[1145]179  cout << "Deleting osp tree...\n";
180  DEL_PTR(mOspTree);
181  cout << "done.\n";
182
[840]183  cout << "Deleting vspbsp tree...\n";
[496]184  DEL_PTR(mVspBspTree);
[840]185  cout << "done.\n";
[1002]186
187   cout << "Deleting scene graph...\n";
188  DEL_PTR(mSceneGraph);
189  cout << "done.\n";
190
191  DEL_PTR(mRenderSimulator);
192  DEL_PTR(renderer);
[372]193}
194
[387]195int
[419]196SplitFilenames(const string str, vector<string> &filenames)
[387]197{
198        int pos = 0;
199
200        while(1) {
[469]201                int npos = (int)str.find(';', pos);
[387]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));
[440]210        return (int)filenames.size();
[387]211}
212
[750]213
[372]214bool
215Preprocessor::LoadScene(const string filename)
216{
[925]217        // use leaf nodes of the original spatial hierarchy as occludees
[508]218        mSceneGraph = new SceneGraph;
[372]219 
[508]220        Parser *parser;
[387]221        vector<string> filenames;
222        int files = SplitFilenames(filename, filenames);
[712]223        cout << "number of input files: " << files << endl;
[387]224        bool result = false;
225        if (files == 1) {
226               
227                if (strstr(filename.c_str(), ".x3d"))
[749]228                  parser = new X3dParser;
[387]229                else
[811]230                  if (strstr(filename.c_str(), ".ply") || strstr(filename.c_str(), ".plb"))
[749]231                        parser = new PlyParser;
[1221]232                  else if (strstr(filename.c_str(), ".obj"))
233                          parser = new ObjParser;
234                  else
235                          parser = new UnigraphicsParser;
[372]236
[387]237                cout<<filename<<endl;
[372]238
[1221]239                if (mRayCastMethod == Preprocessor::INTEL_RAYCASTER)
[1272]240                  result = parser->ParseFile(filename, &mSceneGraph->mRoot,
241                                                                         mLoadPolygonsAsMeshes,
242                                                                         &mFaceParents);
[1221]243                else
[1272]244                  result = parser->ParseFile(filename, &mSceneGraph->mRoot, mLoadPolygonsAsMeshes);
245               
[387]246                delete parser;
[372]247
[387]248        } else {
249                // root for different files
250                mSceneGraph->mRoot = new SceneGraphNode;
251                for (int i= 0; i < filenames.size(); i++) {
[1272]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;
[387]274                }
275        }
[372]276       
[1272]277       
[752]278        if (result)
[1272]279          {
[752]280                // HACK
[1020]281                if (ADDITIONAL_GEOMETRY_HACK)
282                        AddGeometry(mSceneGraph);
[752]283               
[1020]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();
[752]294
[1020]295                if (0)
296                {
297                        Exporter *exporter = Exporter::GetExporter("testload.x3d");
[658]298
[1020]299                        if (exporter)
300                        {
301                                exporter->ExportGeometry(mObjects);
302                                delete exporter;
303                        }
304                }
[387]305        }
[372]306       
[492]307       
308        return result;
[372]309}
310
311bool
312Preprocessor::ExportPreprocessedData(const string filename)
313{
[871]314 
[931]315  mViewCellsManager->ExportViewCells(filename, true, mObjects);
[871]316 
317  return true;
[372]318}
319
320bool
[871]321Preprocessor::PostProcessVisibility()
322{
323 
[904]324  if (mApplyVisibilityFilter || mApplyVisibilitySpatialFilter) {
[997]325        cout<<"Applying visibility filter ...";
[1002]326        cout<<"filter width = " << mVisibilityFilterWidth << endl;
[904]327       
[1002]328        if (!mViewCellsManager)
[1199]329          return false;
330       
[871]331        mViewCellsManager->ApplyFilter(mKdTree,
[904]332                                                                   mApplyVisibilityFilter ? mVisibilityFilterWidth : -1.0f,
333                                                                   mApplyVisibilitySpatialFilter ? mVisibilityFilterWidth : -1.0f);
[997]334        cout << "done." << endl;
[871]335  }
336 
337  // export the preprocessed information to a file
338  if (mExportVisibility)
339        ExportPreprocessedData(mVisibilityFileName);
340 
341  return true;
342}
343
344
345bool
[372]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 
[1201]353  long startTime = GetTime();
354
355  cout << "building kd tree ... " << endl;
[372]356  mKdTree->Construct();
[1201]357  cout << "construction finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs " << endl;
[372]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,
[492]375                                          const bool scene,
376                                          const bool kdtree,
377                                          const bool bsptree
378                                          )
[372]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}
[429]402
[508]403
[463]404bool Preprocessor::PrepareViewCells()
405{
[577]406        //-- parse view cells construction method
[1004]407        Environment::GetSingleton()->GetBoolValue("ViewCells.loadFromFile", mLoadViewCells);
[577]408        char buf[100];
409       
410        if (mLoadViewCells)
[997]411        {       
[1004]412                Environment::GetSingleton()->GetStringValue("ViewCells.filename", buf);
[1264]413                cout << "loading view cells from " << buf << endl;
[1004]414                mViewCellsManager = ViewCellsManager::LoadViewCells(buf, &mObjects, true);
[577]415        }
416        else
417        {
418                //-- parse type of view cell container
[1264]419
[1004]420                Environment::GetSingleton()->GetStringValue("ViewCells.type", buf);             
[1002]421            mViewCellsManager = CreateViewCellsManager(buf);
[1112]422
423                // default view space is the extent of the scene
424                mViewCellsManager->SetViewSpaceBox(mSceneGraph->GetBox());
425
426
[577]427        }
[1112]428       
[997]429        //-- parameters for render heuristics evaluation
[473]430        float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
431
[1004]432        Environment::GetSingleton()->GetFloatValue("Simulation.objRenderCost",objRenderCost);
433        Environment::GetSingleton()->GetFloatValue("Simulation.vcOverhead", vcOverhead);
434        Environment::GetSingleton()->GetFloatValue("Simulation.moveSpeed", moveSpeed);
[694]435       
[473]436        mRenderSimulator =
437                new RenderSimulator(mViewCellsManager, objRenderCost, vcOverhead, moveSpeed);
[440]438
[480]439        mViewCellsManager->SetRenderer(mRenderSimulator);
[440]440
[574]441
[538]442        if (mUseGlRenderer || mUseGlDebugger)
[540]443        {
444                // NOTE: render texture should be power of 2 and square
445                // renderer must be initialised
[1145]446                // $$matt
447//              renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager, mKdTree);
[556]448                //              renderer->makeCurrent();
[746]449               
[540]450        }
[496]451       
[463]452        return true;
[490]453}
454
455
[575]456ViewCellsManager *Preprocessor::CreateViewCellsManager(const char *name)
457{
[1264]458        ViewCellsTree *vcTree = new ViewCellsTree;
459
[575]460        if (strcmp(name, "kdTree") == 0)
461        {
[1264]462                mViewCellsManager = new KdViewCellsManager(vcTree, mKdTree);
[575]463        }
464        else if (strcmp(name, "bspTree") == 0)
465        {
466                Debug << "view cell type: Bsp" << endl;
467
[577]468                mBspTree = new BspTree();
[1264]469                mViewCellsManager = new BspViewCellsManager(vcTree, mBspTree);
[575]470        }
471        else if (strcmp(name, "vspBspTree") == 0)
472        {
473                Debug << "view cell type: VspBsp" << endl;
474
[1004]475                mVspBspTree = new VspBspTree();
[1264]476                mViewCellsManager = new VspBspViewCellsManager(vcTree, mVspBspTree);
[575]477        }
[1006]478        else if (strcmp(name, "vspOspTree") == 0)
[575]479        {
[1022]480                mVspTree = new VspTree();
[1264]481                //mOspTree = new OspTree();
[1174]482               
483                // HACK for testing if per kd evaluation works!!
484                mOspTree = new OspTree(*mKdTree);
[1022]485
[1264]486                mViewCellsManager = new VspOspViewCellsManager(vcTree, mVspTree, mOspTree);
[575]487        }
488        else if (strcmp(name, "sceneDependent") == 0)
489        {
[1143]490                Debug << "view cell type: Bsp" << endl;
491
[575]492                //TODO
493                mBspTree = new BspTree();
[1264]494                mViewCellsManager = new BspViewCellsManager(vcTree, mBspTree);
[575]495        }
496        else
497        {
[664]498                cerr << "Wrong view cells type " << name << "!!!" << endl;
[575]499                exit(1);
500        }
501
[1264]502        //vcTree->SetViewCellsManager(mViewCellsManager);
[575]503        return mViewCellsManager;
504}
505
506
[491]507// use ascii format to store rays
508#define USE_ASCII 0
509
510
[1145]511static inline bool ilt(Intersectable *obj1, Intersectable *obj2)
[490]512{
513        return obj1->mId < obj2->mId;
514}
515
516
[1197]517bool Preprocessor::LoadKdTree()
518{
519        return true;
520}
521
522bool Preprocessor::ExportKdTree()
523{
524        return true;
525}
526
527
[490]528bool Preprocessor::LoadSamples(VssRayContainer &samples,
529                                                           ObjectContainer &objects) const
530{
531        std::stable_sort(objects.begin(), objects.end(), ilt);
532        char fileName[100];
[1004]533        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
[490]534       
[491]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);
[490]540
[491]541#if USE_ASCII
[656]542        ifstream samplesIn(fileName);
[490]543        if (!samplesIn.is_open())
544                return false;
545
546        string buf;
547        while (!(getline(samplesIn, buf)).eof())
548        {
[491]549                sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d",
[490]550                           &origin.x, &origin.y, &origin.z,
[491]551                           &termination.x, &termination.y, &termination.z,
552                           &(sObj.mId), &(tObj.mId));
[490]553               
[491]554                Intersectable *sourceObj = NULL;
555                Intersectable *termObj = NULL;
556               
557                if (sObj.mId >= 0)
[490]558                {
559                        ObjectContainer::iterator oit =
[491]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                }
[490]570
[491]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;
[490]596                }
[491]597               
598                if (tObj.mId >= 0)
[490]599                {
[491]600                        ObjectContainer::iterator oit =
601                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
602                        termObj = *oit;
[490]603                }
[491]604
605                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
[490]606        }
[491]607
608#endif
[490]609        samplesIn.close();
610
611        return true;
612}
613
[508]614
615bool Preprocessor::ExportSamples(const VssRayContainer &samples) const
[490]616{
[491]617        char fileName[100];
[1004]618        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
[491]619       
[490]620
621        VssRayContainer::const_iterator it, it_end = samples.end();
622       
[491]623#if USE_ASCII
624        ofstream samplesOut(fileName);
[490]625        if (!samplesOut.is_open())
626                return false;
627
628        for (it = samples.begin(); it != it_end; ++ it)
629        {
630                VssRay *ray = *it;
[491]631                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
632                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;       
633
[490]634                samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " "
635                                   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " "
[491]636                                   << sourceid << " " << termid << "\n";
[490]637        }
[491]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
[490]658        samplesOut.close();
[1194]659
[490]660        return true;
661}
[563]662
[1020]663#if 0 // matt: implemented interface samplestrategy
[563]664bool
665Preprocessor::GenerateRays(
666                                                   const int number,
667                                                   const int sampleType,
668                                                   SimpleRayContainer &rays
669                                                   )
670{
671  Vector3 origin, direction;
[837]672  int startSize = (int)rays.size();
673  for (int i=0; (int)rays.size() - startSize  < number; i ++) {
[563]674        // now get the direction
675        switch (sampleType) {
676        case OBJECT_BASED_DISTRIBUTION: {
[576]677          mViewCellsManager->GetViewPoint(origin);
[563]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;
[576]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;
[563]695        case DIRECTION_BASED_DISTRIBUTION:
[576]696          mViewCellsManager->GetViewPoint(origin);
[563]697          direction = UniformRandomVector();
698          break;
699        case DIRECTION_BOX_BASED_DISTRIBUTION: {
[576]700          mViewCellsManager->GetViewPoint(origin);
[563]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:
[576]707          mViewCellsManager->GetViewPoint(origin);
[563]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}
[1020]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);
[860]733
[1020]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;
[878]749}
[1020]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);
[1021]766        //case OBJECTS_INTERIOR_DISTRIBUTION:
767        //      return new ObjectsInteriorDistribution(*this);
[1020]768        default: // no valid strategy
769                return NULL;
770        }
[1221]771
[1020]772        // should never come here
773        return NULL;
774}
775
776
[1221]777bool Preprocessor::InitRayCast(const string externKdTree)
778{
779        switch (mRayCastMethod) // use intel ray tracing
780        {
781        case INTEL_RAYCASTER:
[1251]782#ifdef GTP_INTERNAL
[1272]783          cout<<"Ray Cast file: "<<externKdTree<<endl;
784          return mlrtaLoadAS(externKdTree.c_str());
[1232]785#endif
[1221]786        case INTERNAL_RAYCASTER:
787        default:
788                break;
789        }
790
791        return true;
[1020]792}
[1221]793
[1251]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;
[1221]848}
[1251]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];
[1272]866        double pfnorm[3];
[1251]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
[1272]911  int hits = 0;
912  static Ray ray;
913  Intersectable *objectA, *objectB;
914  Vector3 pointA, pointB;
[1251]915
[1272]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;
[1251]923       
[1272]924  SetupRay(ray, viewPoint, direction);
925  ray.mFlags &= ~Ray::CULL_BACKFACES;
[1251]926
[1272]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);
[1251]946        else
[1272]947          return 0;
948  }
[1251]949
950 
[1272]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);
[1251]967        else
[1272]968          return 0;
969  }
[1251]970 
971 
[1272]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 ++;
[1251]985        }
986       
[1272]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 ++;
[1251]997        }
[1272]998  }
999 
1000  return hits;
[1251]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.