Difference between revisions of "Trackball.cpp"
From Immersive Visualization Lab Wiki
(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 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 | + | halfWidth = (float)width / 2.0; |
− | halfHeight | + | halfHeight = (float)height / 2.0; |
− | smallSize | + | smallSize = (halfWidth < halfHeight) ? halfWidth : halfHeight; |
− | v1.x | + | v1.x = ((float)fromX - halfWidth) / smallSize; |
− | v1.y | + | v1.y = ((float)(height-fromY) - halfHeight) / smallSize; |
− | v2.x | + | v2.x = ((float)toX - halfWidth) / smallSize; |
− | v2.y | + | v2.y = ((float)(height-toY) - halfHeight) / smallSize; |
− | // Compute z-coordinates on | + | // 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 | + | // Perform matrix modification: |
− | return rotate(-angle, v2.x, v2.y, v2.z); | + | return rotate(-angle, v2.x, v2.y, v2.z); |
} | } | ||
</pre> | </pre> |
Latest revision as of 22: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); }