示例#1
0
/*
 * Ok, simulate a track-ball.  Project the points onto the virtual
 * trackball, then figure out the axis of rotation, which is the cross
 * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
 * Note:  This is a deformed trackball-- is a trackball in the center,
 * but is deformed into a hyperbolic sheet of rotation away from the
 * center.  This particular function was chosen after trying out
 * several variations.
 *
 * It is assumed that the arguments to this routine are in the range
 * (-1.0 ... 1.0)
 */
void
trackball(float q[4], float p1x, float p1y, float p2x, float p2y)
{
    float a[3]; /* Axis of rotation */
    float phi;  /* how much to rotate about axis */
    float p1[3], p2[3], d[3];
    float t;

    if (p1x == p2x && p1y == p2y) {
        /* Zero rotation */
        vzero(q);
        q[3] = 1.0;
        return;
    }

    /*
     * First, figure out z-coordinates for projection of P1 and P2 to
     * deformed sphere
     */
    vset(p1, p1x, p1y, tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y));
    vset(p2, p2x, p2y, tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y));

    /*
     *  Now, we want the cross product of P1 and P2
     */
    vcross(p2,p1,a);

    /*
     *  Figure out how much to rotate around that axis.
     */
    vsub(p1, p2, d);
    t = vlength(d) / (2.0f*TRACKBALLSIZE);

    /*
     * Avoid problems with out-of-control values...
     */
    if (t > 1.0) t = 1.0;
    if (t < -1.0) t = -1.0;
    phi = 2.0f * (float) asin(t);

    axis_to_quat(a,phi,q);
}
示例#2
0
/*
 * Ok, simulate a track-ball.  Project the points onto the virtual
 * trackball, then figure out the axis of rotation, which is the cross
 * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
 * Note:  This is a deformed trackball-- is a trackball in the center,
 * but is deformed into a hyperbolic sheet of rotation away from the
 * center.  This particular function was chosen after trying out
 * several variations.
 *
 * It is assumed that the arguments to this routine are in the range
 * (-1.0 ... 1.0)
 */
quat & trackball(quat& q, vec2& pt1, vec2& pt2, nv_scalar trackballsize)
{
    vec3 a; // Axis of rotation
    nv_scalar phi;  // how much to rotate about axis
    vec3 d;
    nv_scalar t;

    if (pt1.x == pt2.x && pt1.y == pt2.y) 
    {
        // Zero rotation
        q = quat_id;
        return q;
    }

    // First, figure out z-coordinates for projection of P1 and P2 to
    // deformed sphere
    vec3 p1(pt1.x,pt1.y,tb_project_to_sphere(trackballsize,pt1.x,pt1.y));
    vec3 p2(pt2.x,pt2.y,tb_project_to_sphere(trackballsize,pt2.x,pt2.y));

    //  Now, we want the cross product of P1 and P2
    cross(a,p1,p2);

    //  Figure out how much to rotate around that axis.
    d.x = p1.x - p2.x;
    d.y = p1.y - p2.y;
    d.z = p1.z - p2.z;
    t = _sqrt(d.x * d.x + d.y * d.y + d.z * d.z) / (trackballsize);

    // Avoid problems with out-of-control values...

    if (t > nv_one)
        t = nv_one;
    if (t < -nv_one) 
        t = -nv_one;
    phi = nv_two * nv_scalar(asin(t));
    axis_to_quat(q,a,phi);
    return q;
}
示例#3
0
void rotate(int by, float axis[3][3], int phi) {
    GLfloat m[4][4];
    float q[4] = {0};
    int i;
    for (i=0; i<4; i++) {
        q[i] = 0;
    }
    axis_to_quat(axis[by],RAD(phi), q);
    build_rotmatrix(m, q);
    
    for (i=0; i<3; i++) {
        if (i != by) {
            multiply(m, axis[i], axis[i]);
        }
    }
    
    for (i=0; i<NV; i++) {
        multiply(m, vertexes[i], vertexes[i]);
    }
    for (i=0; i<4; i++) {
        multiply(m, originalVertex[i], originalVertex[i]);
    }
}
示例#4
0
/* Ok, simulate a track-ball.  Project the points onto the virtual
 * trackball, then figure out the axis of rotation, which is the cross
 * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
 * Note:  This is a deformed trackball-- is a trackball in the center,
 * but is deformed into a hyperbolic sheet of rotation away from the
 * center.  This particular function was chosen after trying out
 * several variations.
 *
 * It is assumed that the arguments to this routine are in the range
 * (-1.0 ... 1.0)
 */
