|
@@ -14,7 +14,8 @@ import {
|
|
|
zero3,
|
|
|
one3,
|
|
|
two3,
|
|
|
- eps
|
|
|
+ eps,
|
|
|
+ posInf3
|
|
|
} from './Constants.tests';
|
|
|
|
|
|
export default QUnit.module( 'Maths', () => {
|
|
@@ -89,10 +90,14 @@ export default QUnit.module( 'Maths', () => {
|
|
|
QUnit.test( "at", ( assert ) => {
|
|
|
|
|
|
var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
|
|
|
+ var point = new Vector3();
|
|
|
|
|
|
- assert.ok( a.at( 0 ).equals( one3 ), "Passed!" );
|
|
|
- assert.ok( a.at( - 1 ).equals( new Vector3( 1, 1, 0 ) ), "Passed!" );
|
|
|
- assert.ok( a.at( 1 ).equals( new Vector3( 1, 1, 2 ) ), "Passed!" );
|
|
|
+ a.at( 0, point );
|
|
|
+ assert.ok( point.equals( one3 ), "Passed!" );
|
|
|
+ a.at( - 1, point );
|
|
|
+ assert.ok( point.equals( new Vector3( 1, 1, 0 ) ), "Passed!" );
|
|
|
+ a.at( 1, point );
|
|
|
+ assert.ok( point.equals( new Vector3( 1, 1, 2 ) ), "Passed!" );
|
|
|
|
|
|
} );
|
|
|
|
|
@@ -110,18 +115,19 @@ export default QUnit.module( 'Maths', () => {
|
|
|
QUnit.test( "closestPointToPoint", ( assert ) => {
|
|
|
|
|
|
var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
|
|
|
+ var point = new Vector3();
|
|
|
|
|
|
// behind the ray
|
|
|
- var b = a.closestPointToPoint( zero3 );
|
|
|
- assert.ok( b.equals( one3 ), "Passed!" );
|
|
|
+ a.closestPointToPoint( zero3, point );
|
|
|
+ assert.ok( point.equals( one3 ), "Passed!" );
|
|
|
|
|
|
// front of the ray
|
|
|
- var c = a.closestPointToPoint( new Vector3( 0, 0, 50 ) );
|
|
|
- assert.ok( c.equals( new Vector3( 1, 1, 50 ) ), "Passed!" );
|
|
|
+ a.closestPointToPoint( new Vector3( 0, 0, 50 ), point );
|
|
|
+ assert.ok( point.equals( new Vector3( 1, 1, 50 ) ), "Passed!" );
|
|
|
|
|
|
// exactly on the ray
|
|
|
- var d = a.closestPointToPoint( one3 );
|
|
|
- assert.ok( d.equals( one3 ), "Passed!" );
|
|
|
+ a.closestPointToPoint( one3, point );
|
|
|
+ assert.ok( point.equals( one3 ), "Passed!" );
|
|
|
|
|
|
} );
|
|
|
|
|
@@ -201,6 +207,7 @@ export default QUnit.module( 'Maths', () => {
|
|
|
QUnit.test( "intersectSphere", ( assert ) => {
|
|
|
|
|
|
var TOL = 0.0001;
|
|
|
+ var point = new Vector3();
|
|
|
|
|
|
// ray a0 origin located at ( 0, 0, 0 ) and points outward in negative-z direction
|
|
|
var a0 = new Ray( zero3.clone(), new Vector3( 0, 0, - 1 ) );
|
|
@@ -209,31 +216,38 @@ export default QUnit.module( 'Maths', () => {
|
|
|
|
|
|
// sphere (radius of 2) located behind ray a0, should result in null
|
|
|
var b = new Sphere( new Vector3( 0, 0, 3 ), 2 );
|
|
|
- assert.ok( a0.intersectSphere( b ) === null, "Passed!" );
|
|
|
+ a0.intersectSphere( b, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "Passed!" );
|
|
|
|
|
|
// sphere (radius of 2) located in front of, but too far right of ray a0, should result in null
|
|
|
var b = new Sphere( new Vector3( 3, 0, - 1 ), 2 );
|
|
|
- assert.ok( a0.intersectSphere( b ) === null, "Passed!" );
|
|
|
+ a0.intersectSphere( b, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "Passed!" );
|
|
|
|
|
|
// sphere (radius of 2) located below ray a1, should result in null
|
|
|
var b = new Sphere( new Vector3( 1, - 2, 1 ), 2 );
|
|
|
- assert.ok( a1.intersectSphere( b ) === null, "Passed!" );
|
|
|
+ a1.intersectSphere( b, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "Passed!" );
|
|
|
|
|
|
// sphere (radius of 1) located to the left of ray a1, should result in intersection at 0, 1, 1
|
|
|
var b = new Sphere( new Vector3( - 1, 1, 1 ), 1 );
|
|
|
- assert.ok( a1.intersectSphere( b ).distanceTo( new Vector3( 0, 1, 1 ) ) < TOL, "Passed!" );
|
|
|
+ a1.intersectSphere( b, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( 0, 1, 1 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
// sphere (radius of 1) located in front of ray a0, should result in intersection at 0, 0, -1
|
|
|
var b = new Sphere( new Vector3( 0, 0, - 2 ), 1 );
|
|
|
- assert.ok( a0.intersectSphere( b ).distanceTo( new Vector3( 0, 0, - 1 ) ) < TOL, "Passed!" );
|
|
|
+ a0.intersectSphere( b, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( 0, 0, - 1 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
// sphere (radius of 2) located in front & right of ray a0, should result in intersection at 0, 0, -1, or left-most edge of sphere
|
|
|
var b = new Sphere( new Vector3( 2, 0, - 1 ), 2 );
|
|
|
- assert.ok( a0.intersectSphere( b ).distanceTo( new Vector3( 0, 0, - 1 ) ) < TOL, "Passed!" );
|
|
|
+ a0.intersectSphere( b, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( 0, 0, - 1 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
// same situation as above, but move the sphere a fraction more to the right, and ray a0 should now just miss
|
|
|
var b = new Sphere( new Vector3( 2.01, 0, - 1 ), 2 );
|
|
|
- assert.ok( a0.intersectSphere( b ) === null, "Passed!" );
|
|
|
+ a0.intersectSphere( b, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "Passed!" );
|
|
|
|
|
|
// following QUnit.tests are for situations where the ray origin is inside the sphere
|
|
|
|
|
@@ -241,19 +255,22 @@ export default QUnit.module( 'Maths', () => {
|
|
|
// is behind ray a0. Therefore, second exit point on back of sphere will be returned: 0, 0, -1
|
|
|
// thus keeping the intersection point always in front of the ray.
|
|
|
var b = new Sphere( zero3.clone(), 1 );
|
|
|
- assert.ok( a0.intersectSphere( b ).distanceTo( new Vector3( 0, 0, - 1 ) ) < TOL, "Passed!" );
|
|
|
+ a0.intersectSphere( b, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( 0, 0, - 1 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
// sphere (radius of 4) center located behind ray a0 origin / sphere surrounds the ray origin, so the first intersect point 0, 0, 5,
|
|
|
// is behind ray a0. Therefore, second exit point on back of sphere will be returned: 0, 0, -3
|
|
|
// thus keeping the intersection point always in front of the ray.
|
|
|
var b = new Sphere( new Vector3( 0, 0, 1 ), 4 );
|
|
|
- assert.ok( a0.intersectSphere( b ).distanceTo( new Vector3( 0, 0, - 3 ) ) < TOL, "Passed!" );
|
|
|
+ a0.intersectSphere( b, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( 0, 0, - 3 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
// sphere (radius of 4) center located in front of ray a0 origin / sphere surrounds the ray origin, so the first intersect point 0, 0, 3,
|
|
|
// is behind ray a0. Therefore, second exit point on back of sphere will be returned: 0, 0, -5
|
|
|
// thus keeping the intersection point always in front of the ray.
|
|
|
var b = new Sphere( new Vector3( 0, 0, - 1 ), 4 );
|
|
|
- assert.ok( a0.intersectSphere( b ).distanceTo( new Vector3( 0, 0, - 5 ) ) < TOL, "Passed!" );
|
|
|
+ a0.intersectSphere( b, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( 0, 0, - 5 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
} );
|
|
|
|
|
@@ -283,26 +300,32 @@ export default QUnit.module( 'Maths', () => {
|
|
|
QUnit.test( "intersectPlane", ( assert ) => {
|
|
|
|
|
|
var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
|
|
|
+ var point = new Vector3();
|
|
|
|
|
|
// parallel plane behind
|
|
|
var b = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 0, 0, 1 ), new Vector3( 1, 1, - 1 ) );
|
|
|
- assert.ok( a.intersectPlane( b ) === null, "Passed!" );
|
|
|
+ a.intersectPlane( b, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "Passed!" );
|
|
|
|
|
|
// parallel plane coincident with origin
|
|
|
var c = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 0, 0, 1 ), new Vector3( 1, 1, 0 ) );
|
|
|
- assert.ok( a.intersectPlane( c ) === null, "Passed!" );
|
|
|
+ a.intersectPlane( c, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "Passed!" );
|
|
|
|
|
|
// parallel plane infront
|
|
|
var d = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 0, 0, 1 ), new Vector3( 1, 1, 1 ) );
|
|
|
- assert.ok( a.intersectPlane( d ).equals( a.origin ), "Passed!" );
|
|
|
+ a.intersectPlane( d, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( a.origin ), "Passed!" );
|
|
|
|
|
|
// perpendical ray that overlaps exactly
|
|
|
var e = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 1, 0, 0 ), one3 );
|
|
|
- assert.ok( a.intersectPlane( e ).equals( a.origin ), "Passed!" );
|
|
|
+ a.intersectPlane( e, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( a.origin ), "Passed!" );
|
|
|
|
|
|
// perpendical ray that doesn't overlap
|
|
|
var f = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 1, 0, 0 ), zero3 );
|
|
|
- assert.ok( a.intersectPlane( f ) === null, "Passed!" );
|
|
|
+ a.intersectPlane( f, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "Passed!" );
|
|
|
|
|
|
} );
|
|
|
|
|
@@ -337,36 +360,43 @@ export default QUnit.module( 'Maths', () => {
|
|
|
var TOL = 0.0001;
|
|
|
|
|
|
var box = new Box3( new Vector3( - 1, - 1, - 1 ), new Vector3( 1, 1, 1 ) );
|
|
|
+ var point = new Vector3();
|
|
|
|
|
|
var a = new Ray( new Vector3( - 2, 0, 0 ), new Vector3( 1, 0, 0 ) );
|
|
|
//ray should intersect box at -1,0,0
|
|
|
assert.ok( a.intersectsBox( box ) === true, "Passed!" );
|
|
|
- assert.ok( a.intersectBox( box ).distanceTo( new Vector3( - 1, 0, 0 ) ) < TOL, "Passed!" );
|
|
|
+ a.intersectBox( box, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( - 1, 0, 0 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
var b = new Ray( new Vector3( - 2, 0, 0 ), new Vector3( - 1, 0, 0 ) );
|
|
|
//ray is point away from box, it should not intersect
|
|
|
assert.ok( b.intersectsBox( box ) === false, "Passed!" );
|
|
|
- assert.ok( b.intersectBox( box ) === null, "Passed!" );
|
|
|
+ b.intersectBox( box, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "Passed!" );
|
|
|
|
|
|
var c = new Ray( new Vector3( 0, 0, 0 ), new Vector3( 1, 0, 0 ) );
|
|
|
// ray is inside box, should return exit point
|
|
|
assert.ok( c.intersectsBox( box ) === true, "Passed!" );
|
|
|
- assert.ok( c.intersectBox( box ).distanceTo( new Vector3( 1, 0, 0 ) ) < TOL, "Passed!" );
|
|
|
+ c.intersectBox( box, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( 1, 0, 0 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
var d = new Ray( new Vector3( 0, 2, 1 ), new Vector3( 0, - 1, - 1 ).normalize() );
|
|
|
//tilted ray should intersect box at 0,1,0
|
|
|
assert.ok( d.intersectsBox( box ) === true, "Passed!" );
|
|
|
- assert.ok( d.intersectBox( box ).distanceTo( new Vector3( 0, 1, 0 ) ) < TOL, "Passed!" );
|
|
|
+ d.intersectBox( box, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( 0, 1, 0 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
var e = new Ray( new Vector3( 1, - 2, 1 ), new Vector3( 0, 1, 0 ).normalize() );
|
|
|
//handle case where ray is coplanar with one of the boxes side - box in front of ray
|
|
|
assert.ok( e.intersectsBox( box ) === true, "Passed!" );
|
|
|
- assert.ok( e.intersectBox( box ).distanceTo( new Vector3( 1, - 1, 1 ) ) < TOL, "Passed!" );
|
|
|
+ e.intersectBox( box, point );
|
|
|
+ assert.ok( point.distanceTo( new Vector3( 1, - 1, 1 ) ) < TOL, "Passed!" );
|
|
|
|
|
|
var f = new Ray( new Vector3( 1, - 2, 0 ), new Vector3( 0, - 1, 0 ).normalize() );
|
|
|
//handle case where ray is coplanar with one of the boxes side - box behind ray
|
|
|
assert.ok( f.intersectsBox( box ) === false, "Passed!" );
|
|
|
- assert.ok( f.intersectBox( box ) == null, "Passed!" );
|
|
|
+ f.intersectBox( box, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "Passed!" );
|
|
|
|
|
|
} );
|
|
|
|
|
@@ -382,46 +412,46 @@ export default QUnit.module( 'Maths', () => {
|
|
|
var a = new Vector3( 1, 1, 0 );
|
|
|
var b = new Vector3( 0, 1, 1 );
|
|
|
var c = new Vector3( 1, 0, 1 );
|
|
|
- var intersect;
|
|
|
+ var point = new Vector3();
|
|
|
|
|
|
// DdN == 0
|
|
|
ray.set( ray.origin, zero3.clone() );
|
|
|
- intersect = ray.intersectTriangle( a, b, c, false );
|
|
|
- assert.strictEqual( intersect, null, "No intersection if direction == zero" );
|
|
|
+ ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "No intersection if direction == zero" );
|
|
|
|
|
|
// DdN > 0, backfaceCulling = true
|
|
|
ray.set( ray.origin, one3.clone() );
|
|
|
- intersect = ray.intersectTriangle( a, b, c, true );
|
|
|
- assert.strictEqual( intersect, null, "No intersection with backside faces if backfaceCulling is true" );
|
|
|
+ ray.intersectTriangle( a, b, c, true, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "No intersection with backside faces if backfaceCulling is true" );
|
|
|
|
|
|
// DdN > 0
|
|
|
ray.set( ray.origin, one3.clone() );
|
|
|
- intersect = ray.intersectTriangle( a, b, c, false );
|
|
|
- assert.ok( Math.abs( intersect.x - 2 / 3 ) <= eps, "Successful intersection: check x" );
|
|
|
- assert.ok( Math.abs( intersect.y - 2 / 3 ) <= eps, "Successful intersection: check y" );
|
|
|
- assert.ok( Math.abs( intersect.z - 2 / 3 ) <= eps, "Successful intersection: check z" );
|
|
|
+ ray.intersectTriangle( a, b, c, false, point );
|
|
|
+ assert.ok( Math.abs( point.x - 2 / 3 ) <= eps, "Successful intersection: check x" );
|
|
|
+ assert.ok( Math.abs( point.y - 2 / 3 ) <= eps, "Successful intersection: check y" );
|
|
|
+ assert.ok( Math.abs( point.z - 2 / 3 ) <= eps, "Successful intersection: check z" );
|
|
|
|
|
|
// DdN > 0, DdQxE2 < 0
|
|
|
b.multiplyScalar( - 1 );
|
|
|
- intersect = ray.intersectTriangle( a, b, c, false );
|
|
|
- assert.strictEqual( intersect, null, "No intersection" );
|
|
|
+ ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "No intersection" );
|
|
|
|
|
|
// DdN > 0, DdE1xQ < 0
|
|
|
a.multiplyScalar( - 1 );
|
|
|
- intersect = ray.intersectTriangle( a, b, c, false );
|
|
|
- assert.strictEqual( intersect, null, "No intersection" );
|
|
|
+ ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "No intersection" );
|
|
|
|
|
|
// DdN > 0, DdQxE2 + DdE1xQ > DdN
|
|
|
b.multiplyScalar( - 1 );
|
|
|
- intersect = ray.intersectTriangle( a, b, c, false );
|
|
|
- assert.strictEqual( intersect, null, "No intersection" );
|
|
|
+ ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "No intersection" );
|
|
|
|
|
|
// DdN < 0, QdN < 0
|
|
|
a.multiplyScalar( - 1 );
|
|
|
b.multiplyScalar( - 1 );
|
|
|
ray.direction.multiplyScalar( - 1 );
|
|
|
- intersect = ray.intersectTriangle( a, b, c, false );
|
|
|
- assert.strictEqual( intersect, null, "No intersection when looking in the wrong direction" );
|
|
|
+ ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
|
|
|
+ assert.ok( point.equals( posInf3 ), "No intersection when looking in the wrong direction" );
|
|
|
|
|
|
} );
|
|
|
|