aframe
aframe copied to clipboard
OBB isn't centered (includes proposed fix)
Using obb-collider for entities with child entities creates a collider that isn't centered, causing an offset
- A-Frame Version: 1.5.0
- Platform / Device: any
- Reproducible Code Snippet or URL: glitch code and live example
<html>
<head>
<script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script>
</head>
<body>
<a-scene embedded obb-collider="showColliders: true" xr-mode-ui="enabled: false">
<a-entity obb-collider position="0 1.5 -1" rotation="0 20 0">
<a-box scale="0.1 0.1 0.1" position="0 0.1 0" color="blue"></a-box>
<a-box scale="0.1 0.1 0.1" position="0.5 0 0" color="blue"></a-box>
</a-entity>
</a-scene>
</body>
</html>
I looked into the obb-collider.js and was able to create a fix by modifying the tick function to include the boundingBox's center. I made a simple build and you can see it in action in the glitch url above
tick: (function () {
var auxPosition = new THREE.Vector3();
var auxScale = new THREE.Vector3();
var auxQuaternion = new THREE.Quaternion();
var auxMatrix = new THREE.Matrix4();
var boundingBoxCenter = new THREE.Vector3(); // FOR POSITION FIX
return function () {
var obb = this.obb;
var renderColliderMesh = this.renderColliderMesh;
var trackedObject3D = this.checkTrackedObject() || this.el.object3D;
if (!trackedObject3D) {
return;
}
trackedObject3D.updateMatrix();
trackedObject3D.updateMatrixWorld(true);
trackedObject3D.matrixWorld.decompose(auxPosition, auxQuaternion, auxScale);
// POSITION FIX
this.boundingBox.getCenter(boundingBoxCenter);
boundingBoxCenter.sub(trackedObject3D.position);
boundingBoxCenter.applyQuaternion(trackedObject3D.quaternion);
auxPosition.add(boundingBoxCenter);
// Recalculate collider if scale has changed.
if (
Math.abs(auxScale.x - this.previousScale.x) > 0.0001 ||
Math.abs(auxScale.y - this.previousScale.y) > 0.0001 ||
Math.abs(auxScale.z - this.previousScale.z) > 0.0001
) {
this.updateCollider();
}
this.previousScale.copy(auxScale);
// reset scale, keep position and rotation
auxScale.set(1, 1, 1);
auxMatrix.compose(auxPosition, auxQuaternion, auxScale);
// Update OBB visual representation.
if (renderColliderMesh) {
renderColliderMesh.matrixWorld.copy(auxMatrix);
}
// Reset OBB with AABB and apply entity matrix. applyMatrix4 changes OBB internal state.
obb.copy(this.aabb);
obb.applyMatrix4(auxMatrix);
};
})(),
Can try master? there was some recent fixes
updated glitch example to include the master - same issue
Feel free to open a PR. Thanks!
made a fork and added the change, but then I realized that when the entity is itself a child of another entity, the issue persists (I updated the glitch example so now neither solution works)
not sure how to fix it 🤷, but personally I can just modify my personal use-case so the child primitives are each obb-colliders instead of the parent entity
Yeah. In this case for example:
<a-entity obb-collider position="0 1.5 -1" rotation="0 20 0">
<a-box position="0 3 0" color="blue"></a-box>
<a-box position="0 5 0" color="blue"></a-box>
</a-entity>
In the image below the bounding box is centered in the parent but should be in the middle point between the child boxes in the y-axis:
General solution is the center of mass?
Definitely obb-collider doesn't work at the moment with shifted children with respect to the parent