//Mouse down void ArcBall::click(GLfloat x, GLfloat y, Matrix4fT *stTrans) { Point2fT NewPt; NewPt.T[0] = x; NewPt.T[1] = y; //Map the point to the sphere this->_mapToSphere(&NewPt, &this->StVec); Matrix4fSetRotationScaleFromMatrix4f(&this->StTransform, stTrans); }
void ArcBall::dragAccumulate(GLfloat x, GLfloat y, Matrix4fT *transform) { Quat4fT tmpQuat; Matrix3fT tmpRot; drag(x, y, &tmpQuat); // Set output to the initial transform Matrix4fSetRotationScaleFromMatrix4f(transform, &this->StTransform); // get current rotation matrix Matrix3fSetRotationFromQuat4f(&tmpRot, &tmpQuat); // Apply to initial transform Matrix4fMulRotationFromMatrix3f(transform, &tmpRot); }
/** * Performs SVD on this matrix and gets scale and rotation. * Rotation is placed into rot3, and rot4. * @param rot3 the rotation factor(Matrix3d). if null, ignored * @param rot4 the rotation factor(Matrix4) only upper 3x3 elements are changed. if null, ignored * @return scale factor */ inline static GLfloat Matrix4fSVD(const Matrix4fT* NewObj, Matrix3fT* rot3, Matrix4fT* rot4) { GLfloat s, n; // this is a simple svd. // Not complete but fast and reasonable. // See comment in Matrix3d. s = sqrtf( ( (NewObj->s.XX * NewObj->s.XX) + (NewObj->s.XY * NewObj->s.XY) + (NewObj->s.XZ * NewObj->s.XZ) + (NewObj->s.YX * NewObj->s.YX) + (NewObj->s.YY * NewObj->s.YY) + (NewObj->s.YZ * NewObj->s.YZ) + (NewObj->s.ZX * NewObj->s.ZX) + (NewObj->s.ZY * NewObj->s.ZY) + (NewObj->s.ZZ * NewObj->s.ZZ) ) / 3.0f ); if (rot3) { //if pointer not null //this->getRotationScale(rot3); rot3->s.XX = NewObj->s.XX; rot3->s.XY = NewObj->s.XY; rot3->s.XZ = NewObj->s.XZ; rot3->s.YX = NewObj->s.YX; rot3->s.YY = NewObj->s.YY; rot3->s.YZ = NewObj->s.YZ; rot3->s.ZX = NewObj->s.ZX; rot3->s.ZY = NewObj->s.ZY; rot3->s.ZZ = NewObj->s.ZZ; // zero-div may occur. n = 1.0f / sqrtf( (NewObj->s.XX * NewObj->s.XX) + (NewObj->s.XY * NewObj->s.XY) + (NewObj->s.XZ * NewObj->s.XZ) ); rot3->s.XX *= n; rot3->s.XY *= n; rot3->s.XZ *= n; n = 1.0f / sqrtf( (NewObj->s.YX * NewObj->s.YX) + (NewObj->s.YY * NewObj->s.YY) + (NewObj->s.YZ * NewObj->s.YZ) ); rot3->s.YX *= n; rot3->s.YY *= n; rot3->s.YZ *= n; n = 1.0f / sqrtf( (NewObj->s.ZX * NewObj->s.ZX) + (NewObj->s.ZY * NewObj->s.ZY) + (NewObj->s.ZZ * NewObj->s.ZZ) ); rot3->s.ZX *= n; rot3->s.ZY *= n; rot3->s.ZZ *= n; } if (rot4) { //if pointer not null if (rot4 != NewObj) { Matrix4fSetRotationScaleFromMatrix4f(rot4, NewObj); // private method } // zero-div may occur. n = 1.0f / sqrtf( (NewObj->s.XX * NewObj->s.XX) + (NewObj->s.XY * NewObj->s.XY) + (NewObj->s.XZ * NewObj->s.XZ) ); rot4->s.XX *= n; rot4->s.XY *= n; rot4->s.XZ *= n; n = 1.0f / sqrtf( (NewObj->s.YX * NewObj->s.YX) + (NewObj->s.YY * NewObj->s.YY) + (NewObj->s.YZ * NewObj->s.YZ) ); rot4->s.YX *= n; rot4->s.YY *= n; rot4->s.YZ *= n; n = 1.0f / sqrtf( (NewObj->s.ZX * NewObj->s.ZX) + (NewObj->s.ZY * NewObj->s.ZY) + (NewObj->s.ZZ * NewObj->s.ZZ) ); rot4->s.ZX *= n; rot4->s.ZY *= n; rot4->s.ZZ *= n; } return s; }