How to get "translated" corners?

How can I get the corners of a loaded model in global coordinates?

Say I have a model, and I load it with
model_n = self.scene.loader.loadModel(path)

Then I apply transformations to it

model_n.setHpr(rotation)
model_n.setScale(scale)
model_n.setPos(pos)

Then to get the corners I tried to use getTightBounds() but I found that it always returns the corners of a forward facing bbox and not the “rotated, scaled and translated” corners of the original model.

Tried to show an example of what I mean in this masterful drawing:

Just pass a NodePath as argument to getTightBounds. It’ll return the coordinates in that node’s coordinate system. Pass the NodePath itself as argument to get the box in its own coordinate system, as opposed to its parent’s.

You may then have to convert those coordinates in order to get them into world-space, I believe. It should be possible to do this via NodePath’s “getRelativePoint” method.

Not sure I understand… Which NodePath should I pass?
In continuation to my original post, I’m using model_n.getTightBounds()

I believe that rdb is suggesting that you pass the model itself into “getTightBounds”. i.e.: model_n.getTightBounds(model_n)

That way you end up with the bounds in the coordinate space (which is to say: “from the perspective of”) the model itself.

Then you should be able to use “getRelativePoint” in order to convert these bounds to world-space. And since the transformation from the model’s coordinate-space to world-space should–if I’m not much mistaken–include the model’s scale, rotation, etc., the bounds should end up transformed accordingly.

Note that getTightBounds just returns two points, because it’s always axis-aligned, you can turn that into 8 points using various permutations of min.x, min.y, min.z, max.x, min.y, min.z, etc. to get the oriented bounding box vertices which you can then transform to world space without losing the orientation aspect.

1 Like

I managed to solve this by scaling the model, and applying rotation and position on it’s parent.
model_n.setPos(-c) also centers the model on it’s parent’s (0, 0, 0).

parent = NodePath('')
model_n = self.scene.loader.loadModel(path)
model_n.reparentTo(parent)

min_v, max_v = model_n.getTightBounds()
size = max_v - min_v
max_s = max(size.x, size.y, size.z)
model_n.setScale(scale/max_s)

# offset to center
c = model_n.getBounds().getCenter()
model_n.setPos(-c)

parent.setHpr(rotation * self.rad_to_deg)
parent.setPos(position)

bounds = model_n.getTightBounds()

This of course requires some careful handling when it comes to being able to control the model in 3D space since pos, rot and scale are used differently

1 Like