Ray.tests.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /**
  2. * @author bhouston / http://exocortex.com
  3. * @author TristanVALCKE / https://github.com/Itee
  4. */
  5. /* global QUnit */
  6. import { Ray } from '../../../../src/math/Ray';
  7. import { Box3 } from '../../../../src/math/Box3';
  8. import { Vector3 } from '../../../../src/math/Vector3';
  9. import { Sphere } from '../../../../src/math/Sphere';
  10. import { Plane } from '../../../../src/math/Plane';
  11. import { Matrix4 } from '../../../../src/math/Matrix4';
  12. import {
  13. zero3,
  14. one3,
  15. two3,
  16. eps,
  17. posInf3
  18. } from './Constants.tests';
  19. export default QUnit.module( 'Maths', () => {
  20. QUnit.module( 'Ray', () => {
  21. // INSTANCING
  22. QUnit.test( "Instancing", ( assert ) => {
  23. var a = new Ray();
  24. assert.ok( a.origin.equals( zero3 ), "Passed!" );
  25. assert.ok( a.direction.equals( new Vector3( 0, 0, - 1 ) ), "Passed!" );
  26. var a = new Ray( two3.clone(), one3.clone() );
  27. assert.ok( a.origin.equals( two3 ), "Passed!" );
  28. assert.ok( a.direction.equals( one3 ), "Passed!" );
  29. } );
  30. // PUBLIC STUFF
  31. QUnit.todo( "isRay", ( assert ) => {
  32. assert.ok( false, "everything's gonna be alright" );
  33. } );
  34. QUnit.test( "set", ( assert ) => {
  35. var a = new Ray();
  36. a.set( one3, one3 );
  37. assert.ok( a.origin.equals( one3 ), "Passed!" );
  38. assert.ok( a.direction.equals( one3 ), "Passed!" );
  39. } );
  40. QUnit.test( "recast/clone", ( assert ) => {
  41. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  42. assert.ok( a.recast( 0 ).equals( a ), "Passed!" );
  43. var b = a.clone();
  44. assert.ok( b.recast( - 1 ).equals( new Ray( new Vector3( 1, 1, 0 ), new Vector3( 0, 0, 1 ) ) ), "Passed!" );
  45. var c = a.clone();
  46. assert.ok( c.recast( 1 ).equals( new Ray( new Vector3( 1, 1, 2 ), new Vector3( 0, 0, 1 ) ) ), "Passed!" );
  47. var d = a.clone();
  48. var e = d.clone().recast( 1 );
  49. assert.ok( d.equals( a ), "Passed!" );
  50. assert.ok( ! e.equals( d ), "Passed!" );
  51. assert.ok( e.equals( c ), "Passed!" );
  52. } );
  53. QUnit.test( "copy/equals", ( assert ) => {
  54. var a = new Ray( zero3.clone(), one3.clone() );
  55. var b = new Ray().copy( a );
  56. assert.ok( b.origin.equals( zero3 ), "Passed!" );
  57. assert.ok( b.direction.equals( one3 ), "Passed!" );
  58. // ensure that it is a true copy
  59. a.origin = zero3;
  60. a.direction = one3;
  61. assert.ok( b.origin.equals( zero3 ), "Passed!" );
  62. assert.ok( b.direction.equals( one3 ), "Passed!" );
  63. } );
  64. QUnit.test( "at", ( assert ) => {
  65. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  66. var point = new Vector3();
  67. a.at( 0, point );
  68. assert.ok( point.equals( one3 ), "Passed!" );
  69. a.at( - 1, point );
  70. assert.ok( point.equals( new Vector3( 1, 1, 0 ) ), "Passed!" );
  71. a.at( 1, point );
  72. assert.ok( point.equals( new Vector3( 1, 1, 2 ) ), "Passed!" );
  73. } );
  74. QUnit.test( "lookAt", ( assert ) => {
  75. var a = new Ray( two3.clone(), one3.clone() );
  76. var target = one3.clone();
  77. var expected = target.sub( two3 ).normalize();
  78. a.lookAt( target );
  79. assert.ok( a.direction.equals( expected ), "Check if we're looking in the right direction" );
  80. } );
  81. QUnit.test( "closestPointToPoint", ( assert ) => {
  82. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  83. var point = new Vector3();
  84. // behind the ray
  85. a.closestPointToPoint( zero3, point );
  86. assert.ok( point.equals( one3 ), "Passed!" );
  87. // front of the ray
  88. a.closestPointToPoint( new Vector3( 0, 0, 50 ), point );
  89. assert.ok( point.equals( new Vector3( 1, 1, 50 ) ), "Passed!" );
  90. // exactly on the ray
  91. a.closestPointToPoint( one3, point );
  92. assert.ok( point.equals( one3 ), "Passed!" );
  93. } );
  94. QUnit.test( "distanceToPoint", ( assert ) => {
  95. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  96. // behind the ray
  97. var b = a.distanceToPoint( zero3 );
  98. assert.ok( b === Math.sqrt( 3 ), "Passed!" );
  99. // front of the ray
  100. var c = a.distanceToPoint( new Vector3( 0, 0, 50 ) );
  101. assert.ok( c === Math.sqrt( 2 ), "Passed!" );
  102. // exactly on the ray
  103. var d = a.distanceToPoint( one3 );
  104. assert.ok( d === 0, "Passed!" );
  105. } );
  106. QUnit.test( "distanceSqToPoint", ( assert ) => {
  107. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  108. // behind the ray
  109. var b = a.distanceSqToPoint( zero3 );
  110. assert.ok( b === 3, "Passed!" );
  111. // front of the ray
  112. var c = a.distanceSqToPoint( new Vector3( 0, 0, 50 ) );
  113. assert.ok( c === 2, "Passed!" );
  114. // exactly on the ray
  115. var d = a.distanceSqToPoint( one3 );
  116. assert.ok( d === 0, "Passed!" );
  117. } );
  118. QUnit.test( "distanceSqToSegment", ( assert ) => {
  119. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  120. var ptOnLine = new Vector3();
  121. var ptOnSegment = new Vector3();
  122. //segment in front of the ray
  123. var v0 = new Vector3( 3, 5, 50 );
  124. var v1 = new Vector3( 50, 50, 50 ); // just a far away point
  125. var distSqr = a.distanceSqToSegment( v0, v1, ptOnLine, ptOnSegment );
  126. assert.ok( ptOnSegment.distanceTo( v0 ) < 0.0001, "Passed!" );
  127. assert.ok( ptOnLine.distanceTo( new Vector3( 1, 1, 50 ) ) < 0.0001, "Passed!" );
  128. // ((3-1) * (3-1) + (5-1) * (5-1) = 4 + 16 = 20
  129. assert.ok( Math.abs( distSqr - 20 ) < 0.0001, "Passed!" );
  130. //segment behind the ray
  131. var v0 = new Vector3( - 50, - 50, - 50 ); // just a far away point
  132. var v1 = new Vector3( - 3, - 5, - 4 );
  133. var distSqr = a.distanceSqToSegment( v0, v1, ptOnLine, ptOnSegment );
  134. assert.ok( ptOnSegment.distanceTo( v1 ) < 0.0001, "Passed!" );
  135. assert.ok( ptOnLine.distanceTo( one3 ) < 0.0001, "Passed!" );
  136. // ((-3-1) * (-3-1) + (-5-1) * (-5-1) + (-4-1) + (-4-1) = 16 + 36 + 25 = 77
  137. assert.ok( Math.abs( distSqr - 77 ) < 0.0001, "Passed!" );
  138. //exact intersection between the ray and the segment
  139. var v0 = new Vector3( - 50, - 50, - 50 );
  140. var v1 = new Vector3( 50, 50, 50 );
  141. var distSqr = a.distanceSqToSegment( v0, v1, ptOnLine, ptOnSegment );
  142. assert.ok( ptOnSegment.distanceTo( one3 ) < 0.0001, "Passed!" );
  143. assert.ok( ptOnLine.distanceTo( one3 ) < 0.0001, "Passed!" );
  144. assert.ok( distSqr < 0.0001, "Passed!" );
  145. } );
  146. QUnit.test( "intersectSphere", ( assert ) => {
  147. var TOL = 0.0001;
  148. var point = new Vector3();
  149. // ray a0 origin located at ( 0, 0, 0 ) and points outward in negative-z direction
  150. var a0 = new Ray( zero3.clone(), new Vector3( 0, 0, - 1 ) );
  151. // ray a1 origin located at ( 1, 1, 1 ) and points left in negative-x direction
  152. var a1 = new Ray( one3.clone(), new Vector3( - 1, 0, 0 ) );
  153. // sphere (radius of 2) located behind ray a0, should result in null
  154. var b = new Sphere( new Vector3( 0, 0, 3 ), 2 );
  155. a0.intersectSphere( b, point.copy( posInf3 ) );
  156. assert.ok( point.equals( posInf3 ), "Passed!" );
  157. // sphere (radius of 2) located in front of, but too far right of ray a0, should result in null
  158. var b = new Sphere( new Vector3( 3, 0, - 1 ), 2 );
  159. a0.intersectSphere( b, point.copy( posInf3 ) );
  160. assert.ok( point.equals( posInf3 ), "Passed!" );
  161. // sphere (radius of 2) located below ray a1, should result in null
  162. var b = new Sphere( new Vector3( 1, - 2, 1 ), 2 );
  163. a1.intersectSphere( b, point.copy( posInf3 ) );
  164. assert.ok( point.equals( posInf3 ), "Passed!" );
  165. // sphere (radius of 1) located to the left of ray a1, should result in intersection at 0, 1, 1
  166. var b = new Sphere( new Vector3( - 1, 1, 1 ), 1 );
  167. a1.intersectSphere( b, point );
  168. assert.ok( point.distanceTo( new Vector3( 0, 1, 1 ) ) < TOL, "Passed!" );
  169. // sphere (radius of 1) located in front of ray a0, should result in intersection at 0, 0, -1
  170. var b = new Sphere( new Vector3( 0, 0, - 2 ), 1 );
  171. a0.intersectSphere( b, point );
  172. assert.ok( point.distanceTo( new Vector3( 0, 0, - 1 ) ) < TOL, "Passed!" );
  173. // 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
  174. var b = new Sphere( new Vector3( 2, 0, - 1 ), 2 );
  175. a0.intersectSphere( b, point );
  176. assert.ok( point.distanceTo( new Vector3( 0, 0, - 1 ) ) < TOL, "Passed!" );
  177. // same situation as above, but move the sphere a fraction more to the right, and ray a0 should now just miss
  178. var b = new Sphere( new Vector3( 2.01, 0, - 1 ), 2 );
  179. a0.intersectSphere( b, point.copy( posInf3 ) );
  180. assert.ok( point.equals( posInf3 ), "Passed!" );
  181. // following QUnit.tests are for situations where the ray origin is inside the sphere
  182. // sphere (radius of 1) center located at ray a0 origin / sphere surrounds the ray origin, so the first intersect point 0, 0, 1,
  183. // is behind ray a0. Therefore, second exit point on back of sphere will be returned: 0, 0, -1
  184. // thus keeping the intersection point always in front of the ray.
  185. var b = new Sphere( zero3.clone(), 1 );
  186. a0.intersectSphere( b, point );
  187. assert.ok( point.distanceTo( new Vector3( 0, 0, - 1 ) ) < TOL, "Passed!" );
  188. // sphere (radius of 4) center located behind ray a0 origin / sphere surrounds the ray origin, so the first intersect point 0, 0, 5,
  189. // is behind ray a0. Therefore, second exit point on back of sphere will be returned: 0, 0, -3
  190. // thus keeping the intersection point always in front of the ray.
  191. var b = new Sphere( new Vector3( 0, 0, 1 ), 4 );
  192. a0.intersectSphere( b, point );
  193. assert.ok( point.distanceTo( new Vector3( 0, 0, - 3 ) ) < TOL, "Passed!" );
  194. // 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,
  195. // is behind ray a0. Therefore, second exit point on back of sphere will be returned: 0, 0, -5
  196. // thus keeping the intersection point always in front of the ray.
  197. var b = new Sphere( new Vector3( 0, 0, - 1 ), 4 );
  198. a0.intersectSphere( b, point );
  199. assert.ok( point.distanceTo( new Vector3( 0, 0, - 5 ) ) < TOL, "Passed!" );
  200. } );
  201. QUnit.test( "intersectsSphere", ( assert ) => {
  202. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  203. var b = new Sphere( zero3, 0.5 );
  204. var c = new Sphere( zero3, 1.5 );
  205. var d = new Sphere( one3, 0.1 );
  206. var e = new Sphere( two3, 0.1 );
  207. var f = new Sphere( two3, 1 );
  208. assert.ok( ! a.intersectsSphere( b ), "Passed!" );
  209. assert.ok( ! a.intersectsSphere( c ), "Passed!" );
  210. assert.ok( a.intersectsSphere( d ), "Passed!" );
  211. assert.ok( ! a.intersectsSphere( e ), "Passed!" );
  212. assert.ok( ! a.intersectsSphere( f ), "Passed!" );
  213. } );
  214. QUnit.todo( "distanceToPlane", ( assert ) => {
  215. assert.ok( false, "everything's gonna be alright" );
  216. } );
  217. QUnit.test( "intersectPlane", ( assert ) => {
  218. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  219. var point = new Vector3();
  220. // parallel plane behind
  221. var b = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 0, 0, 1 ), new Vector3( 1, 1, - 1 ) );
  222. a.intersectPlane( b, point.copy( posInf3 ) );
  223. assert.ok( point.equals( posInf3 ), "Passed!" );
  224. // parallel plane coincident with origin
  225. var c = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 0, 0, 1 ), new Vector3( 1, 1, 0 ) );
  226. a.intersectPlane( c, point.copy( posInf3 ) );
  227. assert.ok( point.equals( posInf3 ), "Passed!" );
  228. // parallel plane infront
  229. var d = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 0, 0, 1 ), new Vector3( 1, 1, 1 ) );
  230. a.intersectPlane( d, point.copy( posInf3 ) );
  231. assert.ok( point.equals( a.origin ), "Passed!" );
  232. // perpendical ray that overlaps exactly
  233. var e = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 1, 0, 0 ), one3 );
  234. a.intersectPlane( e, point.copy( posInf3 ) );
  235. assert.ok( point.equals( a.origin ), "Passed!" );
  236. // perpendical ray that doesn't overlap
  237. var f = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 1, 0, 0 ), zero3 );
  238. a.intersectPlane( f, point.copy( posInf3 ) );
  239. assert.ok( point.equals( posInf3 ), "Passed!" );
  240. } );
  241. QUnit.test( "intersectsPlane", ( assert ) => {
  242. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  243. // parallel plane in front of the ray
  244. var b = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 0, 0, 1 ), one3.clone().sub( new Vector3( 0, 0, - 1 ) ) );
  245. assert.ok( a.intersectsPlane( b ), "Passed!" );
  246. // parallel plane coincident with origin
  247. var c = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 0, 0, 1 ), one3.clone().sub( new Vector3( 0, 0, 0 ) ) );
  248. assert.ok( a.intersectsPlane( c ), "Passed!" );
  249. // parallel plane behind the ray
  250. var d = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 0, 0, 1 ), one3.clone().sub( new Vector3( 0, 0, 1 ) ) );
  251. assert.ok( ! a.intersectsPlane( d ), "Passed!" );
  252. // perpendical ray that overlaps exactly
  253. var e = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 1, 0, 0 ), one3 );
  254. assert.ok( a.intersectsPlane( e ), "Passed!" );
  255. // perpendical ray that doesn't overlap
  256. var f = new Plane().setFromNormalAndCoplanarPoint( new Vector3( 1, 0, 0 ), zero3 );
  257. assert.ok( ! a.intersectsPlane( f ), "Passed!" );
  258. } );
  259. QUnit.test( "intersectBox", ( assert ) => {
  260. var TOL = 0.0001;
  261. var box = new Box3( new Vector3( - 1, - 1, - 1 ), new Vector3( 1, 1, 1 ) );
  262. var point = new Vector3();
  263. var a = new Ray( new Vector3( - 2, 0, 0 ), new Vector3( 1, 0, 0 ) );
  264. //ray should intersect box at -1,0,0
  265. assert.ok( a.intersectsBox( box ) === true, "Passed!" );
  266. a.intersectBox( box, point );
  267. assert.ok( point.distanceTo( new Vector3( - 1, 0, 0 ) ) < TOL, "Passed!" );
  268. var b = new Ray( new Vector3( - 2, 0, 0 ), new Vector3( - 1, 0, 0 ) );
  269. //ray is point away from box, it should not intersect
  270. assert.ok( b.intersectsBox( box ) === false, "Passed!" );
  271. b.intersectBox( box, point.copy( posInf3 ) );
  272. assert.ok( point.equals( posInf3 ), "Passed!" );
  273. var c = new Ray( new Vector3( 0, 0, 0 ), new Vector3( 1, 0, 0 ) );
  274. // ray is inside box, should return exit point
  275. assert.ok( c.intersectsBox( box ) === true, "Passed!" );
  276. c.intersectBox( box, point );
  277. assert.ok( point.distanceTo( new Vector3( 1, 0, 0 ) ) < TOL, "Passed!" );
  278. var d = new Ray( new Vector3( 0, 2, 1 ), new Vector3( 0, - 1, - 1 ).normalize() );
  279. //tilted ray should intersect box at 0,1,0
  280. assert.ok( d.intersectsBox( box ) === true, "Passed!" );
  281. d.intersectBox( box, point );
  282. assert.ok( point.distanceTo( new Vector3( 0, 1, 0 ) ) < TOL, "Passed!" );
  283. var e = new Ray( new Vector3( 1, - 2, 1 ), new Vector3( 0, 1, 0 ).normalize() );
  284. //handle case where ray is coplanar with one of the boxes side - box in front of ray
  285. assert.ok( e.intersectsBox( box ) === true, "Passed!" );
  286. e.intersectBox( box, point );
  287. assert.ok( point.distanceTo( new Vector3( 1, - 1, 1 ) ) < TOL, "Passed!" );
  288. var f = new Ray( new Vector3( 1, - 2, 0 ), new Vector3( 0, - 1, 0 ).normalize() );
  289. //handle case where ray is coplanar with one of the boxes side - box behind ray
  290. assert.ok( f.intersectsBox( box ) === false, "Passed!" );
  291. f.intersectBox( box, point.copy( posInf3 ) );
  292. assert.ok( point.equals( posInf3 ), "Passed!" );
  293. } );
  294. QUnit.todo( "intersectsBox", ( assert ) => {
  295. assert.ok( false, "everything's gonna be alright" );
  296. } );
  297. QUnit.test( "intersectTriangle", ( assert ) => {
  298. var ray = new Ray();
  299. var a = new Vector3( 1, 1, 0 );
  300. var b = new Vector3( 0, 1, 1 );
  301. var c = new Vector3( 1, 0, 1 );
  302. var point = new Vector3();
  303. // DdN == 0
  304. ray.set( ray.origin, zero3.clone() );
  305. ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
  306. assert.ok( point.equals( posInf3 ), "No intersection if direction == zero" );
  307. // DdN > 0, backfaceCulling = true
  308. ray.set( ray.origin, one3.clone() );
  309. ray.intersectTriangle( a, b, c, true, point.copy( posInf3 ) );
  310. assert.ok( point.equals( posInf3 ), "No intersection with backside faces if backfaceCulling is true" );
  311. // DdN > 0
  312. ray.set( ray.origin, one3.clone() );
  313. ray.intersectTriangle( a, b, c, false, point );
  314. assert.ok( Math.abs( point.x - 2 / 3 ) <= eps, "Successful intersection: check x" );
  315. assert.ok( Math.abs( point.y - 2 / 3 ) <= eps, "Successful intersection: check y" );
  316. assert.ok( Math.abs( point.z - 2 / 3 ) <= eps, "Successful intersection: check z" );
  317. // DdN > 0, DdQxE2 < 0
  318. b.multiplyScalar( - 1 );
  319. ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
  320. assert.ok( point.equals( posInf3 ), "No intersection" );
  321. // DdN > 0, DdE1xQ < 0
  322. a.multiplyScalar( - 1 );
  323. ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
  324. assert.ok( point.equals( posInf3 ), "No intersection" );
  325. // DdN > 0, DdQxE2 + DdE1xQ > DdN
  326. b.multiplyScalar( - 1 );
  327. ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
  328. assert.ok( point.equals( posInf3 ), "No intersection" );
  329. // DdN < 0, QdN < 0
  330. a.multiplyScalar( - 1 );
  331. b.multiplyScalar( - 1 );
  332. ray.direction.multiplyScalar( - 1 );
  333. ray.intersectTriangle( a, b, c, false, point.copy( posInf3 ) );
  334. assert.ok( point.equals( posInf3 ), "No intersection when looking in the wrong direction" );
  335. } );
  336. QUnit.test( "applyMatrix4", ( assert ) => {
  337. var a = new Ray( one3.clone(), new Vector3( 0, 0, 1 ) );
  338. var m = new Matrix4();
  339. assert.ok( a.clone().applyMatrix4( m ).equals( a ), "Passed!" );
  340. var a = new Ray( zero3.clone(), new Vector3( 0, 0, 1 ) );
  341. m.makeRotationZ( Math.PI );
  342. assert.ok( a.clone().applyMatrix4( m ).equals( a ), "Passed!" );
  343. m.makeRotationX( Math.PI );
  344. var b = a.clone();
  345. b.direction.negate();
  346. var a2 = a.clone().applyMatrix4( m );
  347. assert.ok( a2.origin.distanceTo( b.origin ) < 0.0001, "Passed!" );
  348. assert.ok( a2.direction.distanceTo( b.direction ) < 0.0001, "Passed!" );
  349. a.origin = new Vector3( 0, 0, 1 );
  350. b.origin = new Vector3( 0, 0, - 1 );
  351. var a2 = a.clone().applyMatrix4( m );
  352. assert.ok( a2.origin.distanceTo( b.origin ) < 0.0001, "Passed!" );
  353. assert.ok( a2.direction.distanceTo( b.direction ) < 0.0001, "Passed!" );
  354. } );
  355. QUnit.todo( "equals", ( assert ) => {
  356. assert.ok( false, "everything's gonna be alright" );
  357. } );
  358. } );
  359. } );