Collision From Bounding Box

Hi, I am loading an entities renderer at runtime. Once the load is complete I calculate a bounding box and then I add a collision component (box collision)

I scale the collision component to be the same as the bounding box using;
this.entity.collision.halfExtents = boundingBox.halfExtents;

…but the problem is that I also need to shift the collision so that it matches the same position as the bounding box and not based on the entities initial 0,0,0. I can see that I can use linear offset to guide the position of the collision box but how can I use this to put the collision in the exact same position as the bounding box?

EDIT: However, when I try to modify the linearOffset in code like so, it doesn’t seem to change the collisions position at all:
this.entity.collision.linearOffset.y = 1000;

Maybe there is an easier way? Something like this would be great but I dont think it exists…
this.entity.collision.position = bounding.position

Thanks

Linear offset property is a getter/setter. Don’t modify the element directly, but assign a vector to it instead.

Not sure what you are trying to do, but you can read the center of the AABB, then convert it to local space of the entity with the collision component and assign that as a linear offset.

Great! Thanks.

this.entity.collision.linearOffset = new pc.Vec3(0,0.15,0);

…seems to work. But somehow I need to get the 0.15 fixed value to based on the bounding box centre. Any idea?

As I mentioned, get the bounding box center in world space, convert to local space of the entity and assign it as a linear offset.

const t = new pc.Mat4().copy(entity.getWorldTransform()).invert();
t.transformPoint(centerClone, centerClone);
entity.collision.linearOffset = centerClone;

Okay. Im trying to understand this but having great difficulty :slight_smile:

In your example, what is centerClone? How would I insert my bounding box into that example? I have a pc.BoundingBox(); which gets passed in rather than an entity.
My current code is:

this.entity.addComponent("collision");
this.entity.collision.type="box";
this.entity.collision.halfExtents = bounding.halfExtents;
this.entity.collision.linearOffset = new pc.Vec3(//something here);

Bounding box has a center property:

const bb = new pc.BoundingBox();
const centerClone = bb.center.clone();

// transform centerClone to local space of the entity here, then

entity.addComponent('collision', {
    halfExtents: bb.halfExtents,
    linearOffset: centerClone
});

Thanks. I tried this but it doesnt seem to work. I cant detect any collision around the entity anymore. Maybe its far away? Its written in a slightly different way but I think it should be the same as your example shouldn’t it?

this.entity.addComponent("collision");
this.entity.collision.type="box";
this.entity.collision.halfExtents = bounding.halfExtents;
var centerClone =bounding.center.clone();

// transform centerClone to local space of the entity here
const t = new pc.Mat4().copy(this.entity.getWorldTransform()).invert();
t.transformPoint(centerClone, centerClone);

 this.entity.collision.linearOffset = centerClone ;

Also, the position of the entity should have nothing to do with it because the bounding box is calculated previously from multiple mesh instances which might not be anywhere near the entity itself. The linear offset should only be calculated from the center of the bounding box. Thats why I dont understand this part…

// transform centerClone to local space of the entity here
const t = new pc.Mat4().copy(this.entity.getWorldTransform()).invert();
t.transformPoint(centerClone, centerClone);

Here is an example project:
https://playcanvas.com/project/1155525/overview/bounding-box-collider

const bb = new pc.BoundingBox();
const renders = this.entity.findComponents('render');

const min = new pc.Vec3();
const max = new pc.Vec3();

for (const render of renders) {
    const aabb = render.meshInstances[0].aabb;

    const imin = aabb.getMin();
    const imax = aabb.getMax();

    min.min(imin);
    max.max(imax);
}

bb.setMinMax(min, max);

const t = this.entity.getWorldTransform().clone().invert();
const center = bb.center.clone();

t.transformPoint(center, center);

this.entity.addComponent('collision', {
    halfExtents: bb.halfExtents,
    linearOffset: center
});