Ejemplo n.º 1
0
bool Viewer::on_motion_notify_event(GdkEventMotion* event)
{
  DEBUG_MSG("Stub: Motion at " << event->x << ", " << event->y );

  Point2D dMouse(event->x - m_lastMouse[0], event->y - m_lastMouse[1]);

  bool b1,b2,b3;
  b1 = event->state & GDK_BUTTON1_MASK;
  b2 = event->state & GDK_BUTTON2_MASK;
  b3 = event->state & GDK_BUTTON3_MASK;

  //track ball mode
  if (m_mode == POSITION) {
    // do x,y translation
    if (b1) {

      double translationScale = 50.0;

      Vector3D translate(dMouse[0] / translationScale, -dMouse[1] / translationScale , 0);

      Matrix4x4 t = translation(translate);
      m_trackballTranslation = m_trackballTranslation * t;

    }

    if (b2) {

      Vector3D translate(0.0, 0.0, dMouse[1]/ 35.0);

      Matrix4x4 t = translation(translate);
      m_trackballTranslation = m_trackballTranslation * t;
    }

    if (b3) {
      /*
       * Track ball rotations are being used.
       */
     
          float fDiameter;
          int iCenterX, iCenterY;
          float fNewModX, fNewModY, fOldModX, fOldModY;
    
          /* vCalcRotVec expects new and old positions in relation to the center of the
           * trackball circle which is centered in the middle of the window and
           * half the smaller of nWinWidth or nWinHeight.
           */
          fDiameter = (get_width() < get_height()) ? (float)get_width() * 0.5f : (float)get_height() * 0.5f;
          iCenterX = get_width() / 2;
          iCenterY = get_height() / 2;


          fOldModX = m_lastMouse[0] - iCenterX;
          fOldModY = m_lastMouse[1] - iCenterY;
          fNewModX = event->x - iCenterX;
          fNewModY = event->y - iCenterY;


      float  fRotVecX, fRotVecY, fRotVecZ;

          vCalcRotVec(fNewModX, fNewModY,
                          fOldModX, fOldModY,
                          fDiameter,
                          &fRotVecX, &fRotVecY, &fRotVecZ);
          /* Negate Y component since Y axis increases downwards
           * in screen space and upwards in OpenGL.
           */
          Matrix4x4 mNewMat = vAxisRotMatrix(fRotVecX, -fRotVecY, fRotVecZ);

          // Since all these matrices are meant to be loaded
          // into the OpenGL matrix stack, we need to transpose the
          // rotation matrix (since OpenGL wants rows stored
          // in columns)

          //vTransposeMatrix(mNewMat);
          //vRightMultiply(mRotations, mNewMat);

          m_trackballRotation = m_trackballRotation * mNewMat;
      }
    


    DEBUG_MSG("trackballMatrix: Translation\n" << m_trackballTranslation <<
      "Rotation\n" << m_trackballRotation);
  }
  else {
    // JOINT manipulation mode

    // rotate head up down relative to y when b2
    // rotate head left right with x motion when b3

    // grab all selected nodes
    // grab their parents
    // rotate their joint left/right, up/down

     for (std::list<SceneNode*>::const_iterator it = m_selected.begin(), end = m_selected.end(); it != end; ++it) {
     
      assert((*it)->is_selected());
      
      SceneNode *parent = (*it)->jointParent();

      // check if parent is joint node
      
      DEBUG_MSG("Rotating: " << (*it)->name());
      assert(parent);
      DEBUG_MSG("Parent: name " << parent->name());
      assert(parent->is_joint());
      JointNode *joint = dynamic_cast<JointNode*>(parent);
      assert(joint);

      double rotationScale = -3.0;
      
      if (b2) {
        // rotate in degrees
        joint->rotate( dMouse[1] / rotationScale, 0.0);
      }

      if (b3) {
        joint->rotate(0.0, dMouse[0] / rotationScale);
      }


    }

  }

  m_lastMouse = Point2D(event->x, event->y);

  invalidate();
  return true;
}