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);
}