Skip to content

Commit 16705b3

Browse files
committed
Revert to earlier Convex-to-convex hull collision
Note this includes modifications to account for non-connected faces, as well as some var-to-lets and a new constructor option to pass precalculated geometry and bypass some calculations.
1 parent 63b1574 commit 16705b3

1 file changed

Lines changed: 41 additions & 27 deletions

File tree

src/shapes/ConvexPolyhedron.js

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import { Transform } from '../math/Transform'
2020
*
2121
* @todo Move the clipping functions to ContactGenerator?
2222
* @todo Automatically merge coplanar polygons in constructor.
23-
* @todo Test importing facenormals from THREE.Geometry
2423
*/
2524

2625
export class ConvexPolyhedron extends Shape {
@@ -34,8 +33,10 @@ export class ConvexPolyhedron extends Shape {
3433
this.vertices = precomputedGeometry.vertices.map(v => new Vec3(v.x, v.y, v.z))
3534
this.faces = precomputedGeometry.faces.map(f => [f.a, f.b, f.c])
3635
this.faceNormals = precomputedGeometry.faces.map(f => new Vec3(f.normal.x, f.normal.y, f.normal.z))
37-
this.boundingSphereRadius = precomputedGeometry.boundingSphere.radius
38-
console.log('Constructor received data:', precomputedGeometry)
36+
// THREE.ConeGeometry does not provide a boundingSphere, for example
37+
this.boundingSphereRadius = precomputedGeometry.boundingSphere
38+
? precomputedGeometry.boundingSphere.radius
39+
: this.updateBoundingSphereRadius()
3940
} else {
4041
/**
4142
* Array of Vec3
@@ -230,7 +231,7 @@ export class ConvexPolyhedron extends Shape {
230231
const numFacesA = faceListA ? faceListA.length : hullA.faces.length
231232

232233
// Test face normals from hullA
233-
for (var i = 0; i < numFacesA; i++) {
234+
for (let i = 0; i < numFacesA; i++) {
234235
var fi = faceListA ? faceListA[i] : i
235236

236237
// Get world face normal
@@ -249,7 +250,7 @@ export class ConvexPolyhedron extends Shape {
249250
}
250251
} else {
251252
// Test unique axes
252-
for (var i = 0; i !== hullA.uniqueAxes.length; i++) {
253+
for (let i = 0; i !== hullA.uniqueAxes.length; i++) {
253254
// Get world axis
254255
quatA.vmult(hullA.uniqueAxes[i], faceANormalWS3)
255256

@@ -268,7 +269,7 @@ export class ConvexPolyhedron extends Shape {
268269
if (!hullB.uniqueAxes) {
269270
// Test face normals from hullB
270271
const numFacesB = faceListB ? faceListB.length : hullB.faces.length
271-
for (var i = 0; i < numFacesB; i++) {
272+
for (let i = 0; i < numFacesB; i++) {
272273
var fi = faceListB ? faceListB[i] : i
273274

274275
Worldnormal1.copy(hullB.faceNormals[fi])
@@ -286,7 +287,7 @@ export class ConvexPolyhedron extends Shape {
286287
}
287288
} else {
288289
// Test unique axes in B
289-
for (var i = 0; i !== hullB.uniqueAxes.length; i++) {
290+
for (let i = 0; i !== hullB.uniqueAxes.length; i++) {
290291
quatB.vmult(hullB.uniqueAxes[i], Worldnormal1)
291292

292293
curPlaneTests++
@@ -414,15 +415,15 @@ export class ConvexPolyhedron extends Shape {
414415
const worldA1 = new Vec3()
415416
const localPlaneNormal = new Vec3()
416417
const planeNormalWS = new Vec3()
417-
418418
const hullA = this
419419
const worldVertsB2 = []
420420
const pVtxIn = worldVertsB1
421421
const pVtxOut = worldVertsB2
422-
// Find the face with normal closest to the separating axis
422+
423423
let closestFaceA = -1
424424
let dmin = Number.MAX_VALUE
425425

426+
// Find the face with normal closest to the separating axis
426427
for (let face = 0; face < hullA.faces.length; face++) {
427428
faceANormalWS.copy(hullA.faceNormals[face])
428429
quatA.vmult(faceANormalWS, faceANormalWS)
@@ -439,19 +440,23 @@ export class ConvexPolyhedron extends Shape {
439440
// Get the face and construct connected faces
440441
const polyA = hullA.faces[closestFaceA]
441442
polyA.connectedFaces = []
442-
for (var i = 0; i < hullA.faces.length; i++) {
443+
for (let i = 0; i < hullA.faces.length; i++) {
443444
for (let j = 0; j < hullA.faces[i].length; j++) {
444445
if (
445-
polyA.includes(hullA.faces[i][j]) &&
446-
i !== closestFaceA /* Not the one we are looking for connections from */ &&
447-
!polyA.connectedFaces.includes(i) /* Not already added */
446+
/* Sharing a vertex*/
447+
polyA.indexOf(hullA.faces[i][j]) !== -1 &&
448+
/* Not the one we are looking for connections from */
449+
i !== closestFaceA &&
450+
/* Not already added */
451+
polyA.connectedFaces.indexOf(i) === -1
448452
) {
449453
polyA.connectedFaces.push(i)
450454
}
451455
}
452456
}
453457

