Logo Search packages:      
Sourcecode: earth3d version File versions  Download package

gltest.cpp

#include "winconf.h"
#include "gltest.h"
#include <iostream>
#include "quaternion.h"
#include "matrix.h"
#include "point3d.h"
#include <qnamespace.h>
#include <qcursor.h>
#include <qtimer.h>
#include <qlabel.h>
#include <qimage.h>
#include <qstatusbar.h>
#include <qfont.h>
#include <qclipboard.h>
#include <qmutex.h>
#include <math.h>
#include <assert.h>
#include "geometry2d3dSphere.h"
#include "formview.h"
#include "treeDrawSphere.h"
#include "glcontext.h"
#include "globalsettings.h"

#ifdef WIN32
#include "wingl.h"
#endif

#ifndef M_PI
# define M_PI           3.14159265358979323846  /* pi */
#endif

using namespace std;

#ifdef DAVE
#include "dave.h"
Dave*  dave;
bool daveinit;

struct davedata {
  Point3D viewer, direction, up;
  int rtri;
};

#endif

GLTestWidget::GLTestWidget ( QWidget * parent, const char * name, const GLTestWidget * shareWidget, WFlags f) 
  : QGLWidget(parent, name, shareWidget, f) {
  init();
}

GLTestWidget::GLTestWidget ( const QGLFormat & format, QWidget * parent, const char * name, const GLTestWidget * shareWidget, WFlags f ) : QGLWidget(format, parent, name, shareWidget, f) {
  init();
}

GLTestWidget::GLTestWidget ( QGLContext * context, QWidget * parent, const char * name, const QGLWidget * shareWidget, WFlags f ) 
  : QGLWidget(context, parent, name, shareWidget, f) {
  init();
}

void GLTestWidget::init() {
  rtri = 0;
  rtry = 0;

  formview = NULL;

  pitch = 0;
  roll = 0;

  clippingPlanes[0]=10;
  clippingPlanes[1]=10;

#ifdef DAVE
  dave = new Dave(sizeof(davedata), 42, false);
  davedata *dd = (davedata *) dave->getSyncBuffer();
  dd->rtri = 0;

  setCursor(QCursor(Qt::BlankCursor));
  nav.setViewer(Point3D(0,0,0));

  this->format().setStereo(true);
  daveinit=false;
#else
  nav.setViewer(Point3D(0,0,3));
#endif
  viewCulling = true;
  nav.setDirection(Point3D(0,0,-1));
  setFocusPolicy(QWidget::StrongFocus);
  setAutoBufferSwap(false);
  this->format().setDoubleBuffer(true);

  threadStarted = false;
//   start();
  aspect = 1.;

  alwaysBind = false;

  navRotate = false;
  old_valid = false;
  matrix_valid = false;
  fullscreen = false;

  depthbuffer = NULL;
  grabDepthBuffer = true;
//   grabDepthBuffer = false;

  navtime_ctime = QTime::currentTime();
  navtime_nowtime = QTime::currentTime();

#ifdef GENERATE_FONTS
  generateFonts();
#endif

#ifdef LINUX
#ifdef JOYSTICK
  /* Initialize (open) the joystick, passing it the pointer to
   * the jsd structure.
   */
  joystick_usable = false;
  
  const char *device = "/dev/input/js0";

  int status = JSInit(&jsd, device, "joystick.cal", JSFlagNonBlocking);

  /* Error occured opening joystick? */
  if(status != JSSuccess) {
    /* There was an error opening the joystick, print by the
     * recieved error code from JSInit().
     */
    switch(status)
      {
      case JSBadValue:
      fprintf(
            stderr,
            "%s: Invalid value encountered while initializing joystick.\n",
            device
            );
      break;
        
      case JSNoAccess:
      fprintf(
            stderr,
            "%s: Cannot access resources, check permissions and file locations.\n",
            device
            );
      break;
        
      case JSNoBuffers:
      fprintf(
            stderr,
            "%s: Insufficient memory to initialize.\n",
            device
            );
      break;
        
      default:    /* JSError */
      fprintf(
            stderr,
            "%s: Error occured while initializing.\n",
            device
            );
      break;
      }
      
    /* Print some helpful advice. */
    fprintf(stderr,
          "Make sure that:\n\
    1. Your joystick is connected (and turned on as needed).\n\
    2. Your joystick modules are loaded (`modprobe <driver>').\n\
    3. Your joystick needs to be calibrated (use `jscalibrator').\n\
\n"
          );
      
    /* Close joystick jsd structure (just in case). */
    JSClose(&jsd);
  }
  else {
    joystick_usable = true;
  }
#endif
#endif
}

