Box3.setFromObject(parent): scene.add(box) vs. parent.add(box)

Hello,

Can someone please explain the logic behind the .add() function? The documentation isn’t very clear on this.

I am trying to create a child bounding box and add it to the parent object from which the bounding box is taken. After setting the box from the parent, when I add the box to the scene, the coordinates of the box are correct (i.e. it bounds the parent). And when I move the parent, the box stays in its place - as expected, since the bounding box does not consider transformations of the original object.

What I want is precisely for the box to move with the parent. But when I add the box to the parent as a child, the box appears “off” to the side and no longer bounds the parent, although the box is displayed with the right dimensions (i.e. it still takes the shape of the parent) and moves correctly whenever the parent is moved.

The only thing that goes wrong with the latter approach is the coordinates of the box. I’m not sure why this is the case. My code is exactly the same except for the parent to which the object is attached, so I assume it has to do with the logic behind the .add() function.

Can anyone please shed some light on this? Thanks very much in advance.

Hey there, it’s hard to understand your problem without the respective code. Could you provide some more?

Do you mean something like this?

https://vhn448-5173.csb.app/?component=BoxParent

https://codesandbox.io/p/github/rob-myers/three-js-examples/master?file=%2Fsrc%2FApp.tsx

Hello, thanks for your reply! I’ve attached a few pictures below. (The model isn’t mine. It’s made by boytchev. I’m trying to add a bounding box around the model’s head.)

When my code is model.head.add(box):

A bounding box appears with the correct size, but not in the correct location. When I move the head:

The box moves along with the head, which is what I’m looking for.

Conversely, when my code is scene.add(box):

The box appears with the correct size and in the correct location. But when I move the head:

Only the head moves, as expected of the properties of a bounding box.

My code for the latter two photos is:

let bbox = new THREE.Box3().setFromObject(model.head);
let boxH = new THREE.Box3Helper(bbox);
scene.add(boxH);

My code is exactly the same except for the parent to which the box is added. I’m curious about why this would happen - does the .add() function interpret the matrix of the box differently depending on who the parent is? If so, how does the interpretation work? I’m less interested in resolving my code than in understanding the logic behind what’s happening.

Hope this clarifies my question. Thanks again for your reply, and please let me know if you need any additional information :slight_smile:

1 Like

So Object3D.add specifies a parent-child relationship
The child will inherit transforms from the parent i.e.

child.matrixWorld = child.matrix . parent.matrixWorld

When you add THREE.Box3Helper as a child of model.head, and then transform the head, the helper will inherit that transform.

When you add THREE.Box3Helper as a child of the scene, and then transform the head, nothing should happen to the helper.


The THREE.Box3 docs specify two things you need to do:

  • Initially ensure whatever mesh you’re going to bound has its untransformed bounding box defined. This is done by invoking mesh.geometry.computeBoundingBox(). There might be many meshes in your head, in which case you can model.head.traverse(x => ...).

  • Whenever you transform the target geometry you need to update via bbox.copy( mesh.geometry.boundingBox).applyMatrix4( mesh.matrixWorld );

Here, the docs are assuming bbox is not a child of mesh.

If you do want bbox to be a child of mesh, you only need to get its initial position correct e.g. bbox.copy(mesh.geometry.boundingBox). You don’t need to continually update it.

I hope that helps clarify things.

1 Like

Yes, that makes sense! Thank you very much for the detailed explanation!

There are 2 methods on object3D:

.add
and
.attach

.add literally just pushed the object into the .children array, and sets the objects .parent.

.attach actually goes much deeper into the object and computes the matrix between the objects current parent, and it’s new parent, and applies it to the objects transform to make it appear as if the object hasn’t moved, but has still changed parent.

2 Likes

Thank you, that helps a lot!!

1 Like