Skip to content

Commit 5da7166

Browse files
committed
Consider scale changes on parents to recalculate collider box. Also ignore parent entities rotations before calculating so bounding box has the right size when calculated
1 parent 56a86a9 commit 5da7166

File tree

1 file changed

+57
-40
lines changed

1 file changed

+57
-40
lines changed

src/components/obb-collider.js

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ registerComponent('obb-collider', {
1010
},
1111

1212
init: function () {
13-
this.previousScale = new THREE.Vector3();
13+
this.previousScale = new THREE.Vector3().copy(this.el.object3D.scale);
1414
this.auxEuler = new THREE.Euler();
1515

1616
this.boundingBox = new THREE.Box3();
@@ -22,6 +22,7 @@ registerComponent('obb-collider', {
2222

2323
this.el.addEventListener('model-loaded', this.onModelLoaded);
2424
this.updateCollider();
25+
2526
this.system.addCollider(this.el);
2627
},
2728

@@ -114,41 +115,54 @@ registerComponent('obb-collider', {
114115
this.el.sceneEl.object3D.add(renderColliderMesh);
115116
},
116117

117-
updateBoundingBox: function () {
118-
var auxEuler = this.auxEuler;
119-
var boundingBox = this.boundingBox;
120-
var size = this.data.size;
121-
var trackedObject3D = this.trackedObject3D || this.el.object3D;
122-
var boundingBoxSize = this.boundingBoxSize;
123-
var minimumColliderDimension = this.data.minimumColliderDimension;
124-
125-
// user defined size takes precedence.
126-
if (size) {
127-
this.boundingBoxSize.x = size;
128-
this.boundingBoxSize.y = size;
129-
this.boundingBoxSize.z = size;
130-
return;
131-
}
132-
133-
this.previousScale.copy(trackedObject3D.scale);
134-
135-
// Bounding box is created axis-aligned AABB.
136-
// If there's any local rotation the box will be bigger than expected.
137-
// It undoes the local entity rotation and then restores so box has the expected size.
138-
auxEuler.copy(trackedObject3D.rotation);
139-
trackedObject3D.rotation.set(0, 0, 0);
140-
141-
trackedObject3D.updateMatrixWorld(true);
142-
boundingBox.setFromObject(trackedObject3D, true);
143-
boundingBox.getSize(boundingBoxSize);
118+
updateBoundingBox: (function () {
119+
var auxPosition = new THREE.Vector3();
120+
var auxScale = new THREE.Vector3();
121+
var auxQuaternion = new THREE.Quaternion();
122+
var identityQuaternion = new THREE.Quaternion();
123+
var auxMatrix = new THREE.Matrix4();
144124

145-
boundingBoxSize.x = boundingBoxSize.x < minimumColliderDimension ? minimumColliderDimension : boundingBoxSize.x;
146-
boundingBoxSize.y = boundingBoxSize.y < minimumColliderDimension ? minimumColliderDimension : boundingBoxSize.y;
147-
boundingBoxSize.z = boundingBoxSize.z < minimumColliderDimension ? minimumColliderDimension : boundingBoxSize.z;
125+
return function () {
126+
var auxEuler = this.auxEuler;
127+
var boundingBox = this.boundingBox;
128+
var size = this.data.size;
129+
var trackedObject3D = this.trackedObject3D || this.el.object3D;
130+
var boundingBoxSize = this.boundingBoxSize;
131+
var minimumColliderDimension = this.data.minimumColliderDimension;
132+
133+
// user defined size takes precedence.
134+
if (size) {
135+
this.boundingBoxSize.x = size;
136+
this.boundingBoxSize.y = size;
137+
this.boundingBoxSize.z = size;
138+
return;
139+
}
148140

149-
// Restore rotation.
150-
this.el.object3D.rotation.copy(auxEuler);
151-
},
141+
// Bounding box is created axis-aligned AABB.
142+
// If there's any rotation the box will have the wrong size.
143+
// It undoes the local entity rotation and then restores so box has the expected size.
144+
// We also undo the parent world rotation.
145+
auxEuler.copy(trackedObject3D.rotation);
146+
trackedObject3D.rotation.set(0, 0, 0);
147+
148+
trackedObject3D.parent.matrixWorld.decompose(auxPosition, auxQuaternion, auxScale);
149+
auxMatrix.compose(auxPosition, identityQuaternion, auxScale);
150+
trackedObject3D.parent.matrixWorld.copy(auxMatrix);
151+
152+
// Calculate bounding box size.
153+
boundingBox.setFromObject(trackedObject3D, true);
154+
boundingBox.getSize(boundingBoxSize);
155+
156+
// Enforce minimum dimensions.
157+
boundingBoxSize.x = boundingBoxSize.x < minimumColliderDimension ? minimumColliderDimension : boundingBoxSize.x;
158+
boundingBoxSize.y = boundingBoxSize.y < minimumColliderDimension ? minimumColliderDimension : boundingBoxSize.y;
159+
boundingBoxSize.z = boundingBoxSize.z < minimumColliderDimension ? minimumColliderDimension : boundingBoxSize.z;
160+
161+
// Restore rotations.
162+
trackedObject3D.parent.matrixWorld.compose(auxPosition, auxQuaternion, auxScale);
163+
this.el.object3D.rotation.copy(auxEuler);
164+
};
165+
})(),
152166

153167
checkTrackedObject: function () {
154168
var trackedObject3DPath = this.trackedObject3DPath;
@@ -183,16 +197,19 @@ registerComponent('obb-collider', {
183197

184198
if (!trackedObject3D) { return; }
185199

200+
trackedObject3D.updateMatrix();
201+
trackedObject3D.updateMatrixWorld(true);
202+
trackedObject3D.matrixWorld.decompose(auxPosition, auxQuaternion, auxScale);
203+
186204
// Recalculate collider if scale has changed.
187-
if (trackedObject3D.scale.x !== this.previousScale.x ||
188-
trackedObject3D.scale.y !== this.previousScale.y ||
189-
trackedObject3D.scale.z !== this.previousScale.z) {
205+
if ((Math.abs(auxScale.x - this.previousScale.x) > 0.0001) ||
206+
(Math.abs(auxScale.y - this.previousScale.y) > 0.0001) ||
207+
(Math.abs(auxScale.z - this.previousScale.z) > 0.0001)) {
190208
this.updateCollider();
191209
}
192210

193-
trackedObject3D.updateMatrix();
194-
trackedObject3D.updateMatrixWorld();
195-
trackedObject3D.matrixWorld.decompose(auxPosition, auxQuaternion, auxScale);
211+
this.previousScale.copy(auxScale);
212+
196213
// reset scale, keep position and rotation
197214
auxScale.set(1, 1, 1);
198215
auxMatrix.compose(auxPosition, auxQuaternion, auxScale);

0 commit comments

Comments
 (0)