GLTestWidget::~GLTestWidget () {
  if (depthbuffer) delete[](depthbuffer);
}

/* white ambient light at full intensity (rgba) */
GLfloat ELightAmbient[] = { 1.0f, 1.0f, 1.0f, 1.0f };

/* super bright, full intensity diffuse light. */
GLfloat ELightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };

/* position of light (x, y, z, (position of light)) */
GLfloat ELightPosition[] = { 1.f, 0.0f, 3.0f, 0.0f };
GLfloat Elight0_specular[] = {1,1,1,1};
GLfloat Emat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat Emat_shininess[] = { 50.0 };

void GLTestWidget::render() {
  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity();                                      // Reset The View
#ifdef DAVE
  Point3D viewpoint = nav.direction + nav.viewer;
//   gluLookAt(nav.viewer.x, nav.viewer.y, nav.viewer.z, viewpoint.x, viewpoint.y, viewpoint.z, nav.up.x, nav.up.y, nav.up.z);
  glTranslatef(nav.viewer.x, nav.viewer.y, nav.viewer.z);
  glScalef(0.25, 0.25, 0.25);

//   glRotatef(90,1,0,0);
#endif

  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
  glCullFace(GL_BACK);
  glEnable(GL_CULL_FACE);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
#ifdef DAVE
  glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
#else
  float colorfactor = nav.viewer.length()-1;
  colorfactor *= colorfactor;
  if (colorfactor<=1) colorfactor=1.f;

  glClearColor(0.3f/colorfactor, 0.6f/colorfactor, 0.9f/colorfactor, 1.0f);
#endif

  glEnable(GL_LIGHTING);
  glDisable(GL_COLOR_MATERIAL);
  glEnable(GL_NORMALIZE);

  glShadeModel (GL_SMOOTH);
//   glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
//   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
  
  glLightfv(GL_LIGHT1, GL_AMBIENT, ELightAmbient);  // add lighting. (ambient)
  glLightfv(GL_LIGHT1, GL_DIFFUSE, ELightDiffuse);  // add lighting. (diffuse).
  glLightfv(GL_LIGHT1, GL_POSITION,ELightPosition); // set light position.
  glLightfv(GL_LIGHT1, GL_SPECULAR, Elight0_specular);
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  glEnable(GL_LIGHT1);                             // turn light 1 on.

  /* read environment */
  glGetDoublev( GL_PROJECTION_MATRIX, proj );
  glGetDoublev( GL_MODELVIEW_MATRIX, modl );
  glGetIntegerv( GL_VIEWPORT, viewport );
  matrix_valid = true;

  /* draw phase 0 (background) to 1 (main layer, earth globe) */
  int listsize = goc->getListSize();
  for(int phase=0; phase<2; phase++) {
    for(unsigned int nr=0; nr<listsize; nr++) {
      Draw *td = goc->getListElement(nr);
      td->draw(&nav.viewer, viewCulling, this, nav.direction, phase);
    }
  }

  if (grabDepthBuffer) {
    /* read depth buffer */
    if (!depthbuffer) {
      depthWidth = size().width();
      depthHeight = size().height();
      depthbuffer = new float[depthWidth*depthHeight];
    }
    else {
      if (size().width()!=depthWidth || size().height()!=depthHeight) {
      delete[](depthbuffer);
      depthWidth = size().width();
      depthHeight = size().height();
      depthbuffer = new float[depthWidth*depthHeight];
      }
    }
    glReadPixels(0,0,depthWidth, depthHeight, GL_DEPTH_COMPONENT, GL_FLOAT, depthbuffer);
  }

  glGetFloatv(GL_DEPTH_RANGE, clippingPlanes);

  /* draw phase 2 (sky/sign/object layer) */
  for(unsigned int nr=0; nr<listsize; nr++) {
    Draw *td = goc->getListElement(nr);
    td->draw(&nav.viewer, viewCulling, this, nav.direction, 2);
  }

  /* draw phase 3 (head up layer, no perspective transformation) */
  /* change projection matrix */
  glClear(GL_DEPTH_BUFFER_BIT);     // Clear The Screen And The Depth Buffer
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  gluOrtho2D(-1,1,-1,1);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  listsize = goc->getListSize();
  for(unsigned int nr=0; nr<listsize; nr++) {
    Draw *td = goc->getListElement(nr);
    td->draw(&nav.viewer, viewCulling, this, nav.direction, 3);
  }
  
//   printf("time: %i\n", glutGet(GLUT_ELAPSED_TIME)-time); 
}

