How to get the aabb in model space?

As far as I know, I can calculate a model’s aabb by the following code:

var aabb = new pc.BoundingBox();
this.entity.model.model.meshInstances.forEach((mi, i) => {
    if (i === 0)
        aabb.copy(mi.aabb);
    else
        aabb.add(mi.aabb);
});

But this aabb is in world space, not model space. :cold_sweat:

Now I want to create obb for the model, and I need to know the half extents of aabb in model space, so that I can transform it.

I have no idea how to do it. :thinking:

Hm… Why do you think it’s in world space?..

:fearful: Just a guess. Does it in the model space ?

I want to draw the obb of a model. I have the following code:

var entity = new pc.Entity();
entity.addComponent('cylinder');
entity.setEulerAngles(30, 0, 0);
app.root.addChild(entity);

var aabb = new pc.BoundingBox();
entity.model.model.meshInstances.forEach((mi, i) => {
    if (i === 0)
        aabb.copy(mi.aabb);
    else
        aabb.add(mi.aabb);
});

var obb = new pc.OrientedBox(aabb.halfExtents);
obb._worldTransform = entity.getWorldTransform();

// draw the obb
var vecA = new pc.Vec3();
var vecB = new pc.Vec3();
var color = new pc.Color();
vecA.set(
    obb._aabb.center.x + obb._aabb.halfExtents.x,
    obb._aabb.center.y + obb._aabb.halfExtents.y,
    obb._aabb.center.z + obb._aabb.halfExtents.z
);
vecB.set(
    obb._aabb.center.x - obb._aabb.halfExtents.x,
    obb._aabb.center.y + obb._aabb.halfExtents.y,
    obb._aabb.center.z + obb._aabb.halfExtents.z
);
obb._worldTransform.transformPoint(vecA, vecA);
obb._worldTransform.transformPoint(vecB, vecB);
app.renderLine(vecA, vecB, color);

// ... the rest lines

And I get the following result(wrong):

图片

The correct one is:

图片

Any ideas ? :face_with_raised_eyebrow: @will @yaustar

An AABB is always going to be Axis Aligned with the World axis.

By rotating the entity first and then building the AABB, this is what it looks like:

To get the tightest AABB possible (and even then, it won’t necessarily by the best fit), you would have to reset all the rotations to 0 and then build the AABB.

Edit: You are also passing the wrong params to pc.OrientatedBox

Your code:

var obb = new pc.OrientedBox(aabb.halfExtents);

Constructor

var OrientedBox = function OrientedBox(worldTransform, halfExtents) {
1 Like

Edit: You are also passing the wrong params to pc.OrientatedBox

That’s my hand write mistake. :sweat_smile:

To get the tightest AABB possible (and even then, it won’t necessarily by the best fit), you would have to reset all the rotations to 0 and then build the AABB.

Do you mean I need to do this ?

var obb = new pc.OrientedBox();
var prevQuat = entity.getRotation();
entity.setRotation(pc.Quat.IDENTITY);

var aabb = calculateAabb(); // fake code

obb.halfExtents.copy(aabb.halfExtents);
obb.worldTransform = entity.getWorldTransform();
entity.setRotation(prevQuat);

// draw obb

Yes, that’s the idea I had in mind. There may be some side effects depending if anything is listening to rotation changes (which is very rare).

But how about those models with animation ?

Then you have a bigger problem :sweat_smile:

You have have to work out which frame takes the most space or set the halfextents and center yourself by hand.

Or you have to update the bounding box every frame.

Edit: It should be possible to work out a model space AABB which saves you having to do the double rotation workaround but off the top of head, I wouldn’t know how to do it.

What are these boxes for?

@swh @yaustar
I notice there is a PR improve the oriented box. https://github.com/playcanvas/engine/pull/1171 :smiley:
But I don’t know when it will be merged. :thinking:

1 Like

I’d like to use obb to detect collision.

In which case you might actually be better setting the values your self with a model that has animation.

better setting the values your self with a model that has animation.

What do you mean ? Any examples ?

As in you specify how big the half extents yourself rather than trying to derive from the mesh.

So for example, if you want the box to be 1m high, width and depth, you would pass half extents of 0.5.

var obb = new pc.OrientedBox(center, new pc.Vec3(0.5, 0.5, 0.5);

The WebVR project does something similar using a entity to define where and how big the box should be: https://playcanvas.com/editor/scene/484674

Shape script: https://playcanvas.com/editor/code/446331?tabs=6555307

Look at the teleport areas in the editor:
image

Or even better the Vinyls:
image

Where they have a child of the entity to represent the AABB/OOBB

1 Like