Search code examples
javascriptthree.jsgoogle-cardboardvirtual-reality

Keyboard Controls With DeviceOrientationControls


I am currently creating a VR web app using three.js. As the camera controls I am using the device orientation controls used here in the google cardboard three.js demo.

What I need to do is add keyboard controls to this(e.g Up arrow to go forward etc). I've fiddled around with moving the camera on the two axis (x and z) here:

if (e.keyCode == '38') {
    camera.position.set(0, 10, camera.position.z+4);

    controls.target.set(
        camera.position.x +4,
        camera.position.y,
        camera.position.z
    );
    effect.render(scene, camera);
...

However I want to make the character move relative to where they are looking (e.g You look one way and press the Up arrow and the character moves the way you looking). Like a first person view.

Does anyone have any ideas on how this is done? Ive tried using the first person controls from three.js but this eliminates the head tracking which is essential for a VR game.

Any answers would be greatly appreciated. (My source code is practically just the Google cardboard three.js demo code with a function added in too detect key presses)


Solution

  • I solved this by different approach. I created an object3d which is moving in scene. Model and camera are child of this object.

    I'm rotating object 3d with camera and in the same time rotate model in opposite direction. When i rotate camera object looks keeping direction. when i want to move object, just translateX object with camera and make model rotation to 0. That did the trick.

    On long distances (I have millions of units) started to be jerky. Reason is lost precision.

    I solved it by keeping position of object at 0,0,0 and move all other things in opposite direction. That makes your model is still on 0,0,0 coords with right rotation and world is moving around.

    Most simple example:

    you trying something like

    scene.add(character_model);
    scene.add(camera);
    //camera.rotate ....
    character_model.translateX(1);
    character_model.rotateX(1);
    //etc ...
    

    and now you trying to move camera around the pivot (character_model), but this is overcomplicated mathematics.

    Try:

    var controls_dimension = new THREE.Object3D();
    scene.add(controls_dimension);
    controls_dimension.add(character_model);
    controls_dimension.add(camera);
    
    //use controls to rotate with this object, not with character_model
    controls_dimension.rotateX(2);
    
    // in the same rotate model to opposite direction. You can make 
    // illusion of rotating camera, not a model.
    character_model.rotateX(2*-1);
    
    /* 
    when you want to go in camera direction=controls_dimension=controls_dimension.translateX(1) 
    and we moving (you most only animate model rotation to controls_dimension.rotation)
    */