void GLTestWidget::paintGL() {
#ifdef WIN32
  initGLARB();
#endif

  drawFinished = true;
  if (!rendering.tryLock()) return;

#ifdef DAVE
  if (!daveinit) {
    daveinit = true;
    dave->initOpenGL(false);   // color correction
  }

  davedata *dd = (davedata *) dave->getSyncBuffer();
  nav.viewer = dd->viewer;
  nav.direction = dd->direction;
  nav.up = dd->up;
  rtri = dd->rtri;

  dave->setProjectionGL(true);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  render(); 
  
  dave->setProjectionGL(false);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  render(); 
  
  dave->synchronize();

  swapBuffers();
#else
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();
  //   printf("****** ASPECT: %f\n", aspect);

  float nearplane = nav.viewer.length()-1.3;
  if (nearplane<0.00001f) nearplane=0.00001f;
  float farplane = 20.f;
  if (nearplane<1.5) farplane = 10;

#ifdef WIN32_ZBUFFER_BUG
  nearplane = nav.viewer.length()-1.0001;
  if (nearplane<0.00001f) nearplane=0.00001f;
  if (nearplane<1.3) farplane = 2;
#endif
//   if (nav.viewer.length()<1.1) farplane = 0.5;
  if (nav.viewer.length()<1.1) farplane = 1.5;
  gluPerspective(45.0f,aspect,nearplane,farplane);
  //   gluPerspective(45.0f,aspect,0.01f,10.0f);
  Point3D viewpoint = nav.direction + nav.viewer;
  gluLookAt(nav.viewer.x, nav.viewer.y, nav.viewer.z, viewpoint.x, viewpoint.y, viewpoint.z, nav.up.x, nav.up.y, nav.up.z);
  //  glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
  
  render();

  swapBuffers();
#endif

  /** If the form wants to, it can render it into a movie */
  frameFinished();

  rendered.wakeAll();
  rendering.unlock();
}

void GLTestWidget::resizeGL(int width, int height) {
  QGLWidget::resizeGL(width, height);

  glViewport(0, 0, width, height);
  glEnable(GL_DEPTH_TEST);
  aspect=float(width)/float(height);
//   glDraw();
}

void GLTestWidget::initializeGL() {
  QGLWidget::initializeGL();

#ifdef WIN32
  initGLARB();
#endif

  printf("START THREAD\n");
  if (!threadStarted) {
    threadStarted = true;

    QTimer *t = new QTimer( this );
    connect(t, SIGNAL(timeout()), SLOT(navtimer()));
    t->start(0, FALSE);
  }
}

