OnPickTrigger : scene.activeCamera =

Hello everybody,

First of all - thank you for the great work you’re all doing.
Also (in my case expecially) on the documentation, videos and forum.

My question:

I want to trigger “click through / swipe” the active camera witch OnPick or OnIntersectionEnter of a Mesh in the ActionManager. Each camera has a baked animation exported in Blender with the BJS exporter addon.
There are 4 cameras imported from a gltf. All of them can be triggered with
scene.activeCamera =
but not one after the other.

Please help :face_with_peeking_eye:

Here’s the PG: https://playground.babylonjs.com/#AGPZEK#2

Welcome to the community!

There’s a few issues with your PG, let’s work on them :slight_smile: First, the github link of the asset needs to be changed to avoid CORS issue, you can read about it on: Using External Assets In the Playground | Babylon.js Documentation (babylonjs.com)

Here’s a fixed link: OnPickTrigger | Babylon.js Playground (babylonjs.com)

And with that link, I don’t see multiple cameras on the GLTF? Just a sphere and a cube.

1 Like

Thank you!

I tried to narrow it down with a less complex GLTF.

This one is fully working:

You still have a number of small issues in this PG.
addMouseWheel generates an error. This isn’t the right method so I removed it for now. We can come back to this later.
Essentially, the main issue why nothing is working from your action is that ‘scene’ only supports 3 types of triggers and the pick trigger is not part of it. It’s for mesh only. Please refer to this section in the doc.

I quickly changed your trigger method to demonstrate that it works with a key up. Press ‘R’ to switch camera.

Now, I’m not sure what exactly you want to achieve. What should trigger a new camera and which camera to choose from this action. If you don’t manage after reading the link above, may be you could try explain a little bit further?

Meanwhile, I hope this helps and have a great day :sunglasses:

Edit: I was just looking back at your file and… is it supposed to be a sequence of cameras? Like at the end of each animation, you want to change camera and start the new camera animation? So, it wouldn’t be the user changing camera? In case, you will need to act on the parent node of the camera and its animation (onAnimationEnd) to create a sequence. Currently, you are just switching camera.
As I said, some more explanation would sure help us give the correct input.

1 Like

Thank you mawa - of course this helps!

The action by the user is supposed to trigger one animated camera in the root node after the other:
First: camera3
Second: camera2
Third: camera1
Last: camera0

Is there a better way to act on the parent node than to use the actions available for scene?

The trigger should be an input (touch or click) by the user, not just onAnimationEnd :thinking:

Have a great day as well!

Just to make this clear:

  1. The camera switch is done on user input and at any time of the animation, correct?
  2. The order of switching camera is ‘forced’. On each click, the next camera in order becomes active and when the last camera is active, it returns to the first one, correct?
  3. And when switching camera, the animation of the new active camera starts from the first frame, correct?

Oh, and a last question:
4) Are you sure you really want to switch camera on each click/touch in the canvas? I suppose you realize that activating the canvas will also trigger the camera switch? And each time the user touches or clicks (anywhere?) in the scene it would switch camera!? Honestly, from a UX perspective, I don’t find this all too good (of course, my opinion only).

  1. The camera switch is done on user input after the animation. The loop will be removed.
  2. The order of switching camera is ‘forced’. On each click, the next camera in order becomes active and when the last camera is active, it returns to the first one.
  3. And when switching camera, the animation of the new active camera starts from the first frame.

You’re right about the UX considerations - much appreciated! Best scenario would be to have links/buttons in an overlay as a next step to act on the node and/or the camera animations.

I would use

import {DefaultStage} from ‘./node…/babyonscene.js’;

as shown here:

But my request is for an actionManager to click/touch through the animations.

You’re lucky I was just here when you posted :wink:
FYI: To communicate directly with members or the team, use @, @mawa. This will make sure we are notified :smiley:

Yes, I think so. I believe a small cam icon in a corner wouldn’t harm.

It’s easier when we have the full case scenario. Although, I (or we) will eventually not provide with each and every detail :wink: But, at least the approach will be more accurate towards the final result/behavior.

