// using vDown, vNow, dragging, and axisSet, compute rotations void ArcBall::update () { int setSize = setSizes[axisSet]; Quat *set = (Quat *)(sets[axisSet]); vFrom = mouseOnSphere(vDown, center, radius); vTo = mouseOnSphere(vNow, center, radius); if(dragging) { if(axisSet != NoAxes) { vFrom = constrainToAxis(vFrom, set[axisIndex]); vTo = constrainToAxis(vTo, set[axisIndex]); } qDrag = fromBallPoints(vFrom, vTo); qNow = qDrag * qDown; } else if(axisSet != NoAxes) axisIndex = nearestConstraintAxis(vTo, set, setSize); toBallPoints(qDown, vrFrom, vrTo); getRotation(qNow.conjugate(), mNow); // gives transpose to OpenGL }
//------------------------------------------------------------------------------ void ArcBall::drag(const glm::vec2& msc) { // Regular drag code to follow... mVNow = (mScreenToTCS * glm::vec4(msc.x, msc.y, 0.0, 1.0)).xyz(); mVSphereFrom= mouseOnSphere(mVDown); mVSphereTo = mouseOnSphere(mVNow); // Construct a quaternion from two points on the unit sphere. mQDrag = quatFromUnitSphere(mVSphereFrom, mVSphereTo); mQNow = mQDrag * mQDown; // Perform complex conjugate glm::quat q = mQNow; q.x = -q.x; q.y = -q.y; q.z = -q.z; q.w = q.w; mMatNow = glm::mat4_cast(q); }