Three.js DeviceOrientationControl源码解析

Posted 我的小树林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Three.js DeviceOrientationControl源码解析相关的知识,希望对你有一定的参考价值。

/**
 * @author richt / http://richt.me
 * @author WestLangley / http://github.com/WestLangley
 *
 * W3C Device Orientation control (http://w3c.github.io/deviceorientation/spec-source-orientation.html)
 */

THREE.DeviceOrientationControls = function( object ) {

    var scope = this;

    this.object = object;
    this.object.rotation.reorder( "YXZ" );

    this.enabled = true;

    this.deviceOrientation = {};
    this.screenOrientation = 0;

    this.alpha = 0;
    this.alphaOffsetAngle = 0;


    var onDeviceOrientationChangeEvent = function( event ) {

        scope.deviceOrientation = event;

    };

    var onScreenOrientationChangeEvent = function() {

        scope.screenOrientation = window.orientation || 0;

    };

    // The angles alpha, beta and gamma form a set of intrinsic Tait-Bryan angles of type Z-X\'-Y\'\'

    var setObjectQuaternion = function() {

        var zee = new THREE.Vector3( 0, 0, 1 );

        var euler = new THREE.Euler();

        var q0 = new THREE.Quaternion();
        // Math.cos(Math.PI / 4) = Math.sqrt(0.5)
        // 四元数中x=nx * Math.sin(Math.PI / 4)
        // 因为手机平放时候alpha/beta/gamma都是0;而在3d中相当于相机绕x轴旋转90度,所以这里需要做一个旋转
        var q1 = new THREE.Quaternion( - Math.sqrt( 0.5 ), 0, 0, Math.sqrt( 0.5 ) ); // - PI/2 around the x-axis
        
        return function( quaternion, alpha, beta, gamma, orient ) {
            // 同理因为上文中提到绕x轴旋转90度后角度对应轴关系变为:
            // alpha->y;
            // -gamma->z;
            // beta->x
            ///Euler对象的构造函数.用来创建一个欧拉角的对象.Euler对象的功能函数采用
            ///定义构造的函数原型对象来实现.
            ///
            ///    用法: var euler = new Euler(5,3,2,\'XYZ\')
            ///    创建一个绕某轴旋转5度,绕y轴旋转某度,绕某轴旋转2度,旋转顺序为\'XYZ\'.有了旋转顺序才能确定每个x,y,z轴分别旋转多少度.
            ///    NOTE: 参数x,y,z代表3个轴的旋转角度,具体哪个轴旋转多少度,需要后面的参数(order)旋转顺序来确定.
            ///    NOTE: 参数(x,y,z,order)为可选参数,如果不指定参数(x,y,z,order),将创建一个坐标为(0,0,0,\'XYZ\')的Eular(欧拉角)对象.
            /// NOTE: 参数order(旋转顺序) 默认顺序是\'XYZ\' 取值范围是[\'XYZ\', \'YZX\', \'ZXY\', \'XZY\', \'YXZ\', \'ZYX\' ]
            ///
            /// 通俗的讲,欧拉角就是用来描述一个物体在三维空间中方向的一种常用的方法.举例来说,一个物体在三维空间中,绕x轴转了多少度,
            ///    y轴转了多少度,z轴转了多少度,来描述物体在三维空间中的方向.
            /// 有点类似香港电影里飞虎队队员之间说,"飞鹰,飞鹰,在你的正前方,5点钟方向,发现目标,准备聚集目标."
            euler.set( beta, alpha, - gamma, \'YXZ\' ); // \'ZXY\' for the device, but \'YXZ\' for us

            quaternion.setFromEuler( euler ); // orient the device

            quaternion.multiply( q1 ); // camera looks out the back of the device, not the top

            quaternion.multiply( q0.setFromAxisAngle( zee, - orient ) ); // adjust for screen orientation

        }

    }();

    this.connect = function() {

        onScreenOrientationChangeEvent(); // run once on load

        window.addEventListener( \'orientationchange\', onScreenOrientationChangeEvent, false );
        window.addEventListener( \'deviceorientation\', onDeviceOrientationChangeEvent, false );

        scope.enabled = true;

    };

    this.disconnect = function() {

        window.removeEventListener( \'orientationchange\', onScreenOrientationChangeEvent, false );
        window.removeEventListener( \'deviceorientation\', onDeviceOrientationChangeEvent, false );

        scope.enabled = false;

    };

    this.update = function() {

        if ( scope.enabled === false ) return;

        var alpha = scope.deviceOrientation.alpha ? THREE.Math.degToRad( scope.deviceOrientation.alpha ) + this.alphaOffsetAngle : 0; // Z
        var beta = scope.deviceOrientation.beta ? THREE.Math.degToRad( scope.deviceOrientation.beta ) : 0; // X\'
        var gamma = scope.deviceOrientation.gamma ? THREE.Math.degToRad( scope.deviceOrientation.gamma ) : 0; // Y\'\'
        var orient = scope.screenOrientation ? THREE.Math.degToRad( scope.screenOrientation ) : 0; // O

        setObjectQuaternion( scope.object.quaternion, alpha, beta, gamma, orient );
        this.alpha = alpha;

    };

    this.updateAlphaOffsetAngle = function( angle ) {

        this.alphaOffsetAngle = angle;
        this.update();

    };

    this.dispose = function() {

        this.disconnect();

    };

    this.connect();

};

 

以上是关于Three.js DeviceOrientationControl源码解析的主要内容,如果未能解决你的问题,请参考以下文章

Three.js开发指南---使用three.js的材质(第四章)

three.js(16)-精灵图

three.js源码目录

three.js简介

three.js 入门详解

three.js 入门详解