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

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