I'm trying to rotate an object in three.js by dragging it with the mouse, so it has to rotate around the x and y axis. The code that I wrote works fine if I only try to rotate around one axis, but when I try to rotate around both, the rotation becomes weird, It always rotates around both axis even when the mouse is moving only in one direction:
function onDocumentMouseDown( event ) {
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
//mouse point normalized to world coords
lastPoint = {
x : (event.clientX / windowHalfX) * 2 - 1,
y : -(event.clientY / windowHalfY) * 2 + 1
};
}
function onDocumentMouseMove( event ) {
//new mouse position normalized to world coords
newPoint = {
x : (event.clientX / windowHalfX) * 2 - 1,
y : -(event.clientY / windowHalfY) * 2 + 1
};
//rotation for both x and y axis
rotationY = Math.atan(1 / (newPoint.x - lastPoint.x )) * (Math.PI / 180);
rotationX = Math.atan(1 / (lastPoint.y - newPoint.y )) * (Math.PI / 180);
//apply rotation on Y axis
quaternion.setFromAxisAngle( new THREE.Vector3(0,1,0).normalize(), rotationY);
cube.quaternion.multiplyQuaternions( quaternion, cube.quaternion );
//aply rotation on X axis
quaternion.setFromAxisAngle( new THREE.Vector3(1,0,0).normalize(), rotationX);
cube.quaternion.multiplyQuaternions( quaternion, cube.quaternion );
//update last position to current one
lastPoint = {
x : newPoint.x,
y : newPoint.y
};
}
I'm always applying rotation around both axis, but when the mouse moves in one direction, the rotation around the other axis should be 0 or near 0, but the rotation is very big and noticeable.
Can anyone point what I'm doing wrong?
Thanks
Your key word is "arc ball" control. the pseudocode below illustrate it
/**
help function for arcball
orthogonal projection on sphere of radius 1,
standing in (x = 0, y = 0)
*/
inline vector3 ortho_project_on_sphere( float x , float y )
{
vector3 p(x, y, 0);
float ls = p.len_squared();
if ( ls >= 1.0f )
p.norm();
else
p.z = (float)sqrt(1.0f - ls);
return p;
}
//-------------------------------------------------------------------------------
/*
calculate rotation of arcball user input,
used to perform object rotation by mouse.
"from" and "to" the mouse on screen coordinates (with - x,y on screen)
in range of -1 to +1
the arcball radius is 1.0 and it stand in a center (x = 0, y = 0)
*/
inline xxquaternion arcball(const vector3& from, const vector3& to)
{
vector3 p_f = ortho_project_on_sphere(from.x, from.y );
vector3 p_t = ortho_project_on_sphere(to.x, to.y );
vector3 c = cross(p_f, p_t);
float d = dot(p_f, p_t);
return xxquaternion(c.x, c.y, c.z, d);
}