Recommended Posts

Yo dudes

In my continuing quest to work with Babs for my client project, I'm exploring how to control cameras in response to user actions such as clicking. As usual I have more questions than answers...

The idea is to move the camera to a position in front of a chosen mesh within the scene. I've got a very simple scene going where, upon detecting a click, I create a follow camera, set its position and rotation to the active arc camera, then define the camera target and let it animate to it.

Some questions on this approach:

1) There's a shift in position when switching active cameras from arc to follow. Any reason for this? I set position and rotation to match, but I must be missing something else from the arc camera when switching to the follow camera. Lets face it, I usual am.
2) Detecting a click is a bit of a pain. Not in itself, but when it comes to determining if the user was rotating the scene with the mouse button, or actually clicking a mesh in the scene, when releasing the mouse button it's less than clear. Are there any recommended strategies to follow for this? I looked at the ActionManager example PG (http://www.babylonjs-playground.com/?17) but it has the same issue; if you click down over one of the shapes, move the scene around a bit with the mouse button still down, then move the scene so the original clicked object is under the mouse when you release the button, it's considered a click. Seems obvious to me there should be some clear method to distinguish the two actions, but don't ask me what the solution is because i don't have a scooby.
3) Is there a way to detect when the follow camera finishes animating to the target? Looks like there isn't but I'd have thought this would be useful to someone (me) at some point (now).
4) Is there a way to reverse the animation of the camera. For example once the camera reaches its target, can we make the camera reverse back to where it started with a click of a button?

Probably I'm expecting far too much and I'll have to consider other options (maybe create paths to clickable objects and animate the arc camera along them) but would be great to know for sure.

Cheers!

Share this post


Link to post
Share on other sites

1. Does this help? arc camera has alpha/beta you may need to convert: https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/VR/babylon.vrExperienceHelper.ts#L349
2. Might be able to use the camera inertia (https://doc.babylonjs.com/classes/3.1/camera#inertia-number) to ignore clicks, but I just consider everything a click!
3. If you are doing a regular animation, there is a callback when the animation completes.
4. Reverse the frame keys of the animation and it will play backwards - ie: finish at previous start and start at previous finish.

 

edit: if you are customizing arc rotate camera a lot, maybe check out the new behaviours: https://doc.babylonjs.com/how_to/camera_behaviors

Share this post


Link to post
Share on other sites

Hi guys!

  https://www.babylonjs-playground.com/#199WQ0#4

Wingy goofing-around with animating an arc-cam .lockedTarget... to clickedMesh positions.... including ground.  (click ground to return cam back to starting place)

*shrug*.  Thinkin'.   Trying to avoid switching to followCamera, and instead... trying to make an arcCam act like a followCam somewhat  (via .lockedTarget).

If the picked mesh is moving, you'll need to determine a method to keep the future-invisible locked camTarget... in same position as selected mesh.

If clicked mesh is not rotating, then just parent the (invisible) camTarget... to the moving selected mesh.

But if the selected mesh is spinning around... you might want to avoid parenting, and just use render loop to keep camTarget in same position as selected mesh.

I dunno.   FollowCamera does some nice things when followed mesh takes corners... but... *shrug*.  I'll do more tests and thinking, which will surely back-slide the entire project.  hehe.

Also notice... you can still drag-pan the camera okay, without triggering a click-on-ground.  But, yeah, the discrimination/threshold between cam-drag, and ground-click... are strange, eh?

PointerDown, wait awhile,  move-a-little, pointerUp === camera drag-pan.  PointerDown, wait awhile, pointerUp === click on ground.  :)  Is there a little robot or computer... that makes that decision?  He checks the amount of time button was held, and distance the pointer moved, then sends it to the jury, for deliberation?  "Was it a cam-pan?  Was it a ground click?"  hehe

I wonder if .angularSensibility and .panningSensibility are involved?  I've never played with those.

We also have an ArcFollowCamera!  I hope it has a "onTargetPositionChanged" observer.  :) 

But all in all, I bet .lockedTarget, and .target, and .setTarget()... for an ArcFollowCamera... are FUN to play-with!  :)  A whole afternoon of demented camera experiments, for sure! 

And think about the followCamera.  A GREAT one... is essentially an "easing festival", right?  Well look at this pig... https://www.babylonjs-playground.com/#HH1U5#59

Look at lines 196-236.  Look at all those pre-made easing "things".  Now, if you could teach an ArcFollowCam... to accept those "snap-on" easing functions... you'd surely become the God of the ArcFollowCamera, and be a BJS hero.  It might already be easily possible/ready-to-go!  Usefulness?  Probably not much.  :)  The followCam family would probably thank you for the feature addition.  ArcFollowCamera.easingFunction = function(){};  Currently, it looks like the follow camera doesn't do much easing.  That's why I applied the easing to the camTarget animations, too.  We made our own arcFollowCam... with ease (ar ar ar).