void GLTestWidget::mouseMoveEvent(QMouseEvent * e) {
//   std::cout << "mouseMove" << e->x() << std::endl;
  QMutexLocker qml(&navMutex);

  if (!depthbuffer) return;

#ifdef WIN32
//   assert(mousepressed);
#endif

  if (e->state() & Qt::LeftButton && old_valid) {
    if (flyMode) {
      int omx = mx, omy = my;

      mx = e->x();
      my = e->y();
      
      /* rotate around x */
//       nav.rotate(-(mx-omx)/10.);
// //       float matrix[16];
// //       Quaternion quat;
// //       quat.createFromAxisAngle(nav.up.x, nav.up.y, nav.up.z, (mx-omx)/10.);
// //       quat.createMatrix(matrix);
// //       nav.setDirection(Matrix::multvector(matrix, nav.direction));
// //       nav.up = Matrix::multvector(matrix, nav.up);      

//       /* rotate around y */
//       nav.elevate((my-omy)/10.);
// //       Point3D axis = nav.direction.crossproduct(nav.up);
// //       quat.createFromAxisAngle(axis.x, axis.y, axis.z, (my-omy)/10.);
// //       quat.createMatrix(matrix);
// //       nav.setDirection(Matrix::multvector(matrix, nav.direction));
// //       nav.up = Matrix::multvector(matrix, nav.up);
      roll -= (mx-omx)/30.;
      pitch += (my-omy)/30.;
//       Point3D planerotate = Point3D(pitch+90, 0, roll+180);

    }
    else { // rotate mode
      //     rtri += e->x()-mx;
      //     rtry += e->y()-my;
      float projplane = 0.3;
      int dy = (size().height()-my);
      if (dy<0) dy=0;
      if (dy>=depthHeight) dy=depthHeight-1;
      if (mx>=depthWidth) mx=depthWidth-1;

      float depth1 = depthbuffer[dy*depthWidth+mx];

      float omx = mx, omy = my;

      mx = e->x();
      my = e->y();

      dy = (size().height()-my);
      if (dy<0) dy=0;
      if (dy>=depthHeight) dy=depthHeight-1;
      if (mx>=depthWidth) mx=depthWidth-1;

      /* get mouse position on screen */
      double sdx, sdy, sdz;
      float depth2 = depthbuffer[dy*depthWidth+mx];

#ifdef DEBUG
      printf("clip: %f %f depth: %f %f\n", clippingPlanes[0], clippingPlanes[1], depth1, depth2);
#endif
      if (depth1>=clippingPlanes[1]) {
      depth1 = depth2;
      }
      if (depth2>=clippingPlanes[1]) {
      depth2 = depth1;
      }
      if (depth1>=clippingPlanes[1] || depth2>=clippingPlanes[1]) {
      depth1 = 0.2;
      depth2 = 0.2;
      }
      gluUnProject(omx, size().height()-omy, depth1, modl, proj, viewport, &old_sdx, &old_sdy, &old_sdz);

      //     gluUnProject(mx, size().height()-my, projplane, modl, proj, viewport, &sdx, &sdy, &sdz);
      gluUnProject(mx, size().height()-my, depth2, modl, proj, viewport, &sdx, &sdy, &sdz);

      Point3D oldmouse(old_sdx, old_sdy, old_sdz);
      Point3D newmouse(sdx, sdy, sdz);

      Point3D vector = newmouse-oldmouse;
      //     float len = sqrt((omx-mx)*(omx-mx)+(omy-my)*(omy-my))*1./(2*M_PI*oldmouse.length());
      float len = (vector.length()*360./(2*M_PI*oldmouse.length()));
      Point3D norm_oldmouse = oldmouse.normalize();
      Point3D norm_newmouse = newmouse.normalize();

#ifdef DEBUG
      printf("depth1: %f depth2: %f\n", depth1, depth2);
#endif

      float angle = acos(norm_oldmouse.skalarprodukt(norm_newmouse));
      vector = vector.normalize();
      Point3D axis = norm_oldmouse.crossproduct(norm_newmouse);
      axis = axis.normalize();
    
      //     axis = Point3D(0,1,0);
      float matrix[16];
      Quaternion quat;
#ifdef DEBUG
      printf("angle: %f\n", angle);
#endif
      quat.createFromAxisAngle(axis.x, axis.y, axis.z, len);
      quat.createMatrix(matrix);

      nav.stopAutoNavigation();

      setViewer(Matrix::multvector(matrix, nav.viewer));

      nav.setDirection(Matrix::multvector(matrix, nav.direction));
      nav.up = Matrix::multvector(matrix, nav.up);

#ifdef DEBUG
      printf("viewer: %f, %f, %f, %f\n", nav.viewer.x, nav.viewer.y, nav.viewer.z, nav.viewer.length());
#endif

      old_sdx = sdx;
      old_sdy = sdy;
      old_sdz = sdz;

      updateScreen();
    }
  }
  else {
    if (e->state() & Qt::MidButton) {
      int omx = mx, omy = my;

      mx = e->x();
      my = e->y();
      
      /* rotate around */
      nav.rotateOnSurface(mx-omx);
      nav.elevate(omy-my);

      updateScreen();
    }
  }

  if (!old_valid) {
    if (matrix_valid) {
      gluUnProject(size().width()-mx, my, 0, modl, proj, viewport, &old_sdx, &old_sdy, &old_sdz);
      old_valid = true;
    }
  }
}

