Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dynamically changing camera position #14

Open
weddingdj opened this issue May 26, 2017 · 18 comments
Open

dynamically changing camera position #14

weddingdj opened this issue May 26, 2017 · 18 comments
Assignees

Comments

@weddingdj
Copy link

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!

@tizzle
Copy link
Owner

tizzle commented May 27, 2017

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
Copy link
Owner

tizzle commented May 31, 2017

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

@weddingdj
Copy link
Author

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. :-)

@tizzle
Copy link
Owner

tizzle commented May 31, 2017

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
Copy link
Owner

tizzle commented Jun 7, 2017

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
Copy link
Owner

tizzle commented Jun 7, 2017

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

@weddingdj
Copy link
Author

Hi Till,

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

Cheers!

@weddingdj
Copy link
Author

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...).

@tizzle
Copy link
Owner

tizzle commented Jun 7, 2017

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

Cheers

Till

@tizzle
Copy link
Owner

tizzle commented Jun 8, 2017

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
Copy link
Owner

tizzle commented Jun 8, 2017

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

@weddingdj
Copy link
Author

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.

@tizzle
Copy link
Owner

tizzle commented Jun 8, 2017

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
Copy link
Owner

tizzle commented Jun 8, 2017

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>

@weddingdj
Copy link
Author

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!

@ghost
Copy link

ghost commented Jun 14, 2017

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.

@tizzle
Copy link
Owner

tizzle commented Jun 24, 2017

Hey @codemacabre ,

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

Cheers

@tizzle
Copy link
Owner

tizzle commented Jun 25, 2017

@codemacabre,

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

Thanks and cheers,

Till

@tizzle tizzle self-assigned this Jun 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants