Skip to content

Commit b08534b

Browse files
committed
Adding PR 360 from cannon schteppe#360
1 parent 95b20bd commit b08534b

File tree

3 files changed

+184
-145
lines changed

3 files changed

+184
-145
lines changed

lib/dapao.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/shapes/ConvexPolyhedron.test.ts

+32
Original file line numberDiff line numberDiff line change
@@ -188,5 +188,37 @@ describe('ConvexPolyhedron', () => {
188188
expect(Math.abs(result[0] - 1.5) < 0.01).toBeTruthy();
189189
expect(Math.abs(result[1] - 0.5) < 0.01).toBeTruthy();
190190
});
191+
192+
it('should calculateWorldAABB always decreasing verts NoUndefined', () => {
193+
const vertices = [
194+
new Vec3( 4, 4, 4),
195+
new Vec3( 3, 3, 3),
196+
new Vec3( 2, 2, 2),
197+
new Vec3( 1, 1, 1),
198+
new Vec3( 0, 0, 0),
199+
new Vec3(-1, -1, -1),
200+
new Vec3(-2, -2, -2),
201+
new Vec3(-3, -3, -3)
202+
];
203+
204+
const indices = [
205+
[3, 2, 1, 0],
206+
[4, 5, 6, 7],
207+
[5, 4, 0, 1],
208+
[2, 3, 7, 6],
209+
[0, 4, 7, 3],
210+
[1, 2, 6, 5],
211+
];
212+
const poly = new ConvexPolyhedron(vertices, indices);
213+
const min = new Vec3();
214+
const max = new Vec3();
215+
poly.calculateWorldAABB(new Vec3(0, 0, 0), new Quaternion(0, 0, 0, 1), min, max);
216+
expect(min.x).not.toBeUndefined();
217+
expect(max.x).not.toBeUndefined();
218+
expect(min.y).not.toBeUndefined();
219+
expect(max.y).not.toBeUndefined();
220+
expect(min.z).not.toBeUndefined();
221+
expect(max.z).not.toBeUndefined();
222+
});
191223
});
192224

src/shapes/ConvexPolyhedron.ts

