Jump to content

Trying to animate the target of a Universal camera


Zephos
 Share

Recommended Posts

So after hours of research and finally posting here (thanks Delkatosh), I was able to get this little demo working where I switch between cameras with different control systems when selecting a sphere: http://www.babylonjs-playground.com/index.html#VDZ7IF#3

Now, however, I would like to animate that switch when the sphere moves to the center of the screen. I tries to animate the rotation using some code from this playground: http://www.babylonjs-playground.com/#WG9OY#28

And came up with this: http://www.babylonjs-playground.com/index.html#VDZ7IF#4

But it clearly doesn't quite work the way it should. All my previous attempts to animate the target property have failed as well.

I think I got some moderate success animating the lockedTarget property like this: http://www.babylonjs-playground.com/index.html#VDZ7IF#5

...but that breaks the universal camera so it can't freely fly around again after you deselect the sphere. So I am wondering if there is a way to unlock the universal cam (I tried setting it to null, but to no avail) or some other way to make this work? Animating the target or _currentTarget property didn't work either. 

As a side note, what is the difference between target, lockedTarget, and _currentTarget? I am so confused by all this and the API gives very little descriptions of any properties. 

Thank very much. I will certainly return the favor and answer people's questions when I become an expert haha.

EDIT: So I don't know what happened but setting lockedTarget to null seems to be helping now: http://www.babylonjs-playground.com/index.html#VDZ7IF#6

However, under certain circumstances the switch from universal to arcRotate after moving the camera a lot causes the camera's view to twist so the view doesn't stay the same as you select and deselect the sphers. More importantly, however, the animation only takes the right amount of time when selecting between the two spheres because when nothing is selected, there isn't a starting position for lockedTarget. I tried setting to _currentTarget but that didn't seem to work.

Anyway, I am very grateful for any help I can get on this.

Link to comment
Share on other sites

Hi Z!  I did a little experimenting (and heavy mods)...  http://www.babylonjs-playground.com/index.html#VDZ7IF#7

Got some smooth animating upon selecting... but...  if you nav the universal cam (chosen by having nothing selected as blue) to some strange position, and then select a mesh... it jumps.

This is because universal camera really has no target.  If there IS a target, it is probably 1 meter forward-of the camera's position. 

And, ya can't set a universalCam.lockedTarget, or else it loses its abilities to nav-around.  hmm.  (unless you move the lockedTarget position the same amount as all camera moves).

Anyway, a little note:  This thread is sort-of a continuation of http://www.html5gamedevs.com/topic/40227-smooth-transition-between-camera-control-systems/

(in case anyone cares).  Yep, this is a difficult challenge.

I have a bad idea.  :) Let's say you NEVER change to universal camera.  Instead, you wire-up the cursor keys or WASD keys... to move-around an invisible mesh (like a box).  This box IS the arcCamera's .target... all the time.  SO... user THINKS they are driving-around a universal/free cam when no mesh is selected (nothing turned blue).  But really... they are moving around an invisible box... the arc-Cam's .target.  This would give the arcCam SOME free-navigation power... yet when a mesh is selected, arcCam.target could be easily animated/moved to match selectedMesh.position. 

*shrug*.  Yeah, an arcCam that let's you nav-around it's .target with cursor keys... will not act the same as a universal/free cam... but it will give SOME freedom of navigation.  Unfortunately, it might also "look odd".

I will keep thinking.  This is tough, though.  The switch from universal... to orbit/arc cam... is trouble.  Hopefully, others will have better ideas... but... hmm.

Link to comment
Share on other sites

So:

- target is a free target (ie. it will move when you move the camera)

- lockTarget is a locked target: you can't move the camera anymore (at least the target, the camera can still move on its position but its target will remain readonly)

- _currentTarget like any _property MUST NOT be used, touched, considered, seen :) They are internal properties

 

So to your question,let me first set up some context:

- arcRotateCamera uses 4 properties:

 - alpha: rotation on X axis

 - beta: rotation on Y axis

 - radius: distance from target

 - target: vector3 defining the position of the camera

 

- FreeCamera uses 2 properties:

  - position: Vector3 defining the position

  - rotation: euler angles defining the rotation

 

So when moving from one type to another, you can always read the target and the position (as read only values) to get the current state. Then if you want to update the new camera based on the previous one you can call setTarget() and set the position (writing to position property for FreeCamera or calling setPosition for ArcRotateCamera (as this camera has no writeable position based on the list of properties I mentioned earlier))

For animation, this is a different beast: for instance if you want to animate the rotation of the ArcRotateCamera you have to animate alpha and beta properties. This is feasible (you can store the current values, call setTarget to where you want it to look at, get the new values and then create an animation  (2 actually :)) for alpha and beta.

 

Link to comment
Share on other sites

1 hour ago, Deltakosh said:

