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

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