| // Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details. |
| // All rights reserved. Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| library vector_math.test.ray_test; |
| |
| import 'dart:math' as Math; |
| |
| import 'package:unittest/unittest.dart'; |
| |
| import 'package:vector_math/vector_math.dart'; |
| |
| import 'test_utils.dart'; |
| |
| void testRayAt() { |
| final Ray parent = |
| new Ray.originDirection(v3(1.0, 1.0, 1.0), v3(-1.0, 1.0, 1.0)); |
| |
| final Vector3 atOrigin = parent.at(0.0); |
| final Vector3 atPositive = parent.at(1.0); |
| final Vector3 atNegative = parent.at(-2.0); |
| |
| expect(atOrigin.x, equals(1.0)); |
| expect(atOrigin.y, equals(1.0)); |
| expect(atOrigin.z, equals(1.0)); |
| expect(atPositive.x, equals(0.0)); |
| expect(atPositive.y, equals(2.0)); |
| expect(atPositive.z, equals(2.0)); |
| expect(atNegative.x, equals(3.0)); |
| expect(atNegative.y, equals(-1.0)); |
| expect(atNegative.z, equals(-1.0)); |
| } |
| |
| void testRayIntersectionSphere() { |
| final Ray parent = |
| new Ray.originDirection(v3(1.0, 1.0, 1.0), v3(0.0, 1.0, 0.0)); |
| final Sphere inside = new Sphere.centerRadius(v3(2.0, 1.0, 1.0), 2.0); |
| final Sphere hitting = new Sphere.centerRadius(v3(2.5, 4.5, 1.0), 2.0); |
| final Sphere cutting = new Sphere.centerRadius(v3(0.0, 5.0, 1.0), 1.0); |
| final Sphere outside = new Sphere.centerRadius(v3(-2.5, 1.0, 1.0), 1.0); |
| final Sphere behind = new Sphere.centerRadius(v3(1.0, -1.0, 1.0), 1.0); |
| |
| expect(parent.intersectsWithSphere(inside), equals(Math.sqrt(3.0))); |
| expect(parent.intersectsWithSphere(hitting), equals(3.5 - Math.sqrt(1.75))); |
| expect(parent.intersectsWithSphere(cutting), equals(4.0)); |
| expect(parent.intersectsWithSphere(outside), equals(null)); |
| expect(parent.intersectsWithSphere(behind), equals(null)); |
| } |
| |
| void testRayIntersectionTriangle() { |
| final Ray parent = |
| new Ray.originDirection(v3(1.0, 1.0, 1.0), v3(0.0, 1.0, 0.0)); |
| final Triangle hitting = new Triangle.points( |
| v3(2.0, 2.0, 0.0), v3(0.0, 4.0, -1.0), v3(0.0, 4.0, 3.0)); |
| final Triangle cutting = new Triangle.points( |
| v3(0.0, 1.5, 1.0), v3(2.0, 1.5, 1.0), v3(1.0, 1.5, 3.0)); |
| final Triangle outside = new Triangle.points( |
| v3(2.0, 2.0, 0.0), v3(2.0, 6.0, 0.0), v3(2.0, 2.0, 3.0)); |
| final Triangle behind = new Triangle.points( |
| v3(0.0, 0.0, 0.0), v3(0.0, 3.0, 0.0), v3(0.0, 3.0, 4.0)); |
| |
| expect(parent.intersectsWithTriangle(hitting), equals(2.0)); |
| expect(parent.intersectsWithTriangle(cutting), equals(0.5)); |
| expect(parent.intersectsWithTriangle(outside), equals(null)); |
| expect(parent.intersectsWithTriangle(behind), equals(null)); |
| |
| // Test cases from real-world failures: |
| // Just barely intersects, but gets rounded out |
| final Ray p2 = new Ray.originDirection( |
| v3(0.0, -0.16833500564098358, 0.7677000164985657), |
| v3(-0.0, -0.8124330043792725, -0.5829949975013733)); |
| final Triangle t2 = new Triangle.points( |
| v3(0.03430179879069328, -0.7268069982528687, 0.3532710075378418), |
| v3(0.0, -0.7817990183830261, 0.3641969859600067), |
| v3(0.0, -0.7293699979782104, 0.3516849875450134)); |
| expect(p2.intersectsWithTriangle(t2), closeTo(0.7078371874391822, 1e-10)); |
| // Ray is not quite perpendicular to triangle, but gets rounded out |
| final Ray p3 = new Ray.originDirection( |
| v3(0.023712199181318283, -0.15045200288295746, 0.7751160264015198), |
| v3(0.6024960279464722, -0.739005982875824, -0.3013699948787689)); |
| final Triangle t3 = new Triangle.points( |
| v3(0.16174300014972687, -0.3446039855480194, 0.7121580243110657), |
| v3(0.1857299953699112, -0.3468630015850067, 0.6926270127296448), |
| v3(0.18045000731945038, -0.3193660080432892, 0.6921690106391907)); |
| expect(p3.intersectsWithTriangle(t3), closeTo(0.2538471189773835, 1e-10)); |
| } |
| |
| void testRayIntersectionAabb3() { |
| final Ray parent = |
| new Ray.originDirection(v3(1.0, 1.0, 1.0), v3(0.0, 1.0, 0.0)); |
| final Aabb3 hitting = |
| new Aabb3.minMax(v3(0.5, 3.5, -10.0), v3(2.5, 5.5, 10.0)); |
| final Aabb3 cutting = new Aabb3.minMax(v3(0.0, 2.0, 1.0), v3(2.0, 3.0, 2.0)); |
| final Aabb3 outside = new Aabb3.minMax(v3(2.0, 0.0, 0.0), v3(6.0, 6.0, 6.0)); |
| final Aabb3 behind = new Aabb3.minMax(v3(0.0, -2.0, 0.0), v3(2.0, 0.0, 2.0)); |
| final Aabb3 inside = new Aabb3.minMax(v3(0.0, 0.0, 0.0), v3(2.0, 2.0, 2.0)); |
| |
| expect(parent.intersectsWithAabb3(hitting), equals(2.5)); |
| expect(parent.intersectsWithAabb3(cutting), equals(1.0)); |
| expect(parent.intersectsWithAabb3(outside), equals(null)); |
| expect(parent.intersectsWithAabb3(behind), equals(null)); |
| expect(parent.intersectsWithAabb3(inside), equals(-1.0)); |
| } |
| |
| void main() { |
| test('Ray At', testRayAt); |
| test('Ray Intersection Sphere', testRayIntersectionSphere); |
| test('Ray Intersection Triangle', testRayIntersectionTriangle); |
| test('Ray Intersection Aabb3', testRayIntersectionAabb3); |
| } |