Jump to content

How to make camera snap to rotation point?


Recommended Posts

Hi ozRocker!  Yes, that is quite doable, and in many ways.  One of the problems is that IF the camera is attached to the canvas, then that camera is also the user's main camera, and your "camera .alpha snapper" will get in the way of the user doing drag-panning of their main camera.  (.alpha is the property on an arcRotateCamera that pans it around the Y axis).  But you might want more than Y-only rotation.  Read on.


For our discussion, let's pretend there is a NEXT button or keypress, and that we ARE using the user's main arcRotateCamera.  So, we want to turn the user cam to the NEXT target, but then the user can still do manual drag-panning if they choose.  Sound ok?


Another decision... should the camera go to the next target RIGHT NOW, or should it gently animate to the next target?


Animating the camera to the next target (with optional in/out easing of 12 types of interpolator adjustments or write your own interpolation formula)... is a bit more complicated, but looks LOTS prettier when done.


Can you give us some more details?    Thoughts?  :)


I have been studying Babylon.js animations lately, and have talked about it, starting here, and it continues to thread-end.  It's way way talkie, and likely far more information than you can stand or want.  Generally speaking, meshes, cameras, and lights... have an array property called .animations.  Inside there, you can put BABYLON.Animation-class obects.  Often, they are in there just long enough to complete the animation move, and then they are destroyed.  You CAN re-use stopped animations with our brand new reset() option for animaTIONS and animatABLEs, but I haven't tried it yet.  I'm not sure if you can set a new KEYS before the reset().  Such a move is not really RESETting an Animation, but instead re-using it as a DIFFERENT animation... and I'm not sure it's possible (unlikely).  But it's easy to dispose() a completed/stopped animation and make a new one... for the NEXT animation to the NEXT target.


So, your nextTarget() function will need to build an animation from camera.target (its current target)... to newTarget or newTarget.position (where you want the camera to target next).


This is NOT ONLY a Y-rotater system.  This is a "wherever the camera is aimed" -to- nextTarget -mover.  Would that be ok?  I think you will really like the way an animate-to-next-target ... looks... when you are done... and I think you will be glad that you used animation instead of an "instantly-be-there-now" move.


Let's look at our classes hotlist:  http://babylondoc.azurewebsites.net/page.php?p=24845


Choose arcRotate.  ( http://babylondoc.azurewebsites.net/page.php?p=24872 )


See that the arcRotateCamera has a 'target' property.  That is the secret to your success.  See that its preferred data type is ANY, so maybe you can use a mesh there (like nextTarget mesh) or a vector3 position (like nextTarget.position).  Maybe either will work!  (cool)



I will help you more if you need me to.  Others will, as well.  You actually have everything you need, now.  You can read and steal animation code from that talky thread I gave you (and its playground demos), and you can apply those animations to your camera.target. 


Keep in mind that you can get a handy list of all non-light, non-camera scene items (meshes) that are in the scene.  Check the Scene class for the correct property or func)... or make your own array of mesh or mesh.positions for your nextTarget() func to use. 


I would dispose() all Animation objects in camera.animations prior to building a fresh one for each NEXT.  You might want to make a killOldAndBuildNewCameraAnimation(numberOfKeyFrames, newTarget.position) function that is called BY your nextTarget() func.  Tools to help tools to help tools, ya know?  :)


