Esempio n. 1
0
static void simulate_trackball(quat *q, GLfloat p1x, GLfloat p1y, GLfloat p2x, GLfloat p2y) {
  if (p1x == p2x && p1y == p2y) { 
    quat_identity(q);
  }
  else {
    quat p1, p2, a, d;
    float p1z, p2z;
    float s, t;
    
    p1z = project_to_sphere(p1x, p1y);
    quat_assign(&p1, 0.0, p1x, p1y, p1z);
    
    p2z = project_to_sphere(p2x, p2y);
    quat_assign(&p2, 0.0, p2x, p2y, p2z);
		
    quat_mul(&a, &p1, &p2);
    
    a.w = 0.0;
    s = quat_norm(&a);
    quat_div_real(&a, &a, s);
    
    quat_sub(&d, &p1, &p2);
    t = quat_norm(&d) / (2.0 * R * ROOT_2_INV);
    if (t > 1.0) t = 1.0;
    quat_assign(q, cos(asin(t)), a.x * t, a.y * t, a.z * t);
  }
}
Esempio n. 2
0
void trackball::
rotate(double fx, double fy, double tx, double ty) {
    scm::math::vec3d start(fx, fy, project_to_sphere(fx, fy));
    scm::math::vec3d end(tx, ty, project_to_sphere(tx, ty));

    scm::math::vec3d diff(end - start);
    double diff_len = scm::math::length(diff);

    scm::math::vec3d rot_axis(cross(start, end));

    double rot_angle = 2.0 * asin(scm::math::clamp(diff_len/(2.0 * radius_), -1.0, 1.0));

    scm::math::mat4d tmp(scm::math::mat4d::identity());

    scm::math::mat4d tmp_dolly(scm::math::mat4d::identity());
    scm::math::mat4d tmp_dolly_inv(scm::math::mat4d::identity());
    scm::math::translate(tmp_dolly, 0.0, 0.0, dolly_);
    scm::math::translate(tmp_dolly_inv, 0.0, 0.0, -dolly_);

    scm::math::rotate(tmp, scm::math::rad2deg(rot_angle), rot_axis);

    transform_ = tmp_dolly * tmp * tmp_dolly_inv * transform_;
}