Computing bounding info for parented mesh with a using parent's transform matrix

This feels like a regression/variation of this older issue: Behaviour of computeWorldMatrix() is confusing for nodes with parents

For some reason (which may be by design), when I get the “boundingInfo” for a parented mesh,
it is not computed as I expected. I would expect a 1x1x1 box scaled to .1x.1x.1 parented to a transformnode (not scaling only transformed to 0,1,0) to have a maximum bound of (.05, .05, .05).

instead it remains .5, .5, .5… worldBound looks find, it’s only the “local” bounds that seem unexpected.

Am I thinking about this incorrectly? Is there a way to get bounding info in context of parent matrix?

Playground: playground

Simplified example

    var transform = new BABYLON.TransformNode('t', scene);
    transform.position.y = 1;
    var box = BABYLON.MeshBuilder.CreateBox("box", {size: 1}, scene);
    box.parent = transform;
    box.scaling = new BABYLON.Vector3(.1, .1, .1);
    box.refreshBoundingInfo();
    transform.computeWorldMatrix(true);
    box.computeWorldMatrix(true);
    //PROBLEM: value is .5, I was expecting .05
    box.getBoundingInfo().boundingBox.maximum.y
//This, however is 1.05, which is what expected.
box.getBoundingInfo().boundingBox.maximumWorld.y
    let i = 0;
    scene.onAfterRenderObservable.addOnce(() => {
        if (i++ < 20) {
            //value is .5, I was expecting .05
            console.log('>> this also seems wrong to me: after render local ' + box.getBoundingInfo().boundingBox.maximum.y);  
                    }
    
    })

You are looking at maximum which is in object space. that value will not change unless you change the actual geometry

maximumWorld is the one which is using the world matrix applied to maximum value,

So reading between the lines, there is no way to get bounds in the context of the parent node?

Here’s how I can “make it work”, but it seems “workaroundy”

var max = box.getBoundingInfo().boundingBox.maximumWorld;
var node = new BABYLON.TransformNode('t2', scene);
node.position = max.clone();
node.setParent(transform);
console.log('transformed ' + node.position);


Honestly, it’s surprising to me that this isn’t the default, I’m not sure why I’d want the bounding box of a scaled mesh to equal the unscaled/untransformed bounds.

I may not understand what you mean by “context of the parent node”.

node.position is the world position but becomes the position in the parent world if there is a parent.

Again the bix.getBoundingInfo will always provide both values: the local value (minimum and maximum) and the world value (minimumWorld and maximumWorld).

The engine is always using the world value so the parent is taken in account,

I’m sorry, I must be dumb but I do not get what you need besides that.

Oh sorry…let me declutter what I said with a specific example:

parent = transformnode
child = mesh (size: 1)
child.parent = parent

parent.y = 1
child.y = 0

what I would expect
child.absolutePosition.y == 1
child.position.y == 0
This is how position (and rotation) work, no problems or confusion.

child.getBoundingInfo().boundingBox.maximum.y == 1
child.getBoundingInfo().boundingBox.maximumWorld.y == 1.5
So far, so good…no problems…

child.scaling.y = .1
//assuming we update matrix and boundinfo I get
child.getBoundingInfo().boundingBox.maximumWorld.y == 1.05 …
//i.e. box is now .1 high, totally makes sense in global scene

child.getBoundingInfo().boundingBox.maximum.y == .5 …
//to me, my brain stops…I would totally expect this to be .05 … mesh has been scaled by .1 .5*.1 = .05 … for position and rotation, this is the way it works. I’m sure there’s a good reason, but trips me up mentally. If I wanted to bouding box of the mesh BEFORE I applied scaling, I’d just get the raw mesh data, once I scale it, I would expect bounding box to reflect the scale of the mesh itself and it’s parent’s transform…which it DOES if you use the “world” ones, but the “non world” ones reflect the original mesh geometry instead of the original mesh geometry * scaling. Which IDK, maybe it’s a “good idea” but seems very confusing to me.

Maybe put more succinctly:

if mesh.geometry is a 1x1x1 box
and I scale mesh by .1
I would expect mesh bounding box to be…
.1x.1x.1 box…not 1x1x1 box… I may have confused things a bit by throwing the parent/child stuff in there…the same problem happens even if you don’t scale the mesh.

world bounds match scale
local bounds match original mesh

no bounds match current scale…

This is totally by design and I agree the naming is questionable :slight_smile: maximum and minimum are geometry bounding info and the rest is correctly world.

That said in which case do you need some kind of local to the node only info ?

cause if parent was having scaling too you d need to factor it in ?

in that case boundingBox.maximum would be 1 because it is in local world but boundingBox.maximumWorld will be .1

You have both info. What you need is maximumWorld

In other world maximum is BEFORE world matrix and maximumWorld is AFTER world matrix

I have a (maybe wierd) use case where I have two nodes parented to the same transform node. one node (representing mesh geometry) has ability to be dynamically scaled. Other (child) node is parented to same parent, but is needs to be placed at boundary of other meshes bounding box. I would not at all be surprised if there was some sort of “easier” way to do this and I’ve painted myself into a box (is that PUN??? unintenional) but this is where I am right now.

example of what I’m going for is here: Deep Diagram (note you have to use ‘w’ on keyboard, mouse wheel, or on oculus left stick to navigate closer to nodes to see text…point is the meshes can be at arbitrary scales, but text should stay same scale, but be position at “top of y for bounding box of mesh”…the link shows my “old” implementation which was hacky/cludgy and I’m attempting to “dehack/dekludge” it… :o:

In the implementation in the link I use a variety of hijinx to position it properly, but am hoping for a more “elegant/performant” solution.

in this case you would need to transform the world max/min by the inverse of the parent world matrix to find back your points in “local space” independently of the hierarchy I guess