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

Revision 2572, 40.2 KB checked in by mattausch, 17 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#include "VssRay.h"
21#include "IntelRayCaster.h"
22#include "InternalRayCaster.h"
23#include "GlobalLinesRenderer.h"
24#include "ObjectsParser.h"
25
26
27#define DEBUG_RAYCAST 0
28#define SHOW_RAYCAST_TIMING 1
29
30using namespace std;
31
32namespace GtpVisibilityPreprocessor {
33
34
35inline static bool ilt(Intersectable *obj1, Intersectable *obj2)
36{
37        return obj1->mId < obj2->mId;
38}
39
40
41Preprocessor *preprocessor = NULL;
42 
43
44Preprocessor::Preprocessor():
45mKdTree(NULL),
46mBspTree(NULL),
47mVspBspTree(NULL),
48mViewCellsManager(NULL),
49mRenderSimulator(NULL),
50mPass(0),
51mSceneGraph(NULL),
52mRayCaster(NULL),
53mStopComputation(false),
54mThread(NULL),
55mGlobalLinesRenderer(NULL),
56mUseHwGlobalLines(false)
57{
58        Environment::GetSingleton()->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
59 
60        // renderer will be constructed when the scene graph and viewcell manager will be known
61        renderer = NULL;
62       
63        Environment::GetSingleton()->GetBoolValue("Preprocessor.useGlDebugger", mUseGlDebugger);
64        Environment::GetSingleton()->GetBoolValue("Preprocessor.loadMeshes", mLoadMeshes);
65        Environment::GetSingleton()->GetBoolValue("Preprocessor.quitOnFinish", mQuitOnFinish);
66        Environment::GetSingleton()->GetBoolValue("Preprocessor.computeVisibility", mComputeVisibility);
67        Environment::GetSingleton()->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
68        Environment::GetSingleton()->GetBoolValue("Preprocessor.exportVisibility", mExportVisibility );
69       
70        char buffer[256];
71        Environment::GetSingleton()->GetStringValue("Preprocessor.visibilityFile",  buffer);
72        mVisibilityFileName = buffer;
73       
74        Environment::GetSingleton()->GetStringValue("Preprocessor.stats",  buffer);
75        mStats.open(buffer);
76               
77        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", mApplyVisibilityFilter);
78        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter",
79                                                                                          mApplyVisibilitySpatialFilter );
80        Environment::GetSingleton()->GetFloatValue("Preprocessor.visibilityFilterWidth", mVisibilityFilterWidth);
81
82        Environment::GetSingleton()->GetBoolValue("Preprocessor.exportObj", mExportObj);
83       
84        Environment::GetSingleton()->GetBoolValue("Preprocessor.useViewSpaceBox", mUseViewSpaceBox);
85
86        Environment::GetSingleton()->GetBoolValue("Preprocessor.Export.rays", mExportRays);
87        Environment::GetSingleton()->GetBoolValue("Preprocessor.Export.animation", mExportAnimation);
88        Environment::GetSingleton()->GetIntValue("Preprocessor.Export.numRays", mExportNumRays);
89
90        Environment::GetSingleton()->GetIntValue("Preprocessor.samplesPerPass", mSamplesPerPass);
91        Environment::GetSingleton()->GetIntValue("Preprocessor.totalSamples", mTotalSamples);
92        Environment::GetSingleton()->GetIntValue("Preprocessor.totalTime", mTotalTime);
93        Environment::GetSingleton()->GetIntValue("Preprocessor.samplesPerEvaluation",
94                                                                                         mSamplesPerEvaluation);
95
96        Debug << "******* Preprocessor Options **********" << endl;
97        Debug << "detect empty view space=" << mDetectEmptyViewSpace << endl;
98        Debug << "load meshes: " << mLoadMeshes << endl;
99        Debug << "load meshes: " << mLoadMeshes << endl;
100        Debug << "export obj: " << mExportObj << endl;
101        Debug << "use view space box: " << mUseViewSpaceBox << endl;
102
103        cout << "samples per pass " << mSamplesPerPass << endl;
104}
105
106
107Preprocessor::~Preprocessor()
108{
109        cout << "cleaning up" << endl;
110
111        cout << "Deleting view cells manager ... \n";
112        DEL_PTR(mViewCellsManager);
113        cout << "done.\n";
114
115       
116        cout << "Deleting bsp tree ... \n";
117        DEL_PTR(mBspTree);
118        cout << "done.\n";
119
120        cout << "Deleting kd tree ...\n";
121        DEL_PTR(mKdTree);
122        cout << "done.\n";
123
124        cout << "Deleting vspbsp tree ... \n";
125        DEL_PTR(mVspBspTree);
126        cout << "done.\n";
127
128        cout << "Deleting scene graph ... \n";
129        DEL_PTR(mSceneGraph);
130        cout << "done.\n";
131
132        cout << "deleting render simulator ... \n";
133        DEL_PTR(mRenderSimulator);
134        mRenderSimulator = NULL;
135        cout << "deleting renderer ... \n";
136        DEL_PTR(renderer);
137        renderer = NULL;
138        cout << "deleting ray caster ... \n";
139        DEL_PTR(mRayCaster);
140
141#ifdef USE_CG
142        cout << "deleting global lines renderer ... \n";
143        DEL_PTR(mGlobalLinesRenderer);
144#endif
145        cout << "finished" << endl;
146}
147
148
149GlRendererBuffer *Preprocessor::GetRenderer()
150{
151        return renderer;
152}
153
154
155static int SplitFilenames(const string str, vector<string> &filenames)
156{
157        int pos = 0;
158
159        while(1) {
160                int npos = (int)str.find(';', pos);
161               
162                if (npos < 0 || npos - pos < 1)
163                        break;
164                filenames.push_back(string(str, pos, npos - pos));
165                pos = npos + 1;
166        }
167       
168        filenames.push_back(string(str, pos, str.size() - pos));
169        return (int)filenames.size();
170}
171
172
173void Preprocessor::SetThread(PreprocessorThread *t)
174{
175        mThread = t;
176}
177
178
179PreprocessorThread *Preprocessor::GetThread() const
180{
181        return mThread;
182}
183
184
185bool Preprocessor::LoadBinaryObj(const string &filename,
186                                                                 SceneGraphNode *root,
187                                                                 vector<FaceParentInfo> *parents)
188{
189        //ifstream inStream(filename, ios::binary);
190        igzstream inStream(filename.c_str());
191       
192        if (!inStream.is_open())
193                return false;
194
195        cout << "binary obj dump available, loading " << filename.c_str() << endl;
196       
197        // read in triangle size
198        int numTriangles;
199
200        inStream.read(reinterpret_cast<char *>(&numTriangles), sizeof(int));
201        root->mGeometry.reserve(numTriangles);
202        cout << "loading " << numTriangles << " triangles (" << numTriangles *
203                (sizeof(TriangleIntersectable) + sizeof(TriangleIntersectable *)) /
204                (1024 * 1024) << " MB)" << endl;
205
206        int i = 0;
207
208        while (1)
209        {
210                Triangle3 tri;
211               
212                inStream.read(reinterpret_cast<char *>(tri.mVertices + 0), sizeof(Vector3));
213                inStream.read(reinterpret_cast<char *>(tri.mVertices + 1), sizeof(Vector3));
214                inStream.read(reinterpret_cast<char *>(tri.mVertices + 2), sizeof(Vector3));
215
216                // end of file reached
217                if (inStream.eof())
218                        break;
219
220                TriangleIntersectable *obj = new TriangleIntersectable(tri);
221                root->mGeometry.push_back(obj);
222               
223                if ((i ++) % 500000 == 499999)
224                         cout<<"\r"<<i<<"/"<<numTriangles<<"\r";
225        }
226       
227        if (i != numTriangles)
228        {
229                cout << "warning: triangle size does not match with loaded triangle size" << endl;
230                return false;
231        }
232
233        cout << "loaded " << numTriangles << " triangles" << endl;
234
235        return true;
236}
237
238
239bool Preprocessor::ExportBinaryObj(const string &filename, SceneGraphNode *root)
240{
241        ogzstream samplesOut(filename.c_str());
242
243        if (!samplesOut.is_open())
244                return false;
245
246        int numTriangles = (int)root->mGeometry.size();
247
248        samplesOut.write(reinterpret_cast<char *>(&numTriangles), sizeof(int));
249
250        ObjectContainer::const_iterator oit, oit_end = root->mGeometry.end();
251
252        for (oit = root->mGeometry.begin(); oit != oit_end; ++ oit)
253        {
254                Intersectable *obj = *oit;
255
256                if (obj->Type() == Intersectable::TRIANGLE_INTERSECTABLE)
257                {
258                        Triangle3 tri = static_cast<TriangleIntersectable *>(obj)->GetItem();
259
260                        samplesOut.write(reinterpret_cast<char *>(tri.mVertices + 0), sizeof(Vector3));
261                        samplesOut.write(reinterpret_cast<char *>(tri.mVertices + 1), sizeof(Vector3));
262                        samplesOut.write(reinterpret_cast<char *>(tri.mVertices + 2), sizeof(Vector3));
263                }
264                else
265                {
266                        cout << "not implemented intersectable type " << obj->Type() << endl;
267                }
268        }
269
270        cout << "exported " << numTriangles << " triangles" << endl;
271
272        return true;
273}
274
275
276bool Preprocessor::ExportObj(const string &filename, const ObjectContainer &objects)
277{
278        ofstream samplesOut(filename.c_str());
279
280        if (!samplesOut.is_open())
281                return false;
282
283        ObjectContainer::const_iterator oit, oit_end = objects.end();
284
285        //AxisAlignedBox3 bbox = mSceneGraph->GetBox(); bbox.Enlarge(30.0);
286        for (oit = objects.begin(); oit != oit_end; ++ oit)
287        {
288                Intersectable *obj = *oit;
289
290                if (obj->Type() == Intersectable::TRIANGLE_INTERSECTABLE)
291                {
292                        Triangle3 tri = static_cast<TriangleIntersectable *>(obj)->GetItem();
293                        //if (!(bbox.IsInside(tri.mVertices[0]) && bbox.IsInside(tri.mVertices[1]) && bbox.IsInside(tri.mVertices[2])))continue;
294                       
295                        samplesOut << "v " << tri.mVertices[0].x << " " << tri.mVertices[0].y << " " << tri.mVertices[0].z << endl;
296                        samplesOut << "v " << tri.mVertices[1].x << " " << tri.mVertices[1].y << " " << tri.mVertices[1].z << endl;
297                        samplesOut << "v " << tri.mVertices[2].x << " " << tri.mVertices[2].y << " " << tri.mVertices[2].z << endl;
298                        //}
299                }
300                else
301                {
302                        cout << "not implemented intersectable type " << obj->Type() << endl;
303                }
304        }
305
306        // write faces
307        int i = 1;
308        for (oit = objects.begin(); oit != oit_end; ++ oit)
309        {
310                Intersectable *obj = *oit;
311                if (obj->Type() == Intersectable::TRIANGLE_INTERSECTABLE)
312                {
313                        //Triangle3 tri = static_cast<TriangleIntersectable *>(obj)->GetItem();
314                        //if (!(bbox.IsInside(tri.mVertices[0]) && bbox.IsInside(tri.mVertices[1]) && bbox.IsInside(tri.mVertices[2]))) continue;
315                       
316                        Triangle3 tri = static_cast<TriangleIntersectable *>(obj)->GetItem();
317                        samplesOut << "f " << i << " " << i + 1 << " " << i + 2 << endl;
318                        i += 3;
319                }
320                else
321                {
322                        cout << "not implemented intersectable type " << obj->Type() << endl;
323                }
324        }
325
326        return true;
327
328}
329
330static string ReplaceSuffix(const string &filename, string a, string b)
331{
332        string result = filename;
333
334        int pos = (int)filename.rfind(a, (int)filename.size() - 1);
335        if (pos == filename.size() - a.size()) {
336                result.replace(pos, a.size(), b);
337        }
338        return result;
339}
340
341
342Intersectable *Preprocessor::GetParentObject(const int index) const
343{
344        if (index < 0)
345        {
346                //cerr << "Warning: triangle index smaller zero! " << index << endl;
347                return NULL;
348        }
349       
350        if (!mFaceParents.empty())
351        {
352                if (index >= (int)mFaceParents.size())
353                {
354                        cerr << "Warning: triangle index out of range! " << index << endl;
355                        return NULL;
356                }
357                else
358                {
359                        return mFaceParents[index].mObject;
360                }
361        }
362        else
363        {
364                  if (index >= (int)mObjects.size())
365                  {
366                          cerr<<"Warning: triangle index out of range! " << index << " of " << (int)mObjects.size() << endl;
367                          return NULL;
368                  }
369                  else
370                  {
371                          return mObjects[index];
372                  }
373        }
374}
375
376
377Vector3 Preprocessor::GetParentNormal(const int index) const
378{
379        if (!mFaceParents.empty())
380        {
381                return mFaceParents[index].mObject->GetNormal(mFaceParents[index].mFaceIndex);
382        }       
383        else
384        {
385                return mObjects[index]->GetNormal(0);
386        }
387}
388
389
390bool
391Preprocessor::LoadScene(const string &filename)
392{
393    // use leaf nodes of the original spatial hierarchy as occludees
394        mSceneGraph = new SceneGraph;
395 
396        Parser *parser;
397        vector<string> filenames;
398        const int files = SplitFilenames(filename, filenames);
399        cout << "number of input files: " << files << endl;
400
401        bool result = false;
402        bool isObj = false;
403
404        // root for different files
405        mSceneGraph->SetRoot(new SceneGraphNode());
406
407        // intel ray caster can only trace triangles
408        int rayCastMethod;
409        Environment::GetSingleton()->GetIntValue("Preprocessor.rayCastMethod", rayCastMethod);
410        vector<FaceParentInfo> *fi =
411          ((rayCastMethod == RayCaster::INTEL_RAYCASTER) && mLoadMeshes) ?
412          &mFaceParents : NULL;
413
414        if (files == 1)
415        {
416                if (strstr(filename.c_str(), ".x3d"))
417                {
418                        parser = new X3dParser;
419
420                        result = parser->ParseFile(filename,
421                                mSceneGraph->GetRoot(),
422                                mLoadMeshes,
423                                fi);
424                        delete parser;
425                }
426                else if (strstr(filename.c_str(), ".ply") || strstr(filename.c_str(), ".plb"))
427                {
428                        parser = new PlyParser;
429
430                        result = parser->ParseFile(filename,
431                                mSceneGraph->GetRoot(),
432                                mLoadMeshes,
433                                fi);
434                        delete parser;
435                }
436                else if (strstr(filename.c_str(), ".obj"))
437                {
438                        isObj = true;
439
440                        // hack: load binary dump
441                        const string bnFile = ReplaceSuffix(filename, ".obj", ".bn");
442
443                        if (!mLoadMeshes)
444                        {
445                                result = LoadBinaryObj(bnFile, mSceneGraph->GetRoot(), fi);
446                        }
447
448                        // parse obj
449                        if (!result)
450                        {
451                                cout << "no binary dump available or loading full meshes, parsing file" << endl;
452                                parser = new ObjParser;
453
454                                result = parser->ParseFile(filename, mSceneGraph->GetRoot(), mLoadMeshes, fi);
455
456                                cout << "loaded " << (int)mSceneGraph->GetRoot()->mGeometry.size() << " entities" << endl;
457
458                                // only works for triangles
459                                if (result && !mLoadMeshes)
460                                {
461                                        cout << "exporting binary obj to " << bnFile << "... " << endl;
462
463                                        ExportBinaryObj(bnFile, mSceneGraph->GetRoot());
464
465                                        cout << "finished" << endl;
466                                }
467
468                                delete parser;
469                        }
470                }
471                else
472                {
473                        parser = new UnigraphicsParser;
474                        result = parser->ParseFile(filename, mSceneGraph->GetRoot(), mLoadMeshes, fi);
475                        delete parser;
476                }
477
478                cout << filename << endl;
479        }
480        else
481        {
482                vector<string>::const_iterator fit, fit_end = filenames.end();
483
484                for (fit = filenames.begin(); fit != fit_end; ++ fit)
485                {
486                        const string filename = *fit;
487
488                        cout << "parsing file " << filename.c_str() << endl;
489                        if (strstr(filename.c_str(), ".x3d"))
490                                parser = new X3dParser;
491                        else
492                                parser = new UnigraphicsParser;
493
494                        SceneGraphNode *node = new SceneGraphNode();
495                        const bool success =
496                                parser->ParseFile(filename, node, mLoadMeshes, fi);
497
498                        if (success)
499                        {
500                                mSceneGraph->GetRoot()->mChildren.push_back(node);
501                                result = true; // at least one file parsed
502                        }
503
504                        // temporare hack
505                        //if (!strstr(filename.c_str(), "plane")) mSceneGraph->GetRoot()->UpdateBox();
506
507                        delete parser;
508                }
509        }
510
511        if (result)
512        { 
513                int intersectables, faces;
514                mSceneGraph->GetStatistics(intersectables, faces);
515 
516                cout<<filename<<" parsed successfully."<<endl;
517                cout<<"#NUM_OBJECTS (Total numner of objects)\n"<<intersectables<<endl;
518                cout<<"#NUM_FACES (Total numner of faces)\n"<<faces<<endl;
519               
520                mObjects.reserve(intersectables);
521                mSceneGraph->CollectObjects(&mObjects);
522       
523                mSceneGraph->AssignObjectIds();
524
525                mSceneGraph->GetRoot()->UpdateBox();
526                               
527                cout << "finished loading" << endl;
528        }
529
530        return result;
531}
532
533bool
534Preprocessor::ExportPreprocessedData(const string &filename)
535{
536        mViewCellsManager->ExportViewCells(filename, true, mObjects);
537        return true;
538}
539
540
541bool
542Preprocessor::PostProcessVisibility()
543{
544 
545  if (mApplyVisibilityFilter || mApplyVisibilitySpatialFilter) {
546        cout<<"Applying visibility filter ...";
547        cout<<"filter width = " << mVisibilityFilterWidth << endl;
548       
549        if (!mViewCellsManager)
550          return false;
551       
552       
553        mViewCellsManager->ApplyFilter(mKdTree,
554                                                                   mApplyVisibilityFilter ?
555                                                                   mVisibilityFilterWidth : -1.0f,
556                                                                   mApplyVisibilitySpatialFilter ?
557                                                                   mVisibilityFilterWidth : -1.0f);
558        cout << "done." << endl;
559  }
560 
561  // export the preprocessed information to a file
562  if (1 && mExportVisibility)
563  {
564          ExportPreprocessedData(mVisibilityFileName);
565  }
566
567  return true;
568}
569
570
571bool
572Preprocessor::BuildKdTree()
573{
574  mKdTree = new KdTree;
575
576  // add mesh instances of the scene graph to the root of the tree
577  KdLeaf *root = (KdLeaf *)mKdTree->GetRoot();
578       
579  mSceneGraph->CollectObjects(&root->mObjects);
580 
581  const long startTime = GetTime();
582  cout << "building kd tree ... " << endl;
583
584  mKdTree->Construct();
585
586  cout << "finished kd tree construction in " << TimeDiff(startTime, GetTime()) * 1e-3
587           << " secs " << endl;
588
589  return true;
590}
591
592
593void
594Preprocessor::KdTreeStatistics(ostream &s)
595{
596  s<<mKdTree->GetStatistics();
597}
598
599void
600Preprocessor::BspTreeStatistics(ostream &s)
601{
602        s << mBspTree->GetStatistics();
603}
604
605bool
606Preprocessor::Export( const string &filename,
607                                         const bool scene,
608                                         const bool kdtree
609                                         )
610{
611        Exporter *exporter = Exporter::GetExporter(filename);
612
613        if (exporter) {
614                if (2 && scene)
615                        exporter->ExportScene(mSceneGraph->GetRoot());
616
617                if (1 && kdtree) {
618                        exporter->SetWireframe();
619                        exporter->ExportKdTree(*mKdTree);
620                }
621
622                delete exporter;
623                return true;
624        }
625
626        return false;
627}
628
629
630bool Preprocessor::PrepareViewCells()
631{
632        // load the view cells assigning the found objects to the pvss
633#if 0
634        cerr << "loading binary view cells" << endl;
635        ViewCellsManager *dummyViewCellsManager =
636                LoadViewCellsBinary("test.vc", mObjects, false, NULL);
637
638    //cerr << "reexporting the binary view cells" << endl;
639        //dummyViewCellsManager->ExportViewCellsBinary("outvc.xml.gz", true, mObjects);
640       
641        return false;
642#endif
643
644        ///////
645        //-- parse view cells construction method
646
647        Environment::GetSingleton()->GetBoolValue("ViewCells.loadFromFile", mLoadViewCells);
648        char buf[100];
649
650        if (mLoadViewCells)
651        {       
652               
653#ifdef USE_BIT_PVS
654                // HACK: for kd pvs, set pvs size to maximal number of kd nodes
655                vector<KdLeaf *> leaves;
656                preprocessor->mKdTree->CollectLeaves(leaves);
657
658                ObjectPvs::SetPvsSize((int)leaves.size());
659#endif
660
661                Environment::GetSingleton()->GetStringValue("ViewCells.filename", buf);
662                cout << "loading objects from " << buf << endl;
663
664                // load objects which will be used as pvs entries
665                ObjectContainer pvsObjects;
666                if (0) LoadObjects(buf, pvsObjects, mObjects);
667
668                const bool finalizeViewCells = true;
669                cout << "loading view cells from " << buf << endl;
670
671                mViewCellsManager = ViewCellsManager::LoadViewCells(buf,
672                                                                                                                        pvsObjects,
673                                                                                                                        mObjects,
674                                                                                                                        finalizeViewCells,
675                                                                                                                        NULL);
676
677                cout << "view cells loaded." << endl<<flush;
678
679                if (!mViewCellsManager)
680                {
681                        cerr << "no view cells manager could be loaded" << endl;
682                        return false;
683                }
684        }
685        else
686        {
687                // parse type of view cells manager
688                Environment::GetSingleton()->GetStringValue("ViewCells.type", buf);             
689                mViewCellsManager = CreateViewCellsManager(buf);
690
691                // default view space is the extent of the scene
692                AxisAlignedBox3 viewSpaceBox;
693
694                if (mUseViewSpaceBox)
695                {
696                        viewSpaceBox = mSceneGraph->GetBox();
697
698                        // use a small box outside of the scene
699                        viewSpaceBox.Scale(Vector3(0.15f, 0.3f, 0.5f));
700                        //viewSpaceBox.Translate(Vector3(Magnitude(mSceneGraph->GetBox().Size()) * 0.5f, 0, 0));
701                        viewSpaceBox.Translate(Vector3(Magnitude(mSceneGraph->GetBox().Size()) * 0.3f, 0, 0));
702                        mViewCellsManager->SetViewSpaceBox(viewSpaceBox);
703                }
704                else
705                {
706                        viewSpaceBox = mSceneGraph->GetBox();
707                        mViewCellsManager->SetViewSpaceBox(viewSpaceBox);
708                }
709
710                bool loadVcGeometry;
711                Environment::GetSingleton()->GetBoolValue("ViewCells.loadGeometry", loadVcGeometry);
712
713                bool extrudeBaseTriangles;
714                Environment::GetSingleton()->GetBoolValue("ViewCells.useBaseTrianglesAsGeometry", extrudeBaseTriangles);
715
716                char vcGeomFilename[100];
717                Environment::GetSingleton()->GetStringValue("ViewCells.geometryFilename", vcGeomFilename);
718
719                // create view cells from specified geometry
720                if (loadVcGeometry)
721                {
722                        if (mViewCellsManager->GetType() == ViewCellsManager::BSP)
723                        {
724                                if (!mViewCellsManager->LoadViewCellsGeometry(vcGeomFilename, extrudeBaseTriangles))
725                                {
726                                        cerr << "loading view cells geometry failed" << endl;
727                                }
728                        }
729                        else
730                        {
731                                cerr << "loading view cells geometry is not implemented for this manager" << endl;
732                        }
733                }
734        }
735
736        ////////
737        //-- evaluation of render cost heuristics
738
739        float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
740
741        Environment::GetSingleton()->GetFloatValue("Simulation.objRenderCost",objRenderCost);
742        Environment::GetSingleton()->GetFloatValue("Simulation.vcOverhead", vcOverhead);
743        Environment::GetSingleton()->GetFloatValue("Simulation.moveSpeed", moveSpeed);
744
745        mRenderSimulator =
746                new RenderSimulator(mViewCellsManager, objRenderCost, vcOverhead, moveSpeed);
747
748        mViewCellsManager->SetRenderer(mRenderSimulator);
749       
750        mViewCellsManager->SetPreprocessor(this);
751
752        return true;
753}
754
755 
756bool Preprocessor::ConstructViewCells()
757{
758        // construct view cells using it's own set of samples
759        mViewCellsManager->Construct(this);
760
761        // visualizations and statistics
762        Debug << "finished view cells:" << endl;
763        mViewCellsManager->PrintStatistics(Debug);
764
765        return true;
766}
767
768
769ViewCellsManager *Preprocessor::CreateViewCellsManager(const char *name)
770{
771        ViewCellsTree *vcTree = new ViewCellsTree;
772
773        if (strcmp(name, "kdTree") == 0)
774        {
775                mViewCellsManager = new KdViewCellsManager(vcTree, mKdTree);
776        }
777        else if (strcmp(name, "bspTree") == 0)
778        {
779                Debug << "view cell type: Bsp" << endl;
780
781                mBspTree = new BspTree();
782                mViewCellsManager = new BspViewCellsManager(vcTree, mBspTree);
783        }
784        else if (strcmp(name, "vspBspTree") == 0)
785        {
786                Debug << "view cell type: VspBsp" << endl;
787
788                mVspBspTree = new VspBspTree();
789                mViewCellsManager = new VspBspViewCellsManager(vcTree, mVspBspTree);
790        }
791        else if (strcmp(name, "vspOspTree") == 0)
792        {
793                Debug << "view cell type: VspOsp" << endl;
794                char buf[100];         
795                Environment::GetSingleton()->GetStringValue("Hierarchy.type", buf);     
796
797                mViewCellsManager = new VspOspViewCellsManager(vcTree, buf);
798        }
799        else if (strcmp(name, "sceneDependent") == 0) //TODO
800        {
801                Debug << "view cell type: Bsp" << endl;
802               
803                mBspTree = new BspTree();
804                mViewCellsManager = new BspViewCellsManager(vcTree, mBspTree);
805        }
806        else
807        {
808                cerr << "Wrong view cells type " << name << "!!!" << endl;
809                exit(1);
810        }
811
812        return mViewCellsManager;
813}
814
815
816// use ascii format to store rays
817#define USE_ASCII 0
818
819
820bool Preprocessor::LoadKdTree(const string &filename)
821{
822        mKdTree = new KdTree();
823        return mKdTree->ImportBinTree(filename.c_str(), mObjects);
824}
825
826
827bool Preprocessor::ExportKdTree(const string &filename)
828{
829        return mKdTree->ExportBinTree(filename.c_str());
830}
831
832
833bool Preprocessor::LoadSamples(VssRayContainer &samples,
834                                                           ObjectContainer &objects) const
835{
836        std::stable_sort(objects.begin(), objects.end(), ilt);
837        char fileName[100];
838        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
839       
840    Vector3 origin, termination;
841        // HACK: needed only for lower_bound algorithm to find the
842        // intersected objects
843        MeshInstance sObj(NULL);
844        MeshInstance tObj(NULL);
845
846#if USE_ASCII
847        ifstream inStream(fileName);
848        if (!inStream.is_open())
849                return false;
850
851        string buf;
852        while (!(getline(inStream, buf)).eof())
853        {
854                sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d",
855                           &origin.x, &origin.y, &origin.z,
856                           &termination.x, &termination.y, &termination.z,
857                           &(sObj.mId), &(tObj.mId));
858               
859                Intersectable *sourceObj = NULL;
860                Intersectable *termObj = NULL;
861               
862                if (sObj.mId >= 0)
863                {
864                        ObjectContainer::iterator oit =
865                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
866                        sourceObj = *oit;
867                }
868               
869                if (tObj.mId >= 0)
870                {
871                        ObjectContainer::iterator oit =
872                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
873                        termObj = *oit;
874                }
875
876                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
877        }
878#else
879        ifstream inStream(fileName, ios::binary);
880        if (!inStream.is_open())
881                return false;
882
883        while (1)
884        {
885                 inStream.read(reinterpret_cast<char *>(&origin), sizeof(Vector3));
886                 inStream.read(reinterpret_cast<char *>(&termination), sizeof(Vector3));
887                 inStream.read(reinterpret_cast<char *>(&(sObj.mId)), sizeof(int));
888                 inStream.read(reinterpret_cast<char *>(&(tObj.mId)), sizeof(int));
889               
890                 if (inStream.eof())
891                        break;
892
893                Intersectable *sourceObj = NULL;
894                Intersectable *termObj = NULL;
895               
896                if (sObj.mId >= 0)
897                {
898                        ObjectContainer::iterator oit =
899                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
900                        sourceObj = *oit;
901                }
902               
903                if (tObj.mId >= 0)
904                {
905                        ObjectContainer::iterator oit =
906                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
907                        termObj = *oit;
908                }
909
910                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
911        }
912#endif
913
914        inStream.close();
915
916        return true;
917}
918
919
920bool Preprocessor::ExportSamples(const VssRayContainer &samples) const
921{
922        char fileName[100];
923        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
924       
925
926        VssRayContainer::const_iterator it, it_end = samples.end();
927       
928#if USE_ASCII
929        ofstream samplesOut(fileName);
930        if (!samplesOut.is_open())
931                return false;
932
933        for (it = samples.begin(); it != it_end; ++ it)
934        {
935                VssRay *ray = *it;
936                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
937                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;       
938
939                samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " "
940                                   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " "
941                                   << sourceid << " " << termid << "\n";
942        }
943#else
944        ofstream samplesOut(fileName, ios::binary);
945        if (!samplesOut.is_open())
946                return false;
947
948        for (it = samples.begin(); it != it_end; ++ it)
949        {       
950                VssRay *ray = *it;
951                Vector3 origin(ray->GetOrigin());
952                Vector3 termination(ray->GetTermination());
953               
954                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
955                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;               
956
957                samplesOut.write(reinterpret_cast<char *>(&origin), sizeof(Vector3));
958                samplesOut.write(reinterpret_cast<char *>(&termination), sizeof(Vector3));
959                samplesOut.write(reinterpret_cast<char *>(&sourceid), sizeof(int));
960                samplesOut.write(reinterpret_cast<char *>(&termid), sizeof(int));
961    }
962#endif
963        samplesOut.close();
964
965        return true;
966}
967
968
969int
970Preprocessor::GenerateRays(const int number,
971                                                   SamplingStrategy &strategy,
972                                                   SimpleRayContainer &rays)
973{
974  return strategy.GenerateSamples(number, rays);
975}
976
977
978int
979Preprocessor::GenerateRays(const int number,
980                                                   const int sampleType,
981                                                   SimpleRayContainer &rays)
982{
983        const int startSize = (int)rays.size();
984        SamplingStrategy *strategy = GenerateSamplingStrategy(sampleType);
985        int castRays = 0;
986
987        if (!strategy)
988        {
989                return 0;
990        }
991
992#if 1
993        castRays = strategy->GenerateSamples(number, rays);
994#else
995        GenerateRayBundle(rays, newRay, 16, 0);
996        castRays += 16;
997#endif
998
999        delete strategy;
1000        return castRays;
1001}
1002
1003
1004SamplingStrategy *Preprocessor::GenerateSamplingStrategy(const int strategyId)
1005{
1006        switch (strategyId)
1007        {
1008        case SamplingStrategy::OBJECT_BASED_DISTRIBUTION:
1009                return new ObjectBasedDistribution(*this);
1010        case SamplingStrategy::OBJECT_DIRECTION_BASED_DISTRIBUTION:
1011                return new ObjectDirectionBasedDistribution(*this);
1012        case SamplingStrategy::DIRECTION_BASED_DISTRIBUTION:
1013                return new DirectionBasedDistribution(*this);
1014        case SamplingStrategy::DIRECTION_BOX_BASED_DISTRIBUTION:
1015                return new DirectionBoxBasedDistribution(*this);
1016        case SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION:
1017                return new SpatialBoxBasedDistribution(*this);
1018        case SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION:
1019                return new ReverseObjectBasedDistribution(*this);
1020        case SamplingStrategy::VIEWCELL_BORDER_BASED_DISTRIBUTION:
1021                return new ViewCellBorderBasedDistribution(*this);
1022        case SamplingStrategy::VIEWSPACE_BORDER_BASED_DISTRIBUTION:
1023                return new ViewSpaceBorderBasedDistribution(*this);
1024        case SamplingStrategy::REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION:
1025                return new ReverseViewSpaceBorderBasedDistribution(*this);
1026        case SamplingStrategy::GLOBAL_LINES_DISTRIBUTION:
1027                return new GlobalLinesDistribution(*this);
1028               
1029                //case OBJECTS_INTERIOR_DISTRIBUTION:
1030                //      return new ObjectsInteriorDistribution(*this);
1031        default: // no valid strategy
1032                Debug << "warning: no valid sampling strategy" << endl;
1033                return NULL;
1034        }
1035
1036        return NULL; // should never come here
1037}
1038
1039
1040bool Preprocessor::LoadInternKdTree(const string &internKdTree)
1041{
1042        bool mUseKdTree = true;
1043
1044        if (!mUseKdTree) {
1045                // create just a dummy KdTree
1046                mKdTree = new KdTree;
1047                return true;
1048        }
1049
1050        // always try to load the kd tree
1051        cout << "loading kd tree file " << internKdTree << " ... " << endl;
1052
1053        if (!LoadKdTree(internKdTree)) {
1054                cout << "error loading kd tree with filename "
1055                        << internKdTree << ", rebuilding it instead ... " << endl;
1056                // build new kd tree from scene geometry
1057                BuildKdTree();
1058
1059                // export kd tree?
1060                const long startTime = GetTime();
1061                cout << "exporting kd tree ... ";
1062
1063                if (!ExportKdTree(internKdTree))
1064                {
1065                        cout << " error exporting kd tree with filename "
1066                                << internKdTree << endl;
1067                }
1068                else
1069                {
1070                        cout << "finished in "
1071                                << TimeDiff(startTime, GetTime()) * 1e-3
1072                                << " secs" << endl;
1073                }
1074        }
1075
1076        KdTreeStatistics(cout);
1077        cout << mKdTree->GetBox() << endl;
1078
1079        return true;
1080}
1081
1082
1083bool Preprocessor::InitRayCast(const string &externKdTree,
1084                                                           const string &internKdTree)
1085{
1086        // always try to load the kd tree
1087/*      cout << "loading kd tree file " << internKdTree << " ... " << endl;
1088
1089        if (!LoadKdTree(internKdTree))
1090        {
1091                cout << "error loading kd tree with filename "
1092                         << internKdTree << ", rebuilding it instead ... " << endl;
1093                // build new kd tree from scene geometry
1094                BuildKdTree();
1095
1096                // export kd tree?
1097                const long startTime = GetTime();
1098                cout << "exporting kd tree ... ";
1099
1100                if (!ExportKdTree(internKdTree))
1101                {
1102                        cout << " error exporting kd tree with filename "
1103                                 << internKdTree << endl;
1104                }
1105                else
1106                {
1107                        cout << "finished in "
1108                                 << TimeDiff(startTime, GetTime()) * 1e-3
1109                                 << " secs" << endl;
1110                }
1111        }
1112       
1113        KdTreeStatistics(cout);
1114        cout << mKdTree->GetBox() << endl;
1115*/
1116        int rayCastMethod;
1117        Environment::GetSingleton()->
1118                GetIntValue("Preprocessor.rayCastMethod", rayCastMethod);
1119
1120        if (rayCastMethod == 0)
1121        {
1122                cout << "ray cast method: internal" << endl;
1123                mRayCaster = new InternalRayCaster(*this);
1124        }
1125        else
1126        {
1127#ifdef GTP_INTERNAL
1128          cout << "ray cast method: intel" << endl;
1129          mRayCaster = new IntelRayCaster(*this, externKdTree);
1130#endif
1131        }
1132       
1133        /////////////////
1134        //-- reserve constant block of rays
1135       
1136        // hack: If we dont't use view cells loading, there must be at least as much rays
1137        // as are needed for the view cells construction
1138        bool loadViewCells;
1139        Environment::GetSingleton()->GetBoolValue("ViewCells.loadFromFile", loadViewCells);
1140
1141        int reserveRays;       
1142        int constructionSamples;
1143
1144        if (!loadViewCells)
1145        {
1146                cout << "hack: setting ray pool size to view cell construction or evaluation size" << endl;
1147
1148                constructionSamples = 1000000;
1149
1150                char buf[100];
1151                Environment::GetSingleton()->GetStringValue("ViewCells.type", buf);     
1152
1153                if (strcmp(buf, "vspBspTree") == 0)
1154                {
1155                        Environment::GetSingleton()->GetIntValue("VspBspTree.Construction.samples", constructionSamples);
1156                       
1157                }
1158                else if (strcmp(buf, "vspOspTree") == 0)
1159                {
1160                        Environment::GetSingleton()->GetIntValue("Hierarchy.Construction.samples", constructionSamples);               
1161                }
1162
1163                int evalSamplesPerPass;
1164
1165                Environment::GetSingleton()->GetIntValue("ViewCells.Evaluation.samplesPerPass", evalSamplesPerPass);
1166
1167                reserveRays = max(constructionSamples, evalSamplesPerPass);
1168                reserveRays *= 2;
1169        }
1170        else
1171        {
1172                cout << "setting ray pool size to samples per pass" << endl;       
1173                reserveRays = mSamplesPerPass * 2;
1174        }
1175
1176        cout << "======================" << endl;
1177        cout << "reserving " << reserveRays << " rays " << endl;
1178        mRayCaster->ReserveVssRayPool(reserveRays);
1179       
1180        return true;
1181}
1182
1183
1184void
1185Preprocessor::CastRays(
1186                                           SimpleRayContainer &rays,
1187                                           VssRayContainer &vssRays,
1188                                           const bool castDoubleRays,
1189                                           const bool pruneInvalidRays
1190                                           )
1191{
1192
1193        const long t1 = GetTime();
1194       
1195        if (rays.size() > 10000)
1196        {
1197
1198                mRayCaster->SortRays(rays);
1199                cout<<"Rays sorted in "<<TimeDiff(t1, GetTime())<<" ms."<<endl;
1200        }
1201
1202
1203        if (mUseHwGlobalLines)
1204        {
1205                CastRaysWithHwGlobalLines(
1206                        rays,
1207                        vssRays,
1208                        castDoubleRays,
1209                        pruneInvalidRays
1210                        );
1211        }
1212        else
1213        {
1214                mRayCaster->CastRays(
1215                        rays,                           
1216                        vssRays,
1217                        mViewCellsManager->GetViewSpaceBox(),
1218                        castDoubleRays,
1219                        pruneInvalidRays);
1220        }
1221
1222        if (rays.size() > 10000)
1223        {
1224                cout << endl;
1225                long t2 = GetTime();
1226
1227#if SHOW_RAYCAST_TIMING
1228                if (castDoubleRays)
1229                        cout << 2 * rays.size() / (1e3f * TimeDiff(t1, t2)) << "M rays/s" << endl;
1230                else
1231                        cout << rays.size() / (1e3f * TimeDiff(t1, t2)) << "M rays/s" << endl;
1232#endif
1233        }
1234
1235        DeterminePvsObjects(vssRays);
1236}
1237
1238 
1239void
1240Preprocessor::CastRaysWithHwGlobalLines(
1241                                                                                SimpleRayContainer &rays,
1242                                                                                VssRayContainer &vssRays,
1243                                                                                const bool castDoubleRays,
1244                                                                                const bool pruneInvalidRays)
1245{
1246  SimpleRayContainer::const_iterator rit, rit_end = rays.end();
1247  SimpleRayContainer rayBucket;
1248  int i = 0;
1249  for (rit = rays.begin(); rit != rit_end; ++ rit, ++ i)
1250        {
1251          SimpleRay ray = *rit;
1252#ifdef USE_CG
1253                // HACK: global lines must be treated special
1254          if (ray.mDistribution == SamplingStrategy::HW_GLOBAL_LINES_DISTRIBUTION)
1255                {
1256                  mGlobalLinesRenderer->CastGlobalLines(ray, vssRays);
1257                  continue;
1258                }
1259#endif
1260                rayBucket.push_back(ray);
1261
1262                // 16 rays gathered => do ray casting
1263                if (rayBucket.size() >= 16)
1264                {
1265                        mRayCaster->CastRays16(
1266                                rayBucket,                             
1267                                vssRays,
1268                                mViewCellsManager->GetViewSpaceBox(),
1269                                castDoubleRays,
1270                                pruneInvalidRays);
1271
1272                        rayBucket.clear();
1273                }
1274
1275                if (rays.size() > 100000 && i % 100000 == 0)
1276                        cout<<"\r"<<i<<"/"<<(int)rays.size()<<"\r";
1277        }
1278   
1279        // cast rest of rays
1280        SimpleRayContainer::const_iterator sit, sit_end = rayBucket.end();
1281
1282        for (sit = rayBucket.begin(); sit != sit_end; ++ sit)
1283        {
1284                SimpleRay ray = *sit;
1285
1286#ifdef USE_CG
1287                // HACK: global lines must be treated special
1288                if (ray.mDistribution == SamplingStrategy::HW_GLOBAL_LINES_DISTRIBUTION)
1289                {
1290                        mGlobalLinesRenderer->CastGlobalLines(ray, vssRays);
1291                        continue;
1292                }
1293#endif
1294                mRayCaster->CastRay(
1295                                                        ray,
1296                                                        vssRays,
1297                                                        mViewCellsManager->GetViewSpaceBox(),
1298                                                        castDoubleRays,
1299                                                        pruneInvalidRays);
1300               
1301        }
1302
1303}
1304
1305
1306bool Preprocessor::GenerateRayBundle(SimpleRayContainer &rayBundle,                                                                     
1307                                                                         const SimpleRay &mainRay,
1308                                                                         const int number,
1309                                                                         const int pertubType) const
1310{
1311        rayBundle.push_back(mainRay);
1312
1313        const float pertubOrigin = 0.0f;
1314        const float pertubDir = 0.2f;
1315
1316        for (int i = 0; i < number - 1; ++ i)
1317        {
1318                Vector3 pertub;
1319
1320                pertub.x = RandomValue(0.0f, pertubDir);
1321                pertub.y = RandomValue(0.0f, pertubDir);
1322                pertub.z = RandomValue(0.0f, pertubDir);
1323
1324                const Vector3 newDir = mainRay.mDirection + pertub;
1325                //const Vector3 newDir = mainRay.mDirection;
1326
1327                pertub.x = RandomValue(0.0f, pertubOrigin);
1328                pertub.y = RandomValue(0.0f, pertubOrigin);
1329                pertub.z = RandomValue(0.0f, pertubOrigin);
1330
1331                const Vector3 newOrigin = mainRay.mOrigin + pertub;
1332                //const Vector3 newOrigin = mainRay.mOrigin;
1333
1334                rayBundle.push_back(SimpleRay(newOrigin, newDir, 0, 1.0f));
1335        }
1336
1337        return true;
1338}
1339
1340
1341void Preprocessor::SetupRay(Ray &ray,
1342                                                        const Vector3 &point,
1343                                                        const Vector3 &direction) const
1344{
1345        ray.Clear();
1346        // do not store anything else then intersections at the ray
1347        ray.Init(point, direction, Ray::LOCAL_RAY);     
1348}
1349
1350
1351void Preprocessor::EvalViewCellHistogram()
1352{
1353        char filename[256];
1354        Environment::GetSingleton()->GetStringValue("Preprocessor.histogram.file", filename);
1355 
1356        // mViewCellsManager->EvalViewCellHistogram(filename, 1000000);
1357        mViewCellsManager->EvalViewCellHistogramForPvsSize(filename, 1000000);
1358}
1359
1360
1361bool
1362Preprocessor::ExportRays(const char *filename,
1363                                                 const VssRayContainer &vssRays,
1364                                                 const int number,
1365                                                 const bool exportScene
1366                                                 )
1367{
1368  cout<<"Exporting vss rays..."<<endl<<flush;
1369 
1370  Exporter *exporter = NULL;
1371  exporter = Exporter::GetExporter(filename);
1372
1373  if (0) {
1374        exporter->SetWireframe();
1375        exporter->ExportKdTree(*mKdTree);
1376  }
1377 
1378  exporter->SetFilled();
1379  // $$JB temporarily do not export the scene
1380  if (exportScene)
1381        exporter->ExportScene(mSceneGraph->GetRoot());
1382
1383  exporter->SetWireframe();
1384
1385  if (1) {
1386        exporter->SetForcedMaterial(RgbColor(1,0,1));
1387        exporter->ExportBox(mViewCellsManager->GetViewSpaceBox());
1388        exporter->ResetForcedMaterial();
1389  }
1390 
1391  VssRayContainer rays;
1392  vssRays.SelectRays(number, rays);
1393  exporter->ExportRays(rays, RgbColor(1, 0, 0));
1394  delete exporter;
1395  cout<<"done."<<endl<<flush;
1396
1397  return true;
1398}
1399
1400bool
1401Preprocessor::ExportRayAnimation(const char *filename,
1402                                                                 const vector<VssRayContainer> &vssRays
1403                                                                 )
1404{
1405  cout<<"Exporting vss rays..."<<endl<<flush;
1406       
1407  Exporter *exporter = NULL;
1408  exporter = Exporter::GetExporter(filename);
1409  if (0) {
1410        exporter->SetWireframe();
1411        exporter->ExportKdTree(*mKdTree);
1412  }
1413  exporter->SetFilled();
1414  // $$JB temporarily do not export the scene
1415  if (0)
1416        exporter->ExportScene(mSceneGraph->GetRoot());
1417  exporter->SetWireframe();
1418
1419  if (1) {
1420        exporter->SetForcedMaterial(RgbColor(1,0,1));
1421        exporter->ExportBox(mViewCellsManager->GetViewSpaceBox());
1422        exporter->ResetForcedMaterial();
1423  }
1424 
1425  exporter->ExportRaySets(vssRays, RgbColor(1, 0, 0));
1426       
1427  delete exporter;
1428
1429  cout<<"done."<<endl<<flush;
1430
1431  return true;
1432}
1433
1434void
1435Preprocessor::ComputeRenderError()
1436{
1437  // compute rendering error
1438       
1439  if (renderer && renderer->mPvsStatFrames) {
1440        //      emit EvalPvsStat();
1441        //      QMutex mutex;
1442        //      mutex.lock();
1443        //      renderer->mRenderingFinished.wait(&mutex);
1444        //      mutex.unlock();
1445
1446        if (mViewCellsManager->GetViewCellPoints()->size()) {
1447         
1448          vector<ViewCellPoints *> *vcPoints = mViewCellsManager->GetViewCellPoints();
1449         
1450          vector<ViewCellPoints *>::const_iterator
1451                vit = vcPoints->begin(),
1452                vit_end = vcPoints->end();
1453
1454          SimpleRayContainer viewPoints;
1455         
1456          for (; vit != vit_end; ++ vit) {
1457                ViewCellPoints *vp = *vit;
1458
1459                SimpleRayContainer::const_iterator rit = vp->second.begin(), rit_end = vp->second.end();
1460                for (; rit!=rit_end; ++rit)
1461                  viewPoints.push_back(*rit);
1462          }
1463
1464          if (viewPoints.size() != renderer->mPvsErrorBuffer.size()) {
1465                renderer->mPvsErrorBuffer.resize(viewPoints.size());
1466                renderer->ClearErrorBuffer();
1467          }
1468
1469          renderer->EvalPvsStat(viewPoints);
1470        } else
1471          renderer->EvalPvsStat();
1472
1473        mStats <<
1474          "#AvgPvsRenderError\n" <<renderer->mPvsStat.GetAvgError()<<endl<<
1475          "#AvgPixelError\n" <<renderer->GetAvgPixelError()<<endl<<
1476          "#MaxPixelError\n" <<renderer->GetMaxPixelError()<<endl<<
1477          "#MaxPvsRenderError\n" <<renderer->mPvsStat.GetMaxError()<<endl<<
1478          "#ErrorFreeFrames\n" <<renderer->mPvsStat.GetErrorFreeFrames()<<endl<<
1479          "#AvgRenderPvs\n" <<renderer->mPvsStat.GetAvgPvs()<<endl;
1480  }
1481}
1482
1483
1484Intersectable *Preprocessor::GetObjectById(const int id)
1485{
1486#if 1
1487        // create a dummy mesh instance to be able to use stl
1488        MeshInstance object(NULL);
1489        object.SetId(id);
1490
1491        ObjectContainer::const_iterator oit =
1492                lower_bound(mObjects.begin(), mObjects.end(), &object, ilt);
1493                               
1494        // objects sorted by id
1495        if ((oit != mObjects.end()) && ((*oit)->GetId() == object.GetId()))
1496        {
1497                return (*oit);
1498        }
1499        else
1500        {
1501                return NULL;
1502        }
1503#else
1504        return mObjects[id - 1];
1505#endif
1506}
1507
1508
1509void Preprocessor::PrepareHwGlobalLines()
1510{
1511        int texHeight, texWidth;
1512        float eps;
1513        int maxDepth;
1514        bool sampleReverse;
1515
1516        Environment::GetSingleton()->GetIntValue("Preprocessor.HwGlobalLines.texHeight", texHeight);
1517        Environment::GetSingleton()->GetIntValue("Preprocessor.HwGlobalLines.texWidth", texWidth);
1518        Environment::GetSingleton()->GetFloatValue("Preprocessor.HwGlobalLines.stepSize", eps);
1519        Environment::GetSingleton()->GetIntValue("Preprocessor.HwGlobalLines.maxDepth", maxDepth);
1520        Environment::GetSingleton()->GetBoolValue("Preprocessor.HwGlobalLines.sampleReverse", sampleReverse);
1521
1522        Debug << "****** hw global line options *******" << endl;
1523        Debug << "texWidth: " << texWidth << endl;
1524        Debug << "texHeight: " << texHeight << endl;
1525        Debug << "sampleReverse: " << sampleReverse << endl;
1526        Debug << "max depth: " << maxDepth << endl;
1527        Debug << "step size: " << eps << endl;
1528        Debug << endl;
1529
1530#ifdef USE_CG
1531        globalLinesRenderer = mGlobalLinesRenderer =
1532                new GlobalLinesRenderer(this,
1533                                                                texHeight,
1534                                                                texWidth,
1535                                                                eps,
1536                                                                maxDepth,
1537                                                                sampleReverse);
1538
1539        mGlobalLinesRenderer->InitGl();
1540
1541#endif
1542}
1543
1544
1545void Preprocessor::DeterminePvsObjects(VssRayContainer &rays)
1546{
1547        mViewCellsManager->DeterminePvsObjects(rays, false);
1548}
1549
1550
1551bool Preprocessor::LoadObjects(const string &filename,
1552                                                           ObjectContainer &pvsObjects,
1553                                                           const ObjectContainer &preprocessorObjects)
1554{
1555        ObjectsParser parser;
1556
1557        const bool success = parser.ParseObjects(filename,
1558                                                                                         pvsObjects,
1559                                                                                         preprocessorObjects);
1560
1561        if (!success)
1562        {
1563                Debug << "Error: loading objects failed!" << endl;
1564        }
1565
1566        // hack: no bvh object could be found => take preprocessor objects
1567        if (pvsObjects.empty())
1568        {
1569                Debug << "no objects" << endl;
1570                pvsObjects = preprocessorObjects;
1571        }
1572
1573        return success;
1574}
1575
1576
1577}
Note: See TracBrowser for help on using the repository browser.