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

Revision 2004, 38.7 KB checked in by mattausch, 17 years ago (diff)

put #triangles into new format. warning! problems with power plant

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