So when moving from one type to another, you can always read the target and the position (as read only values) to get the current state.

Thanks, that helps a lot.

Can I get a target property from a Universal camera? I never actually see that property on the object when I log it, so what value will it provide?

I think what you are suggesting is that I move the ArcCamera to the position of the UniversalCamera, switch cameras and then animate the ArcCamera camera to the new position. My current approach was to animate the current camera, THEN switch. Either way makes sense. The problem is getting the two camera rotations to match up. Your suggestion seems like a work around that could work, where we force the arc camera to a position just to get the starting alpha and beta to animate from, but I am unsure if it would produce good results. I will try it tonight though.

Also, isn't there a way I can take the new alpha and beta values that we want to end up with and translate those into a rotation for the Universal Camera to animate to, or better yet, to set the rotation on the arc rotate camera to match the universal camera so the view subject stays in the same orientation to the camera? This last part is what I am ultimately trying to achieve. When you click on a sphere, it should just move to the center without any orientation changes, and when you deselect it, the orientation should not change. Currently this doesn't happen because the cameras have different rotation paradigms and I don't know how to resolve this.

Thanks for your help.

Link to comment
Share on other sites

Sorry I may have been unclear. Let me try to rephrase. Based on the properties I gave you earlier, if you want to animate the rotation, you need to get the target (for FreeCamera) or the alpha/beta (for ArcRotatecamera). That's it!

Pseudo code when switching to ArcRotate:

- get current target (scene.activeCamera.getTarget())

- store orBitCamera.alpha/beta

- call orbitCamera.setTarget(currentTarget)

- get alpha/beta and store them (targetAlpha, targetBeta)

- restore orbitCamera.alpha/beta

- create two animations (one from currentAlpha-> targetAlpha, one from beta->targetBeta)

- Enjoy

 

Pseudo code when switching to FreeCamera:

- get current target (scene.activeCamera.getTarget())

- store freeCamera.rotation vector

- call freeCamera.setTarget(currentTarget)

- get rotation and store it into targetRotation

- restore freeCamera.rotation vector

- create animation from freeCamera.rotation to targetRotation

- enjoy

Link to comment
Share on other sites

Thank you Deltakosh,

I will try to get it working tonight when I am home.

 

1 hour ago, Deltakosh said:

Actually, if you play around with that one, I think something strange is happening. If you select and deselect a sphere, the mouse controls start to rotate the view around a center point instead of just pivoting from the camera. That leads to the orientation twisting when you change cameras. You have to keep playing with it and rotating and selecting things to get it to happen, but it happens enough to be a problem.

Do know why the controls would do that? Could it be doing that because of the rotation restriction? I am at work but I will try to play around with it more later. Thanks.

Link to comment
Share on other sites

2 minutes ago, Deltakosh said:

I do not repro this problem :( Can you precisely tell me how you do it? (video perhaps?)

Here are some simple steps to reproduce it: 

Load the scene.

Zoom out a little with down arrow key.

select the left sphere.

rotate the camera with mouse to make the red sphere go above the blue one.

click the blue sphere to  deselect

click and drag mouse to the right (notice how the spheres travel in an arch, not straight). This changes the spheres orientation to the camera.

Now select one of the spheres again. The sphere gets centered, as it should, but the orientation changes. Both spheres should just slide over in the orientation they are already in.

Hope that helps.

Thanks. I can do a video later if needed.

Link to comment
Share on other sites

Ok this is interesting! This is because of that: "rotate the camera with mouse to make the red sphere go above the blue one."

In this situation the FreeCamera is perpendicular to the target (ie: the target and the position are on the same x and z values). 

This is not supported by the FreeCamera and it will end up with messed up data :)

 

So you have to add a check to make sure that we are not in this situation

 

Link to comment
Share on other sites

2 hours ago, Deltakosh said:

Ok this is interesting! This is because of that: "rotate the camera with mouse to make the red sphere go above the blue one."

In this situation the FreeCamera is perpendicular to the target (ie: the target and the position are on the same x and z values). 

This is not supported by the FreeCamera and it will end up with messed up data :)

 

So you have to add a check to make sure that we are not in this situation

 

Oh okay... so why is that not supported? I bet the answer is complicated so if it is you can just say so. I just don't understand how the z value would be the same, though , as the rotation occurs around the z axis I believe, so the z isn't changing.

So I can easily start the camera in a different position, but how do I avoid this from happening naturally as the camera moves around? Where do you suggest I put a check? When the target is set, perhaps?

UPDATE: I just tried changing the starting position of both cameras and that did not fix the issue.

 

Link to comment
Share on other sites

The problem is not Z but Y. FreeCamera cannot be perpendicular on Y axis (which is the up vector) because of how the maths are done internally. It is a bit like your head. There is no way your head can look to your feet in a perfectly aligned way :)

