我试图通过用鼠标拖动来旋转three.js中的对象,因此它必须围绕x和y轴旋转。如果我只尝试围绕一个轴旋转,我编写的代码工作得很好,但是当我尝试围绕两个轴旋转时,旋转变得奇怪,即使鼠标只朝一个方向移动,它也总是围绕两个轴旋转:
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
};
}
我总是围绕两个轴应用旋转,但是当鼠标沿一个方向移动时,围绕另一个轴的旋转应该是0或接近0,但旋转非常大且明显。
任何人都可以指出我做错了吗?
由于
答案 0 :(得分:1)
你的关键词是"弧球"控制。下面的伪代码说明了它
/**
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);
}