Add offset to DeviceOrientationControls in three.js

烂漫一生 提交于 2019-12-08 07:54:43

问题


I'm trying to add an offset to the camera after deviceControls.update(); command. I used DeviceOrientationControls as shown in this first example.

The offset will be the result of a drag gesture, as presents in this example.

When I multiply the 2 quaternions (I have tried a x b and b x a), the final result is not correct.

Here is my operation :

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 is my final drag target (Vector3), and camera.quaternion has been set by deviceControls.update() and is equals to the camera orientation, according to the device gyroscope.

Thanks for your help

Update : I have tried to changer rotate order, same problem. I think it is due to the origin change after the device orientation update, but can't find how to solve.


回答1:


DeviceOrientationControls now has a property alphaOffsetAngle, and a method

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

that will rotate the scene around the three.js 'Y' axis.

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

add this to your init 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 );


来源:https://stackoverflow.com/questions/36314415/add-offset-to-deviceorientationcontrols-in-three-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!