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

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