Still, though, a follow camera really needs to act like it is being dragged-behind the mesh on a cable (especially for chase plane views).  Waterskier-cam view.  :)  And the "easing" needs to be applied-to "the whip".  ie.  How much was the camera-person "deeked" by the abrupt turn of the fast-moving followed mesh?  How much over-compensation from trying to correct? (overshoot).  Cam-on-a-trailer...  at 100 mph behind a Ferrari, on a curvy mountain road, with black ice.  :)  "Ok, mister followCam... let's see how well ya follow THIS!"

I smell joint grease and physics engine ozone.  Smell it?  *nod*.  hmm.

Share this post


Link to post
Share on other sites

Hey Wingnut

Thanks for taking a look at my question, I like what you've done with the test scene you created. It's interesting that your approach seems to have a higher threshold for ignoring ground clicks than my demo did, so I'll try implementing the actions the same way you did. Probably the easiest way to avoid a click on the ground is to simply filter it out of the resulting event function; you already have it commented out with "//ground.isPickable = false;", so just need to add a check in the event and return if that isPickable flag is false.

For my problem however, clicking the ground isn't so much an issue as discerning the difference between an intended click and a click - drag - release = click. So in your test scene you can click over a shape, rotate the camera with the mouse button still down so that the cursor exists the shape, then rotate the camera so the cursor is back over the clicked object, release, and it is detected as a click. That's going to be an issue for me at some point I feel. One might expect there to be a timed check between mouse down and mouse up that determines that "no, the mouse button has been down too long, this can't be a click" going on behind the scenes in the mouse events, but it doesn't appear to be the case.

I dunno, maybe I'm worrying too much about that particular issue. My scene's main surface area is probably not going to be clickable so in reality the chances of someone mouse-downing over a clickable object, scrolling around, releasing over the same object, and not exacting a click action is probably quite thin. If that happens though I'll just look in to some timer based check.

 

Share this post


Link to post
Share on other sites
1 hour ago, Snouto said:

in your test scene you can click over a shape, rotate the camera with the mouse button still down so that the cursor exists the shape, then rotate the camera so the cursor is back over the clicked object, release, and it is detected as a click.

Yeah, ain't that weird?  :)  hmm.

Check this out:  http://doc.babylonjs.com/how_to/how_to_use_actions#triggers

"BABYLON.ActionManager.OnPickOutTrigger: Raised when the user touches/clicks down on a mesh and then move off-of the mesh."

What could we do with that?  Let's try some crap...

https://www.babylonjs-playground.com/#199WQ0#5

Added 2nd action... onAnyMeshPickOut.  But guess what?  It doesn't trigger WHILE a camera drag is underway.  AND it doesn't trigger if pointerDown on mesh, pan camera, and pointerUP on same mesh.  Our pickOutTrigger sees that as "pointer never left the mesh"... even though we went panning.  hmm.

An interesting challenge/quagmire, Lord Snouto.  Thanks alot!  hehe.  Just what we needed... yet another brain tumor.  :D

Hover, pointerDown, drag-pan, re-hover, pointerUp... that's the magic sequence under test.

Customer desires:  If pointer un-hovers after pointerDown (cam drag), cancel all chances for mesh OnPickTrigger.  (I think I got that worded correctly).

Why I felt I needed to re-state?  I dunno.  :) 

Share this post


Link to post
Share on other sites

I aim to seize(ure). I aim to please... I aim to seize.... yeah never mind

Your latest test is interesting. Mouse down inside an object, move ever so slightly so you don't exit the object, then release. no click (your previous test will register that as a click). But if you move the camera just enough to exit the object, then go back to the object and release, detects a click. very odd. Pity because we want the exact opposite!

I'm not going to worry about this. Like I said, chances are this will be an edge case in my scene and worst come to the worst I'll stick some timer on the mouse down while recording the clicked mesh, and check the delta & mesh on the mouse up for a threshold amount of say 500ms, and if it's above that or a different mesh discard as a click. Not ideal but it will work I think.

Or maybe use BABYLON.ActionManager.OnLongPressTrigger in conjunction with OnPick, setting a flag to true in OnLongPressTrigger that I check for in OnPick or maybe OnPickUpTrigger. If there's one thing I'm good at, it's hacking stuff together!

Hmm well this is also interesting. In the scene class:

/** The distance in pixel that you have to move to prevent some events */
        public static DragMovementThreshold = 10; // in pixels
        /** Time in milliseconds to wait to raise long press events if button is still pressed */
        public static LongPressDelay = 500; // in milliseconds
        /** Time in milliseconds with two consecutive clicks will be considered as a double click */
        public static DoubleClickDelay = 300; // in milliseconds

I wonder if there's something in there we can utilise.

Seems like my previous plan using long press is being foiled, and looking at the code i think it's because the event is tied to initial clicks over meshes (it's not a general long press event) and also depends on that DragMovementThreshold value:

https://www.babylonjs-playground.com/#199WQ0#6

If you click hold over an object without moving, the event is fired. If you move around though the event never fires.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.