//Mouse drag, calculate rotation public void drag(Point NewPt, Quat4f NewRot) { //Map the point to the sphere this.mapToSphere(NewPt, EnVec); //Return the quaternion equivalent to the rotation if (NewRot != null) { Vector3f Perp = new Vector3f(); //Compute the vector perpendicular to the begin and end vectors Vector3f.cross(Perp, StVec, EnVec); //Compute the length of the perpendicular vector if (Perp.length() > Epsilon) //if its non-zero { //We're ok, so return the perpendicular vector as the transform after all NewRot.x = Perp.x; NewRot.y = Perp.y; NewRot.z = Perp.z; //In the quaternion values, w is cosine (theta / 2), where theta is the rotation angle NewRot.w = Vector3f.dot(StVec, EnVec); } //if it is zero else { //The begin and end vectors coincide, so return an identity transform NewRot.x = NewRot.y = NewRot.z = NewRot.w = 0.0f; } } }
private void drag(Point MousePt) { Quat4f ThisQuat = new Quat4f(); arcBall.drag(MousePt, ThisQuat); // Update End Vector And Get Rotation As Quaternion lock (matrixLock) { ThisRot.Rotation = ThisQuat; // Convert Quaternion Into Matrix3fT ThisRot.mul(ThisRot, LastRot); // Accumulate Last Rotation Into This One } }
private void drag_Transfer(Point MousePt) { Quat4f ThisQuat = new Quat4f(); arcBall.drag(MousePt, ThisQuat); // Update End Vector And Get Rotation As Quaternion lock (matrixLock) { //lock 的目的很明确:就是不想让别人使用这段代码, //体现在多线程情况下,只允许当前线程执行该代码区域, //其他线程等待直到该线程执行结束;这样可以多线程避免同时使用某一方法造成数据混乱。 ThisRot.Transfer = ThisQuat; // Convert Quaternion Into Matrix3fT ThisRot.mul(ThisRot, LastRot); // Accumulate Last Rotation Into This One } }