I'll do it for you (but this is exceptional, do not get use to it :)): http://www.babylonjs-playground.com/index.html#VDZ7IF#9

Check line #35

Doc: http://doc.babylonjs.com/api/classes/babylon.arcrotatecamera#lowerbetalimit

Link to comment
Share on other sites

1 hour ago, Deltakosh said:

The problem is not Z but Y. FreeCamera cannot be perpendicular on Y axis (which is the up vector) because of how the maths are done internally. It is a bit like your head. There is no way your head can look to your feet in a perfectly aligned way :)

I'll do it for you (but this is exceptional, do not get use to it :)): http://www.babylonjs-playground.com/index.html#VDZ7IF#9

Check line #35

Doc: http://doc.babylonjs.com/api/classes/babylon.arcrotatecamera#lowerbetalimit

It is still broken. If you follow the steps I posted earlier, then try to move the free camera with your mouse, it doesn't behave properly (the view rotates instead of pans with the mouse). Something is getting screwed up when you attach controls for the orbitCamera... something global I think. I have tried noRotationConstraint, I have tried cloning the free camera before changing it and then switching back to the unchanged version (which then starts behaving incorrectly)... I think I am at a loss.

Thanks again,

Zephos

Link to comment
Share on other sites

3 hours ago, Deltakosh said:

The view always rotate when you use the mouse with the FreeCamera. Not sure to get your point here.

I suppose it could be the intended behavior, but could you help me understand why, as soon as you load the scene, using your mouse to drag the view just drags the view in linear fashion. The view does not travel in an arc if you drag the mouse straight across horizontally, but it does as soon as you select and rotate the spheres around and then deselect. Once you do that and return to the free camera, the mouse starts rotating the scene. That's fine I guess... but why does it not do it at the very beginning?

Thanks Deltakosh. I know I am probably being frustrating so I apologize for that.

Link to comment
Share on other sites

Zeph, when you load the scene... then drag left/right... the camera is rotating around its Y axis.  It is NOT side-sliding (slewing/strafing).  But I think you CAN side-slide a universal/free cam... by holding down the control button while dragging.  Not sure.  It works on non-lockedTarget arcCams, anyway.

And after you de-select a sphere and return to universal cam, dragging left and right does the same thing... rotates the camera around it's Y-axis.

You MIGHT be getting an "optical illusion" when you drag the mouse just after loading.  You THINK it is side-sliding, but it isn't.  It is "panning" (turning around Y)... which IS a type of arc/orbit, but it is a rotational orbit around itself, and not a rotational and translational orbit around an external target (like an arcCam would do).

Anyway, http://www.babylonjs-playground.com/index.html#VDZ7IF#10

This STARTS with the arcCam instead of the universal cam.  It is initially set to orbit around external target 0,0,0.  The camera's position is 12 units away from 0,0,0.

But I don't think you WANT to start with an arc.  I think you are getting fooled.  In PG #9,  the initial camera is doing exactly the same thing... as when you have selected and then deselected a sphere (return to universal cam after a switch to arcCam).  I think both are behaving the same... both spinning around their Y-axis (panning).

Am I wrong?  I could be.  :)

Link to comment
Share on other sites

@Deltakosh  Thanks... but... I'm not sure I understand problem.   The scene needs more mesh... to keep from confusing pan and strafe.  :)  

Two spheres leave view - difficult to determine if panned-out-of-view, or side-slide out-of-view.  Fun with 3D.  :)  I think Zephos was thinking that default cam was side-sliding on drag.

We will listen for Zephos... see if he has more words... and keep working/trying.  :)

Link to comment
Share on other sites

11 hours ago, Wingnut said:

@Deltakosh  Thanks... but... I'm not sure I understand problem.   The scene needs more mesh... to keep from confusing pan and strafe.  :)  

Two spheres leave view - difficult to determine if panned-out-of-view, or side-slide out-of-view.  Fun with 3D.  :)  I think Zephos was thinking that default cam was side-sliding on drag.

We will listen for Zephos... see if he has more words... and keep working/trying.  :)

Hey guys thanks again for all your help. I think I was just being thick headed more than anything.

Honestly I think I was just confused about the rotation. I knew the drag was rotating the camera around the Y axis, but the fact that Y rotations are applied first before the other rotations was throwing me off I think. I was expecting the rotation around Y to be relative to the camera's orientation, but it was the first one applied so the orientation it was relative to was always the same. I have started implementing my own control system following the documentation where I will apply the rotations in local space in a different order. I think I have come up with a better idea for my controls too, which doesn't involve switching cameras. After thinking about it, the only feature of the arc rotate camera I really needed was the ability to center on object in the view, and I can do that with any target camera. Orbiting was a nice touch, but one I can do without and probably isn't worth the trouble.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...