Using actions manually

I’m trying to build a site that has a series of lightbulbs arranged in the space. When a lightbulb is clicked, it should move towards the camera as the camera realigns itself to face directly towards the target bulb from the world origin.

I’ve managed to register a CombineAction to move the target and reposition the camera to a fixed orientation for each bulb. I then got a function working that calculates the new alpha value of the camera taking the shortest path to face the target.

What I cannot figure out is how to get the camera movement actions to use the new alpha value. It seems that when you register an action it hard bakes the value you supplied into the action rather than a reference to the variable.

I tried to register the CombineAction after updating the camRotate variable but it doesn’t do anything (obviously is not being called).

Is there a way to perhaps create and then manually trigger the action?

Here’s the relevant code. Sorry, not sure about using a playground as I’m loading an HDRI directly and not sure about uploading it etc…

for (let i = 0; i < itemCount; i++) {
                   
                    bulbs[i] = bulbProto.clone("bulb" + i);
                    bulbs[i].position.x = -2;
                    parents[i] = new BABYLON.Mesh("empty" + i, scene);
                    bulbs[i].parent = parents[i];
                    
                    parents[i].rotation.y = ((Math.PI * 2) % (itemRotation)) * i;
                    parents[i].position.y = (-i / (Math.PI * 2 / itemRotation)) / 2;

                    var calcCamRot = function(evt) {
                    
                        console.group("CamRotCalc");
                       
                        camRotate = (evt.source.parent.rotation.y % (Math.PI * 2)) - (-camera.alpha % (Math.PI * 2));//Get the difference in orientation

                        //change it to the shortest route......if (camRotate > Math.PI / 2) {
                            console.log(`Spinning Positive! ${radsToDeg(camRotate)}`);
                            camRotate -= Math.PI * 2;
                            console.log(`Better? ${radsToDeg(camRotate)}`)
                        } else if (camRotate < -Math.PI / 2) {
                            console.log(`Spinning Negative! ${radsToDeg(camRotate)}`);
                            camRotate += Math.PI * 2;
                            console.log(`Better? ${radsToDeg(camRotate)}`)
                        }
                        
                        camRotate = camera.alpha - camRotate;
                        console.log('Camera to rotate to: ' + radsToDeg(camRotate));

                        console.groupEnd("CamRotCalc");

                        ///Ideally this would be manually calling the CombineAction
                        evt.source.actionManager.registerAction(new BABYLON.CombineAction(
                            BABYLON.ActionManager.NothingTrigger,
                            [new BABYLON.InterpolateValueAction(
                                    BABYLON.ActionManager.NothingTrigger,
                                    bulbs[i],//or evt.source
                                    'position.x',
                                    -.5,
                                    1000
                                ),
                                new BABYLON.InterpolateValueAction(
                                    BABYLON.ActionManager.NothingTrigger,
                                    camera,
                                    'target',
                                    new BABYLON.Vector3(0, parents[i].position.y/*or evt.source.parent*/, 0),
                                    500
                                ),
                                new BABYLON.InterpolateValueAction(
                                    BABYLON.ActionManager.NothingTrigger,
                                    camera,
                                    'alpha',
                                    camRotate,
                                    1000
                                ),
                                new BABYLON.InterpolateValueAction(
                                    BABYLON.ActionManager.NothingTrigger,
                                    camera,
                                    'beta',
                                    Math.PI / 2,
                                    1000
                                )

                            ]
                        ))
                    }


                    bulbs[i].actionManager = new BABYLON.ActionManager(scene);

                    var getCamRot = new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, calcCamRot);

                    bulbs[i].actionManager.registerAction(getCamRot);

}

Welcome aboard!

I don’t think the HDR file is relevant to the problem, so simply remove it or use an existing picture from the playground. A repro would definitely help here.

https://playground.babylonjs.com/#QJHZE7#6

Can’t even seem to get get the actions I got working on my server to work on the playground… Not sure what I’m doing wrong but after and hour of reworking my code to run on the playground at all I’m stumped. Sorry if there’s something really obvious.

It’s hitting the bulbProto mesh when picking. That mesh needs to be removed from the equation. One way to do it is to disable it. Like this:

https://playground.babylonjs.com#QJHZE7#7

There are still issues with the code, but at least it’s calling the callback function now. :slight_smile:

Strange, It didn’t give me problems on my local server.

https://playground.babylonjs.com/#QJHZE7#11

So this is working except for the issue of it moving camera to a fixed spot instead of to a dynamically calculated spot.

https://playground.babylonjs.com/#QJHZE7#13

I have made some progress! So instead of using actions, I’ve set up an animations to move the camera. All works well except for changing the target (You can see I’ve set up the animation but not implemented it)

I’ve ended implementing changing the target as I originally intended to do all the animation: using the event action. However, this seems to snap the camera looking straight down before the other animations take over and rectify. Any way I can change the y position of the camera using animation parameters?

EDIT:: So turns out, target animation works fine as long as you call it first: https://playground.babylonjs.com/#QJHZE7#14

2 Likes