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

Revision 2707, 68.5 KB checked in by bittner, 16 years ago (diff)

shaft culling for dynamic updates

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