# WebXR: camera's position not changing when using OrbitControls

**URL:** <https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334>\
**Category:** Questions\
**Tags:** webxr, orbitcontrols\
**Created:** [February 25, 2022, 7:25pm UTC](https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334 "2022-02-25T19:25:56Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![JohnCinaaa](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/johncinaaa/32/24481_2.png) [@JohnCinaaa](https://discourse.threejs.org/u/JohnCinaaa)\
**Post date:** [February 25, 2022, 7:25pm UTC](https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334/1 "2022-02-25T19:25:56Z")

</div>

I am trying to change the position of the camera using

```nohighlight
camera.position.set(a, 0, 0);
controls.update();

```

with “a” being a Number changing each frame from 0 to 20, then from 20 to 0 and so on.

The camera’s position is changing when the immersive-vr session is still off:

However when the vr button is triggered, the immersive-vr session opens, but the scene isn’t changing position.

Using the webxr dev tool from the browser, I can change the orientation of the headset so the image isn’t frozen.

Any idea?

The html:

```nohighlight
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js ar - cones</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
		<link type="text/css" rel="stylesheet" href="main.css">
	</head>
	<body>

		<!-- <div id="info">
			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> ar - cones<br/>(Chrome Android 81+)
		</div> -->

		<!-- Import maps polyfill -->
		<!-- Remove this when import maps will be widely supported -->

		<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
		<script type="importmap">
			{
				"imports": {
					"three": "/node_modules/three/build/three.module.js"
				}
			}
		</script>

		<script type="module" src="immersion4.js"></script>
	</body>
</html>

```

The immersion4.js script :

```nohighlight
import * as THREE from '/node_modules/three/build/three.module.js';
import { GLTFLoader } from '/node_modules/three/examples/jsm/loaders/GLTFLoader.js';
import { ARButton } from '/node_modules/three/examples/jsm/webxr/ARButton.js';
import { VRButton } from '/node_modules/three/examples/jsm/webxr/VRButton.js';
import { OrbitControls } from '/node_modules/three/examples/jsm/controls/OrbitControls.js';

let camera, scene, renderer, views, frame, refSpace, pos;
let controls;
let a=0, b=null;

init();
animate();

function init() {

  const container = document.createElement( 'div' );
  document.body.appendChild( container );

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 20 );

  const light = new THREE.HemisphereLight( 0xffffff, 0xbbbbff, 1 );
  light.position.set( 0.5, 1, 0.25 );
  scene.add( light );

  let loader = new GLTFLoader()
  loader.load(
      'media/gltf/space/space.gltf',
      function ( gltf ) {
          gltf.scale = [0.1, 0.1, 0.1];
          scene.add(gltf.scene);
      },
    // called while loading is progressing
    function ( xhr ) {

      console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

    },
    // called when loading has errors
    function ( error ) {

      console.log( 'An error happened: ' + error);

    });

  //

  renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  renderer.xr.enabled = true;
  renderer.xr.setReferenceSpaceType('local'); // thought this could change something
  container.appendChild( renderer.domElement );

  document.body.appendChild( VRButton.createButton( renderer ) );

  //
  controls = new OrbitControls( camera, renderer.domElement );

}

function animate() {

  renderer.setAnimationLoop( render );

}

function render() {

  // To make the back and fourth motion
  if ( b == null ) {
    a += 0.1;
  } else if ( b == 'back' ) {
    a -= 0.1;
  }

  if ( a > 20 && b == null ) {
    b = 'back';
  } else if ( a < 0 ) {
    b = null;
  }

  frame = renderer.xr.getFrame();
  // frame = null when none XRSession got requested
  if ( frame != null ) {
    refSpace = renderer.xr.getReferenceSpace();

    views = frame.getViewerPose(refSpace).views;

    pos = views[0].transform.position;
    //console.log([pos.x, pos.y, pos.z]);
    //console.log(pos);
    //camera.position.set(pos.x + a, pos.y, pos.z);

    // SCENE ISN'T CHANGING WHEN XRSession IS OPENED
    camera.position.set(a, 0, 0);
    controls.update();
    console.log(camera.position);
  }

  // SCENE IS CHANGING IF NO XRSession IS OPENED
  camera.position.set(a, 0, 0);
  controls.update();
  console.log(camera.position);
  

  renderer.render( scene, camera );

}

```

Thank youuu 🙂

---

<div class="post-metadata">

**Author:** ![stanis3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/stanis3d/32/24506_2.png) [@stanis3d](https://discourse.threejs.org/u/stanis3d)\
**Post date:** [February 25, 2022, 10:50pm UTC](https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334/2 "2022-02-25T22:50:00Z")

</div>

Function ANIMATE is a recursive function

> function animate(){  
> //Your Action per Frame  
> requestAnimatonFrame(animate)/_call next \_possble\_for\_you\_system frame_/  
> }

---

<div class="post-metadata">

**Author:** ![JohnCinaaa](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/johncinaaa/32/24481_2.png) [@JohnCinaaa](https://discourse.threejs.org/u/JohnCinaaa)\
**Post date:** [February 26, 2022, 11:09am UTC](https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334/3 "2022-02-26T11:09:52Z")

</div>

Thanks for looking into it Stan!

If I do :

```nohighlight
function animate(){
//Your Action per Frame
requestAnimatonFrame(animate)/ *call next _possble_for_you_system frame* /
}

```

Where should I use the

```nohighlight
renderer.setAnimationLoop( render );

```

and the :

```nohighlight
renderer.render(scene, camera);

```

?

After your message, I changed, the animate function by this but it’s still the same result :

```nohighlight
function animate() {

  renderer.setAnimationLoop( render );

  var f = renderer.xr.getFrame();

  if (f != null) {

    f.session.requestAnimatonFrame( animate );

  }

}

```

---

<div class="post-metadata">

**Author:** ![stanis3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/stanis3d/32/24506_2.png) [@stanis3d](https://discourse.threejs.org/u/stanis3d)\
**Post date:** [February 26, 2022, 12:58pm UTC](https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334/4 "2022-02-26T12:58:04Z")

</div>

Hello John  
🤔  
I meant that the function animate has to call upon itself, whereas in your case it is only called once.  
Now I see that you don’t actually need to use the function **animate**  
It’s possible to use either setAnimationLoop or requestAnimationFrame, but not both!

For a better explanation you can read this thread:  
[Is there a performance difference between requestAnimationFrame() and setAnimationLoop()? - Questions - three.js forum (threejs.org)](https://discourse.threejs.org/t/is-there-a-performance-difference-between-requestanimationframe-and-setanimationloop/27771)

Best regards

---

<div class="post-metadata">

**Author:** ![stanis3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/stanis3d/32/24506_2.png) [@stanis3d](https://discourse.threejs.org/u/stanis3d)\
**Post date:** [February 26, 2022, 1:13pm UTC](https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334/5 "2022-02-26T13:13:24Z")

</div>

That is the problem : the function **render()** by frame-non-null returns the same result as frame-null

> [@JohnCinaaa](#):
>
> ```javascript
> function render() {
> 
> // To make the back and fourth motion
> if ( b == null ) {
> a += 0.1;
> } else if ( b == 'back' ) {
> a -= 0.1;
> }
> 
> if ( a > 20 && b == null ) {
> b = 'back';
> } else if ( a < 0 ) {
> b = null;
> }
> 
> frame = renderer.xr.getFrame();
> // frame = null when none XRSession got requested
> if ( frame != null ) {
> refSpace = renderer.xr.getReferenceSpace();
> 
> views = frame.getViewerPose(refSpace).views;
> 
> pos = views[0].transform.position;
> //console.log([pos.x, pos.y, pos.z]);
> //console.log(pos);
> //camera.position.set(pos.x + a, pos.y, pos.z);
> 
> // SCENE ISN'T CHANGING WHEN XRSession IS OPENED
> camera.position.set(a, 0, 0);
> controls.update();
> console.log(camera.position);
> }
> 
> // SCENE IS CHANGING IF NO XRSession IS OPENED
> camera.position.set(a, 0, 0);
> controls.update();
> console.log(camera.position);
>   
> 
> renderer.render( scene, camera );
> 
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![stanis3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/stanis3d/32/24506_2.png) [@stanis3d](https://discourse.threejs.org/u/stanis3d)\
**Post date:** [February 26, 2022, 1:25pm UTC](https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334/6 "2022-02-26T13:25:50Z")

</div>

Try to write your function like this, maybe it will help:

> function render() {
> 
> // To make the back and fourth motion  
> if ( b == null ) {  
> a += 0.1;  
> } else if ( b == ‘back’ ) {  
> a -= 0.1;  
> }
> 
> if ( a \> 20 && b == null ) {  
> b = ‘back’;  
> } else if ( a \< 0 ) {  
> b = null;  
> }
> 
> frame = renderer.xr.getFrame();  
> // frame = null when none XRSession got requested  
> if ( frame != null ) {  
> refSpace = renderer.xr.getReferenceSpace();
> 
> views = frame.getViewerPose(refSpace).views;
> 
> pos = views[0].transform.position;  
> console.log([pos.x, pos.y, pos.z]);  
> console.log(pos);  
> camera.position.set(pos.x + a, pos.y, pos.z);
> 
> **} else {**
> 
> // SCENE IS CHANGING IF NO XRSession IS OPENED  
> camera.position.set(a, 0, 0);  
> controls.update();  
> console.log(camera.position);  
> }
> 
> renderer.render( scene, camera );
> 
> }

---

<div class="post-metadata">

**Author:** ![JohnCinaaa](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/johncinaaa/32/24481_2.png) [@JohnCinaaa](https://discourse.threejs.org/u/JohnCinaaa)\
**Post date:** [February 27, 2022, 2:47pm UTC](https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334/7 "2022-02-27T14:47:54Z")

</div>

Nice try Stan, but it was still blocking, and

I found out !

So with WebXR, when a session is opened via requestSession(), the renderer object is using another camera than the one given. So I wasn’t moving the camera used by the renderer, even if I was giving the camera object to renderer.render( scene, camera).

To get the camera of the session and change its position, in immersive-vr, you have to do this:

```nohighlight
function render() {

  if ( b == null ) {
    a += 0.1;
  } else if ( b == 'back' ) {
    a -= 0.1;
  }

  if ( a > 20 && b == null ) {
    b = 'back';
  } else if ( a < 0 ) {
    b = null;
  }
  renderer.xr.getCamera().cameras[0].position.x = a;

  console.log(renderer.xr.getCamera().cameras[0].position);

  renderer.render( scene, renderer.xr.getCamera().cameras[0] );

```

Then you can launch the loop like this:

```nohighlight
function animate() {

  renderer.setAnimationLoop( render );
  
}

```

---

<div class="post-metadata">

**Author:** ![JohnCinaaa](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/johncinaaa/32/24481_2.png) [@JohnCinaaa](https://discourse.threejs.org/u/JohnCinaaa)\
**Post date:** [February 27, 2022, 3:43pm UTC](https://discourse.threejs.org/t/webxr-cameras-position-not-changing-when-using-orbitcontrols/35334/8 "2022-02-27T15:43:33Z")

</div>

This is my final render function 😍 😍 😍

```nohighlight
function render() {

  if ( b == null ) {
    a += 0.1;
  } else if ( b == 'back' ) {
    a -= 0.1;
  }

  if ( a > 20 && b == null ) {
    b = 'back';
  } else if ( a < 0 ) {
    b = null;
  }

  try {
    frame = renderer.xr.getFrame();

    refSpace = renderer.xr.getReferenceSpace();

    views = frame.getViewerPose(refSpace).views;

    pos = views[0].transform.position;

    var c = renderer.xr.getCamera().cameras[0].position;

    renderer.xr.getCamera().cameras[0].position.x = pos.x;
    renderer.xr.getCamera().cameras[0].position.y = pos.y;
    renderer.xr.getCamera().cameras[0].position.z = pos.z;
    socket.send(pos)
    renderer.render( scene, renderer.xr.getCamera().cameras[0] );

  } catch (e) {

    var c = 'yupi';

  }

  socket.send(c);

}

```

(The socket is a [socket.io](http://socket.io) to get the data from my computer).  
Don’t hesitate if you have any remarks or questions, I can answer.
