aframevr / aframevr/aframe

OBB isn't centered (includes proposed fix)

Open
#5,506 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
17.6k
Forks
4.4k
PR merge metrics
No merged PRs in 30d

Description

Using obb-collider for entities with child entities creates a collider that isn't centered, causing an offset

<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);
        };
    })(),

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/components/obb-collider.js around the tick function referenced in the issue, then reproduce the offset using the linked Glitch example. Check how the bounding box center and tracked object transform are applied for entities with child entities. Done means the collider is centered on the child-entity bounds without breaking scale or rotation behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, three.js
Domain
computer-graphics, game-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.