void trackball(double q[4], double p1x, double p1y, double p2x, double p2y){
   double axis[3];             /* Axis of rotation              */
   double phi;                 /* how much to rotate about axis */
   double p1[3], p2[3], d[3];
   double t;

   /* if zero rotation */
   if(p1x == p2x && p1y == p2y){
      vset(q, 0.0, 0.0, 0.0);
      q[3] = 1.0;
      return;
      }

   /* First, figure out z-coordinates for projection of P1 and P2 to  */
   /* the deformed sphere                                                 */
   p1[0] = p1x;
   p1[1] = p1y;
   p1[2] = tb_project_to_sphere(TRACKBALLSIZE, p1x, p1y);

   p2[0] = p2x;
   p2[1] = p2y;
   p2[2] = tb_project_to_sphere(TRACKBALLSIZE, p2x, p2y);

   /* Now, we want the cross product of P1 and P2     */
   vcross(axis, p2, p1);

   /* Figure out how much to rotate around that axis. */
   vsub(d, p1, p2);
   t = vlength(d)/(2.0*TRACKBALLSIZE);

   /* Avoid problems with out-of-control values.      */
   if(t >  1.0){ t =  1.0; }
   if(t < -1.0){ t = -1.0; }
   phi = 2.0 * asin(t);

   axis_to_quat(axis, phi, q);
   }
示例#5
0
/*
 * Ok, simulate a track-ball.  Project the points onto the virtual
 * trackball, then figure out the axis of rotation, which is the cross
 * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
 * Note:  This is a deformed trackball-- is a trackball in the center,
 * but is deformed into a hyperbolic sheet of rotation away from the
 * center.  This particular function was chosen after trying out
 * several variations.
 *
 * It is assumed that the arguments to this routine are in the range
 * (-1.0 ... 1.0)
 */