454-
// Clip the polygon to the back of the planes of all faces of hull A, that are adjacent to the witness face
458+
// Clip the polygon to the back of the planes of all faces of hull A,
459+
// that are adjacent to the witness face
455460
const numVerticesA = polyA.length
456461
for (let i = 0; i < numVerticesA; i++) {
457462
const a = hullA.vertices[polyA[i]]
@@ -469,14 +474,22 @@ export class ConvexPolyhedron extends Shape {
469474
quatA.vmult(worldA1, worldA1)
470475
posA.vadd(worldA1, worldA1)
471476

472-
const otherFace = polyA.connectedFaces[i]
473-
localPlaneNormal.copy(this.faceNormals[otherFace])
474-
const localPlaneEq = this.getPlaneConstantOfFace(otherFace)
477+
let planeEqWS1 = -worldA1.dot(planeNormalWS1)
478+
let planeEqWS
479+
let otherFace = polyA.connectedFaces[i]
475480

476-
planeNormalWS.copy(localPlaneNormal)
477-
quatA.vmult(planeNormalWS, planeNormalWS)
481+
if (otherFace != null) {
482+
localPlaneNormal.copy(this.faceNormals[otherFace])
483+
const localPlaneEq = this.getPlaneConstantOfFace(otherFace)
478484

479-
const planeEqWS = localPlaneEq - planeNormalWS.dot(posA)
485+
planeNormalWS.copy(localPlaneNormal)
486+
quatA.vmult(planeNormalWS, planeNormalWS)
487+
posA.vadd(planeNormalWS, planeNormalWS)
488+
planeEqWS = localPlaneEq - planeNormalWS.dot(posA)
489+
} else {
490+
planeNormalWS.copy(planeNormalWS1)
491+
planeEqWS = planeEqWS1
492+
}
480493

481494
// Clip face against our constructed plane
482495
this.clipFaceAgainstPlane(pVtxIn, pVtxOut, planeNormalWS, planeEqWS)
@@ -508,7 +521,7 @@ export class ConvexPolyhedron extends Shape {
508521

509522
if (depth <= maxDist) {
510523
const point = pVtxIn[i]
511-
if (depth <= 0) {
524+
if (depth <= 1e-6) {
512525
const p = {
513526
point,
514527
normal: planeNormalWS,
@@ -736,34 +749,36 @@ export class ConvexPolyhedron extends Shape {
736749
// Apply rotation
737750
if (quat) {
738751
// Rotate vertices
739-
for (var i = 0; i < n; i++) {
752+
for (let i = 0; i < n; i++) {
740753
var v = verts[i]
741754
quat.vmult(v, v)
742755
}
743756
// Rotate face normals
744-
for (var i = 0; i < this.faceNormals.length; i++) {
757+
for (let i = 0; i < this.faceNormals.length; i++) {
745758
var v = this.faceNormals[i]
746759
quat.vmult(v, v)
747760
}
748761
/*
749762
// Rotate edges
750-
for(var i=0; i<this.uniqueEdges.length; i++){
763+
for(let i=0; i<this.uniqueEdges.length; i++){
751764
var v = this.uniqueEdges[i];
752765
quat.vmult(v,v);
753766
}*/
754767
}
755768

756769
// Apply offset
757770
if (offset) {
758-
for (var i = 0; i < n; i++) {
771+
for (let i = 0; i < n; i++) {
759772
var v = verts[i]
760773
v.vadd(offset, v)
761774
}
762775
}
763776
}
764777

765778
/**
766-
* Checks whether p is inside the polyhedra. Must be in local coords. The point lies outside of the convex hull of the other points if and only if the direction of all the vectors from it to those other points are on less than one half of a sphere around it.
779+
* Checks whether p is inside the polyhedra. Must be in local coords.
780+
* The point lies outside of the convex hull of the other points if and only if the direction
781+
* of all the vectors from it to those other points are on less than one half of a sphere around it.
767782
* @method pointIsInside
768783
* @param {Vec3} p A point given in local coordinates
769784
* @return {Boolean}
@@ -819,7 +834,6 @@ ConvexPolyhedron.computeNormal = (va, vb, vc, target) => {
819834
}
820835
}
821836

822-
823837
const maxminA = []
824838
const maxminB = []
825839

0 commit comments

Comments
 (0)