Domanda

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

È stato utile?

Soluzione

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top