Just to be fair, we also have a cool device called an ActionManager... and it can be put on a Scene, and/or on a mesh, camera, or light.  (Many ActionManagers in a single scene, is common.)  That device would make it easy to CLICK-ON (pick) the nextTarget, and the camera will animate to aim at that target.  The ActionManager will build the animation/keyFrames FOR you, and/or you can write your own interpolator formula if you like (interpolator = math/code used to calculate the animation's trajectory).  I am not sure if an ActionManager can use our pre-built easing formulas, but you can copy their code...  into an ActionManager interpolator... maybe.  Otherwise, the ActionManager uses 'linear' interpolation... sometimes called LERP.


Your post sounded like you wanted to snap to points of interest... WHILE the user was panning the camera.  Do you see that you will be taking control of the camera WHILE the user is controlling it?  I don't think you or your users will enjoy that, but maybe.  It might be wiser to "outline" or "showBoundingBox" or maybe flash the colors... on points of interest... as the user pans.  That way, you aren't stealing camera control, but you are still pointing-out the things you want the user to examine more closely.


Good luck, keep us posted.  I'll make a demo for you if you run into troubles or want more assistance.  Be well.  Others may have more ideas.

Link to comment
Share on other sites

Man, that's beautiful!  Nicely done!  Wow!


Yeah, I think I would put a left and right arrow at the top center of the screen.  Some FANCY arrows... commensurate with the beauty of the scene.  A couple planes with nice arrow textures.... maybe constantly rock them back and forth a tiny bit to make specular shines pass across them... click either... and go to one of the 4 (so far) auto-alignment locations, eh?


Parent the arrow planes to the camera (plus some offsets)... and they will remain top-center. 


Or you could make them be part of an invisible HTML toolbar and be animated pngs/gifs (absolute positioned html).  You might have a need for more buttons or info along the top edge of the screen someday.  *shrug*


Nice scene.  Nice presentation taste.  Good stuff!

Link to comment
Share on other sites

Oh yeah, you are still looking for a WAY to do this, eh?  heh.  Sorry.


Um...  you don't need animations for this, but you still CAN use them if you like.  Here is a simple playground where I did some camera.alpha stuff in the renderLoop (registerBeforeRender).  Might be interesting for you.




There is some serious accuracy drifting because of the way I'm doing this (with soFar).  It's bad coding.  (sorry)


Maybe something in lines 20-40 will assist.  I'm not a very good programmer, so it's likely others (or you) will find more efficient ways.  :)


I did think of one other cool way.  Don't animate camera.alpha.  Instead, animate an invisible camera target ... to pre-set locations behind each text plane.  As the invisible target moves from one "behind the text" location, to another... the camera will follow it (and do an ease-in and ease-out automagically)...  but you probably need to do constant camera.setTarget(target) in the renderLoop, because most of our cameras don't have .lockedTarget.  But check, maybe arcRotate does.  *shrug*  You'll also be doing the target moving in the renderLoop, if you don't use Babylon Animation objects/system.


Inside the renderLoop... you know... if (camera.target.position == myPresetBehindTheTextPosition) { this animation is done, quit moving the target for now } else { keep on going }   Fun challenge!

Link to comment
Share on other sites

I just posted in the from thread because I confused the browser tabs and didn't figure out how I can delete that post. So just ignore me ;)


Well, I thought since I have this post now anyway, I could also do a playground on the matter (it's pretty much the same as wingys)  :P




When you click anywhere the camera rotates to the next object. You could combine that with the arrows that wingy suggested (maybe even 3D arrows? ;) ) or you could implement something like touch events. You know, when you swipe left the camera turns to the right... you kinda reduce the amount of control the user has over how far the camera turns. Also you probably would have to implement some easing for the turning animation or use a different way to animate the turning altogether like wingnut suggested.

Link to comment
Share on other sites

thanks for the tips guys.  I'll try out a few options and see which one is best.  It would still be neat to allow the user to have full control to rotate where they want then to add snapping to that.  It just gives a bit more interactivity

Link to comment
Share on other sites

You can also have a kind of smooth transition to the nearest target: http://www.babylonjs-playground.com/#JE6HE#1

It should be possible to ease out things even more with easing functions!

That's awesome!  Pretty close to what I'm looking for.   I wouldn't want snapping to happen all the time though.  I only want to snap if the camera is a close distance to the snapping points, so they have the option of stopping where ever they want (as long as its not close to snapping points)


EDIT: I tried it out and I think your way is better than what I initially envisioned.  The user still has control and I don't see any reason why they really need to stop and stare at a blank corner.

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.

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.


  • Recently Browsing   0 members

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