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

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