• 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();
    
    };
    您可以考虑给树发个小额微信红包以资鼓励
  • 相关阅读:
    【HEVC帧间预测论文】P1.8 Complexity Control of High Efficiency Video Encoders for Power-Constrained Devices
    【HEVC帧间预测论文】P1.7 Content Based Hierarchical Fast Coding Unit Decision Algorithm
    【HEVC帧间预测论文】P1.6 A Fast HEVC Inter CU Selection Method Based on Pyramid Motion Divergence
    【HEVC帧间预测论文】P1.5 Fast Coding Unit Size Selection for HEVC based on Bayesian Decision Rule
    【HEVC帧间预测论文】P1.4 Motion Vectors Merging: Low Complexity Prediction Unit Decision
    【HEVC帧间预测论文】P1.3 Fast Inter-Frame Prediction Algorithm of HEVC Based on Graphic Information
    【HEVC帧间预测论文】P1.2 An Efficient Inter Mode Decision Approach for H.264 Video Codin
    【HEVC帧间预测论文】P1.1 基于运动特征的HEVC快速帧间预测算法
    【HEVC简介】DB-DeBlock Filter
    【HEVC简介】ALF-Adative Loop Filter
  • 原文地址:https://www.cnblogs.com/dojo-lzz/p/14902182.html
Copyright © 2020-2023  润新知