我想修改TrackballControls,以便相机仅在Z轴上旋转。但是,我有一段时间了解鼠标/触摸坐标的映射方式。下面的功能接收鼠标/触摸x / y坐标和"投影"矢量,我假设是投影相机预期旋转的位置,但对我来说也不是特别清楚。
基本上我需要知道在下面的if语句中该怎么做才能说明"这里有什么?"我需要基本上剪切矢量,以便旋转仅发生在Z轴上。我知道我可以通过简单的旋转来实现这一点,但是我想在TrackballControls中实现它,所以我可以切换到"仅滚动"随意模式(仅限摄像机"在Z轴上滚动")。那些擅长矢量数学的人可以帮我一把吗?
this.getMouseProjectionOnBall = (function(){
var objectUp = new THREE.Vector3(),
mouseOnBall = new THREE.Vector3();
return function ( pageX, pageY, projection ) {
mouseOnBall.set(
( pageX - _this.screen.width * 0.5 - _this.screen.left ) / (_this.screen.width*.5),
( _this.screen.height * 0.5 + _this.screen.top - pageY ) / (_this.screen.height*.5),
0.0
);
var length = mouseOnBall.length();
if ( _this.noRoll ) {
if ( length < Math.SQRT1_2 ) {
mouseOnBall.z = Math.sqrt( 1.0 - length*length );
} else {
mouseOnBall.z = .5 / length;
}
} else if (_this.rollOnly === true) {
// What goes here?
} else if ( length > 1.0 ) {
mouseOnBall.normalize();
} else {
mouseOnBall.z = Math.sqrt( 1.0 - length * length );
}
_eye.copy( _this.object.position ).sub( _this.target );
projection.copy( _this.object.up ).setLength( mouseOnBall.y )
projection.add( objectUp.copy( _this.object.up ).cross( _eye ).setLength( mouseOnBall.x ) );
projection.add( _eye.setLength( mouseOnBall.z ) );
return projection;
}
}());
实际的相机旋转在每帧下面的功能中完成。这个功能对我来说更容易理解。只是基本角度和四元数的东西。上述功能让我大吃一惊。
this.rotateCamera = (function(){
var axis = new THREE.Vector3(),
quaternion = new THREE.Quaternion();
return function () {
var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
if ( angle ) {
axis.crossVectors( _rotateStart, _rotateEnd ).normalize();
angle *= _this.rotateSpeed;
quaternion.setFromAxisAngle( axis, -angle );
_eye.applyQuaternion( quaternion );
_this.object.up.applyQuaternion( quaternion );
_rotateEnd.applyQuaternion( quaternion );
if ( _this.staticMoving ) {
_rotateStart.copy( _rotateEnd );
} else {
quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
_rotateStart.applyQuaternion( quaternion );
}
}
}
}());