void GLTestWidget::mousePressEvent ( QMouseEvent * e ) {
  mx = e->x();
  my = e->y();
  old_valid = false;

#ifdef WIN32
  mousepressed = true;
#endif

  if (matrix_valid) {
    gluUnProject(size().width()-mx, my, 0, modl, proj, viewport, &old_sdx, &old_sdy, &old_sdz);
    old_valid = true;
  }

  grabDepthBuffer = true;
}

void GLTestWidget::mouseReleaseEvent ( QMouseEvent * e ) {
  //  grabDepthBuffer = false;
  old_valid = false;

#ifdef WIN32
  mousepressed=false;
#endif
}

void GLTestWidget::contextMenuEvent ( QContextMenuEvent * e ) {
  QPopupMenu *contextMenu = new QPopupMenu( this );
  Q_CHECK_PTR( contextMenu );
  contextMenu->insertItem( "&Texture",  this, SLOT(viewTextureSlot()) );
  contextMenu->insertItem( "&Screenshot", this, SLOT(screenshotSlot()), Qt::CTRL+Qt::Key_S );
  contextMenu->insertItem( "&GPS coordinates", this, SLOT(gpsCoordinatesSlot()) );
  contextMenu->insertItem( "&Show marker", this, SLOT(showMarkerSlot()) );
  if (agentPopupList.size()>0 || 1) {
    contextMenu->insertSeparator();
//     QPopupMenu *agentMenu = new QPopupMenu(contextMenu);
    int agentId = 0;
    QValueVector<ListViewServiceItem *>::iterator it;
    for(it = agentPopupList.begin(); it != agentPopupList.end(); it++) {
      contextMenu->insertItem((*it)->text(0), (agentId++));
    }
    connect(contextMenu, SIGNAL(activated(int)), this, SLOT(agentPopupSlot(int)));
//     contextMenu->insertItem("&Agents", agentMenu);
  }

  contextPos = mapFromGlobal(QCursor::pos());
  int result = contextMenu->exec( QCursor::pos() );

  delete(contextMenu);
}

void GLTestWidget::agentPopupClicked(ListViewServiceItem *item, Point2D worldcoord) {
  double x= worldcoord.x*360.-180.;
  double y =-(worldcoord.y*180.-90.);

  QMap<QString, QString> propertiesMap;
  propertiesMap["longitude"] = QString().setNum(x);
  propertiesMap["latitude"] = QString().setNum(y);

  formview->loadFunction(item, propertiesMap);
}

void GLTestWidget::setGraphicsObjectsContainer(GraphicsObjectsContainer *goc) {
  this->goc = goc;
}

void GLTestWidget::setViewer(Point3D p) {
  nav.setViewer(p);
}

void GLTestWidget::setViewCulling(bool state) {
  viewCulling = state;
}

void GLTestWidget::keyPressEvent (QKeyEvent * e) {
  printf("pressed key\n");
  if (e->key()==Qt::Key_A) {
    nav.accelerate(0.01);
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_Z || e->key()==Qt::Key_Y) {
    nav.accelerate(-0.01);
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_Right) {
    nav.rotate(-5);
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_Left) {
    nav.rotate(5);
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_Up) {
    nav.elevate(-5);
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_Down) {
    nav.elevate(5);
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_C) {
    nav.rotateLeftRight(5);
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_X) {
    nav.rotateLeftRight(-5);
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_S) {
    nav.stop();
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_F) {
    if (fullscreen) {
      setFullscreen(false);
    }
    else {
      setFullscreen(true);
    }
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_Prior) {
    nav.elevateUp(5);
    updateScreen();
    return;
  }
  if (e->key()==Qt::Key_Next) {
    nav.elevateUp(-5);
    updateScreen();
    return;
  }

  e->ignore();
}