Did you consider the BJS GUI? It’s powerful, simple and all built-in. Though, you can sure use the UI you want :smiley:

With the above, I think I have enough to quickly sketch you something. Knowing that there are always more than just one approach and method to it in BJS (one of the many reasons why I love this framework :smile:). Give me a couple of hours, will you? Right now, is launch time for me, but after that I shall quickly set-up a PG for you that should at least give you some clues…


Without further waiting, here below my first rush of the updated behavior. Missing is the handling of camera switch ONLY AFTER animation end.

In this PG, there’s no actionManager anymore.

  1. Actions are triggered through the click/touch on the camera button, currently to the bottom right and represented by a default ‘cog’ icon from the BJS asset library. Sorry, there’s no cam icon in the library. Just imagine it would be a camera icon (and next, replace the image with your camera icon :wink: Didn’t I tell you I won’t do everything for you :joy:

  2. So the button now triggers the camera switch and in order to change cameras in the correct order, I have assigned a numeric/integer ID to all cameras. Cameras now have an id from 0 to 3. In the button interactions, onPointerDown and before triggering the switch in camera, I retrieve the current id of the camera from a (local) variable. Then I increment this id by one, except if the id is higher than the last camera, I return it to 0 (zero).

  3. Using the camera id (and stored camId variable), onPointerUp I perform the camera switch making for the ‘activeCamera’ and also for the ‘controls’ of the camera.

I will quickly enhance it with the handling of the animations. This will be done by adding some parameters to the animation themselves (like no loop) and triggering the variable I already created to monitor the state of the animation with an onAnimationEnd for each. Then, we’ll simply add this camState variable as a condition to actually trigger the camera switch.

Shouldn’t be all too long…

Sidenote: For the button, I have made a very basic ADT (Advanced Dynamic Texture) layout from the BJS GUI. But as I said, it could be HTML/DOM as well. And then of course, as I said, this is just very rushed… The BJS GUI lets you do beautiful and fully integrated UI… Trust me on that :smile:

OK , again just roughly done.
Currently only through the ‘animationGroup’ state (assuming all animations are of the same length), you could simply do it this way. Animation group is first stopped, which removes the loop. We play the animation group on each triggering of the camera switch. At the same time, we set the variable of camstate to ‘animation in progress’ (1). In button interactions functions, camera switch can only occur if the variable passed through the onAnimationEndObservable is set to ‘animation ended’ (0).

Let me know if anything. Else, I hope this will help anyways.
Meanwhile, have a good one :sunglasses:

EDIT: Quickly added grayed out button while animation is playing so to detect when the button is active or inactive. Can be done in many ways, including completely disabling the button when animation is in progress. Else, open the ‘inspector’ and the ‘console’ to see the states and infos.

1 Like

Amazing! Thank you so much.
The button isn’t working outside the playground yet but maybe that’s also because BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI doesn’t work yet.

Do you maybe have a suggestion on how to find a way to trigger a button with a link from index.html that produces an overlay?

What do you mean by saying ‘the button is not working’. Are you doing a react project or something?
Then, I also lately found that since we allow the user to interact with the camera, we would likely need to add a reinit of the camera position and rotation to the initial when switching camera. This can be done easily and (again) in a number of ways. Essentially, we would need to capture and store the initial position and rotation at frame 0 animation for all cameras and pass them on when switching cam. We can either store it in a variable or as a base string in the parent camera node’s id (and I’m sure there are other methods). May be also use a function for camera switch instead of having everything in the pointer observable. Doesn’t really change anything but might be better organized and more versatile for later changes/adaptations.

If you wanna go the route of the html UI overlay, may be have a quick look at this section in the doc. And there are a number of examples available, including in this forum. Make a search for something like “html + gui” or “html + ui”. You can try set-up something and if you’re stuck, come back here anytime of course :smiley: Meanwhile, gl with your project and apprenticeship and have a great day :sunglasses:

Edit: to use the GUI, you need to make sure you load the script (or from your NPM package), ensure you have:

    <script src="https://cdn.babylonjs.com/gui/babylon.gui.min.js"></script>
1 Like