Difference between revisions of "Trackball.cpp"

From Immersive Visualization Lab Wiki
Jump to: navigation, search
(New page: <pre> /** Applies a rotation to a matrix according to a fictitious trackball, placed in the middle of the window. The trackball is approximated by a Gaussian curve. The trackba...)
 
 
Line 2: Line 2:
 
/** Applies a rotation to a matrix according to a fictitious trackball, placed in
 
/** Applies a rotation to a matrix according to a fictitious trackball, placed in
 
     the middle of the window.
 
     the middle of the window.
    The trackball is approximated by a Gaussian curve.
 
 
     The trackball coordinate system is: x=right, y=up, z=to viewer<BR>
 
     The trackball coordinate system is: x=right, y=up, z=to viewer<BR>
 
     The origin of the mouse coordinates zero (0,0) is considered to be top left.
 
     The origin of the mouse coordinates zero (0,0) is considered to be top left.
Line 20: Line 19:
  
 
   // Compute mouse coordinates in window and normalize to -1..1
 
   // Compute mouse coordinates in window and normalize to -1..1
   // ((0,0)=window center, (-1,-1) = bottom left, (1,1) = top right)
+
   // ((0,0) = window center, (-1,-1) = bottom left, (1,1) = top right)
   halfWidth   = (float)width  / 2.0;
+
   halfWidth = (float)width  / 2.0;
   halfHeight = (float)height / 2.0;
+
   halfHeight = (float)height / 2.0;
   smallSize   = (halfWidth < halfHeight) ? halfWidth : halfHeight;
+
   smallSize = (halfWidth < halfHeight) ? halfWidth : halfHeight;
   v1.x     = ((float)fromX - halfWidth)  / smallSize;
+
   v1.x   = ((float)fromX - halfWidth)  / smallSize;
   v1.y     = ((float)(height-fromY) - halfHeight) / smallSize;
+
   v1.y   = ((float)(height-fromY) - halfHeight) / smallSize;
   v2.x     = ((float)toX  - halfWidth)  / smallSize;
+
   v2.x   = ((float)toX  - halfWidth)  / smallSize;
   v2.y     = ((float)(height-toY)  - halfHeight) / smallSize;
+
   v2.y   = ((float)(height-toY)  - halfHeight) / smallSize;
  
   // Compute z-coordinates on Gaussian trackball:
+
   // Compute z-coordinates on trackball:
 
   d      = sqrtf(v1.x * v1.x + v1.y * v1.y);
 
   d      = sqrtf(v1.x * v1.x + v1.y * v1.y);
 
   v1.z    = expf(-TRACKBALL_SIZE * d * d);
 
   v1.z    = expf(-TRACKBALL_SIZE * d * d);
Line 48: Line 47:
 
   v2.normalize();                                // normalize v2 before rotation
 
   v2.normalize();                                // normalize v2 before rotation
  
   // Perform acutal model view matrix modification:
+
   // Perform matrix modification:
   return rotate(-angle, v2.x, v2.y, v2.z);     // rotate model view matrix
+
   return rotate(-angle, v2.x, v2.y, v2.z);
 
}
 
}
 
</pre>
 
</pre>

Latest revision as of 23:58, 28 October 2011

/** Applies a rotation to a matrix according to a fictitious trackball, placed in
    the middle of the window.
    The trackball coordinate system is: x=right, y=up, z=to viewer<BR>
    The origin of the mouse coordinates zero (0,0) is considered to be top left.
  @param width, height  window size in pixels
  @param fromX, fromY   mouse starting position in pixels
  @param toX, toY       mouse end position in pixels
*/
Matrix trackballRotation(int width, int height, int fromX, int fromY, int toX, int toY)
{
  const float TRACKBALL_SIZE = 1.3f;            // virtual trackball size
  Matrix mInv;                                  // inverse of ObjectView matrix
  Vector3 v1, v2;                               // mouse drag positions in normalized 3D space
  float smallSize;                              // smaller window size between width and height
  float halfWidth, halfHeight;                  // half window sizes
  float angle;                                  // rotational angle
  float d;                                      // distance

  // Compute mouse coordinates in window and normalize to -1..1
  // ((0,0) = window center, (-1,-1) = bottom left, (1,1) = top right)
  halfWidth  = (float)width  / 2.0;
  halfHeight = (float)height / 2.0;
  smallSize  = (halfWidth < halfHeight) ? halfWidth : halfHeight;
  v1.x    = ((float)fromX - halfWidth)  / smallSize;
  v1.y    = ((float)(height-fromY) - halfHeight) / smallSize;
  v2.x    = ((float)toX   - halfWidth)  / smallSize;
  v2.y    = ((float)(height-toY)   - halfHeight) / smallSize;

  // Compute z-coordinates on trackball:
  d       = sqrtf(v1.x * v1.x + v1.y * v1.y);
  v1.z    = expf(-TRACKBALL_SIZE * d * d);
  d       = sqrtf(v2.x * v2.x + v2.y * v2.y);
  v2.z    = expf(-TRACKBALL_SIZE * d * d);

  // Compute rotational angle:
  angle = v1.angle(v2);                           // angle between v1 and v2

  // Compute rotational axis:
  v2.cross(v1);                                   // v2 = v2 x v1 (cross product)

  // Convert axis coordinates (v2) from world coordinates to object coordinates:
  mInv.identity();
  mInv.copyRot(this);                             // copy rotational part of mv to mInv
  mInv.invertOrtho();                             // invert orthogonal matrix mInv
  v2.multiply(mInv);                              // v2 = v2 x mInv (matrix multiplication)
  v2.normalize();                                 // normalize v2 before rotation

  // Perform matrix modification:
  return rotate(-angle, v2.x, v2.y, v2.z);
}