TrackballControls rotate only on the Z axis

I would like to change the TrackballControls so that the camera rotates only along the Z axis. However, I have a time devil who understands how the mouse / touch coordinates are displayed. The function below gets the mouse / touch coordinates x / y and the "projection" vector, which I assume is the projection of where the camera should rotate, but this is not particularly clear to me.

Basically, I need to know what to do in the if statement below, which says: "What is happening here?" I essentially need to fix the vector so that the rotation occurs only along the Z axis. I know that I can do this with a simple rotation, but I would like to implement it in TrackballControls, so I can switch to the "only rotate" mode as desired ( the camera is only a “roll” on the Z axis). Can anyone who is better at vector math give me a hand?

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;
        }

    }());

Actual camera rotation is performed in a function below each frame. This function is much more clear to me. Just basic angles and quaternion. This is the above function that scares my mind.

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 );
            }

        }
    }

}());
+4
source share

Source: https://habr.com/ru/post/1535878/


All Articles