Get correct bounding box of group with animated meshes

Hello,

I know that you can get the bounding box of a group with “new Box3().setFromObject(group)”.

Unfortunately this does not work if there are SkinnedMeshes in the group. The bounding box always includes the initial pose of the meshes.

How do I update the bounding box?

Best regards

This is a known limitation – see InstancedMesh/SkinnedMesh and computeBoundingBox(). · Issue #18334 · mrdoob/three.js · GitHub.

SkinnedMesh does have a boneTransform() method you could use to compute the exact bounding box, that is pretty expensive and requires checking vertex by vertex. If you don’t need the bounding box to be exact it might be better to put non-rendered ‘collider’ meshes on the bones of the mesh and use those, or perhaps just use a static bounding box for the SkinnedMesh that is roughly the size of the area you think it will occupy during animation.

1 Like

Thanks for your reply!

In my case, it is sufficient to calculate the bounding box once. Therefore, it is okay if the process is expensive. It works.

const box = new Box3()
const target = new Vector3()
for (let i = 0; i < mesh.geometry.attributes.position.count; i++) {
        target.fromBufferAttribute(mesh.geometry.attributes.position, i)
        mesh.boneTransform(i, target)
        box.expandByPoint(target)
}

Best

1 Like

Unfortunately, I have to come back to this problem. I noticed that no transformations of parents are taken into account.

That is, if the skinnedMesh is in a group that has, for example, position=[0, 2, 0], the bounding box of the skinnedMesh is 2 units too low on the y-axis.

Is this the way it is supposed to be? What is the best way around this so that you get the actual absolute bounding box?

@mannitou Try something like this to get global coordinates. In my application, I also had to multiply by the inverse matrix of a parent object to get the bounding box of my object including its children for the parent object

const box = new Box3()
const target = new Vector3()
for (let i = 0; i < mesh.geometry.attributes.position.count; i++) {
        target.fromBufferAttribute(mesh.geometry.attributes.position, i)
        mesh.boneTransform(i, target)
        target.applyMatrix4(mesh.matrixWorld)
        box.expandByPoint(target)
}