void GLTestWidget::setFullscreen(bool fullscreen) {
  this->fullscreen = fullscreen;
  if (fullscreen) {
    oldparent = parentWidget();
    oldflags = getWFlags();
    oldpos = pos();
    reparent(NULL, Qt::WType_TopLevel, QPoint(0, 0), true);
    showFullScreen();
  }
  else {
    reparent(oldparent, oldflags, oldpos, true);
    showNormal();
  }
}

void GLTestWidget::keyReleaseEvent (QKeyEvent * e) {
}

void GLTestWidget::navtimer() {
  navMutex.lock();
  navtime_nowtime = QTime::currentTime();
  float step;
  if (frameByFrame) {
    step = 1;
  }
  else {
    step = navtime_ctime.msecsTo(navtime_nowtime)/100.;
    if (step>10) step=10;
  }
  nav.step(step/10);

  if (flyMode) {
    // gravitation
    Point3D axis = nav.viewer.crossproduct(nav.direction).normalize();
    float matrix[16];
    Quaternion quat;
    quat.createFromAxisAngle(axis.x, axis.y, axis.z, -1);
    quat.createMatrix(matrix);
    nav.setDirection(Matrix::multvector(matrix, nav.direction));
    nav.up = Matrix::multvector(matrix, nav.up);

//     nav.setViewer(nav.viewer-(nav.viewer.normalize()/6000.));
//     if (nav.viewer.length()<1) nav.viewer = nav.viewer.normalize();
    /* rotate around x */
    nav.rotate(roll);
//     float matrix[16];
//     Quaternion quat;
//     quat.createFromAxisAngle(nav.up.x, nav.up.y, nav.up.z, (mx-omx)/10.);
//     quat.createMatrix(matrix);
//     nav.setDirection(Matrix::multvector(matrix, nav.direction));
//     nav.up = Matrix::multvector(matrix, nav.up);      
    
    /* rotate around y */
    nav.elevate(pitch);
//     Point3D axis = nav.direction.crossproduct(nav.up);
//     quat.createFromAxisAngle(axis.x, axis.y, axis.z, (my-omy)/10.);
//     quat.createMatrix(matrix);
//     nav.setDirection(Matrix::multvector(matrix, nav.direction));
//     nav.up = Matrix::multvector(matrix, nav.up);
  }

  navMutex.unlock();

  //    repaint();
#ifdef DAVE
  if(dave->isServer()) { 
    Point3D mousedir;
    while(!dave->isStopped()) { 
      printf("Hallo\n");

      davedata *dd = (davedata *) dave->getSyncBuffer();
      switch(dave->getMouseButton()) {
      case 1:
      dd->rtri += 10;
      break;
      case 3:
      // move forward
      mousedir.x = dave->getMouseZ().x/3.;
      mousedir.y = dave->getMouseZ().y/3.;
      mousedir.z = dave->getMouseZ().z/3.;
      nav.setViewer(nav.getViewer()+mousedir);
      break;
      case 2:
      dd->rtri += 350;
      break;
      }
      dd->rtri = dd->rtri % 360;
      dd->viewer = nav.viewer;
      dd->direction = nav.direction;
      dd->up = nav.up;

      dave->synchronize(); 
    }
  }
  else {
    updateScreen();
  }
#else

#ifdef LINUX
#ifdef JOYSTICK
  checkJoystick();
#endif
#endif

  /** continuous redraw while moving */
  if (nav.speed || needRedraw) {
    needRedraw = false;
    //       rendering.lock();
    drawFinished = false;
    updateScreen();
#ifdef WIN32
    // due to some reason windows needs *both* commands to redraw
    //       updateGL();
#endif
    //       rendering.unlock();
    //      if (!drawFinished) rendered.wait();
  }
  else {
    usleep(10000);
  }
#endif

  navtime_ctime = navtime_nowtime;
}

