//-------------------------------------------------------------------------------------------------- /// Transforms the plane with the given homogeneous transformation \a matrix //-------------------------------------------------------------------------------------------------- void Plane::transform(const Mat4d& matrix) { Vec3d n = normal(); Vec3d point = pointInPlane(); n.transformVector(matrix); point.transformPoint(matrix); setFromPointAndNormal(point, n); }
//-------------------------------------------------------------------------------------------------- /// Compute quaternion rotation /// /// \param oldPosX x coordinate of the last position of the mouse, in the range [-1.0, 1.0] /// \param oldPosY y coordinate of the last position of the mouse, in the range [-1.0, 1.0] /// \param newPosX x coordinate of current position of the mouse, in the range [-1.0, 1.0] /// \param newPosY y coordinate of current position of the mouse, in the range [-1.0, 1.0] /// \param currViewMatrix Current transformation matrix. The inverse is used when calculating the rotation /// \param sensitivityFactor Mouse sensitivity factor /// /// Simulate a track-ball. Project the points onto the virtual trackball, then figure out the axis /// of rotation. This is a deformed trackball-- is a trackball in the center, but is deformed into a /// hyperbolic sheet of rotation away from the center. //-------------------------------------------------------------------------------------------------- Quatd ManipulatorTrackball::trackballRotation(double oldPosX, double oldPosY, double newPosX, double newPosY, const Mat4d& currViewMatrix, double sensitivityFactor) { // This particular function was chosen after trying out several variations. // Implemented by Gavin Bell, lots of ideas from Thant Tessman and the August '88 // issue of Siggraph's "Computer Graphics," pp. 121-129. // This size should really be based on the distance from the center of rotation to the point on // the object underneath the mouse. That point would then track the mouse as closely as possible. const double TRACKBALL_RADIUS = 0.8f; // Clamp to valid range oldPosX = Math::clamp(oldPosX, -1.0, 1.0); oldPosY = Math::clamp(oldPosY, -1.0, 1.0); newPosX = Math::clamp(newPosX, -1.0, 1.0); newPosY = Math::clamp(newPosY, -1.0, 1.0); // First, figure out z-coordinates for projection of P1 and P2 to deformed sphere Vec3d p1 = projectToSphere(TRACKBALL_RADIUS, oldPosX, oldPosY); Vec3d p2 = projectToSphere(TRACKBALL_RADIUS, newPosX, newPosY); // Axis of rotation is the cross product of P1 and P2 Vec3d a = p1 ^ p2; // Figure out how much to rotate around that axis. Vec3d d = p1 - p2; double t = d.length()/(2.0*TRACKBALL_RADIUS); // Avoid problems with out-of-control values... t = Math::clamp(t, -1.0, 1.0); double phi = 2.0*asin(t); // Scale by sensitivity factor phi *= sensitivityFactor; // Use inverted matrix to find rotation axis Mat4d invMatr = currViewMatrix.getInverted(); a.transformVector(invMatr); // Get quaternion to be returned by pointer Quatd quat = Quatd::fromAxisAngle(a, phi); return quat; }