aframe-orbit-controls-component icon indicating copy to clipboard operation
aframe-orbit-controls-component copied to clipboard

dynamically changing camera position

Open weddingdj opened this issue 7 years ago • 18 comments

I have a use case where I dynamically set the position of the camera after the scene and a model is loaded. I realised that the orbit controls component still thinks that the camera is at the original position when the component was initialised. So the camera jumps back to its original position because of this.dolly.position.copy(this.object.position); in the init function.

I did a workaround and added this line of code to the update function and trigger an update event by calling camera.setAttribute('orbit-controls', 'distance', '2'); in order to get the dolly position updated with the new values.

Would you consider putting this.dolly.position.copy(this.object.position); into the update function or do you have a better solution?

Thanks!

weddingdj avatar May 26 '17 22:05 weddingdj

Hey @weddingdj,

sounds like a solid idea to me and like a bug on my side. I will look into this in the next few days.

Thanks for the catch!

cheers

Till

tizzle avatar May 27 '17 00:05 tizzle

Hey @weddingdj,

i'm currently looking into this and was able to reproduce the issue. I will now try to fix this.

I have one question, though: Can you explain why you are moving the camera around? Maybe this might be a good feature :)

Cheers

Till

tizzle avatar May 31 '17 21:05 tizzle

Great!

First I am moving (animating) the model from the background to the origin, like on Sketchfab when you look at models. But that has no influence on your component. But then I calculate the distance of the camera according to the model size, so that the 3D model fits on the screen. And that's why I position the camera.

The whole thing will be a IdeaSpaceVR theme. :-)

weddingdj avatar May 31 '17 21:05 weddingdj

Ah,

i thought you might be doing something like this. We already have the rotateTo functionality. Maybe i can build something like moveTo as well.

Cheers

tizzle avatar May 31 '17 21:05 tizzle

Hey @weddingdj,

can you tell me how you achieve the animations in the beginning? I tried to implement this using an a-animation entity as a child of the camera. This works ok, but it only works flawless when the camera is disabled during the animation. Do you follow the same principle, or do you use aome animation library?

Edit: Sorry, i got that all wrong :D Ignore that request.

Cheers

Till

tizzle avatar Jun 07 '17 11:06 tizzle

Hey @weddingdj,

i dove into the issue again and have some news! I pushed a new version, so please use this when testing.

Funnily the changed attributes of the camera never make it into the orbit-controls. So there it is not to have a lifecycle method inside the component handle outside manipulation, apart from an event listener looking for changes. I'm reluctant to add something like this, as it would always fire when moving the orbit controls, as i update the camera properties from the component.

Nevertheless i found a way to accomplish what you are looking for that is a little less hackish than setting distance. You simply disable the orbit-controls on the camera, then set the new camera attributes and enable the orbit controls. This will trigger the orbit-control's lifecycle update() method, where i now update the controls position from the camera's position.

You can also see this in action in the basic example.

var cam = document.querySelector('#camera');
cam.setAttribute( 'orbit-controls', 'enabled', false);
cam.setAttribute( 'position', '0 2 10');
cam.setAttribute( 'orbit-controls', 'enabled', true);

Hope you are fine with this. :)

Cheers

Till

tizzle avatar Jun 07 '17 14:06 tizzle

Hi Till,

that sounds great, I will play with it. Thanks!

Cheers!

weddingdj avatar Jun 07 '17 16:06 weddingdj

It works great, there is just one little issue. Since I am animating the model (the target in your code) as well, moving towards the camera, I have to update the target position as well.

What do you think of adding this line of code to the update function as well?

this.target = this.sceneEl.querySelector(this.data.target).object3D.position.clone();

If I don't add this line, the rotation is wrong (I am not sure though why...).

weddingdj avatar Jun 07 '17 22:06 weddingdj

Yep, that should definitely fix this issue. I will add that tomorrow and get back to you.