#ifdef LINUX
#ifdef JOYSTICK
void GLTestWidget::checkJoystick() {
  /* Fetch for event, JSUpdate() will return JSGotEvent
   * if we got an event.
   */
  if(JSUpdate(&jsd) == JSGotEvent) {
    /** we do not need an event since an event signals a change
     *  but we also want to move if there is no change,
     *  i.e. when the user pushes the joystick or spacemouse constantly
     *  forward
     */
  }
  if (jsd.total_axises>0) { // move left/right
    float axis = JSGetAxisCoeffNZ(&jsd, 0);
    if (fabs(axis)>0.1) {
      nav.strafeOnSurface(axis*0.03);
      needRedraw = true;
    }
  }
  if (jsd.total_axises>2) { // move forward/backward
    float axis = JSGetAxisCoeffNZ(&jsd, 2);
    if (fabs(axis)>0.1) {
      nav.forwardOnSurface(-axis*0.03);
      needRedraw = true;
    }
  }
  if (jsd.total_axises>1) { // move up/down
    float axis = JSGetAxisCoeffNZ(&jsd, 1);
    if (fabs(axis)>0.1) {
      nav.strafeUpDown(-axis*1.);
      needRedraw = true;
    }
  }
  if (jsd.total_axises>4) { // rotate left/right
    float axis = JSGetAxisCoeffNZ(&jsd, 4);
    if (fabs(axis)>0.1) {
      nav.rotateOnSurface(-axis*1.);
      needRedraw = true;
    }
  }
  if (jsd.total_axises>3) { // rotate up/down
    float axis = JSGetAxisCoeffNZ(&jsd, 3);
    if (fabs(axis)>0.1) {
      nav.elevate(-axis*1.);
      needRedraw = true;
    }
  }
  if (jsd.total_axises>5) { // roll
    float axis = JSGetAxisCoeffNZ(&jsd, 5);
    if (fabs(axis)>0.1) {
      nav.rotate(-axis*0.3);
      needRedraw = true;
    }
  }
}
#endif
#endif


void GLTestWidget::run() {
  printf("RUN\n");
  do {
//     usleep(40000);
    /* navigate and redraw */
    navtimer();
//    printf("thread\n");
  } while(true);
}

void GLTestWidget::setNavigation(bool rotate) {
  navRotate = rotate;
}

void GLTestWidget::updateScreen() {
#ifdef LINUX
  update();
#else
  updateGL();
#endif
}

void GLTestWidget::screenshotSlot(QString filename) {
  alwaysBind = true;
  /*   QPixmap pixmap = gLMainWidget->renderPixmap(0, 0, FALSE); */
  /*   pixmap.save("screenshot.png", "PNG"); */
  QImage image = grabFrameBuffer();
  bool result=image.save(filename, "PNG");
//   printf("Screenshot save result=%i\n", result);

  alwaysBind = false;
}

Point2D GLTestWidget::getWorldCoordinates(int mx, int my) {
  /* get map coordinates */
  float projplane = 0.3;
  int dy = (size().height()-my);
  if (dy<0) dy=0;
  if (dy>=depthHeight) dy=depthHeight-1;
  if (mx>=depthWidth) mx=depthWidth-1;

  float depth1 = depthbuffer[dy*depthWidth+mx];
  double sdx, sdy, sdz;
  gluUnProject(mx, size().height()-my, depth1, modl, proj, viewport, &sdx, &sdy, &sdz);

  Point2D mappos = sphere.inverse(Point3D(sdx, sdy, sdz));

  /* get texture at coordinates */
  printf("coordinates: %f %f %f / %f %f\n", sdx, sdy, sdz, mappos.x, mappos.y);

  return(mappos);
}

void GLTestWidget::viewTextureSlot() {
  /* get texture at position contextPos */
  Point2D worldcoord = getWorldCoordinates(contextPos.x(), contextPos.y());

  /* find first treeDrawSphere object */
  TreeDrawSphere *sphere = NULL;

  int listsize = goc->getListSize();
  for(unsigned int nr=0; nr<listsize; nr++) {
    Draw *td = goc->getListElement(nr);
    if (strcmp(td->getType(), "sphere")==0) {
      sphere = (TreeDrawSphere *) td;
    }
  }

  if (sphere) {
    /* get texture at coordinates */
    QImage image = sphere->getTextureAtCoordinates(worldcoord.x, worldcoord.y);

    /* view window with texture */
    QLabel *widget = new QLabel(NULL);
    widget->setCaption("Texture");
    widget->setPixmap(QPixmap(image));
    widget->show();
  }
}

