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

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