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

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