Cheers

Till

tizzle avatar Jun 07 '17 22:06 tizzle

Hey @weddingdj,

now i'm able to come back to my earlier question, that was totally nonsensical back then :D How do you animate? When using the a-animation to animate, everything seems to work ok.

Do you use some library?

Cheers

Till

tizzle avatar Jun 08 '17 19:06 tizzle

I just thought of an easy-peasy workaround for this. Couldn't you just use another entity as the target? One that you don't animate?

Cheers

Till

tizzle avatar Jun 08 '17 20:06 tizzle

I am just using the basic a-frame animation system. I disable orbit controls, then I move the target from the background to 0, 0, 0, then I enable orbit controls. But if I rotate the target it is wrong, like there would be an offset from 0, 0, 0. But if I set the target position in your update method, it works fine.

weddingdj avatar Jun 08 '17 20:06 weddingdj

I'm a litte unsure how to proceed. In the current version the target's position is simply copied into a variable. This was mostly because i didn't want unnecessary references in the component. This leads to the situation that when the target moves the camera rotation does not follow.

I just played around a little and simply referenced the target object in the orbit-controls, which makes the camera rotation always follow the target. This is quite nice, because it allows to use a separate target entity without any geometry and move that around to different areas of interest. Also i feel this the expected behavior.

But... This also interferes with what you want to accomplish. Say the object should fly in from the top. The camera then would look at the item floating in the air and follow it as it animates to e.g. 0 0 0. For you this would mean you had to use the workaround with the separate target entity i mentioned.

What do you think?

tizzle avatar Jun 08 '17 20:06 tizzle

you could then do something like this:

<a-scene id="a-scene">

  <a-entity
    id="camera"
    camera="fov: 80; zoom: 1;"
    position="0 2 5"
    orbit-controls="
      target: #target;
      enableDamping: true;
      dampingFactor: 0.125;
      rotateSpeed:0.25;
      minDistance:3;
      maxDistance:100;
    "
    mouse-cursor=""
  >

  <a-entity id="target" position="0 0 0"></a-entity>

  <a-entity position="0 -14 0">
    <a-box id="box" position="-1 0.5 1" rotation="0 45 0" color="#4CC3D9"></a-box>
    <a-sphere id="sphere" position="0 1.25 -1" radius="1.25" color="#EF2D5E"></a-sphere>
    <a-cylinder id="cylinder" position="1 0.75 1" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
    <a-plane id="plane" position="0 0 0" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
    <a-animation
      duration="2000"
      delay="500"
      attribute="position"
      to="0 0 0"
    >
    </a-animation>
  </a-entity>

  <a-sky color="#ECECEC"></a-sky>

</a-scene>

tizzle avatar Jun 08 '17 21:06 tizzle

I see you point, and that workaround is a possibility. Thanks!

Btw, I saw on your website that you live in Hamburg, I lived there for 4 years until 2006, close to the Schanze, in der Eimsbüttelerstrasse 13 ;-)

Cheers!

weddingdj avatar Jun 09 '17 01:06 weddingdj

I'm encountering a similar issue. In my web app, I'm using removeAttribute and setAttribute on the camera entity itself:

camera.removeAttribute('animation');
camera.setAttribute('animation', 'property: position; dur: 2000; easing: easeInOutSine; to: ' + camZoom + ';');

This works fine but recently rotating the camera offsets the target, so the animated zoom is off-centre. I'll try using the workarounds above but wanted to highlight in case it helps with a more permanent fix.

ghost avatar Jun 14 '17 13:06 ghost

Hey @CodeMacabre ,

i will look into this tomorrow, as i got some spare time. Will get back to you!

Cheers

tizzle avatar Jun 24 '17 18:06 tizzle

@CodeMacabre,

do you by any chance have a minimal example i can play around with?

Thanks and cheers,

Till

tizzle avatar Jun 25 '17 12:06 tizzle