for (const mesh of meshes) {
mesh.showBoundingBox = true;
}
A successful workaround is alwaysSelectAsActiveMesh thanks to @labris in the same post above
It seems that the bounding boxes (white wireframe) aren’t following the bones and visual mesh. Maybe if bounding boxes followed the bones, we wouldn’t need to use alwaysSelectAsActiveMesh?
Recalculating bounding boxes every frame would take too long, so we usually simply set alwaysSelectAsActiveMesh = true; to ensure that the mesh doesn’t disappear when the bounding box is not in the camera frustum.
If you still want culling for your meshes, you can try defining a bounding box large enough to encompass all the frames in the animation. You can use the computeMaxExtents function to calculate this bounding box.
Thank you so much, @Evgeni_Popov! computeMaxExtents() seems to work great in making the bounding boxes follow the mesh. I hope the code below looks like correct usage:
const maxExtents = BABYLON.computeMaxExtents(meshes);
const numMeshes = meshes.length;
for (let i = 0; i < numMeshes; ++i) {
const mesh = meshes[i]!;
const { minimum, maximum } = maxExtents[i]!;
mesh.setBoundingInfo(
new BABYLON.BoundingInfo(
//
minimum.scaleInPlace(1 / YBOT_SCALE), // YBOT_SCALE = 0.1
maximum.scaleInPlace(1 / YBOT_SCALE),
),
);
}
As you mentioned, recalculating the bounding boxes every frame seems to drop the FPS:
You should do the calculation once per mesh, not every frame. Something like:
const numMeshes = meshes.length;
for (let i = 0; i < numMeshes; ++i) {
const mesh = meshes[i]!;
const { minimum, maximum } = BABYLON.computeMaxExtents(mesh, animOfMesh[i]);
mesh.setBoundingInfo(
new BABYLON.BoundingInfo(
//
minimum.scaleInPlace(1 / YBOT_SCALE), // YBOT_SCALE = 0.1
maximum.scaleInPlace(1 / YBOT_SCALE),
),
);
}
If you have several animations for a mesh, you should call computeMaxExtents for each of them and union the results.
Note that I’m not sure why you apply a scale on the bounding box, it should not be needed. Also, as the doc states, the animation(s) should be started if you want computeMaxExtents to work as expected.
My bad for the confusion. By every frame, I meant that I was running computeMaxExtents() inside BABYLON.Engine.runRenderLoop() instead of for every key frame of an animation.
When the skeleton is in ragdoll mode, an animation isn’t playing, so I thought I should leave the animationGroup? field empty?
I also wasn’t sure why I needed to apply a scale though the boxes turned out looking nice in the video. I may have missed applying a scale somewhere, so I had to compensate in computeMaxExtents(), though I’m not yet sure where I could have missed this.
You don’t have to do the calculation once per (rendering loop) frame, but only once at the beginning. The aim is to calculate a bounding box that will be large enough to encompass all the frames of all the animations, so you only need to calculate it once.
Ragdoll mode is special, the animation is driven by the physics engine, so there’s no way to know in advance the position of the bones and to calculate a bounding box that would encompass all the animation… It’s probably easier to simply switch to alwaysSelectAsActiveMesh = true when you switch to ragdoll mode.