void trackball(float q[4], float p1x, float p1y, float p2x, float p2y,  float tbSize)
{
    float a[3];		// Axis of rotation
    float phi;		// how much to rotate about axis
    float p1[3], p2[3], d[3];
    float t;

    if( p1x == p2x && p1y == p2y ) {
        /* Zero rotation */
        vzero(q);
        q[3] = 1.0;
        return;
    }

    // First, figure out z-coordinates for projection of P1 and P2 to deformed sphere
    vset( p1, p1x, p1y, tb_project_to_sphere(tbSize, p1x, p1y) );
    vset( p2, p2x, p2y, tb_project_to_sphere(tbSize, p2x, p2y) );

    // Now, we want the cross product of P1 and P2
    vcross( p2, p1, a);

    // Figure out how much to rotate around that axis
    vsub( p1, p2, d);
    t = vlength(d) / ( 2.0f * tbSize );

    // Avoid problems with out-of-control values
    if (t > 1.0) {
		t = 1.0;
	}
    if (t < -1.0) {
		t = -1.0;
	}
    phi = 2.0f * (float)asin(t);

    axis_to_quat( a, phi, q );
}
示例#6
0
文件: rubik.cpp 项目: ZoeQIAN/rubik
Rubik::Rubik(Level lv,int sz){/*
	Up[0] = v[0];
	Up[1] = v[1];
	Up[2] = v[2];
	Up[3] = v[3];
	Down[0] = v[7];
	Down[1] = v[6];
	Down[2] = v[5];
	Down[3] = v[4];

	Front[0] = v[3];
	Front[1] = v[2];
	Front[2] = v[6];
	Front[3] = v[7];

	Back[0] = v[1];
	Back[1] = v[0];
	Back[2] = v[4];
	Back[3] = v[5];

	Left[0] = v[0];
	Left[1] = v[3];
	Left[2] = v[7];
	Left[3] = v[4];


	Right[0] = v[2];
	Right[1] = v[1];
	Right[2] = v[5];
	Right[3] = v[6];
*/

	p[0] = Vec3f(1.5*edge_length, -1.5*edge_length, 1.5*edge_length);
	p[1] = Vec3f(1.5*edge_length, 1.5*edge_length, 1.5*edge_length);
	p[2] = Vec3f(-1.5*edge_length, 1.5*edge_length, 1.5*edge_length);
	p[3] = Vec3f(-1.5*edge_length, -1.5*edge_length, 1.5*edge_length);

	for (int i = 0; i < 3; ++i)
		for (int j=0; j<3; ++j)
			for(int k=0; k<3; ++k){
				int p = k+j*3+i*3*3;
				blocks[p].pos = Vec3i(k,j,i);
				switch(i){
					case 0: blocks[p].sf.push_back(Surface(DOWN,DOWN,1));
					break;
					case 2: blocks[p].sf.push_back(Surface(UP,UP,2));
					break;
					default:
					break;
				}
				switch(j){
					case 0: blocks[p].sf.push_back(Surface(LEFT,LEFT,3));
					break;
					case 2: blocks[p].sf.push_back(Surface(RIGHT,RIGHT,4));
					break;
					default:
					break;
				}
				switch(k){
					case 0: blocks[p].sf.push_back(Surface(BACK,BACK,5));
					break;
					case 2: blocks[p].sf.push_back(Surface(FRONT,FRONT,6));
					break;
					default:
					break;
				}
			}
	shuffle(lv);
	std::cout << "Selected level is: " << lv << std::endl;
	angle=0;
	trackball(0,0,curPos);
	trackball(0,0,lastPos);
	//std::cout << curPos << std::endl;
	//std::cout << lastPos << std::endl;
	calRotation();
	//std::cout << axis[0] << "," << axis[1] << ","<< axis[2] << "," << angle<< std::endl;
	axis_to_quat(axis,angle,curquat);
	std::printf("curquat = %f %f %f %f\n", curquat[0], curquat[1], curquat[2], curquat[3]);
}
int tachyon_spaceball_update(sbHandle * bh, SceneHandle scene) {
  int tx, ty, tz, rx, ry, rz, buttons;
  float qq[4];
  float xx[3]={1.0, 0.0, 0.0};
  float yy[3]={0.0, 1.0, 0.0};
  float zz[3]={0.0, 0.0, 1.0};

  float m[4][4];
  float t[3];

  static float transdivisor = 5000.0;
  static float angdivisor = 20000.0;

  if (bh->sball == NULL)
    return -1;
 
  if (sball_getstatus(bh->sball, &tx, &ty, &tz, &rx, &ry, &rz, &buttons)) {
    /* negate rotations given by spaceball */
    rx = -rx;
    ry = -ry;
    rz = -rz;

    if (buttons) {
      if (buttons & SBALL_BUTTON_PICK) {
        bh->curtrans[0] = 0.0;
        bh->curtrans[1] = 0.0;
        bh->curtrans[2] = 0.0;
        trackball(bh->curquat, 0.0, 0.0, 0.0, 0.0);
        transdivisor = 5000.0;
        angdivisor = 20000.0; 
  
        bh->camviewvec = bh->orig_camviewvec;
        bh->camupvec = bh->orig_camupvec;
        bh->camcent = bh->orig_camcent;
      }

      if (buttons & SBALL_BUTTON_1) {
        transdivisor /= 1.2;
        angdivisor /= 1.2;
      }
      else if (buttons & SBALL_BUTTON_2) {
        transdivisor *= 1.2; 
        angdivisor *= 1.2;
      }

      if (buttons & SBALL_BUTTON_3)
        transdivisor /= 1.2;
      else if (buttons & SBALL_BUTTON_4)
        transdivisor *= 1.2; 

      if (buttons & SBALL_BUTTON_5) 
        angdivisor *= 1.2;
      else if (buttons & SBALL_BUTTON_6)
        angdivisor /= 1.2;


      if (buttons & SBALL_BUTTON_7) {
        return 1;  /* quit the fly through */
      }
    } /* end of button handling */
      
    t[0] = tx / transdivisor; 
    t[1] = ty / transdivisor;
    t[2] = tz / transdivisor;

    /* 
     * convert rotations and translations from the
     * spaceball's coordinate frame into the camera's frame.
     */
    bh->newtrans[0] = 
      t[0] * bh->orig_camrightvec.x +
      t[1] * bh->orig_camupvec.x +
      t[2] * bh->orig_camviewvec.x;

    bh->newtrans[1] = 
      t[0] * bh->orig_camrightvec.y +
      t[1] * bh->orig_camupvec.y +
      t[2] * bh->orig_camviewvec.y;

    bh->newtrans[2] = 
      t[0] * bh->orig_camrightvec.z +
      t[1] * bh->orig_camupvec.z +
      t[2] * bh->orig_camviewvec.z;

    /* 
     * rotate around camera's coordinate frame
     */ 
    xx[0] = bh->orig_camrightvec.x;
    xx[1] = bh->orig_camrightvec.y;
    xx[2] = bh->orig_camrightvec.z;

    yy[0] = bh->orig_camupvec.x;
    yy[1] = bh->orig_camupvec.y;
    yy[2] = bh->orig_camupvec.z;

    zz[0] = bh->orig_camviewvec.x;
    zz[1] = bh->orig_camviewvec.y;
    zz[2] = bh->orig_camviewvec.z;
 
    /* do rotations */ 
    axis_to_quat(xx, rx / angdivisor, bh->lastquat);

    axis_to_quat(yy, ry / angdivisor, qq);
    add_quats(qq, bh->lastquat, bh->lastquat);

    axis_to_quat(zz, rz / angdivisor, qq);
    add_quats(qq, bh->lastquat, bh->lastquat);

    add_quats(bh->lastquat, bh->curquat, bh->curquat);
  }
  else {
    usleep(5); /* if no movement then sleep for a tiny bit.. */
  }

  build_rotmatrix(m, bh->curquat);

  /*
   * translate along the new axes
   */
  t[0] = m[0][0] * bh->newtrans[0] + m[0][1] * bh->newtrans[1] + m[0][2] * bh->newtrans[2];
  t[1] = m[1][0] * bh->newtrans[0] + m[1][1] * bh->newtrans[1] + m[1][2] * bh->newtrans[2];
  t[2] = m[2][0] * bh->newtrans[0] + m[2][1] * bh->newtrans[1] + m[2][2] * bh->newtrans[2];

  bh->camcent.x += t[0];
  bh->camcent.y += t[1];
  bh->camcent.z += t[2];


  /*
   * rotate view system with spaceball
   */
  bh->camviewvec.x = m[0][0] * bh->orig_camviewvec.x + m[0][1] * bh->orig_camviewvec.y + m[0][2] * bh->orig_camviewvec.z;
  bh->camviewvec.y = m[1][0] * bh->orig_camviewvec.x + m[1][1] * bh->orig_camviewvec.y + m[1][2] * bh->orig_camviewvec.z;
  bh->camviewvec.z = m[2][0] * bh->orig_camviewvec.x + m[2][1] * bh->orig_camviewvec.y + m[2][2] * bh->orig_camviewvec.z;

  bh->camupvec.x = m[0][0] * bh->orig_camupvec.x + m[0][1] * bh->orig_camupvec.y + m[0][2] * bh->orig_camupvec.z;
  bh->camupvec.y = m[1][0] * bh->orig_camupvec.x + m[1][1] * bh->orig_camupvec.y + m[1][2] * bh->orig_camupvec.z;
  bh->camupvec.z = m[2][0] * bh->orig_camupvec.x + m[2][1] * bh->orig_camupvec.y + m[2][2] * bh->orig_camupvec.z;

  /*
   * update camera parameters before we render again
   */
  rt_camera_position(scene, bh->camcent, bh->camviewvec, bh->camupvec);

  return 0;
}
示例#8
0
void drawContext::eventHandler(int event, float x, float y)
{
  int width = _width, height = _height;
  if(_retina){ // x,y for retina are still the same as for non-retina
    width /= 2;
    height /= 2;
  }

  _current.set(_scale, _translate, _right, _left,
               _bottom, _top, width, height, x, y);
  double xx[3] = {1.,0.,0.};
  double yy[3] = {0.,1.,0.};
  double q[4];
  switch(event){
  case 0: // finger(s) press the screen
    // in this case x and y represent the start point
    _start.set(_scale, _translate, _right, _left,
               _bottom, _top, width, height, x, y);
    _previous.set(_scale, _translate, _right, _left,
                  _bottom, _top, width, height, x, y);
    break;
  case 1: // finger move (translate)
    // in this case x and y represent the current point
    _translate[0] += (_current.wnr[0] - _previous.wnr[0]);
    _translate[1] += (_current.wnr[1] - _previous.wnr[1]);
    _translate[2] = 0.;
    break;
  case 2: // fingers move (scale)
    // in this case we don't care about previous and current position, x
    // represent the scale
    _scale[0] = _scale[1] = _scale[2] = x;
    _start.recenter(_scale, _translate);
    break;
  case 3: // fingers move (rotate)
    addQuaternion((2. * _previous.win[0] - width) / width,
                  (height - 2. * _previous.win[1]) / height,
                  (2. * _current.win[0] - width) / width,
                  (height - 2. * _current.win[1]) / height);
    break;
  case 4: // release the finger(s)
    // Do nothing ?
    break;
  case 5: // X view
    axis_to_quat(xx, M_PI/2, q);
    setQuaternion(q[0], q[1], q[2], q[3]);
    break;
  case 6: // Y view
    axis_to_quat(yy, M_PI/2, q);
    setQuaternion(q[0], q[1], q[2], q[3]);
    break;
  case 7: // Z view
    setQuaternion(0., 0., 0., 1.);
    break;
  default: // all other reset the position
    setQuaternion(0., 0., 0., 1.);
    for(int i = 0; i < 3; i++){
      _translate[i] = 0.;
      _scale[i] = 1.;
    }
    break;
  }
  _previous.set(_scale, _translate, _right, _left,
                _bottom, _top, width, height, x, y);
}
示例#9
0
static gboolean
expose_event (GtkWidget      *widget,
	      GdkEventExpose *event,
	      gpointer        data)
{
  GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
  GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);

  float d_quat[4];
  float m[4][4];

  if (animate)
    {

      if (counter == rot_count)
	{
	  if (rot_mode[++mode].axis == NULL)
	    mode = 0;
	  counter = 0;
	}

      axis_to_quat (rot_mode[mode].axis,
		    rot_mode[mode].sign * G_PI_2 / rot_count,
		    d_quat);
      add_quats (d_quat, logo_quat, logo_quat);

      counter++;

    }

  /*** OpenGL BEGIN ***/
  if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
    return FALSE;

  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glLoadIdentity ();

  /* View transformation. */
  glTranslatef (0.0, 0.0, -30.0);
  glScalef (view_scale, view_scale, view_scale);
  build_rotmatrix (m, view_quat);
  glMultMatrixf (&m[0][0]);

  /* Logo model. */
  glPushMatrix ();
    build_rotmatrix (m, logo_quat);
    glMultMatrixf (&m[0][0]);

    glRotatef (90.0, 1.0, 0.0, 0.0);
    glCallList (LOGO_CUBE);
    glCallList (LOGO_G_FORWARD);
    glCallList (LOGO_G_BACKWARD);
    glCallList (LOGO_T_FORWARD);
    glCallList (LOGO_T_BACKWARD);
    glCallList (LOGO_K_FORWARD);
    glCallList (LOGO_K_BACKWARD);
  glPopMatrix ();

  /* Swap buffers. */
  if (gdk_gl_drawable_is_double_buffered (gldrawable))
    gdk_gl_drawable_swap_buffers (gldrawable);
  else
    glFlush ();

  gdk_gl_drawable_gl_end (gldrawable);
  /*** OpenGL END ***/

  return TRUE;
}