void GLTestWidget::gpsCoordinatesSlot() {
  /* view gps coordinates */
  Point2D worldcoord = getWorldCoordinates(contextPos.x(), contextPos.y());

  if (formview) {
    formview->statusBar()->message("GPS coordinates: "+QString::number(worldcoord.x*360-180)+" "+QString::number(-(worldcoord.y*180-90)));
  }
}

void GLTestWidget::showMarkerSlot() {
  /* show an XML marker of the current position and copy it to the clipboard */
  if (formview) {
    Point2D v = getCurrentCoordinates();
    double x = v.x;
    double y = v.y;
    double z = nav.getViewer().length();
    Point3D dir = nav.getDirection();
    dir = nav.getEarthIntersection(dir, nav.getViewer());
    Point3D up = nav.getUp();
    
    QString msg = QString().sprintf("<mark name=\"noname\" x=\"%f\" y=\"%f\" z=\"%f\" dirx=\"%f\" diry=\"%f\" dirz=\"%f\" upx=\"%f\" upy=\"%f\" upz=\"%f\" />", x, y, z, dir.x, dir.y, dir.z, up.x, up.y, up.z);
    formview->statusBar()->message(msg);
    QApplication::clipboard()->setText(msg);
  }
}

void GLTestWidget::setFormView(FormView *formview) {
  this->formview = formview;
}

Navigator *GLTestWidget::getNavigator() {
  return(&nav);
}

void GLTestWidget::generateFonts() {
  printf("==> Generate Fonts\n");

  QFont font;
  font.setPointSize(POIFONTSIZE);
  renderText(0,0,0,"Hallo", font);
}

void GLTestWidget::wheelEvent( QWheelEvent * e ) {
  float distance = float(e->delta()/float(120));
  distance /= 20;
  nav.forward(distance);
  updateScreen();
}

void GLTestWidget::moveToPosition(Point3D mark, Point3D dir, Point3D up, bool lowerquality) {
  nav.moveToPosition(mark, dir, up, lowerquality);
}

Point2D GLTestWidget::getCurrentCoordinates() {
  return(sphere.inverse(nav.getViewer()));
}

void GLTestWidget::mouseDoubleClickEvent(QMouseEvent *e) {
  bool done = false;
  int listsize = goc->getListSize();
  for(unsigned int nr=0; nr<listsize; nr++) {
    Draw *td = goc->getListElement(nr);
    done = td->mouseDoubleClickEvent(&nav.viewer, viewCulling, this, nav.direction, e);
    if (done) break;
  }

  if (!done) {
    /* zoom to selected point */

    if (matrix_valid) {
      Point2D newcoordinates = getWorldCoordinates(e->x(), e->y());
      Point3D newcoordinates3D = sphere.getPoint(newcoordinates, 1.);

      Point2D currentcoordinates = getCurrentCoordinates();
      Point2D destcoordinates = newcoordinates/*+currentcoordinates)*//*2.*/;

      moveToPosition(Point3D(destcoordinates.x, destcoordinates.y, (nav.getViewer().length()-1)/2+1), Point3D(0,0,0), nav.getUp(), false);
    }
  }
}

void GLTestWidget::addAgentPopupEntry(QString text, ListViewServiceItem *item) {
  agentPopupList.push_back(item);
}

void GLTestWidget::agentPopupSlot(int agentSelected) {
  Point2D worldcoord = getWorldCoordinates(contextPos.x(), contextPos.y());

  printf("agentSelected = %i\n", agentSelected);
  QValueVector<ListViewServiceItem *>::iterator it;
  int agentId = 0;
  for(it = agentPopupList.begin(); it != agentPopupList.end(); it++) {
    if (agentId == agentSelected) {
      agentPopupClicked(*it, worldcoord);
      break;
    }
    agentId++;
  }
}

Generated by  Doxygen 1.6.0   Back to index