+151-144
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ export class ConvexPolyhedron extends Shape {
214214
*/
215215
clipAgainstHull(posA: Vec3, quatA: Quaternion, hullB: ConvexPolyhedron, posB: Vec3,
216216
quatB: Quaternion, separatingNormal: Vec3, minDist: number, maxDist: number, result: HullResult[]) {
217-
const cah_WorldNormal = new Vec3();
217+
const cah_WorldNormal = new Vec3();
218218

219219
const WorldNormal = cah_WorldNormal;
220220
const hullA = this;
@@ -266,7 +266,7 @@ export class ConvexPolyhedron extends Shape {
266266
* @return {bool} Returns false if a separation is found, else true
267267
*/
268268
findSeparatingAxis(hullB: ConvexPolyhedron, posA: Vec3, quatA: Quaternion, posB: Vec3,
269-
quatB: Quaternion, target: Vec3, faceListA?: any[], faceListB?: any[]): boolean {
269+
quatB: Quaternion, target: Vec3, faceListA?: any[], faceListB?: any[]): boolean {
270270
const fsa_faceANormalWS3 = new Vec3(),
271271
fsa_Worldnormal1 = new Vec3(),
272272
fsa_deltaC = new Vec3(),
@@ -781,142 +781,149 @@ export class ConvexPolyhedron extends Shape {
781781
tempWorldVertex.copy(verts[i]);
782782
quat.vmult(tempWorldVertex, tempWorldVertex);
783783
pos.vadd(tempWorldVertex, tempWorldVertex);
784+
784785
const v = tempWorldVertex;
785786
if (v.x < minx || minx === undefined) {
786787
minx = v.x;
787-
} else if (v.x > maxx || maxx === undefined) {
788+
}
789+
790+
if (v.x > maxx || maxx === undefined) {
788791
maxx = v.x;
789792
}
790793

791794
if (v.y < miny || miny === undefined) {
792795
miny = v.y;
793-
} else if (v.y > maxy || maxy === undefined) {
796+
}
797+
798+
if (v.y > maxy || maxy === undefined) {
794799
maxy = v.y;
795800
}
796801

797802
if (v.z < minz || minz === undefined) {
798803
minz = v.z;
799-
} else if (v.z > maxz || maxz === undefined) {
804+
}
805+
806+
if (v.z > maxz || maxz === undefined) {
800807
maxz = v.z;
801808
}
802-
}
803-
min.set(minx, miny, minz);
804-
max.set(maxx, maxy, maxz);
805809
}
810+
min.set(minx, miny, minz);
811+
max.set(maxx, maxy, maxz);
812+
}
806813

807-
/**
808-
* Get approximate convex volume
809-
* @method volume
810-
* @return {Number}
811-
*/
812-
volume(): number {
813-
return 4.0 * Math.PI * this.boundingSphereRadius / 3.0;
814+
/**
815+
* Get approximate convex volume
816+
* @method volume
817+
* @return {Number}
818+
*/
819+
volume(): number {
820+
return 4.0 * Math.PI * this.boundingSphereRadius / 3.0;
821+
}
822+
823+
/**
824+
* Get an average of all the vertices positions
825+
* @method getAveragePointLocal
826+
* @param {Vec3} target
827+
* @return {Vec3}
828+
*/
829+
getAveragePointLocal(target: Vec3): Vec3 {
830+
target = target || new Vec3();
831+
const n = this.vertices.length,
832+
verts = this.vertices;
833+
for (let i = 0; i < n; i++) {
834+
target.vadd(verts[i], target);
814835
}
836+
target.mult(1 / n, target);
837+
return target;
838+
}
815839

816-
/**
817-
* Get an average of all the vertices positions
818-
* @method getAveragePointLocal
819-
* @param {Vec3} target
820-
* @return {Vec3}
821-
*/
822-
getAveragePointLocal(target: Vec3): Vec3 {
823-
target = target || new Vec3();
824-
const n = this.vertices.length,
825-
verts = this.vertices;
840+
/**
841+
* Transform all local points. Will change the .vertices
842+
* @method transformAllPoints
843+
* @param {Vec3} offset
844+
* @param {Quaternion} quat
845+
*/
846+
transformAllPoints(offset: Vec3, quat: Quaternion) {
847+
const n = this.vertices.length,
848+
verts = this.vertices;
849+
850+
// Apply rotation
851+
if (quat) {
852+
// Rotate vertices
826853
for (let i = 0; i < n; i++) {
827-
target.vadd(verts[i], target);
854+
const v = verts[i];
855+
quat.vmult(v, v);
828856
}
829-
target.mult(1 / n, target);
830-
return target;
831-
}
832-
833-
/**
834-
* Transform all local points. Will change the .vertices
835-
* @method transformAllPoints
836-
* @param {Vec3} offset
837-
* @param {Quaternion} quat
838-
*/
839-
transformAllPoints(offset: Vec3, quat: Quaternion) {
840-
const n = this.vertices.length,
841-
verts = this.vertices;
842-
843-
// Apply rotation
844-
if (quat) {
845-
// Rotate vertices
846-
for (let i = 0; i < n; i++) {
847-
const v = verts[i];
848-
quat.vmult(v, v);
849-
}
850-
// Rotate face normals
851-
for (let i = 0; i < this.faceNormals.length; i++) {
852-
const v = this.faceNormals[i];
853-
quat.vmult(v, v);
854-
}
855-
/*
856-
// Rotate edges
857-
for(let i=0; i<this.uniqueEdges.length; i++){
858-
let v = this.uniqueEdges[i];
859-
quat.vmult(v,v);
860-
}*/
857+
// Rotate face normals
858+
for (let i = 0; i < this.faceNormals.length; i++) {
859+
const v = this.faceNormals[i];
860+
quat.vmult(v, v);
861861
}
862+
/*
863+
// Rotate edges
864+
for(let i=0; i<this.uniqueEdges.length; i++){
865+
let v = this.uniqueEdges[i];
866+
quat.vmult(v,v);
867+
}*/
868+
}
862869

863-
// Apply offset
864-
if (offset) {
865-
for (let i = 0; i < n; i++) {
866-
const v = verts[i];
867-
v.vadd(offset, v);
868-
}
870+
// Apply offset
871+
if (offset) {
872+
for (let i = 0; i < n; i++) {
873+
const v = verts[i];
874+
v.vadd(offset, v);
869875
}
870876
}
877+
}
871878

872-
/**
873-
* Checks whether p is inside the polyhedra. Must be in local coords. The point lies
874-
* outside of the convex hull of the other points if and only if the direction of
875-
* all the vectors from it to those other points are on less than one half of a
876-
* sphere around it.
877-
* @method pointIsInside
878-
* @param {Vec3} p A point given in local coordinates
879-
* @return {Boolean}
880-
*/
881-
pointIsInside(p: Vec3): boolean | number {
882-
const ConvexPolyhedron_pointIsInside = new Vec3();
883-
const ConvexPolyhedron_vToP = new Vec3();
884-
const ConvexPolyhedron_vToPointInside = new Vec3();
885-
886-
const verts = this.vertices;
887-
const faces = this.faces;
888-
const normals = this.faceNormals;
889-
890-
const positiveResult: any = null;
891-
const N = this.faces.length;
892-
const pointInside = ConvexPolyhedron_pointIsInside;
893-
this.getAveragePointLocal(pointInside);
894-
895-
for (let i = 0; i < N; i++) {
896-
const numVertices = this.faces[i].length;
897-
const vec = normals[i];
898-
const v = verts[faces[i][0]]; // We only need one point in the face
899-
900-
// This dot product determines which side of the edge the point is
901-
const vToP = ConvexPolyhedron_vToP;
902-
p.vsub(v, vToP);
903-
const r1 = vec.dot(vToP);
904-
905-
const vToPointInside = ConvexPolyhedron_vToPointInside;
906-
pointInside.vsub(v, vToPointInside);
907-
const r2 = vec.dot(vToPointInside);
908-
909-
if ((r1 < 0 && r2 > 0) || (r1 > 0 && r2 < 0)) {
910-
return false; // Encountered some other sign. Exit.
911-
} else {
912-
}
879+
/**
880+
* Checks whether p is inside the polyhedra. Must be in local coords. The point lies
881+
* outside of the convex hull of the other points if and only if the direction of
882+
* all the vectors from it to those other points are on less than one half of a
883+
* sphere around it.
884+
* @method pointIsInside
885+
* @param {Vec3} p A point given in local coordinates
886+
* @return {Boolean}
887+
*/
888+
pointIsInside(p: Vec3): boolean | number {
889+
const ConvexPolyhedron_pointIsInside = new Vec3();
890+
const ConvexPolyhedron_vToP = new Vec3();
891+
const ConvexPolyhedron_vToPointInside = new Vec3();
892+
893+
const verts = this.vertices;
894+
const faces = this.faces;
895+
const normals = this.faceNormals;
896+
897+
const positiveResult: any = null;
898+
const N = this.faces.length;
899+
const pointInside = ConvexPolyhedron_pointIsInside;
900+
this.getAveragePointLocal(pointInside);
901+
902+
for (let i = 0; i < N; i++) {
903+
const numVertices = this.faces[i].length;
904+
const vec = normals[i];
905+
const v = verts[faces[i][0]]; // We only need one point in the face
906+
907+
// This dot product determines which side of the edge the point is
908+
const vToP = ConvexPolyhedron_vToP;
909+
p.vsub(v, vToP);
910+
const r1 = vec.dot(vToP);
911+
912+
const vToPointInside = ConvexPolyhedron_vToPointInside;
913+
pointInside.vsub(v, vToPointInside);
914+
const r2 = vec.dot(vToPointInside);
915+
916+
if ((r1 < 0 && r2 > 0) || (r1 > 0 && r2 < 0)) {
917+
return false; // Encountered some other sign. Exit.
918+
} else {
913919
}
914-
915-
// If we got here, all dot products were of the same sign.
916-
// TODO: fix the return here. ???
917-
return positiveResult ? 1 : -1;
918920
}
919921

922+
// If we got here, all dot products were of the same sign.
923+
// TODO: fix the return here. ???
924+
return positiveResult ? 1 : -1;
925+
}
926+
920927
/**
921928
* Get max and min dot product of a convex hull at position (pos,quat) projected onto an axis. Results are saved in the array maxmin.
922929
* @static
@@ -928,50 +935,50 @@ export class ConvexPolyhedron extends Shape {
928935
* @param {array} result result[0] and result[1] will be set to maximum and minimum, respectively.
929936
*/
930937
static project(hull: ConvexPolyhedron, axis: Vec3, pos: Vec3, quat: Quaternion, result: number[]) {
931-
const project_worldVertex = new Vec3();
932-
const project_localAxis = new Vec3();
933-
const project_localOrigin = new Vec3();
938+
const project_worldVertex = new Vec3();
939+
const project_localAxis = new Vec3();
940+
const project_localOrigin = new Vec3();
934941

935-
const n = hull.vertices.length,
936-
worldVertex = project_worldVertex,
937-
localAxis = project_localAxis,
938-
localOrigin = project_localOrigin,
939-
vs = hull.vertices;
940-
let max = 0,
941-
min = 0;
942+
const n = hull.vertices.length,
943+
worldVertex = project_worldVertex,
944+
localAxis = project_localAxis,
945+
localOrigin = project_localOrigin,
946+
vs = hull.vertices;
947+
let max = 0,
948+
min = 0;
942949

943-
localOrigin.setZero();
950+
localOrigin.setZero();
944951

945-
// Transform the axis to local
946-
Transform.vectorToLocalFrame(pos, quat, axis, localAxis);
947-
Transform.pointToLocalFrame(pos, quat, localOrigin, localOrigin);
948-
const add = localOrigin.dot(localAxis);
952+
// Transform the axis to local
953+
Transform.vectorToLocalFrame(pos, quat, axis, localAxis);
954+
Transform.pointToLocalFrame(pos, quat, localOrigin, localOrigin);
955+
const add = localOrigin.dot(localAxis);
949956

950-
min = max = vs[0].dot(localAxis);
957+
min = max = vs[0].dot(localAxis);
951958

952-
for (let i = 1; i < n; i++) {
953-
const val = vs[i].dot(localAxis);
959+
for (let i = 1; i < n; i++) {
960+
const val = vs[i].dot(localAxis);
954961

955-
if (val > max) {
956-
max = val;
957-
}
962+
if (val > max) {
963+
max = val;
964+
}
958965

959-
if (val < min) {
960-
min = val;
961-
}
966+
if (val < min) {
967+
min = val;
962968
}
969+
}
963970

964-
min -= add;
965-
max -= add;
971+
min -= add;
972+
max -= add;
966973

967-
if (min > max) {
968-
// Inconsistent - swap
969-
const temp = min;
970-
min = max;
971-
max = temp;
972-
}
973-
// Output
974-
result[0] = max;
975-
result[1] = min;
974+
if (min > max) {
975+
// Inconsistent - swap
976+
const temp = min;
977+
min = max;
978+
max = temp;
976979
}
980+
// Output
981+
result[0] = max;
982+
result[1] = min;
983+
}
977984
}

0 commit comments

Comments
 (0)