source: GTP/trunk/Lib/Vis/Preprocessing/src/QtInterface/QtGlRenderer.cpp @ 2715

Revision 2715, 71.3 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "glInterface.h"
2#include "QtGlRenderer.h"
3#include "Mesh.h"
4#include "OcclusionQuery.h"
5#include "ViewCellsManager.h"
6#include "SceneGraph.h"
7#include "Pvs.h"
8#include "Viewcell.h"
9#include "Beam.h"
10#include "KdTree.h"
11#include "Environment.h"
12#include "RssPreprocessor.h"
13#include "RssTree.h"
14#include "Trackball.h"
15#include "QtPreprocessorThread.h"
16#include "Material.h"
17#include "IntersectableWrapper.h"
18#include "LogWriter.h"
19#include "RayCaster.h"
20#include "ObjectPlacer.h"
21
22
23#define USE_CG 1
24
25#define TEST_PVS_RENDERING 0
26
27#if USE_CG
28#include <Cg/cg.h>
29#include <Cg/cgGL.h>
30#endif
31
32#include <QVBoxLayout>
33
34
35using namespace std;
36
37
38namespace GtpVisibilityPreprocessor
39{
40
41 
42class ViewCellsManager;
43
44static CGcontext sCgContext = NULL;
45static CGprogram sCgFragmentProgram = NULL;
46static CGprofile sCgFragmentProfile;
47
48
49QtGlRendererWidget *rendererWidget = NULL;
50QtGlDebuggerWidget *debuggerWidget = NULL;
51
52
53
54static SimpleRayContainer sViewPointsList;
55static SimpleRayContainer::const_iterator sViewPointsListIt;
56static int sCurrentSamples = 0;
57static int sNextSamplesThreshold[] = {10000000, 50000000, 100000000, 250000000};
58//static int sNextSamplesThreshold[] = {100000000, 200000000};
59static int sNumReplays = 4;
60static int sCurrentSamplesThreshold = 0;
61
62
63void processHits (GLint hits, GLuint buffer[])
64{
65   unsigned int i, j;
66   GLuint names, *ptr;
67
68   cout << "hits: " << hits << endl;;
69   ptr = (GLuint *) buffer;
70
71   for (i = 0; i < hits; i++)
72   {
73           /*  for each hit  */
74           names = *ptr;
75
76           printf ("number of names for hit: %d\n", names); ptr ++;
77           printf("z1: %g;", (float) *ptr / 0x7fffffff); ptr ++;
78           printf("z2: %g\n", (float) *ptr / 0x7fffffff); ptr ++;
79           printf ("the name is ");
80
81           // for each name
82           for (j = 0; j < names; j++)
83                   printf ("%d ", *ptr); ptr++;
84
85           printf ("\n");
86   }
87}
88
89
90static inline bool ilt(Intersectable *obj1, Intersectable *obj2)
91{
92        return obj1->mId < obj2->mId;
93}
94
95
96inline static bool nearerThan(ViewCell *vc1, ViewCell *vc2)
97{
98        return vc1->GetDistance() > vc2->GetDistance();
99}
100
101
102#if USE_CG
103static void handleCgError()
104{
105    Debug << "Cg error: " << cgGetErrorString(cgGetError()) << endl;
106    exit(1);
107}
108#endif
109
110
111void QtGlRendererBuffer::MakeLive()
112{
113        QGLPixelBuffer::makeCurrent();
114        //makeCurrent();
115}
116
117
118void QtGlRendererBuffer::DoneLive()
119{
120        QGLPixelBuffer::doneCurrent();
121        //doneCurrent();
122}
123 
124
125QtGlRendererBuffer::QtGlRendererBuffer(int w, int h,
126                                                                           SceneGraph *sceneGraph,
127                                                                           ViewCellsManager *viewcells,
128                                                                           KdTree *tree):
129QGLPixelBuffer(QSize(w, h),
130                           QGLFormat(QGL::SampleBuffers)
131                           /*,|
132                                                 QGL::StencilBuffer |
133                                                 QGL::DepthBuffer |
134                                                 QGL::DoubleBuffer |
135                                                 QGL::Rgba)
136                                                 */),
137GlRendererBuffer(sceneGraph, viewcells, tree)
138{
139        //makeCurrent();
140        MakeLive();
141        glViewport(0, 0, w, h);
142    glMatrixMode(GL_PROJECTION);
143    glLoadIdentity();
144    glOrtho(-1, 1, -1, 1, -99, 99);
145    glMatrixMode(GL_MODELVIEW);
146    glLoadIdentity();
147
148        InitGL();
149
150        //doneCurrent();
151        //DoneLive();
152}
153
154
155void QtGlRendererBuffer::RenderPvs(const ObjectPvs &pvs)
156{
157        EnableDrawArrays();
158       
159        // prepare pvs for rendering
160        PreparePvs(pvs);
161
162        if (mUseVbos)
163                glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId);
164
165        int offset = (int)mObjects.size() * 3;
166        char *arrayPtr = mUseVbos ? NULL : (char *)mData;
167
168        glVertexPointer(3, GL_FLOAT, 0, (char *)arrayPtr);
169        glNormalPointer(GL_FLOAT, 0, (char *)arrayPtr + offset * sizeof(Vector3));
170        glDrawElements(GL_TRIANGLES, mIndexBufferSize, GL_UNSIGNED_INT, mIndices);
171}
172
173
174void QtGlRendererBuffer::RenderTrianglePvs()
175{
176        ObjectContainer::const_iterator oit, oit_end =
177                mViewCellsManager->GetPreprocessor()->mTrianglePvs.end();
178
179        //int sz = mViewCellsManager->GetPreprocessor()->mDummyBuffer.size();
180
181        int i = 0;
182        for (oit = mViewCellsManager->GetPreprocessor()->mTrianglePvs.begin();
183                 oit != oit_end; ++ oit, ++ i)
184        {
185                //int dum = mViewCellsManager->GetPreprocessor()->mDummyBuffer[i];
186                //glColor3f(0, (float)dum / 20.0f, 1);
187                if (mUseFalseColors) SetupFalseColor((*oit)->mId);
188
189                RenderIntersectable(*oit);
190        }
191}
192
193
194
195// reimplemented here so that we can snap the error windows
196float QtGlRendererBuffer::GetPixelError(int &pvsSize, int pass)
197{
198        MakeLive();
199
200        if (0)
201        {
202                cout << "stencil: " << format().stencil() << endl;
203                cout << "depth: " << format().depth() << endl;
204                cout << "rgba: " << format().rgba() << endl;
205                cout << "double: " << format().doubleBuffer() << endl;
206                cout << "depth: " << format().depth() << endl;
207                cout << "gl:" << format().hasOpenGL() << endl;
208                cout << "dir:" << format().directRendering() << endl;
209        }
210
211        ++ mCurrentFrame;
212
213        float pErrorPixels = -1.0f;
214
215        mUseFalseColors = false;
216        unsigned int pixelCount = 0;
217
218       
219        ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
220
221        if (viewcell == NULL)
222                return -1.0f;
223
224        bool evaluateFilter;
225        Environment::GetSingleton()->GetBoolValue("Preprocessor.evaluateFilter", evaluateFilter);
226
227        ObjectPvs pvs;
228
229        if (!evaluateFilter)
230                pvs = viewcell->GetPvs();
231        else
232                mViewCellsManager->ApplyFilter2(viewcell, false, mViewCellsManager->GetFilterWidth(), pvs);
233
234        pvsSize = pvs.GetSize();
235       
236        // hack: assume that view cell empty
237        if (pvsSize == 0)
238                return 0.0f;
239
240        SetupCamera();
241
242        // use shading
243        if (1)//mSnapErrorFrames)
244        {
245                glEnable(GL_NORMALIZE);
246
247                // mat_specular and mat_shininess are NOT default values
248        GLfloat mat_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
249        GLfloat mat_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
250        GLfloat mat_specular[] = {0.3f, 0.3f, 0.3f, 1.0f};
251        GLfloat mat_shininess[] = {1.0f};
252
253        glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
254        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
255        glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
256        glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
257
258                GLfloat light_ambient[] = {0.3, 0.3, 0.3, 1.0};
259                //GLfloat light_diffuse[] = {0.6, 0.6, 0.6, 1.0};
260                GLfloat light_diffuse[] = {0.6, 0.6, 0.6, 1.0};
261                GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
262
263                glEnable(GL_LIGHTING);
264                //GLfloat light_position[] =  {278.0f, 548.8f,279.0f, 1.0f};
265                //GLfloat light_position[] =  {0.f, 0.f, 0.f, 1.0f};
266                GLfloat light_position[] =  {0.f, 0.0f, 0.f, 1.0f};
267
268                glEnable(GL_LIGHT0);
269
270                // a light
271                glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
272                glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
273                glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
274                glLightfv (GL_LIGHT0, GL_POSITION, light_position);
275
276                glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
277                //glEnable(GL_COLOR_MATERIAL);
278
279                GLfloat lmodel_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
280                glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
281
282                glShadeModel(GL_SMOOTH);
283        }
284
285        //glDisable(GL_ALPHA_TEST);
286               
287        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
288        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
289
290        glColor3f(0.6f, 0.6f, 0.6f);
291        //glColor3f(0, 1, 0);
292
293        glDepthFunc(GL_LESS);
294        glDepthMask(GL_TRUE);
295        glEnable(GL_DEPTH_TEST);
296
297        glFrontFace(GL_CCW);
298        glCullFace(GL_BACK);
299
300        glStencilFunc(GL_EQUAL, 0x0, 0x1);
301        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
302
303        KdNode::NewMail2();
304        Intersectable::NewMail();
305
306        // render pvs once
307        RenderPvs(pvs);
308
309        //cout << "rendered nodes: " << mRenderedNodes << endl;
310
311        //glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
312        //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
313        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
314
315        glEnable(GL_STENCIL_TEST);
316        glColor3f(1, 0, 0);
317
318
319        // render scene, record differences
320        OcclusionQuery *query = mOcclusionQueries[0];
321
322        KdNode::NewMail2();
323        Intersectable::NewMail();
324
325        query->BeginQuery();
326
327        // current frame has to be increased at each rendering pass
328        ++ mCurrentFrame;
329
330        RenderScene();
331
332        glFlush();
333
334        query->EndQuery();
335        glDisable(GL_STENCIL_TEST);
336       
337        pixelCount = query->GetQueryResult();
338
339        pErrorPixels = (float)pixelCount / (GetWidth() * GetHeight());
340
341        const int pixelThres = 0;
342
343        // some error happened
344        if (1) // pixelCount > pixelThres)
345        {
346                cout << "f " << mFrame << " id " << viewcell->GetId() << " pvs " << pvsSize
347                         << " e " << pixelCount << " vp " << mViewPoint << " vd " << mViewDirection << endl;
348       
349                format().setSampleBuffers(true);
350                cout << "here3 " << format().sampleBuffers() << endl;
351                if (mSnapErrorFrames)
352                {
353                        glReadBuffer(GL_BACK);
354                        //glReadBuffer(GL_FRONT);
355
356                        //////////////
357                        //-- output error visualization
358
359                        char filename[256];
360                        sprintf(filename, "error-frame-%04d-%05d.bmp", pass, mFrame);
361                        //sprintf(filename, "error-frame-%05d-%0.5f.png", mFrame, pErrorPixels);
362                        //sprintf_s(filename, "error-frame-%05d-%04d-%08d.png", mFrame, viewcell->GetId(), pixelCount);
363
364                        QImage im = toImage();
365                        string str = mSnapPrefix + filename;
366                        QString qstr(str.c_str());
367
368                        //im.save(qstr, "PNG");
369                        // use bmp for lossless storage (for video)
370                        im.save(qstr, "BMP");
371
372                        if (0)
373                        {
374                                ///////////
375                                //-- output computed pvs
376
377                                //mUseFalseColors = false;
378                                mUseFalseColors = true;
379                                glPushAttrib(GL_CURRENT_BIT);
380                                glColor3f(0, 1, 0);
381
382                                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
383                                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
384
385                                KdNode::NewMail2();
386                                Intersectable::NewMail();
387
388                                ++ mCurrentFrame;
389
390                                // render pvs once
391                                //RenderPvs(pvs);
392                                RenderTrianglePvs();
393
394                                glFlush();
395
396                                mUseFalseColors = false;
397
398                                im = toImage();
399                                sprintf_s(filename, "error-frame-%04d-%04d-%08d-pvs.png", mFrame, viewcell->GetId(), pixelCount);
400                                str = mSnapPrefix + filename;
401                                qstr = str.c_str();
402                                im.save(qstr, "PNG");
403
404                                glPopAttrib();
405                        }
406                }
407        }
408
409        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
410
411        //DoneLive();
412
413        return pErrorPixels;
414}
415
416int
417QtGlRendererBuffer::ComputePvs(ObjectContainer &objects,
418                                                           ObjectContainer &pvs) const
419{
420        int pvsSize = 0;
421        QImage image = toImage();
422
423        Intersectable::NewMail();
424
425        std::stable_sort(objects.begin(), objects.end(), ilt);
426
427        MeshInstance dummy(NULL);
428
429        Intersectable *obj = NULL;
430
431        for (int x = 0; x < image.width(); ++ x)
432        {
433                for (int y = 0; y < image.height(); ++ y)
434                {
435                        QRgb pix = image.pixel(x, y);
436                        const int id = GetId(qRed(pix), qGreen(pix), qBlue(pix));
437
438                        dummy.SetId(id);
439
440                        ObjectContainer::iterator oit =
441                                lower_bound(objects.begin(), objects.end(), &dummy, ilt);
442
443                        if (//(oit != oit.end()) &&
444                                ((*oit)->GetId() == id) &&
445                                !obj->Mailed())
446                        {
447                                obj = *oit;
448                                obj->Mail();
449                                ++ pvsSize;
450                                pvs.push_back(obj);
451                        }
452                }
453        }
454
455        return pvsSize;
456}
457
458
459void QtGlRendererWidget::InitGL()
460{
461        GlRenderer::InitGL();
462
463        //glEnable(GL_FOG);
464        //glFogi(GL_FOG_MODE, GL_EXP);
465        //glFogf(GL_FOG_DENSITY, .2f);
466        glFogi(GL_FOG_MODE, GL_LINEAR);
467        glFogf(GL_FOG_START, 50.f);
468        glFogf(GL_FOG_END, 500.f);
469
470       
471        // mat_specular and mat_shininess are NOT default values
472        GLfloat mat_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
473        GLfloat mat_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};
474        GLfloat mat_specular[] = {0.3f, 0.3f, 0.3f, 1.0f};
475        GLfloat mat_shininess[] = {1.0f};
476
477        glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
478        glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
479        glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
480        glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
481
482
483        glEnable(GL_LIGHTING);
484
485        // a light     
486        GLfloat light_ambient[] = {0.3, 0.3, 0.3, 1.0};
487    GLfloat light_diffuse[] = {0.6, 0.6, 0.6, 1.0};
488    GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
489    GLfloat light_position[] =  {0.f, .0f, 0.f, 1.0f};
490    //GLfloat light_position[] =  {600.0f, 250.0f, -500.f, 1.0f};
491    //GLfloat light_position[] = {278.0f, 548.8f,279.0f, 1.0f};
492
493        glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
494        glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
495        glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
496
497        glLightfv(GL_LIGHT0, GL_POSITION, light_position);
498
499        //glDisable(GL_LIGHT0);
500        glEnable(GL_LIGHT0);
501
502        glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
503        glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
504        glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
505               
506        // set position of the light2
507        GLfloat infinite_light2[] = {  -0.3, 1.5, 1.0, 0.0  };
508        glLightfv (GL_LIGHT1, GL_POSITION, infinite_light2);
509        //glEnable(GL_LIGHT1);
510
511        GLfloat lmodel_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
512        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
513
514        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
515        //glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
516        glEnable(GL_COLOR_MATERIAL);
517
518        glShadeModel(GL_SMOOTH);
519}
520
521
522void
523QtGlRendererWidget::SetupCameraProjection(const int w, const int h, const float angle)
524{
525        if (!mTopView) {
526                int ww = w;
527                int hh = h;
528                glViewport(0, 0, ww, hh);
529                glMatrixMode(GL_PROJECTION);
530                glLoadIdentity();
531                gluPerspective(angle, ww/(float)hh, 0.1, 2.0 * Magnitude(mSceneGraph->GetBox().Diagonal()));
532                glMatrixMode(GL_MODELVIEW);
533        } else {
534                int ww = w;
535                int hh = h;
536                glViewport(0, 0, ww, hh);
537                glMatrixMode(GL_PROJECTION);
538                glLoadIdentity();
539                gluPerspective(50.0, ww / (float)hh, 0.1, 20.0 * Magnitude(mSceneGraph->GetBox().Diagonal()));
540                glMatrixMode(GL_MODELVIEW);
541        }
542}
543
544
545bool QtGlRendererWidget::PvsChanged(ViewCell *viewCell) const
546{
547        if (viewCell != mPvsCache.mViewCell)
548                return true;
549
550        if (viewCell->GetPvs().GetSize() != mPvsCache.mUnfilteredPvsSize)
551                return true;
552
553        return false;
554}
555
556
557void QtGlRendererWidget::_RenderPvs()
558{
559        EnableDrawArrays();
560
561        if (mUseVbos)
562                glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId);
563
564        mUseFalseColors = false;
565
566        int offset = (int)mObjects.size() * 3;
567        char *arrayPtr = mUseVbos ? NULL : (char *)mData;
568
569        glVertexPointer(3, GL_FLOAT, 0, (char *)arrayPtr);
570        glNormalPointer(GL_FLOAT, 0, (char *)arrayPtr + offset * sizeof(Vector3));
571        glDrawElements(GL_TRIANGLES, mIndexBufferSize, GL_UNSIGNED_INT, mIndices);
572
573        // handle dynamic objects in pvss
574        DynamicObjectsContainer::const_iterator dit, dit_end = mDynamicPvsObjects.end();
575
576        //cout << "dynamic objects in pvs " << mDynamicPvsObjects.size() << endl;;
577
578        for (dit = mDynamicPvsObjects.begin(); dit != dit_end; ++ dit)
579        {
580                _RenderDynamicObject(*dit);
581        }
582
583        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
584
585        // show placed dynamic objects as wireframe
586        Preprocessor *p = mViewCellsManager->GetPreprocessor();
587        dit_end = p->mDynamicObjects.end();
588
589        int i = 0;
590        for (dit = p->mDynamicObjects.begin(); dit != dit_end; ++ dit, ++ i)
591        {
592                if (i == mCurrentDynamicObjectIdx)
593                        glColor3f(1, 0, 1);
594                else
595                        glColor3f(0, 1, 0);
596
597                _RenderDynamicObject(*dit);
598        }
599       
600        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
601}
602
603
604void QtGlRendererWidget::PreparePvs(const ObjectPvs &pvs)
605{
606        int indexBufferSize = 0;
607       
608        // hack: mail not working with multiple threads
609        KdNode::NewMail2();
610
611        mPvsSize = pvs.GetSize();
612
613        mDynamicPvsObjects.clear();
614
615        ObjectPvsIterator it = pvs.GetIterator();
616
617        while (it.HasMoreEntries())
618        {
619                Intersectable *obj = it.Next();
620
621                switch (obj->Type())
622                {
623                case Intersectable::KD_INTERSECTABLE:
624                        {
625                                KdNode *node = static_cast<KdIntersectable *>(obj)->GetItem();
626                                _UpdatePvsIndices(node, indexBufferSize);
627                        }
628                        break;
629
630                case Intersectable::SCENEGRAPHLEAF_INTERSECTABLE:
631                        mDynamicPvsObjects.push_back(static_cast<SceneGraphLeafIntersectable *>(obj)->GetItem());
632                        break;
633                default:
634                        cerr << "PreparePvs: type " << Intersectable::GetTypeName(obj) << " not handled yet" << endl;
635                }
636        }
637
638        mIndexBufferSize = indexBufferSize;
639}
640
641
642void QtGlRendererWidget::VisualizePvs()
643{
644        if (mUseVbos)
645                glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId);
646
647        ++ mCurrentFrame;
648
649        EnableDrawArrays();
650               
651        if (mDetectEmptyViewSpace)
652                glEnable(GL_CULL_FACE);
653        else
654                glDisable(GL_CULL_FACE);
655
656        ViewCell *viewcell = NULL;
657        viewcell = mViewCellsManager->GetViewCell(mViewPoint, true);
658
659        if (viewcell)
660        {
661                // copy the pvs so that it can be filtered ...
662                if (PvsChanged(viewcell))
663                {
664                        mPvsCache.Reset();
665                        mPvsCache.mViewCell = viewcell;
666                        mPvsCache.mUnfilteredPvsSize = viewcell->GetPvs().GetSize();
667
668                        if (mUseSpatialFilter)
669                        {
670                                //mMutex.lock();
671                                // mSpatialFilter size is in range 0.001 - 0.1
672                                mViewCellsManager->ApplyFilter2(viewcell,
673                                        mUseFilter,
674                                        100.0f * mSpatialFilterSize,
675                                        mPvsCache.mPvs,         
676                                        &mPvsCache.filteredBoxes);
677                                //mPvsCache.mPvs = pvs;
678                                //mMutex.unlock();
679                                //cout << "pvs size: " << mPvsCache.mPvs.GetSize() << endl;
680                        }
681                        else
682                        {
683                                mPvsCache.mPvs = viewcell->GetPvs();
684                        }
685                       
686                        // update the indices for rendering
687                        PreparePvs(mPvsCache.mPvs);
688                        emit PvsUpdated();
689
690                        mCurrentPvsCost = mPvsCache.mPvs.EvalPvsCost();
691                }
692
693                // Render PVS
694                if (mUseSpatialFilter && mRenderBoxes)
695                {
696                        for (size_t i=0; i < mPvsCache.filteredBoxes.size(); ++ i)
697                        {
698                                RenderBox(mPvsCache.filteredBoxes[i]);
699                        }
700                }
701                else
702                {
703                        if (!mRenderVisibilityEstimates && !mUseRandomColorPerPvsObject)
704                                _RenderPvs();
705                        else
706                                _RenderColoredPvs();
707                }
708
709                if (mRenderFilter)
710                {
711                        mWireFrame = true;
712                        RenderIntersectable(viewcell);
713                       
714                        mWireFrame = false;
715                }
716        }
717        else
718        {
719                RenderScene();
720        }
721
722        //cout << "vp: " << mViewPoint << " vd: " << mViewDirection << endl;
723}
724
725float
726QtGlRendererWidget::RenderErrors()
727{
728        float pErrorPixels = -1.0f;
729
730        SetupCamera();
731        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
732
733        glPushAttrib(GL_ENABLE_BIT);
734
735        glStencilFunc(GL_EQUAL, 0x0, 0x1);
736        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
737
738        glColor3f(0.6f, 0.6f, 0.6f);
739
740        // Render PVS
741        VisualizePvs();
742
743        glEnable(GL_STENCIL_TEST);
744        glDisable(GL_LIGHTING);
745
746        SetupCamera();
747
748        mUseForcedColors = true;
749
750        glColor3f(1.0f, 0.0f, 0.0f);
751
752        OcclusionQuery *query = mOcclusionQueries[0];
753        query->BeginQuery();
754
755        RenderScene();
756
757        mUseForcedColors = false;
758
759        query->EndQuery();
760
761        glDisable(GL_STENCIL_TEST);
762        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
763
764        glPopAttrib();
765
766        // reenable other state
767        //  int wait=0;
768        //  while (!query.ResultAvailable()) {
769        //      wait++;
770        //  }
771
772        int pixelCount = query->GetQueryResult();
773        pErrorPixels = ((float)pixelCount) / (GetWidth() * GetHeight());
774       
775        if (0) cout << "error pixels=" << pixelCount << endl;
776
777        mRenderError = pErrorPixels;
778
779        return pErrorPixels;
780}
781
782
783void QtGlRendererWidget::timerEvent(QTimerEvent *timerEvent)
784{
785        if (mReplayMode && (timerEvent->timerId() == mReplayTimerId))
786        {
787                if (sViewPointsListIt == sViewPointsList.end())
788                {
789                        cout << "stopping replay" << endl;
790                        mReplayMode = false;
791                        GetPreprocessor()->mSynchronize = false;
792                }
793                else
794                {
795                        SimpleRay sray = *sViewPointsListIt;
796
797                        mViewPoint = sray.mOrigin;
798                        mViewDirection = sray.mDirection;
799
800                        ++ sViewPointsListIt;
801                }
802
803                updateGL();
804
805                // output the current frame buffer
806                if (mExportFrameBuffer)
807                {
808                        const int dist = sViewPointsListIt - sViewPointsList.begin();
809
810                        char filename[200];
811                        sprintf(filename, "error-frame-%04d-%05d.bmp", sCurrentSamples, dist);
812                        //QPixmap img = renderPixmap(0, 0, true);
813                        QImage im = grabFrameBuffer();
814
815                        string str = mSnapPrefix + filename;
816                        QString qstr(str.c_str());
817
818                        //im.save(qstr, "PNG");
819                        // use bmp for lossless storage (for video)
820                        im.save(qstr, "BMP");
821                }
822        }
823        else if (timerEvent->timerId() == mUpdateTimerId)
824                // update pvss from time to time
825                update();
826
827        // grab frame buffer after a certain number of samples
828        if (!mReplayMode &&
829                (sCurrentSamplesThreshold < sNumReplays) &&
830                ((GetPreprocessor()->mCurrentSamples > sNextSamplesThreshold[sCurrentSamplesThreshold])))
831        {
832                ++ sCurrentSamplesThreshold;
833                cout << "replaying at total samples: " << GetPreprocessor()->mCurrentSamples << endl;
834                ReplayViewPoints();
835        }
836
837}
838
839
840void QtGlRendererWidget::mousePressEvent(QMouseEvent *e)
841{
842        int x = e->pos().x();
843        int y = e->pos().y();
844
845        mousePoint.x = x;
846        mousePoint.y = y;
847
848        if (e->button() == Qt::RightButton)
849        {
850                if (mPlacer->GetCurrentObject())
851                {
852                        Vector3 pt = Unproject(x, y);
853
854                        mPlacer->PlaceObject(pt);
855                        SceneGraphLeaf *leaf = mPlacer->GetCurrentObject();
856
857                        // hack: should just pass a IntersectableGroup as a whole
858                        // instead we duplicate the object container and create a new
859                        // leaf
860                        SceneGraphLeaf *newObj = new SceneGraphLeaf(*leaf);
861
862                        // make current object
863                        // the object is added at the end of the vector
864                        mCurrentDynamicObjectIdx = (int)GetPreprocessor()->mDynamicObjects.size();
865
866                        GetPreprocessor()->RegisterDynamicObject(newObj);
867                }
868        }
869}
870
871
872void QtGlRendererWidget::mouseReleaseEvent(QMouseEvent *e)
873{
874        int x = e->pos().x();
875        int y = e->pos().y();
876
877        mousePoint.x = x;
878        mousePoint.y = y;
879
880        if (e->modifiers() & Qt::ShiftModifier)
881        {
882                const Vector3 pt = Unproject(x, y);
883
884                int idx = FindDynamicObject(x, y);
885               
886                if (idx >= 0)
887                {
888                        mCurrentDynamicObjectIdx = idx;
889                }
890        }
891}
892
893void
894QtGlRendererWidget::mouseMoveEvent(QMouseEvent *e)
895{
896        if (mReplayMode)
897                return;
898
899        float MOVE_SENSITIVITY = Magnitude(mSceneGraph->GetBox().Diagonal())*1e-3;
900        float TURN_SENSITIVITY = 0.1f;
901        float TILT_SENSITIVITY = 32.0 ;
902        float TURN_ANGLE= M_PI / 36.0 ;
903
904        int x = e->pos().x();
905        int y = e->pos().y();
906
907        int diffx = -(mousePoint.x - x);
908        int diffy = -(mousePoint.y - y);
909
910        const float t = 1.0f;
911        if (e->modifiers() & Qt::ControlModifier)
912        {
913                mViewPoint.y += (y-mousePoint.y)*MOVE_SENSITIVITY / 2.0;
914                mViewPoint.x += (x-mousePoint.x)*MOVE_SENSITIVITY / 2.0;
915        }
916        else if (e->modifiers() & Qt::AltModifier)
917        {
918                if (mCurrentDynamicObjectIdx >= 0)
919                {
920                        Matrix4x4 tm;
921
922                        SceneGraphLeaf *l =
923                          mViewCellsManager->GetPreprocessor()->mDynamicObjects[mCurrentDynamicObjectIdx];
924
925                        switch (mTrafoType)
926                        {
927                        case 0:
928                                {
929                                  if (e->modifiers() & Qt::ShiftModifier) {
930                                        const Vector3 transl(0, diffy, 0);
931                                        tm = TranslationMatrix(transl);
932                                 
933                                  } else {
934                                        const Vector3 transl(diffx, 0, diffy);
935                                        tm = TranslationMatrix(transl);
936                                  }
937                                }
938                                break;
939                        case 1:
940                                {
941                                        float scalef = 1.0f + 0.01f * (diffx + diffy);
942                                        if (scalef < 0.9) scalef = 0.9f;
943                                        else if (scalef > 1.1f) scalef = 1.1f;
944                                        tm = ScaleMatrix(scalef, scalef, scalef);
945                                }
946                                break;
947                        case 2:
948                                {
949                                        // tm = RotationXMatrix(diffx) * RotationYMatrix(diffy);
950                                        tm = RotationYMatrix(diffx);
951                                }
952                                break;
953                        default:
954                                cerr << "not implemented" << endl;
955                        }
956                       
957                        l->ApplyTransform(tm);
958
959                        updateGL();
960                }
961        }
962        else
963        {
964                mViewPoint += mViewDirection*((mousePoint.y - y)*MOVE_SENSITIVITY);
965                float adiff = TURN_ANGLE*(x - mousePoint.x)*-TURN_SENSITIVITY;
966                float angle = atan2(mViewDirection.x, mViewDirection.z);
967                mViewDirection.x = sin(angle + adiff);
968                mViewDirection.z = cos(angle + adiff);
969        }
970
971        mousePoint.x = x;
972        mousePoint.y = y;
973
974        updateGL();
975}
976
977
978void
979QtGlRendererWidget::resizeGL(int w, int h)
980{
981        SetupCameraProjection(w, h);
982        updateGL();
983}
984
985
986void QtGlRendererWidget::paintGL()
987{
988        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
989
990        SetupCameraProjection(width(), height());
991        SetupCamera();
992
993        if (mRenderErrors)
994                RenderErrors();
995        else
996        {
997                glColor3f(0.6f, 0.6f, 0.6f);
998                VisualizePvs();
999        }
1000
1001        if (mShowRays)
1002                RenderRays(mViewCellsManager->mVizBuffer.GetRays(), mRayVisualizationMethod, mShowDistribution, 1);
1003       
1004        RenderInfo();
1005
1006        ++ mFrame;
1007        //      cout<<"vp="<<mViewPoint<<" vd="<<mViewDirection<<endl;
1008}
1009
1010
1011void
1012QtGlRendererWidget::SetupCamera()
1013{
1014        if (!mTopView)
1015                GlRenderer::SetupCamera();
1016        else
1017        {
1018                if (0)
1019                {
1020                        float dist = Magnitude(mSceneGraph->GetBox().Diagonal())*0.05;
1021                        Vector3 pos = mViewPoint - dist*Vector3(mViewDirection.x,
1022                                -1,
1023                                mViewDirection.y);
1024
1025                        Vector3 target = mViewPoint + dist*mViewDirection;
1026                        Vector3 up(0,1,0);
1027
1028                        glLoadIdentity();
1029                        gluLookAt(pos.x, pos.y, pos.z,
1030                                target.x, target.y, target.z,
1031                                up.x, up.y, up.z);
1032                }
1033                else
1034                {
1035                        float dist = Magnitude(mSceneGraph->GetBox().Diagonal()) * mTopDistance;
1036                        Vector3 pos = mViewPoint  + dist * Vector3(0,   1, 0);
1037
1038                        Vector3 target = mViewPoint;
1039                        Vector3 up(mViewDirection.x, 0, mViewDirection.z);
1040
1041                        glLoadIdentity();
1042                        gluLookAt(pos.x, pos.y, pos.z,
1043                                target.x, target.y, target.z,
1044                                up.x, up.y, up.z);
1045
1046                }
1047        }
1048
1049}
1050
1051
1052void
1053QtGlRendererWidget::keyPressEvent ( QKeyEvent * e )
1054{
1055        switch (e->key())
1056        {
1057        case Qt::Key_E:
1058                mRenderErrors = !mRenderErrors;
1059                updateGL();
1060                break;
1061        case Qt::Key_R:
1062                mUseRandomColorPerPvsObject = !mUseRandomColorPerPvsObject;;
1063                updateGL();
1064                break;
1065        case Qt::Key_T:
1066                mTopView = !mTopView;
1067                SetupCameraProjection(width(), height());
1068                updateGL();
1069                break;
1070        case Qt::Key_V:
1071                mRenderViewCells = !mRenderViewCells;
1072                updateGL();
1073                break;
1074        case Qt::Key_P:
1075                // set random viewpoint
1076                mViewCellsManager->GetViewPoint(mViewPoint);
1077                updateGL();
1078                break;
1079        case Qt::Key_S: {
1080                // set view poitn and direction
1081                QString text;
1082                bool ok;
1083                text.sprintf("%f %f %f", mViewPoint.x, mViewPoint.y, mViewPoint.z);
1084                text = QInputDialog::getText(this,
1085                        "Enter a view point",
1086                        "",
1087                        QLineEdit::Normal,
1088                        text,
1089                        &ok);
1090                if (!ok)
1091                        break;
1092
1093                if (sscanf_s(text.toAscii(), "%f %f %f", &mViewPoint.x, &mViewPoint.y, &mViewPoint.z) == 3) {
1094                        text.sprintf("%f %f %f", mViewDirection.x, mViewDirection.y, mViewDirection.z);
1095                        text = QInputDialog::getText(this,
1096                                "Enter a direction",
1097                                "",
1098                                QLineEdit::Normal,
1099                                text,
1100                                &ok);
1101                        if (!ok)
1102                                break;
1103                        if (sscanf_s(text.toAscii(), "%f %f %f", &mViewDirection.x,
1104                                &mViewDirection.y, &mViewDirection.z) == 3) {
1105                                        updateGL();
1106                        }
1107                        break;
1108                }
1109                                        }
1110        default:
1111                cerr << "unknown key" << endl;
1112                e->ignore();
1113                break;
1114        }
1115}
1116
1117
1118
1119QtGlRendererWidget::QtGlRendererWidget(
1120                                                                           SceneGraph *sceneGraph,
1121                                                                           ViewCellsManager *viewcells,
1122                                                                           KdTree *tree,
1123                                                                           QWidget * parent,
1124                                                                           const QGLWidget * shareWidget,
1125                                                                           Qt::WFlags f):
1126GlRendererWidget(sceneGraph, viewcells, tree),
1127QGLWidget(QGLFormat(QGL::SampleBuffers), parent, shareWidget, f)
1128{
1129        mPreprocessorThread = NULL;
1130        mTopView = false;
1131        mRenderViewCells = false;
1132        mTopDistance = 1.0f;
1133        mCutViewCells = false;
1134        mCutScene = false;
1135        mRenderErrors = false;
1136        mRenderBoxes = false;
1137        mRenderFilter = true;
1138        mRenderVisibilityEstimates = false;
1139        //mRenderVisibilityEstimates = true;
1140
1141        mComputeGVS = false;
1142        mUseRandomColorPerPvsObject = false;
1143        //mUseRandomColorPerPvsObject = true;
1144
1145        mHideByCost = false;
1146        mUseTransparency = false;
1147
1148        mTransferFunction = 1.0f;
1149        mIndexBufferSize = 0;
1150
1151        const int delay = 250; // in milliseconds
1152        mUpdateTimerId = startTimer(delay);
1153        mReplayTimerId = startTimer(1); // use fastest replay rate
1154
1155        bool tmp;
1156
1157        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp );
1158        mUseFilter = tmp;
1159
1160        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", tmp );
1161        mUseSpatialFilter = tmp;
1162
1163        mShowRenderCost = false;
1164        mShowPvsSizes = false;
1165        mShowComparison = false;
1166        mShowPiercingRays = false;
1167        mShowWeightedRays = false;
1168        mUseStandardColors = false;
1169        mShowWeightedCost = true;
1170
1171        mShowDistanceWeightedPvs = true;
1172        mShowDistanceWeightedTriangles = false;
1173        mShowWeightedTriangles = false;
1174        mShowDistribution = 15;
1175
1176        mSpatialFilterSize = 0.01;
1177        mPvsSize = 0;
1178        mRayVisualizationMethod = 0;
1179        mTrafoType = 0;
1180
1181        mRenderError = 0.0f;
1182
1183        mShowRays = false;
1184        mReplayMode = false;
1185
1186        mPlacer = new ObjectPlacer();
1187
1188        mCurrentDynamicObjectIdx = -1;
1189
1190        // export frame buffer during walkthrough
1191        mExportFrameBuffer = true;
1192        //mExportFrameBuffer = false;
1193
1194        SetSceneCut(1000);
1195        mControlWidget = new QtRendererControlWidget(NULL);
1196
1197        connect(mControlWidget, SIGNAL(SetViewCellGranularity(int)), this, SLOT(SetViewCellGranularity(int)));
1198        connect(mControlWidget, SIGNAL(SetTransferFunction(int)), this, SLOT(SetTransferFunction(int)));
1199
1200        connect(mControlWidget, SIGNAL(UpdateAllPvs()), this, SLOT(UpdateAllPvs()));
1201        connect(mControlWidget, SIGNAL(ComputeVisibility()), this, SLOT(ComputeVisibility()));
1202        connect(mControlWidget, SIGNAL(StopComputation()), this, SLOT(StopComputation()));
1203        connect(mControlWidget, SIGNAL(SetRandomViewPoint()), this,     SLOT(SetRandomViewPoint()));
1204        connect(mControlWidget, SIGNAL(StoreStatistics(void)), this, SLOT(StoreStatistics(void)));
1205        connect(mControlWidget, SIGNAL(ComputeGVS(void)), this, SLOT(ComputeGVS(void)));
1206        connect(mControlWidget, SIGNAL(ReplayViewPoints(void)), this, SLOT(ReplayViewPoints(void)));
1207        connect(mControlWidget, SIGNAL(NextObject(void)), this, SLOT(NextObject(void)));
1208
1209        connect(mControlWidget, SIGNAL(SetSceneCut(int)), this, SLOT(SetSceneCut(int)));
1210        connect(mControlWidget, SIGNAL(SetTopDistance(int)), this, SLOT(SetTopDistance(int)));
1211        connect(mControlWidget, SIGNAL(SetTransparency(int)), this, SLOT(SetTransparency(int)));
1212
1213        connect(mControlWidget, SIGNAL(SetVisibilityFilterSize(int)), this, SLOT(SetVisibilityFilterSize(int)));
1214        connect(mControlWidget, SIGNAL(SetSpatialFilterSize(int)), this, SLOT(SetSpatialFilterSize(int)));
1215        connect(mControlWidget, SIGNAL(SetHidingCost(int)), this, SLOT(SetHidingCost(int)));
1216
1217        connect(mControlWidget, SIGNAL(SetShowViewCells(bool)), this, SLOT(SetShowViewCells(bool)));
1218        connect(mControlWidget, SIGNAL(SetShowRenderCost(bool)), this, SLOT(SetShowRenderCost(bool)));
1219        connect(mControlWidget, SIGNAL(SetUseTransparency(bool)), this, SLOT(SetUseTransparency(bool)));
1220        connect(mControlWidget, SIGNAL(SetShowPvsSizes(bool)), this, SLOT(SetShowPvsSizes(bool)));
1221        connect(mControlWidget, SIGNAL(SetShowComparison(bool)), this, SLOT(SetShowComparison(bool)));
1222        connect(mControlWidget, SIGNAL(SetTopView(bool)), this, SLOT(SetTopView(bool)));
1223        connect(mControlWidget, SIGNAL(SetCutViewCells(bool)), this, SLOT(SetCutViewCells(bool)));
1224        connect(mControlWidget, SIGNAL(SetHideByCost(bool)), this, SLOT(SetHideByCost(bool)));
1225        connect(mControlWidget, SIGNAL(SetCutScene(bool)), this, SLOT(SetCutScene(bool)));
1226        connect(mControlWidget, SIGNAL(SetRenderErrors(bool)), this, SLOT(SetRenderErrors(bool)));
1227        connect(mControlWidget, SIGNAL(SetRenderBoxes(bool)), this, SLOT(SetRenderBoxes(bool)));
1228        connect(mControlWidget, SIGNAL(SetRenderFilter(bool)), this, SLOT(SetRenderFilter(bool)));
1229        connect(mControlWidget, SIGNAL(SetRenderVisibilityEstimates(bool)), this, SLOT(SetRenderVisibilityEstimates(bool)));
1230        connect(mControlWidget, SIGNAL(SetUseFilter(bool)), this, SLOT(SetUseFilter(bool)));
1231        connect(mControlWidget, SIGNAL(SetUseSpatialFilter(bool)), this, SLOT(SetUseSpatialFilter(bool)));
1232        connect(mControlWidget, SIGNAL(SetShowPiercingRays(bool)), this, SLOT(SetShowPiercingRays(bool)));
1233        connect(mControlWidget, SIGNAL(SetShowWireFrame(bool)), this, SLOT(SetShowWireFrame(bool)));
1234        connect(mControlWidget, SIGNAL(SetShowWeightedRays(bool)), this, SLOT(SetShowWeightedRays(bool)));
1235        connect(mControlWidget, SIGNAL(SetShowWeightedCost(bool)), this, SLOT(SetShowWeightedCost(bool)));
1236
1237        connect(mControlWidget, SIGNAL(SetShowDistanceWeightedTriangles(bool)), this, SLOT(SetShowDistanceWeightedTriangles(bool)));
1238        connect(mControlWidget, SIGNAL(SetShowDistanceWeightedPvs(bool)), this, SLOT(SetShowDistanceWeightedPvs(bool)));
1239        connect(mControlWidget, SIGNAL(SetShowWeightedTriangles(bool)), this, SLOT(SetShowWeightedTriangles(bool)));
1240
1241        connect(mControlWidget, SIGNAL(UseConstColorForRayViz(bool)), this, SLOT(UseConstColorForRayViz(bool)));
1242        connect(mControlWidget, SIGNAL(UseRayLengthForRayViz(bool)), this, SLOT(UseRayLengthForRayViz(bool)));
1243        connect(mControlWidget, SIGNAL(SetShowContribution(bool)), this, SLOT(SetShowContribution(bool)));
1244        connect(mControlWidget, SIGNAL(SetShowDistribution(bool)), this, SLOT(SetShowDistribution(bool)));
1245
1246        connect(mControlWidget, SIGNAL(SetShowDistribution1(bool)), this, SLOT(SetShowDistribution1(bool)));
1247        connect(mControlWidget, SIGNAL(SetShowDistribution2(bool)), this, SLOT(SetShowDistribution2(bool)));
1248        connect(mControlWidget, SIGNAL(SetShowDistribution3(bool)), this, SLOT(SetShowDistribution3(bool)));
1249        connect(mControlWidget, SIGNAL(SetShowDistribution4(bool)), this, SLOT(SetShowDistribution4(bool)));
1250
1251        connect(mControlWidget, SIGNAL(SetShowRays(bool)), this, SLOT(SetShowRays(bool)));
1252
1253#if 1
1254        connect(mControlWidget, SIGNAL(SetTranslation(bool)), this, SLOT(SetTranslation(bool)));
1255        connect(mControlWidget, SIGNAL(SetRotation(bool)), this, SLOT(SetRotation(bool)));
1256        connect(mControlWidget, SIGNAL(SetScale(bool)), this, SLOT(SetScale(bool)));
1257#endif
1258        connect(mControlWidget, SIGNAL(UpdateDynamicObjects()), this, SLOT(UpdateDynamicObjects()));
1259        connect(mControlWidget, SIGNAL(DeleteDynamicObject()), this, SLOT(DeleteDynamicObject()));
1260
1261        setWindowTitle("PVS Visualization");
1262
1263        // setting the main window size here
1264        //resize(800, 600);
1265        resize(640, 480);
1266       
1267        mControlWidget->show();
1268
1269        LoadObjects();
1270}
1271
1272void
1273QtGlRendererWidget::UpdateAllPvs()
1274{
1275        // $$ does not work so far:(
1276        mViewCellsManager->UpdatePvsForEvaluation();
1277        //      mViewCellsManager->FinalizeViewCells(false);
1278}
1279
1280void
1281QtGlRendererWidget::ComputeVisibility()
1282{
1283        cerr<<"Compute Visibility called!\n"<<endl;
1284        if (!mPreprocessorThread->isRunning())
1285                mPreprocessorThread->RunThread();
1286}
1287
1288void
1289QtGlRendererWidget::StopComputation()
1290{
1291        cerr<<"stop computation called!\n"<<endl;
1292        mViewCellsManager->GetPreprocessor()->mStopComputation = true;
1293}
1294
1295void
1296QtGlRendererWidget::SetRandomViewPoint()
1297{
1298        cerr<<"setting random view point!\n"<<endl;
1299        mViewCellsManager->GetViewPoint(mViewPoint);
1300        updateGL();
1301}
1302
1303
1304void QtGlRendererWidget::StoreStatistics()
1305{
1306        cerr<<"storing statistics!\n"<<endl;
1307        const int currentSamples = mViewCellsManager->GetPreprocessor()->mCurrentSamples;
1308
1309        cout<<"**********************************************" << endl;
1310        cout << "reached " << currentSamples << " samples " << " => writing file" << endl;
1311               
1312        LogWriter writer;
1313        writer.SetFilename("compare.log");
1314        writer.Write(currentSamples, mViewCellsManager->GetViewCells());
1315        cout << "finished writing file" << endl;
1316        mCompareInfo.clear();
1317        updateGL();
1318}
1319
1320
1321void QtGlRendererWidget::LoadObjects()
1322{
1323        LoadObject("../data/teapot.bn");
1324        LoadObject("../data/bunny.bn");
1325        LoadObject("../data/horse.bn");
1326}
1327
1328
1329void QtGlRendererWidget::NextObject()
1330{
1331        mPlacer->NextObject();
1332}
1333
1334
1335void QtGlRendererWidget::LoadObject(const string &filename)
1336{
1337        cout << "Loading model " << filename << endl;
1338
1339        SceneGraphLeaf *leaf =
1340                mViewCellsManager->GetPreprocessor()->LoadDynamicGeometry(filename);
1341
1342        if (leaf)
1343        {
1344                mPlacer->AddObject(leaf);
1345                cout << "Loading finished" << endl;
1346        }
1347        else
1348                cerr << "Loading failed" << endl;
1349       
1350    //updateGL();
1351}
1352
1353
1354QtGlRendererWidget::~QtGlRendererWidget()
1355{
1356        delete mPlacer;
1357}
1358
1359
1360void
1361QtGlRendererWidget::RenderRenderCost()
1362{
1363        static vector<float> costFunction;
1364        static float maxCost = -1;
1365        if (costFunction.size()==0) {
1366                ViewCellsTree *tree = mViewCellsManager->GetViewCellsTree();
1367                if (tree) {
1368                        tree->GetCostFunction(costFunction);
1369                        maxCost = -1;
1370                        for (int i=0;  i < costFunction.size(); i++) {
1371                                //                cout<<i<<":"<<costFunction[i]<<" ";
1372                                // update cost function to an absolute value based on the total geometry count
1373                                costFunction[i] *= mSceneGraph->GetSize();
1374                                if (costFunction[i] > maxCost)
1375                                        maxCost = costFunction[i];
1376                        }
1377                }
1378        }
1379
1380
1381        int currentPos = (int)mViewCellsManager->GetViewCells().size();
1382        float currentCost= -1;
1383
1384        if (currentPos < costFunction.size())
1385                currentCost = costFunction[currentPos];
1386#if 1   
1387        cout<<"costFunction.size()="<<(int)costFunction.size()<<endl;
1388        cout<<"CP="<<currentPos<<endl;
1389        cout<<"MC="<<maxCost<<endl;
1390        cout<<"CC="<<currentCost<<endl;
1391#endif
1392        if (costFunction.size()) {
1393                float scaley = 1.0f/log10(maxCost);
1394                float scalex = 1.0f/(float)costFunction.size();
1395
1396                glDisable(GL_DEPTH_TEST);
1397                // init ortographic projection
1398                glMatrixMode(GL_PROJECTION);
1399
1400                glPushMatrix();
1401
1402                glLoadIdentity();
1403                gluOrtho2D(0, 1.0f, 0, 1.0f);
1404
1405                glTranslatef(0.1f, 0.1f, 0.0f);
1406                glScalef(0.8f, 0.8f, 1.0f);
1407                glMatrixMode(GL_MODELVIEW);
1408                glLoadIdentity();
1409
1410                glColor3f(1.0f,0,0);
1411                glBegin(GL_LINE_STRIP);
1412                //        glVertex3f(0,0,0);
1413
1414                for (int i=0;  i < costFunction.size(); i++) {
1415                        float x =  i*scalex;
1416                        float y = log10(costFunction[i])*scaley;
1417                        glVertex3f(x,y,0.0f);
1418                }
1419                glEnd();
1420
1421                glColor3f(1.0f,0,0);
1422                glBegin(GL_LINES);
1423                float x =  currentPos*scalex;
1424                glVertex3f(x,0.0,0.0f);
1425                glVertex3f(x,1.0f,0.0f);
1426                glEnd();
1427
1428                glColor3f(0.0f,0,0);
1429                // show a grid
1430                glBegin(GL_LINE_LOOP);
1431                glVertex3f(0,0,0.0f);
1432                glVertex3f(1,0,0.0f);
1433                glVertex3f(1,1,0.0f);
1434                glVertex3f(0,1,0.0f);
1435                glEnd();
1436
1437                glBegin(GL_LINES);
1438                for (int i=0;  i < costFunction.size(); i += 1000) {
1439                        float x =  i*scalex;
1440                        glVertex3f(x,0.0,0.0f);
1441                        glVertex3f(x,1.0f,0.0f);
1442                }
1443
1444                for (int i=0;  pow(10.0f, i) < maxCost; i+=1) {
1445                        float y = i*scaley;
1446                        //              QString s;
1447                        //              s.sprintf("%d", (int)pow(10,i));
1448                        //              renderText(width()/2+5, y*height(), s);
1449                        glVertex3f(0.0f, y, 0.0f);
1450                        glVertex3f(1.0f, y, 0.0f);
1451                }
1452
1453                glEnd();
1454
1455
1456                // restore the projection matrix
1457                glMatrixMode(GL_PROJECTION);
1458                glPopMatrix();
1459                glMatrixMode(GL_MODELVIEW);
1460                glEnable(GL_DEPTH_TEST);
1461
1462        }
1463
1464
1465
1466}
1467
1468void
1469QtGlRendererWidget::RenderInfo()
1470{
1471
1472        QString s;
1473
1474        int vc = 0;
1475        if (mViewCellsManager)
1476                vc = (int)mViewCellsManager->GetViewCells().size();
1477
1478        int filter = 0;
1479        if (mViewCellsManager)
1480                filter = mViewCellsManager->GetMaxFilterSize();
1481
1482#if 0 //REMOVE_TEMPORARY
1483        s.sprintf("frame:%04d viewpoint:(%4.1f,%4.1f,%4.1f) dir:(%4.1f,%4.1f,%4.1f)",
1484                mFrame,
1485                mViewPoint.x,
1486                mViewPoint.y,
1487                mViewPoint.z,
1488                mViewDirection.x,
1489                mViewDirection.y,
1490                mViewDirection.z
1491                );
1492
1493        renderText(20, 20, s);
1494
1495        s.sprintf("viewcells:%04d filter:%04d pvs:%04d error:%5.5f %",
1496                vc,
1497                filter,
1498                mPvsSize,
1499                mRenderError * 100.0f);
1500
1501        renderText(20, 40, s);
1502#endif
1503
1504        glDisable(GL_LIGHTING);
1505        //qglColor(QColor(0, 255, 0));
1506        glColor3f(0, 1, 0);
1507        QFont font40; font40.setPointSize(25);
1508        //s.sprintf("PVS: %04d", mPvsSize);
1509        //renderText(20, 40, s, font40);
1510       
1511        //s.sprintf("RAW TRI: %07d", mViewCellsManager->GetPreprocessor()->mGenericStats);
1512        //renderText(290, 40, s, font40);
1513        //s.sprintf("PVS TRI: %07d", mViewCellsManager->GetPreprocessor()->mGenericStats2);
1514        //renderText(290, 70, s, font40);
1515
1516        s.sprintf("PVS TRI: %08d", (int)mCurrentPvsCost);
1517        //renderText(290, 70, s, font40);
1518        renderText(325, 40, s, font40);
1519        s.sprintf("error: %3.3f %", mRenderError * 100.0f);
1520        renderText(20, 40, s, font40);
1521
1522        //renderText(290, 70, s, font40);
1523        glEnable(GL_LIGHTING);
1524
1525}
1526
1527
1528void
1529QtGlRendererWidget::SetViewCellGranularity(int number)
1530{
1531        if (mViewCellsManager)
1532        {
1533                //      mViewCellsManager->SetMaxFilterSize(number);
1534
1535                // $$ tmp off
1536                mViewCellsManager->CollectViewCells(number);
1537
1538                // $$ does not work so far:(
1539                //      mViewCellsManager->UpdatePvsForEvaluation();
1540                //      mViewCellsManager->FinalizeViewCells(false);
1541        }
1542        updateGL();
1543}
1544
1545void
1546QtGlRendererWidget::SetVisibilityFilterSize(int number)
1547{
1548        if (mViewCellsManager)
1549                mViewCellsManager->SetMaxFilterSize(number);
1550
1551        mPvsCache.Reset();
1552        updateGL();
1553}
1554
1555void
1556QtGlRendererWidget::SetSpatialFilterSize(int number)
1557{
1558        mSpatialFilterSize = 1e-3*number;
1559        mPvsCache.Reset();
1560        updateGL();
1561}
1562
1563void
1564QtGlRendererWidget::SetSceneCut(int number)
1565{
1566        // assume the cut plane can only be aligned with xz plane
1567        // shift it along y according to number, which is percentage of the bounding
1568        // box position
1569        if (mViewCellsManager)
1570        {
1571                const float f = number / 1000.0f;
1572                AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
1573                Vector3 p = (1.0f - f) * box.Min() + f * box.Max();
1574                mSceneCutPlane.mNormal = Vector3(0, -1, 0);
1575                mSceneCutPlane.mD = -DotProd(mSceneCutPlane.mNormal, p);
1576
1577                updateGL();
1578        }
1579}
1580
1581void
1582QtGlRendererWidget::SetHidingCost(int number)
1583{
1584        mHidingCost = (float)number / 1000.0f;
1585}
1586
1587
1588void
1589QtGlRendererWidget::SetTopDistance(int number)
1590{
1591        mTopDistance = number / 1000.0f;
1592        updateGL();
1593}
1594
1595void QtGlRendererWidget::SetTransparency(int number)
1596{
1597        mTransparency = number / 1000.0f;
1598        updateGL();
1599}
1600
1601#if 0
1602float QtGlRendererWidget::ComputeRenderCost(ViewCell *vc)
1603{
1604        ObjectPvs basePvs;
1605       
1606        basePvs = vc->CopyPvs();
1607        ObjectPvsIterator pit = basePvs.GetIterator();
1608
1609        float renderCost = 0;
1610
1611        //cout << "cost vis: " << mShowDistanceWeightedPvs << " " << " " << mShowDistanceWeightedTriangles << " " << mShowWeightedTriangles << endl;
1612       
1613        // first mark all objects from this pvs
1614        while (pit.HasMoreEntries())   
1615        {
1616                KdIntersectable *kdObj = static_cast<KdIntersectable *>(pit.Next());
1617
1618                if (mShowDistanceWeightedPvs)
1619                {
1620                        const AxisAlignedBox3 box = kdObj->GetBox();
1621
1622                        const float dist = SqrDistance(vc->GetBox().Center(), box.Center());
1623                        renderCost += 1.0f / dist;
1624                }
1625                else if (mShowDistanceWeightedTriangles)
1626                {
1627                        const AxisAlignedBox3 box = kdObj->GetBox();
1628
1629                        const float dist = SqrDistance(vc->GetBox().Center(), box.Center());
1630                        renderCost += kdObj->ComputeNumTriangles() / dist;
1631                }
1632                else //if (mShowWeightedTriangles)
1633                {
1634                        renderCost += kdObj->ComputeNumTriangles();
1635                }
1636                //if (pit.Next()->Mail();
1637        }
1638
1639        return renderCost;
1640}
1641#else
1642
1643float QtGlRendererWidget::ComputeRenderCost(ViewCell *vc)
1644{
1645        float renderCost = 0;
1646
1647#ifdef USE_VERBOSE_PVS
1648        if (mShowDistanceWeightedPvs)
1649        {
1650                return vc->GetPvs().mStats.mDistanceWeightedPvs;
1651        }
1652        else if (mShowDistanceWeightedTriangles)
1653        {
1654                return vc->GetPvs().mStats.mDistanceWeightedTriangles;
1655        }
1656        else //if (mShowWeightedTriangles)
1657        {
1658                return vc->GetPvs().mStats.mWeightedTriangles;
1659        }
1660#else
1661        return 0.0f;
1662#endif
1663}
1664#endif
1665
1666
1667
1668void QtGlRendererWidget::ComputeMaxValues(const ViewCellContainer &viewCells,
1669                                                                                  int &maxPvs,
1670                                                                                  int &maxPiercingRays,
1671                                                                                  float &maxRelativeRays,
1672                                                                                  float &maxRcCost)
1673{
1674        maxPvs = -1;
1675        maxPiercingRays = 1; // not zero for savety
1676        maxRelativeRays = Limits::Small; // not zero for savety
1677        maxRcCost = Limits::Small;
1678
1679        for (size_t i = 0; i < viewCells.size(); ++ i)
1680        {
1681                ViewCell *vc = viewCells[i];
1682
1683                if (mShowPvsSizes) // pvs size
1684                {
1685                        //const int p = vc->GetPvs().CountObjectsInPvs();
1686                        const int p = vc->GetPvs().GetSize();
1687                        if (p > maxPvs)
1688                                maxPvs = p;
1689                }
1690                else if (mShowPiercingRays) // relative number of rays
1691                {
1692                        const int piercingRays = vc->GetNumPiercingRays();
1693
1694                        if (piercingRays > maxPiercingRays)
1695                                maxPiercingRays = piercingRays;
1696                }
1697                else if (mShowWeightedRays)
1698                {
1699                        const int piercingRays = vc->GetNumPiercingRays();
1700
1701                        const float relativeArea =
1702                                vc->GetBox().SurfaceArea() / mViewCellsManager->GetViewSpaceBox().SurfaceArea();
1703
1704                        if ((float)piercingRays / relativeArea > maxRelativeRays)
1705                                maxRelativeRays = (float)piercingRays / relativeArea;
1706                }
1707                else if (mShowWeightedCost)
1708                {
1709                        const float rcCost = ComputeRenderCost(vc);
1710                        mViewCellsManager->UpdateScalarPvsCost(vc, rcCost);
1711
1712                        if (rcCost > maxRcCost)
1713                                maxRcCost = rcCost;
1714                }
1715        }
1716}
1717
1718
1719void QtGlRendererWidget::RenderViewCells()
1720{
1721        mUseFalseColors = true;
1722        //glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT);
1723
1724        glEnable(GL_CULL_FACE);
1725        glCullFace(GL_FRONT);
1726        //glDisable(GL_CULL_FACE);
1727
1728        if (mCutViewCells)
1729        {
1730                double eq[4];
1731                eq[0] = mSceneCutPlane.mNormal.x;
1732                eq[1] = mSceneCutPlane.mNormal.y;
1733                eq[2] = mSceneCutPlane.mNormal.z;
1734                eq[3] = mSceneCutPlane.mD;
1735
1736                glClipPlane(GL_CLIP_PLANE0, eq);
1737                glEnable(GL_CLIP_PLANE0);
1738        }
1739
1740        ViewCellContainer &viewcells = mViewCellsManager->GetViewCells();
1741       
1742        int maxPvs, maxPiercingRays;
1743        float maxRelativeRays, maxRcCost;
1744
1745        ComputeMaxValues(viewcells, maxPvs, maxPiercingRays, maxRelativeRays, maxRcCost);
1746       
1747        // matt: temp hack
1748        //maxRcCost = 5000.0f;
1749        //cout << "maxRcCost: " << maxRcCost << endl;
1750
1751        int i;
1752
1753        // transparency
1754        if (!mUseTransparency)
1755        {
1756                glEnable(GL_DEPTH_TEST);
1757                glDisable(GL_BLEND);
1758        }
1759        else
1760        {
1761                glDisable(GL_DEPTH_TEST);
1762                glEnable(GL_BLEND);
1763
1764                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1765                //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1766
1767                for (i = 0; i < viewcells.size(); ++ i)
1768                {
1769                        ViewCell *vc = viewcells[i];
1770
1771                        const float dist = SqrDistance(mDummyViewPoint, vc->GetBox().Center());
1772                        vc->SetDistance(dist);
1773                }
1774
1775                sort(viewcells.begin(), viewcells.end(), nearerThan);
1776        }
1777
1778        //mWireFrame = true;
1779               
1780        // normal rendering
1781        //if (!mShowPvsSizes && !mShowPiercingRays && !mShowWeightedRays && !mShowWeightedCost && !mShowComparison)
1782        if (mUseStandardColors)
1783        {
1784                for (i = 0; i < viewcells.size(); ++ i)
1785                {
1786                        ViewCell *vc = viewcells[i];
1787                        RgbColor c;
1788
1789                        //if (!mShowPvsSizes && !mShowPiercingRays)
1790                        c = vc->GetColor();
1791                       
1792                        glColor3f(c.r, c.g, c.b);
1793
1794                        if (!mHideByCost || (mHidingCost < (vc->GetNumPiercingRays() / (float)maxPiercingRays)))
1795                        {
1796                RenderViewCell(vc);
1797                        }
1798                }
1799        }
1800        else // using specialised colors
1801        {
1802                if (!mShowComparison)
1803                        AssignImportanceByRelativeValue(viewcells, maxPvs, maxPiercingRays, maxRelativeRays, maxRcCost);
1804                else
1805                {
1806                        if (mCompareInfo.empty())
1807                        {
1808                                LogReader reader;
1809                                reader.SetFilename("compare.log");
1810                                int samples;
1811                                reader.Read(samples, mCompareInfo);
1812                        }
1813
1814                        AssignColorByComparison(viewcells, mCompareInfo);
1815                }
1816
1817                glEnable(GL_DEPTH_TEST);       
1818        }
1819       
1820        glEnable(GL_CULL_FACE);
1821        glDisable(GL_CULL_FACE);
1822
1823        glDisable(GL_CLIP_PLANE0);
1824
1825        mUseFalseColors = false;
1826        mWireFrame = false;
1827
1828        glPopAttrib();
1829}
1830
1831
1832void QtGlRendererWidget::AssignImportanceByRelativeValue(const ViewCellContainer &viewCells,
1833                                                                                                                 int &maxPvs,
1834                                                                                                                 int &maxPiercingRays,
1835                                                                                                                 float &maxRelativeRays,
1836                                                                                                                 float &maxRcCost)
1837{
1838        for (size_t i = 0; i < viewCells.size(); ++ i)
1839        {
1840                RgbColor c;
1841                ViewCell *vc = viewCells[i];
1842
1843                float importance;
1844
1845                if (mShowPiercingRays)
1846                {
1847                        importance = mTransferFunction *
1848                                ((float)vc->GetNumPiercingRays() / (float)maxPiercingRays);
1849                }
1850                else if (mShowWeightedRays) // relative number of rays
1851                {
1852                        float relativeArea = vc->GetBox().SurfaceArea() / mViewCellsManager->GetViewSpaceBox().SurfaceArea();
1853
1854                        if (relativeArea < Limits::Small)
1855                                relativeArea = Limits::Small;
1856
1857                        importance = mTransferFunction * ((float)vc->GetNumPiercingRays() / relativeArea) / maxRelativeRays;
1858                }
1859                else if (mShowPvsSizes) // pvs size
1860                {
1861                        importance = mTransferFunction *
1862                                ((float)vc->GetPvs().GetSize() / (float)maxPvs);
1863                } // weighted render cost
1864                else if (mShowWeightedCost)
1865                {
1866                        const float rcCost = mTransferFunction * ComputeRenderCost(vc);
1867                        importance = rcCost / maxRcCost;
1868                }
1869               
1870                if (importance > 1.0f) importance = 1.0f;
1871                // c = RgbColor(importance, 1.0f - importance, 0.0f);
1872                c = RainbowColorMapping(importance);
1873
1874                glColor4f(c.r, c.g, c.b, 1.0f - mTransparency);
1875
1876                if (!mHideByCost || (mHidingCost < importance))
1877                {
1878                        RenderViewCell(vc);
1879                }
1880        }
1881}
1882
1883
1884void QtGlRendererWidget::AssignColorByComparison(const ViewCellContainer &viewcells,
1885                                                                                                 //const ViewCellInfoContainer &infos1,
1886                                                                                                 const ViewCellInfoContainer &compareInfo)
1887{
1888        if (viewcells.size() > compareInfo.size())
1889        {
1890                cerr << "loaded size (" << (int)compareInfo.size()
1891                         << ") does not fit to view cells size (" << (int)viewcells.size() << ")" << endl;
1892                return;
1893        }
1894
1895        //const float maxRatio = 1.0f;
1896        const float maxRatio = 2.0f;
1897        const float minRatio = 0.0f;
1898
1899        const float scale = 1.0f / (maxRatio - minRatio);
1900
1901        for (size_t i = 0; i < viewcells.size(); ++ i)
1902        {
1903                RgbColor c;
1904                ViewCell *vc = viewcells[i];
1905
1906                //ViewCellInfo vc1Info = infos1[i];
1907                ViewCellInfo vc2Info = compareInfo[i];
1908
1909                //const float vcRatio = vc->GetNumPiercingRays() / vc2Info.mPiercingRays + Limits::Small;
1910                float vcRatio = 1.0f;//maxRatio;
1911               
1912                if (vc2Info.mPvsSize > Limits::Small)
1913                        vcRatio = (float)vc->GetPvs().GetSize() / vc2Info.mPvsSize;
1914
1915                // truncate here
1916                if (vcRatio > maxRatio) vcRatio = 1.0f;
1917
1918                const float importance = (vcRatio - minRatio) * scale;
1919       
1920                if (0 && (i < 20))
1921                {
1922                        cout << "pvs1: " << vc->GetPvs().GetSize() << " pvs2: " << compareInfo[i].mPvsSize << " importance: " << importance << endl;
1923                }
1924
1925                // c = RgbColor(importance, 1.0f - importance, 0.0f);
1926                c = RainbowColorMapping(importance);
1927
1928                glColor4f(c.r, c.g, c.b, 1.0f);
1929
1930                if (1)//!mHideByCost || (mHidingCost < importance))
1931                {
1932                        RenderViewCell(vc);
1933                }
1934        }
1935}
1936
1937
1938
1939/**********************************************************************/
1940/*              QtRendererControlWidget implementation                */
1941/**********************************************************************/
1942
1943
1944QGroupBox *QtRendererControlWidget::CreateVisualizationPanel(QWidget *parent)
1945{
1946        QRadioButton *rb1, *rb2, *rb3, *rb4, *rb5;
1947       
1948        rb1 = new QRadioButton("random colors", parent);
1949        rb1->setText("random");
1950        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetShowWireFrame(bool)));
1951
1952        // Create a check box to be in the group box
1953        rb2 = new QRadioButton("piercing rays", parent);
1954        rb2->setText("piercing rays");
1955        //vl->addWidget(rb1);
1956        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetShowPiercingRays(bool)));
1957
1958        rb3 = new QRadioButton("pvs size", parent);
1959        rb3->setText("pvs size");
1960        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowPvsSizes(bool)));
1961       
1962        rb4 = new QRadioButton("weighted rays", parent);
1963        rb4->setText("weighted rays");
1964        connect(rb4, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedRays(bool)));
1965       
1966        rb5 = new QRadioButton("pvs cost", parent);
1967        rb5->setText("pvs cost");
1968        connect(rb5, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedCost(bool)));
1969
1970        QGroupBox *groupBox = new QGroupBox("PVS Visualization");
1971
1972        QVBoxLayout *vbox2 = new QVBoxLayout;
1973   
1974        vbox2->addWidget(rb1);
1975        vbox2->addWidget(rb2);
1976        vbox2->addWidget(rb3);
1977        vbox2->addWidget(rb4);
1978        vbox2->addWidget(rb5);
1979       
1980        rb5->setChecked(true);
1981
1982        vbox2->addStretch(1);
1983        groupBox->setLayout(vbox2);
1984
1985        return groupBox;
1986}
1987
1988
1989QGroupBox *QtRendererControlWidget::CreateTrafoPanel(QWidget *parent)
1990{
1991        QRadioButton *rb1, *rb2, *rb3;
1992       
1993        rb1 = new QRadioButton("translation", parent);
1994        rb1->setText("translation");
1995        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetTranslation(bool)));
1996
1997        // Create a check box to be in the group box
1998        rb2 = new QRadioButton("scale", parent);
1999        rb2->setText("scale");
2000        //vl->addWidget(rb1);
2001        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetScale(bool)));
2002
2003        rb3 = new QRadioButton("rotation", parent);
2004        rb3->setText("rotation");
2005        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetRotation(bool)));
2006   
2007        QVBoxLayout *vbox2 = new QVBoxLayout;
2008        QGroupBox *groupBox = new QGroupBox("Dynamic Obojects");
2009
2010        vbox2->addWidget(rb1);
2011        vbox2->addWidget(rb2);
2012        vbox2->addWidget(rb3);
2013       
2014        rb1->setChecked(true);
2015
2016        vbox2->addStretch(1);
2017
2018
2019        QPushButton *button = new QPushButton("Update", groupBox);
2020        vbox2->addWidget(button);
2021        connect(button, SIGNAL(clicked()), SIGNAL(UpdateDynamicObjects()));
2022       
2023        button = new QPushButton("Delete", groupBox);
2024        vbox2->addWidget(button);
2025        connect(button, SIGNAL(clicked()), SIGNAL(DeleteDynamicObject()));
2026       
2027        button = new QPushButton("Next object", groupBox);
2028        vbox2->layout()->addWidget(button);
2029        connect(button, SIGNAL(clicked()), SIGNAL(NextObject()));
2030
2031        groupBox->setLayout(vbox2);
2032       
2033        return groupBox;
2034}
2035
2036
2037QGroupBox *QtRendererControlWidget::CreateRenderCostPanel(QWidget *parent)
2038{
2039        QRadioButton *rb1, *rb2, *rb3;
2040       
2041        // Create a check box to be in the group box
2042        rb1 = new QRadioButton("triangles", parent);
2043        rb1->setText("triangles");
2044        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(SetShowWeightedTriangles(bool)));
2045
2046        rb2 = new QRadioButton("distance weighted pvs", parent);
2047        rb2->setText("distance weighted");
2048        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(SetShowDistanceWeightedPvs(bool)));
2049
2050        rb3 = new QRadioButton("distance weighted triangles", parent);
2051        rb3->setText("distance weighted triangles");
2052        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowDistanceWeightedTriangles(bool)));
2053
2054        QGroupBox *groupBox = new QGroupBox("Render cost options");
2055        QVBoxLayout *vbox2 = new QVBoxLayout;
2056   
2057        vbox2->addWidget(rb1);
2058        vbox2->addWidget(rb2);
2059        vbox2->addWidget(rb3);
2060       
2061        rb1->setChecked(true);
2062
2063        vbox2->addStretch(1);
2064        groupBox->setLayout(vbox2);
2065
2066        return groupBox;
2067}
2068
2069
2070QGroupBox *QtRendererControlWidget::CreateRayVisualizationPanel(QWidget *parent)
2071{
2072        QRadioButton *rb1, *rb2, *rb3, *rb4;
2073       
2074        // Create a check box to be in the group box
2075        rb1 = new QRadioButton("const color", parent);
2076        rb1->setText("const color");
2077        //vl->addWidget(rb1);
2078        connect(rb1, SIGNAL(toggled(bool)), SIGNAL(UseConstColorForRayViz(bool)));
2079
2080        rb2 = new QRadioButton("ray length", parent);
2081        rb2->setText("ray length");
2082        connect(rb2, SIGNAL(toggled(bool)), SIGNAL(UseRayLengthForRayViz(bool)));
2083       
2084        rb3 = new QRadioButton("contribution", parent);
2085        rb3->setText("contribution");
2086        connect(rb3, SIGNAL(toggled(bool)), SIGNAL(SetShowContribution(bool)));
2087       
2088        rb4 = new QRadioButton("distribution", parent);
2089        rb4->setText("distribution");
2090        connect(rb4, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution(bool)));
2091
2092
2093        ///////////////////////////
2094
2095       
2096        QGroupBox *groupBox = new QGroupBox("Ray visualization");
2097        QVBoxLayout *vbox2 = new QVBoxLayout;
2098   
2099        vbox2->addWidget(rb1);
2100        vbox2->addWidget(rb2);
2101        vbox2->addWidget(rb3);
2102        vbox2->addWidget(rb4);
2103       
2104        rb1->setChecked(true);
2105
2106
2107        QCheckBox *cb = new QCheckBox("Distribution 1", parent);
2108        vbox2->addWidget(cb);
2109        cb->setChecked(true);
2110        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution1(bool)));
2111
2112        cb = new QCheckBox("Distribution 2", parent);
2113        vbox2->addWidget(cb);
2114        cb->setChecked(true);
2115        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution2(bool)));
2116
2117        cb = new QCheckBox("Distribution 3", parent);
2118        vbox2->addWidget(cb);
2119        cb->setChecked(true);
2120        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution3(bool)));
2121       
2122        cb = new QCheckBox("Distribution 4", parent);
2123        vbox2->addWidget(cb);
2124        cb->setChecked(true);
2125        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowDistribution4(bool)));
2126
2127
2128        vbox2->addStretch(1);
2129        groupBox->setLayout(vbox2);
2130
2131        return groupBox;
2132}
2133
2134
2135QtRendererControlWidget::QtRendererControlWidget(QWidget * parent, Qt::WFlags f):
2136QWidget(parent, f)
2137{
2138
2139        QVBoxLayout *vl = new QVBoxLayout;
2140        setLayout(vl);
2141       
2142        //QWidget *vbox;
2143
2144        //vbox = new QGroupBox("Render Controls", this);
2145        //layout()->addWidget(vbox);
2146        //vl = new QVBoxLayout;
2147        //vbox->setLayout(vl);
2148
2149        QLabel *label;
2150        QSlider *slider;
2151        QPushButton *button;
2152
2153#if 0//REMOVE_TEMPORARY
2154
2155        label = new QLabel("Granularity");
2156        //vbox->layout()->addWidget(label);
2157        vl->addWidget(label);
2158
2159        slider = new QSlider(Qt::Horizontal);
2160        vl->addWidget(slider);
2161        slider->show();
2162        slider->setRange(1, 10000);
2163        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2164        slider->setValue(200);
2165
2166        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetViewCellGranularity(int)));
2167
2168        ///////////////////////////
2169
2170        label = new QLabel("Transfer function");
2171        vl->addWidget(label);
2172
2173        slider = new QSlider(Qt::Horizontal);
2174        vl->addWidget(slider);
2175        slider->show();
2176        slider->setRange(1, 10000);
2177        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2178        slider->setValue(100);
2179
2180
2181        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransferFunction(int)));
2182
2183        ////////////////////////////////////////7
2184
2185        button = new QPushButton("Update all PVSs");
2186        vl->addWidget(button);
2187        connect(button, SIGNAL(clicked()), SLOT(UpdateAllPvs()));
2188
2189        ////////////////////////////////////////77777
2190
2191        label = new QLabel("Filter size");
2192        vl->addWidget(label);
2193
2194        slider = new QSlider(Qt::Horizontal);
2195        vl->addWidget(slider);
2196        slider->show();
2197        slider->setRange(1, 100);
2198        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2199        slider->setValue(3);
2200
2201        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetVisibilityFilterSize(int)));
2202
2203#endif
2204
2205
2206       
2207        ///////////////////////////////////
2208
2209
2210        QWidget *hbox = new QWidget();
2211        vl->addWidget(hbox);
2212        QHBoxLayout *hlayout = new QHBoxLayout;
2213        hbox->setLayout(hlayout);
2214
2215        QCheckBox *cb = new QCheckBox("Show viewcells", hbox);
2216        hlayout->addWidget(cb);
2217        cb->setChecked(false);
2218        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowViewCells(bool)));
2219       
2220        cb = new QCheckBox("Render errors", hbox);
2221        hlayout->layout()->addWidget(cb);
2222        cb->setChecked(false);
2223        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderErrors(bool)));
2224
2225#if REMOVE_TEMPORARY
2226        cb = new QCheckBox("Render cost curve", hbox);
2227        hlayout->addWidget(cb);
2228        cb->setChecked(false);
2229        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRenderCost(bool)));
2230#endif
2231        cb = new QCheckBox("Show rays", hbox);
2232        hlayout->addWidget(cb);
2233        cb->setChecked(false);
2234        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowRays(bool)));
2235#if REMOVE_TEMPORARY   
2236        cb = new QCheckBox("Show Comparison", hbox);
2237        hlayout->addWidget(cb);
2238        cb->setChecked(false);
2239        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetShowComparison(bool)));
2240#endif
2241
2242        //////////////////
2243
2244        QHBoxLayout *vh = new QHBoxLayout;
2245
2246        QGroupBox *myBox = new QGroupBox("Visualization");
2247
2248        myBox->setLayout(vh);
2249        vl->addWidget(myBox, 0, 0);
2250
2251        QGroupBox *groupBox = CreateVisualizationPanel(hbox);
2252        vh->addWidget(groupBox, 0, 0);
2253
2254#if REMOVE_TEMPORARY
2255        QGroupBox *groupBox2 = CreateRenderCostPanel(hbox);
2256        vh->addWidget(groupBox2, 0, 0);
2257       
2258        QGroupBox *groupBox3 = CreateRayVisualizationPanel(hbox);
2259        vh->addWidget(groupBox3, 0, 0);
2260#endif
2261
2262#if 1
2263        QGroupBox *groupBox4 = CreateTrafoPanel(hbox);
2264        vh->addWidget(groupBox4, 0, 0);
2265#endif
2266
2267        //////////////////////////////////
2268
2269        bool tmp = false;
2270        const int range = 1000;
2271
2272        //vbox->resize(800,150);
2273        QWidget *vbox;
2274
2275        vbox = new QGroupBox("Rendering", this);
2276        layout()->addWidget(vbox);
2277
2278        vl = new QVBoxLayout;
2279        vbox->setLayout(vl);
2280
2281
2282        cb = new QCheckBox("Cut view cells", vbox);
2283        vbox->layout()->addWidget(cb);
2284        cb->setChecked(false);
2285        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutViewCells(bool)));
2286
2287
2288        slider = new QSlider(Qt::Horizontal, vbox);
2289        vbox->layout()->addWidget(slider);
2290        slider->show();
2291        slider->setRange(0, 1000);
2292        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2293        slider->setValue(1000);
2294
2295        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSceneCut(int)));
2296
2297
2298        cb = new QCheckBox("Use spatial filter", vbox);
2299        vbox->layout()->addWidget(cb);
2300        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter", tmp);
2301        cb->setChecked(tmp);
2302        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseSpatialFilter(bool)));
2303
2304
2305        label = new QLabel("Spatial Filter size");
2306        vbox->layout()->addWidget(label);
2307       
2308        slider = new QSlider(Qt::Horizontal, vbox);
2309        vbox->layout()->addWidget(slider);
2310        slider->show();
2311        slider->setRange(1, 100);
2312        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2313        slider->setValue(10);
2314
2315        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSpatialFilterSize(int)));
2316
2317        ////////////////////////////
2318
2319       
2320        cb = new QCheckBox("Hide view cells by render cost ", vbox);
2321        vbox->layout()->addWidget(cb);
2322        cb->setChecked(false);
2323        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetHideByCost(bool)));
2324
2325        label = new QLabel("Hide by cost");
2326        vbox->layout()->addWidget(label);
2327
2328        // the render cost visualization
2329        slider = new QSlider(Qt::Horizontal, vbox);
2330        vbox->layout()->addWidget(slider);
2331        slider->show();
2332        slider->setRange(0, range);
2333        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2334        slider->setValue(0);
2335        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetHidingCost(int)));
2336
2337        ///////////////////////////////////////////
2338
2339        cb = new QCheckBox("Top View", vbox);
2340        vbox->layout()->addWidget(cb);
2341        cb->setChecked(false);
2342        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetTopView(bool)));
2343
2344
2345        label = new QLabel("Top distance");
2346        vbox->layout()->addWidget(label);
2347       
2348        slider = new QSlider(Qt::Horizontal, vbox);
2349        vbox->layout()->addWidget(slider);
2350        slider->show();
2351        slider->setRange(1, 1000);
2352        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2353        slider->setValue(500);
2354
2355        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTopDistance(int)));
2356       
2357
2358        ///////////////////////////////////////////
2359#if REMOVE_TEMPORARY
2360        cb = new QCheckBox("Transparency", vbox);
2361        vbox->layout()->addWidget(cb);
2362        cb->setChecked(false);
2363        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseTransparency(bool)));
2364
2365        label = new QLabel("Use transparency");
2366        vbox->layout()->addWidget(label);
2367
2368        // the render cost visualization
2369        slider = new QSlider(Qt::Horizontal, vbox);
2370        vbox->layout()->addWidget(slider);
2371        slider->show();
2372        slider->setRange(0, range);
2373        slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
2374        slider->setValue(0);
2375        connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetTransparency(int)));
2376#endif
2377       
2378
2379        //////////////////////////////
2380
2381#if REMOVE_TEMPORARY
2382
2383        cb = new QCheckBox("Cut scene", vbox);
2384        vbox->layout()->addWidget(cb);
2385        cb->setChecked(false);
2386        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetCutScene(bool)));
2387
2388        cb = new QCheckBox("Render boxes", vbox);
2389        vbox->layout()->addWidget(cb);
2390        cb->setChecked(false);
2391        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderBoxes(bool)));
2392
2393        cb = new QCheckBox("Render visibility estimates", vbox);
2394        vbox->layout()->addWidget(cb);
2395        cb->setChecked(false);
2396        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderVisibilityEstimates(bool)));
2397#endif
2398
2399#if REMOVE_TEMPORARY
2400
2401        cb = new QCheckBox("Use filter", vbox);
2402        vbox->layout()->addWidget(cb);
2403        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp);
2404        cb->setChecked(tmp);
2405        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseFilter(bool)));
2406#endif
2407
2408#if REMOVE_TEMPORARY
2409       
2410        cb = new QCheckBox("Render filter", vbox);
2411        vbox->layout()->addWidget(cb);
2412        cb->setChecked(true);
2413        connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderFilter(bool)));
2414
2415        /*vbox = new QGroupBox("PVS Errors", this);
2416        layout()->addWidget(vbox);
2417
2418        vl = new QVBoxLayout;
2419        vbox->setLayout(vl);
2420
2421        button = new QPushButton("Compute Visibility", vbox);
2422        vbox->layout()->addWidget(button);
2423        connect(button, SIGNAL(clicked()), SLOT(ComputeVisibility()));
2424
2425        button = new QPushButton("Stop Computation", vbox);
2426        vbox->layout()->addWidget(button);
2427        connect(button, SIGNAL(clicked()), SLOT(StopComputation()));
2428
2429        button = new QPushButton("Set Random View Point", vbox);
2430        vbox->layout()->addWidget(button);
2431        connect(button, SIGNAL(clicked()), SLOT(SetRandomViewPoint()));*/
2432
2433        button = new QPushButton("Store statistics", vbox);
2434        vbox->layout()->addWidget(button);
2435        connect(button, SIGNAL(clicked()), SIGNAL(StoreStatistics()));
2436
2437#endif
2438
2439#if 0
2440       
2441        button = new QPushButton("Compute GVS", vbox);
2442        vbox->layout()->addWidget(button);
2443        connect(button, SIGNAL(clicked()), SIGNAL(ComputeGVS()));
2444#endif
2445       
2446        button = new QPushButton("Replay view points", vbox);
2447        vbox->layout()->addWidget(button);
2448        connect(button, SIGNAL(clicked()), SIGNAL(ReplayViewPoints()));
2449
2450
2451        /*cb = new QCheckBox("Stats", vbox);
2452        vbox->layout()->addWidget(cb);
2453        cb->setChecked(false);
2454        connect(cb, SIGNAL(toggled(bool)), SIGNAL(StoreStatistics()));*/
2455
2456        if (0)
2457        {
2458                vbox = new QGroupBox("PVS Errors", this);
2459                layout()->addWidget(vbox);
2460
2461                vl = new QVBoxLayout;
2462                vbox->setLayout(vl);
2463
2464                mPvsErrorWidget = new QListWidget(vbox);
2465                vbox->layout()->addWidget(mPvsErrorWidget);
2466
2467                connect(mPvsErrorWidget,
2468                        SIGNAL(doubleClicked(const QModelIndex &)),
2469                        this,
2470                        SLOT(PvsErrorClicked(const QModelIndex &)));
2471
2472                button = new QPushButton("Next Error Frame", vbox);
2473                vbox->layout()->addWidget(button);
2474                connect(button, SIGNAL(clicked(void)), SLOT(FocusNextPvsErrorFrame(void)));
2475        }
2476       
2477        //connect(button, SIGNAL(clicked(void)), SLOT(StoreStatistics(void)));
2478       
2479        //////////////////////////////////////////
2480
2481
2482        setWindowTitle("Preprocessor Control Widget");
2483        adjustSize();
2484}
2485
2486
2487
2488
2489void
2490QtRendererControlWidget::FocusNextPvsErrorFrame(void)
2491{}
2492
2493void
2494QtRendererControlWidget::UpdatePvsErrorItem(int row,
2495                                                                                        GlRendererBuffer::PvsErrorEntry &pvsErrorEntry)
2496{
2497
2498        QListWidgetItem *i = mPvsErrorWidget->item(row);
2499        QString s;
2500        s.sprintf("%5.5f", pvsErrorEntry.mError);
2501        if (i) {
2502                i->setText(s);
2503        } else {
2504                new QListWidgetItem(s, mPvsErrorWidget);
2505        }
2506        mPvsErrorWidget->update();
2507}
2508
2509
2510
2511
2512/*********************************************************************/
2513/*                   QtGlDebuggerWidget implementation               */
2514/*********************************************************************/
2515
2516
2517QtGlDebuggerWidget::QtGlDebuggerWidget(QtGlRendererBuffer *buf, QWidget *parent)
2518: QGLWidget(QGLFormat(QGL::SampleBuffers), parent), mRenderBuffer(buf)
2519{
2520        // create the pbuffer
2521        //pbuffer = new QGLPixelBuffer(QSize(512, 512), format(), this);
2522        //mUpdateTimerId = startTimer(20);
2523        setWindowTitle(("OpenGL pbuffers"));
2524}
2525
2526
2527QtGlDebuggerWidget::~QtGlDebuggerWidget()
2528{
2529        mRenderBuffer->releaseFromDynamicTexture();
2530        glDeleteTextures(1, &dynamicTexture);
2531
2532        DEL_PTR(mRenderBuffer);
2533}
2534
2535
2536void QtGlDebuggerWidget::initializeGL()
2537{
2538        glMatrixMode(GL_PROJECTION);
2539        glLoadIdentity();
2540
2541        glFrustum(-1, 1, -1, 1, 10, 100);
2542        glTranslatef(-0.5f, -0.5f, -0.5f);
2543        glTranslatef(0.0f, 0.0f, -15.0f);
2544        glMatrixMode(GL_MODELVIEW);
2545
2546        glEnable(GL_CULL_FACE);
2547        initCommon();
2548        initPbuffer();
2549
2550}
2551
2552
2553void QtGlDebuggerWidget::resizeGL(int w, int h)
2554{
2555        glViewport(0, 0, w, h);
2556}
2557
2558
2559void QtGlDebuggerWidget::paintGL()
2560{
2561        // draw a spinning cube into the pbuffer..
2562        mRenderBuffer->makeCurrent();
2563
2564        BeamSampleStatistics stats;
2565        mRenderBuffer->SampleBeamContributions(mSourceObject, mBeam, mSamples, stats);
2566
2567        glFlush();
2568
2569        // rendering directly to a texture is not supported on X11, unfortunately
2570        mRenderBuffer->updateDynamicTexture(dynamicTexture);
2571
2572        // and use the pbuffer contents as a texture when rendering the
2573        // background and the bouncing cubes
2574        makeCurrent();
2575        glBindTexture(GL_TEXTURE_2D, dynamicTexture);
2576        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2577
2578        // draw the background
2579        glMatrixMode(GL_MODELVIEW);
2580        glPushMatrix();
2581        glLoadIdentity();
2582        glMatrixMode(GL_PROJECTION);
2583        glPushMatrix();
2584        glLoadIdentity();
2585
2586        glPopMatrix();
2587        glMatrixMode(GL_MODELVIEW);
2588        glPopMatrix();
2589}
2590
2591
2592void QtGlDebuggerWidget::initPbuffer()
2593{
2594        // set up the pbuffer context
2595        mRenderBuffer->makeCurrent();
2596        // generate a texture that has the same size/format as the pbuffer
2597        dynamicTexture = mRenderBuffer->generateDynamicTexture();
2598        // bind the dynamic texture to the pbuffer - this is a no-op under X11
2599        mRenderBuffer->bindToDynamicTexture(dynamicTexture);
2600        //makeCurrent();
2601}
2602
2603
2604void QtGlDebuggerWidget::initCommon()
2605{
2606        glEnable(GL_TEXTURE_2D);
2607        glEnable(GL_DEPTH_TEST);
2608
2609        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
2610}
2611
2612
2613void QtGlRendererWidget::_RenderColoredPvs()
2614{
2615        // note: could be done more efficiently using color buffers
2616        mPvsSize = mPvsCache.mPvs.GetSize();
2617
2618        ObjectPvsIterator it = mPvsCache.mPvs.GetIterator();
2619
2620        PvsData pvsData;
2621
2622        while (it.HasMoreEntries())
2623        {
2624                Intersectable *obj = it.Next(pvsData);
2625
2626                RgbColor color;
2627
2628                //cerr << "sumpdf: " << pvsData.mSumPdf << endl;
2629                if (mUseRandomColorPerPvsObject)
2630                {
2631                        if (obj->Type() == Intersectable::KD_INTERSECTABLE)
2632                        {
2633                                KdIntersectable *kdint = static_cast<KdIntersectable *>(obj);
2634
2635                                if (kdint->mGenericIdx == -1)
2636                                {
2637                                        kdint->mGenericIdx = (int)mColors.size();
2638                                        mColors.push_back(RandomColor(0, 1));
2639                                }
2640                                color = mColors[kdint->mGenericIdx];
2641                        }
2642                }
2643                else
2644                {
2645                        color = RainbowColorMapping(mTransferFunction * log10(pvsData.mSumPdf + 1));
2646                }
2647
2648                glColor3f(color.r, color.g, color.b);
2649
2650                mUseForcedColors = true;
2651                RenderIntersectable(obj);
2652                mUseForcedColors = false;
2653        }
2654}
2655
2656
2657void QtGlRendererWidget::UpdateDynamicObjects()
2658{
2659        preprocessor->ScheduleUpdateDynamicObjects(); 
2660}
2661
2662
2663void QtGlRendererWidget::ReplayViewPoints()
2664{
2665        ViewCellPointsList *vcPoints = mViewCellsManager->GetViewCellPointsList();
2666
2667        ViewCellPointsList::const_iterator vit, vit_end = vcPoints->end();
2668
2669        sViewPointsList.clear();
2670
2671        for (vit = vcPoints->begin(); vit != vit_end; ++ vit)
2672        {
2673                ViewCellPoints *vp = *vit;
2674
2675                SimpleRayContainer::const_iterator rit, rit_end = vp->second.end();
2676       
2677                for (rit = vp->second.begin(); rit != rit_end; ++ rit)
2678                {
2679                        sViewPointsList.push_back(*rit);
2680                }
2681        }
2682
2683        if (!sViewPointsList.empty())
2684        {
2685                cout << "replaying " << (int)sViewPointsList.size() << " view points " << endl;
2686               
2687                mReplayMode = true;
2688               
2689                if (mExportFrameBuffer)
2690                        GetPreprocessor()->mSynchronize = true;
2691
2692                sCurrentSamples = GetPreprocessor()->mCurrentSamples;
2693                sViewPointsListIt = sViewPointsList.begin();
2694        }
2695}
2696
2697
2698
2699Vector3 QtGlRendererWidget::Unproject(int x, int y)
2700{
2701        // swap y coordinate
2702        y = GetHeight() - y;
2703
2704        // HACK: should come from camera!
2705        double projection[16];
2706        glGetDoublev(GL_PROJECTION_MATRIX, projection);
2707        double modelview[16];
2708        glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
2709
2710        const int viewport[4] = {0,0, GetWidth(), GetHeight()};
2711
2712        RenderScene();
2713
2714        float z;
2715        glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
2716       
2717        GLdouble rx, ry, rz;
2718        gluUnProject(x, y, z, modelview, projection, viewport, &rx, &ry, &rz);
2719
2720        return Vector3(rx, ry, rz);
2721}
2722
2723
2724int QtGlRendererWidget::FindDynamicObject(float x, float y)
2725{
2726
2727        if (GetPreprocessor()->mDynamicObjects.empty())
2728                return -1;
2729
2730        makeCurrent();
2731       
2732        // this is the same as in every OpenGL picking example
2733        const int maxSize = 512;
2734       
2735        // see below for an explanation on the buffer content
2736        GLuint buffer[maxSize];
2737        glSelectBuffer(maxSize, buffer);
2738       
2739        // enter select mode
2740        glRenderMode(GL_SELECT);
2741        glInitNames();
2742        glPushName(0);
2743       
2744        glMatrixMode(GL_PROJECTION);
2745        glPushMatrix();
2746        glLoadIdentity();
2747
2748        glViewport(0, 0, width(), height());
2749
2750        GLint viewport[4];
2751        glGetIntegerv(GL_VIEWPORT, viewport);
2752
2753        const float w = 1.0f;
2754
2755        //gluPickMatrix(x, y, 1000.0, 1000.0, viewport);
2756        gluPickMatrix((GLdouble)x, (GLdouble)(viewport[3] - y), w, w, viewport);
2757
2758        GLfloat aspect = (GLfloat) width() / height();
2759        gluPerspective(70.0f, aspect, 0.1f, 2.0f * Magnitude(mSceneGraph->GetBox().Diagonal()));
2760       
2761        glMatrixMode(GL_MODELVIEW);
2762        glPushMatrix();
2763        glLoadIdentity();
2764        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2765       
2766       
2767        SetupCamera();
2768
2769        for (GLuint i = 0; i < GetPreprocessor()->mDynamicObjects.size(); ++ i)
2770        {
2771                glLoadName(i);
2772                _RenderDynamicObject(GetPreprocessor()->mDynamicObjects[i]);
2773        }
2774
2775        glFlush();
2776        glPopMatrix();
2777
2778        glMatrixMode(GL_PROJECTION);
2779        glPopMatrix();
2780
2781        int hits = glRenderMode(GL_RENDER);
2782
2783        // finally release the rendering context again
2784        if (!hits)
2785        {
2786                cout << "no object picked" << endl;
2787                return -1;
2788        }
2789
2790        //processHits(hits, buffer);
2791       
2792        // Each hit takes 4 items in the buffer.
2793        // The first item is the number of names on the name stack when the hit occured.
2794        // The second item is the minimum z value of all the verticies that intersected
2795        // the viewing area at the time of the hit. The third item is the maximum z value
2796        // of all the vertices that intersected the viewing area at the time of the hit
2797        // and the last item is the content of the name stack at the time of the hit
2798        // (name of the object). We are only interested in the object name
2799        // (number of the surface).
2800        // return the name of the clicked surface
2801        return buffer[3];
2802}
2803
2804
2805void QtGlRendererWidget::DeleteDynamicObject()
2806{
2807        Preprocessor *p = GetPreprocessor();
2808
2809        if ((mCurrentDynamicObjectIdx < 0) ||
2810                (mCurrentDynamicObjectIdx >= p->mDynamicObjects.size()))
2811                return;
2812
2813        cout << "deleting object" << endl;
2814
2815        SceneGraphLeaf *l = p->mDynamicObjects[mCurrentDynamicObjectIdx];
2816
2817        // tell the preprocessor that an object was deleted
2818        p->ObjectRemoved(l);
2819
2820        swap(p->mDynamicObjects[mCurrentDynamicObjectIdx], p->mDynamicObjects.back());
2821        p->mDynamicObjects.pop_back();
2822
2823        delete l;
2824
2825        mCurrentDynamicObjectIdx = -1;
2826}       
2827
2828}
Note: See TracBrowser for help on using the repository browser.