【问题标题】:Add offset to DeviceOrientationControls in three.js在 three.js 中为 DeviceOrientationControls 添加偏移量
【发布时间】:2016-03-30 16:20:15
【问题描述】:

我正在尝试在deviceControls.update(); 命令之后向相机添加偏移量。我使用了DeviceOrientationControls,如first example.所示

偏移量将是拖动手势的结果,如this example.中所示

当我将 2 个四元数相乘时(我试过 a x b 和 b x a),最终结果不正确。

这是我的操作:

const m1 = new THREE.Matrix4();
m1.lookAt(new THREE.Vector3(), camera.target, THREE.Object3D.DefaultUp.clone());

const quater = new THREE.Quaternion();
quater.setFromRotationMatrix(m1);

const finalQuater = new THREE.Quaternion();
finalQuater.multiplyQuaternions(quater, camera.quaternion);

camera.quaternion.copy(finalQuater);

camera.target 是我的最终拖动目标(Vector3),camera.quaternion 已由deviceControls.update() 设置,等于相机方向,根据设备陀螺仪。

感谢您的帮助

更新:我尝试更改轮换顺序,同样的问题。我认为是由于设备方向更新后原点发生变化,但找不到解决方法。

【问题讨论】:

标签: javascript three.js quaternions device-orientation


【解决方案1】:

DeviceOrientationControls 现在有一个属性alphaOffsetAngle 和一个方法

controls.updateAlphaOffsetAngle( angle ); // angle is in radians

这将围绕三个.js 'Y' 轴旋转场景。

three.js r.77

【讨论】:

  • 谢谢,我为其他轴添加了相同的功能,它工作正常。
【解决方案2】:
    var rotY = 0;
    var rotX = 0;    
    function setObjectQuaternion(quaternion, alpha, beta, gamma, orient) {
        var zee = new THREE.Vector3( 0, 0, 1 );
        var euler = new THREE.Euler();
        var q0 = new THREE.Quaternion();
        var q1 = new THREE.Quaternion( -Math.sqrt( 0.5 ), 0, 0, Math.sqrt( 0.5 ) ); // - PI/2 around the x-axis

        if (screenOrientation == 0) {
            var vectorFingerY = new THREE.Vector3( 1, 0, 0 ); 
            var fingerQY = new THREE.Quaternion();
            fingerQY.setFromAxisAngle ( vectorFingerY, -rotX );
        }else if (screenOrientation == 180) {
            var vectorFingerY = new THREE.Vector3( 1, 0, 0 ); 
            var fingerQY = new THREE.Quaternion();
            fingerQY.setFromAxisAngle ( vectorFingerY, rotX );
        }else if (screenOrientation == 90) {
            var vectorFingerY = new THREE.Vector3( 0, 1, 0 ); 
            var fingerQY = new THREE.Quaternion();
            fingerQY.setFromAxisAngle ( vectorFingerY, rotX );
        }else if (screenOrientation == -90) {
            var vectorFingerY = new THREE.Vector3( 0, 1, 0 ); 
            var fingerQY = new THREE.Quaternion();
            fingerQY.setFromAxisAngle ( vectorFingerY, -rotX );
        }
        q1.multiply( fingerQY );

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

    function update(camera) {
        if (window.orientation !== undefined && window.orientation !== null) screenOrientation = window.orientation; 

        var alpha  = deviceOrientation.alpha ? THREE.Math.degToRad( deviceOrientation.alpha ) : 0; // Z
        var beta   = deviceOrientation.beta  ? THREE.Math.degToRad( deviceOrientation.beta  ) : 0; // X'
        var gamma  = deviceOrientation.gamma ? THREE.Math.degToRad( deviceOrientation.gamma ) : 0; // Y''
        var orient = screenOrientation       ? THREE.Math.degToRad( screenOrientation       ) : 0; // O
        setObjectQuaternion( camera.quaternion, alpha, beta, gamma, orient );
    };

将此添加到您的初始化中 container.appendChild(renderer.domElement);

            renderer.domElement.addEventListener( 'touchstart', function (e) {
                if (controls) {
                    e.preventDefault();
                    e.stopPropagation();
                    tempX = e.touches[ 0 ].pageX;
                    tempY = e.touches[ 0 ].pageY;
                }
            }, false );
            renderer.domElement.addEventListener( 'touchmove', function (e) {
                if (controls) {
                    e.preventDefault();
                    e.stopPropagation();
                    rotY += THREE.Math.degToRad((tempX - e.touches[ 0 ].pageX)/4);
                    rotX += THREE.Math.degToRad((tempY - e.touches[ 0 ].pageY)/4);

                    mesh.quaternion.copy(MeshStartQY);
                    var vectorFingerY = new THREE.Vector3( 0, 1, 0 ); 
                    var fingerQY = new THREE.Quaternion();
                    fingerQY.setFromAxisAngle ( vectorFingerY, rotY );

                    mesh.quaternion.multiply(fingerQY);

                    tempX = e.touches[ 0 ].pageX;
                    tempY = e.touches[ 0 ].pageY;
                }
            }, false );

【讨论】:

  • new THREE.Quaternion(); - 创建 QuaternionVector 的单个实例并重用它们。这就是闭包的用途。
猜你喜欢
  • 1970-01-01
  • 2021-07-22
  • 2021-11-10
  • 2018-03-24
  • 2019-03-20
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
相关资源
最近更新 更多