Hi
I have got an animation working
??Is there anything that lets me ‘single-step’ through the animation keyFrame to keyFrame
OR
lets me execute a callback-function at each keyFrame
Thanks
Hi
I have got an animation working
??Is there anything that lets me ‘single-step’ through the animation keyFrame to keyFrame
OR
lets me execute a callback-function at each keyFrame
Thanks
Like this?
It is all the frames defined for the animation. But it is not the key frames.
I don’t think the exact key frames are rendered at runtime. If I understand correctly, the runtime rendering of animation works like this:
Input is current time T.
And this happens at bond level. Each bond can have different key frames.
There’s animation events: Advanced Animation Methods | Babylon.js Documentation (babylonjs.com)
Hi
Have just been experimenting with AnimationEvents
I have a for loop to setup my keyFrame array
This now includes adding AnimationEvents to my animation
For example my for loop creates 64 keyFrames / AnimationEvents
When the animation runs - I only get 63 function calls
also the frame numbers are NOT integers - so I don’t seem to be getting back my keyFrame numbers
??Does this make sense
Thanks
It will be much better if we can see your code on a Playground
Here’s the relevant code snippet
function animateModelSlicer(){
console.log("in animateModelSlicer");
var modelMesh = findMesh(scene.meshes, "Mesh");
if(modelMesh != null){
var bBox = modelMesh.getBoundingInfo();
var minXYZ = bBox.minimum;
var maxXYZ = bBox.maximum;
var h = Math.abs(maxXYZ.y - minXYZ.y);
var kFrames = [];
for(i = 0; i < Math.trunc((modelZOffest + h) / zScannerHeight); i++){
kFrames.push({
frame: i,
value: (zScannerHeight / 2) + i * zScannerHeight
});
// Now add animationEvent for this keyFrame
scanningAnimation.addEvent(new BABYLON.AnimationEvent(i,
(frame) => {
processKeyFrame(frame);
}, true)
);
}
scanningAnimation.setKeys(kFrames);
console.log("set '" + kFrames.length + "' keyFrames");
}
}
function processKeyFrame(frame){
console.log("processing keyFrame '" + frame + "'");
}
It’s more helpful if it’s on a Playground: playground.babylonjs.com with a minimal example that reproduces your situation
Please take a look at
At runtime, it is not giving you exactly the key frame.
I didn’t know you are doing the animations programmatically. In this case, you just need to iterate through your keyframes array. And set the animated property to be the value of that keyframe.
<targetMesh>.<animProperty>=keyframes[i].value
Hi
That code
// scene.beginAnimation(box, 0, 2 * frameRate, true);
let i = 0;
let intervalId;
intervalId = setInterval(()=>{
box.position.x = keyFrames[i].value;
if (i < keyFrames.length - 1) {
i++;
}
else {
clearInterval(intervalId);
}
}, 1000);
Still ONLY ‘sees’ 2 of the 3 KeyFrame steps you’ve set up
as controlled by
if (i < keyFrames.length - 1) {
My code is correct. All 3 frames are executed. Let me change the original position of the box to 0. So it doesn’t start at the same position as key frame 0. Then you should see all 3 steps executed.
intervalId = setInterval(()=>{
box.position.x = keyFrames[i].value;
if (i < keyFrames.length - 1) {
console.log("Doing something at keyFrame " + i);
i++;
}
else {
clearInterval(intervalId);
}
}, 1000);
When run console shows
Doing something at keyFrame 0
Doing something at keyFrame 1
So your code is ONLY ‘seeing’ 2 of the 3 KeyFrame steps you’ve set up
Why don’t you log at the place the position update is executed?
there’s a thought
Your method is avoiding use of the scene animation functionality
and you have to figure out your own keyFrame stepping interval in order to get a smooth animation
??Won’t this become awkward when the animation required is quite long / traverses a large part of the screen
??Have you used this method to get smooth animation over 100s of keyFrames
Thanks for your patience & time
Well. Animation is doing the same thing behind the scene: updating the position/rotation/scale of the models. Since you defined the keyframes yourself. You can directly apply the changes.
To make sure the keyframes are animated at 60 FPS, instead of using setInterval, you should put it in an observer. It will be too fast to notice for 3 frames.
let i = 0;
scene.onBeforeRenderObservable.add(() => {
if (i < keyFrames.length) {
box.position.x = keyFrames[i].value;
}
i++;
});