blob: 567976aee0ceed4f8ebff2437f34fb45f072afd8 [file] [log] [blame]
// 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.
import 'dart:math' as math;
import 'dart:typed_data';
import 'package:test/test.dart';
import 'package:vector_math/vector_math.dart';
import 'test_utils.dart';
void testVector3InstacinfFromFloat32List() {
final float32List = Float32List.fromList([1.0, 2.0, 3.0]);
final input = Vector3.fromFloat32List(float32List);
expect(input.x, equals(1.0));
expect(input.y, equals(2.0));
expect(input.z, equals(3.0));
}
void testVector3InstacingFromByteBuffer() {
final float32List = Float32List.fromList([1.0, 2.0, 3.0, 4.0]);
final buffer = float32List.buffer;
final zeroOffset = Vector3.fromBuffer(buffer, 0);
final offsetVector = Vector3.fromBuffer(buffer, Float32List.bytesPerElement);
expect(zeroOffset.x, equals(1.0));
expect(zeroOffset.y, equals(2.0));
expect(zeroOffset.z, equals(3.0));
expect(offsetVector.x, equals(2.0));
expect(offsetVector.y, equals(3.0));
expect(offsetVector.z, equals(4.0));
}
void testVector3Add() {
final a = Vector3(5.0, 7.0, 3.0);
final b = Vector3(3.0, 8.0, 2.0);
a.add(b);
expect(a.x, equals(8.0));
expect(a.y, equals(15.0));
expect(a.z, equals(5.0));
b.addScaled(a, 0.5);
expect(b.x, equals(7.0));
expect(b.y, equals(15.5));
expect(b.z, equals(4.5));
}
void testVector3MinMax() {
final a = Vector3(5.0, 7.0, -3.0);
final b = Vector3(3.0, 8.0, 2.0);
final result = Vector3.zero();
Vector3.min(a, b, result);
expect(result.x, equals(3.0));
expect(result.y, equals(7.0));
expect(result.z, equals(-3.0));
Vector3.max(a, b, result);
expect(result.x, equals(5.0));
expect(result.y, equals(8.0));
expect(result.z, equals(2.0));
}
void testVector3Mix() {
final a = Vector3(5.0, 7.0, 3.0);
final b = Vector3(3.0, 8.0, 2.0);
final result = Vector3.zero();
Vector3.mix(a, b, 0.5, result);
expect(result.x, equals(4.0));
expect(result.y, equals(7.5));
expect(result.z, equals(2.5));
Vector3.mix(a, b, 0.0, result);
expect(result.x, equals(5.0));
expect(result.y, equals(7.0));
expect(result.z, equals(3.0));
Vector3.mix(a, b, 1.0, result);
expect(result.x, equals(3.0));
expect(result.y, equals(8.0));
expect(result.z, equals(2.0));
}
void testVector3DotProduct() {
final inputA = <Vector3>[];
final inputB = <Vector3>[];
final expectedOutput = <double>[];
inputA.add(parseVector<Vector3>('''0.417267069084370
0.049654430325742
0.902716109915281'''));
inputB.add(parseVector<Vector3>('''0.944787189721646
0.490864092468080
0.489252638400019'''));
expectedOutput.add(0.860258396944727);
assert(inputA.length == inputB.length);
assert(inputB.length == expectedOutput.length);
for (var i = 0; i < inputA.length; i++) {
final output1 = dot3(inputA[i], inputB[i]);
final output2 = dot3(inputB[i], inputA[i]);
relativeTest(output1, expectedOutput[i]);
relativeTest(output2, expectedOutput[i]);
}
}
void testVector3Postmultiplication() {
final inputMatrix =
(Matrix3.rotationX(.4)) * (Matrix3.rotationZ(.5)) as Matrix3;
final inputVector = Vector3(1.0, 2.0, 3.0);
final inputInv = Matrix3.copy(inputMatrix);
inputInv.invert();
final resultOld = inputMatrix.transposed() * inputVector as Vector3;
final resultOldvInv = inputInv * inputVector as Vector3;
final resultNew = inputVector..postmultiply(inputMatrix);
expect(resultNew.x, equals(resultOld.x));
expect(resultNew.y, equals(resultOld.y));
expect(resultNew.z, equals(resultOld.z));
expect(resultNew.x, equals(resultOldvInv.x));
expect(resultNew.y, equals(resultOldvInv.y));
expect(resultNew.z, equals(resultOldvInv.z));
}
void testVector3CrossProduct() {
final inputA = <Vector3>[];
final inputB = <Vector3>[];
final expectedOutput = <Vector3>[];
inputA.add(parseVector<Vector3>('''0.417267069084370
0.049654430325742
0.902716109915281'''));
inputB.add(parseVector<Vector3>('''0.944787189721646
0.490864092468080
0.489252638400019'''));
expectedOutput.add(parseVector<Vector3>(''' -0.418817363004761
0.648725602136344
0.157908551498227'''));
inputA.add(parseVector<Vector3>('''0.944787189721646
0.490864092468080
0.489252638400019'''));
inputB.add(parseVector<Vector3>('''0.417267069084370
0.049654430325742
0.902716109915281'''));
expectedOutput.add(parseVector<Vector3>(''' 0.418817363004761
-0.648725602136344
-0.157908551498227'''));
assert(inputA.length == inputB.length);
assert(inputB.length == expectedOutput.length);
for (var i = 0; i < inputA.length; i++) {
final output = Vector3.zero();
cross3(inputA[i], inputB[i], output);
relativeTest(output, expectedOutput[i]);
}
{
final x = Vector3(1.0, 0.0, 0.0);
final y = Vector3(0.0, 1.0, 0.0);
final z = Vector3(0.0, 0.0, 1.0);
Vector3 output;
output = x.cross(y);
relativeTest(output, Vector3(0.0, 0.0, 1.0));
output = y.cross(x);
relativeTest(output, Vector3(0.0, 0.0, -1.0));
output = x.cross(z);
relativeTest(output, Vector3(0.0, -1.0, 0.0));
output = z.cross(x);
relativeTest(output, Vector3(0.0, 1.0, 0.0));
output = y.cross(z);
relativeTest(output, Vector3(1.0, 0.0, 0.0));
output = z.cross(y);
relativeTest(output, Vector3(-1.0, 0.0, 0.0));
}
}
void testVector3Constructor() {
final v1 = Vector3(2.0, 4.0, -1.5);
expect(v1.x, equals(2.0));
expect(v1.y, equals(4.0));
expect(v1.z, equals(-1.5));
final v2 = Vector3.all(2.0);
expect(v2.x, equals(2.0));
expect(v2.y, equals(2.0));
expect(v2.z, equals(2.0));
final v3 = Vector3.random(math.Random());
expect(v3.x, greaterThanOrEqualTo(0.0));
expect(v3.x, lessThanOrEqualTo(1.0));
expect(v3.y, greaterThanOrEqualTo(0.0));
expect(v3.y, lessThanOrEqualTo(1.0));
expect(v3.z, greaterThanOrEqualTo(0.0));
expect(v3.z, lessThanOrEqualTo(1.0));
}
void testVector3Length() {
final a = Vector3(5.0, 7.0, 3.0);
relativeTest(a.length, 9.1104);
relativeTest(a.length2, 83.0);
relativeTest(a.normalize(), 9.1104);
relativeTest(a.x, 0.5488);
relativeTest(a.y, 0.7683);
relativeTest(a.z, 0.3292);
}
void testVector3SetLength() {
final v0 = Vector3(1.0, 2.0, 1.0);
final v1 = Vector3(3.0, -2.0, 2.0);
final v2 = Vector3(-1.0, 2.0, -2.0);
final v3 = Vector3(1.0, 0.0, 0.0);
v0.length = 0.0;
relativeTest(v0, Vector3.zero());
relativeTest(v0.length, 0.0);
v1.length = 2.0;
relativeTest(
v1, Vector3(1.4552137851715088, -0.9701424837112427, 0.9701424837112427));
relativeTest(v1.length, 2.0);
v2.length = 0.5;
relativeTest(v2,
Vector3(-0.1666666716337204, 0.3333333432674408, -0.3333333432674408));
relativeTest(v2.length, 0.5);
v3.length = -1.0;
relativeTest(v3, Vector3(-1.0, 0.0, 0.0));
relativeTest(v3.length, 1.0);
}
void testVector3Negate() {
final vec3 = Vector4(1.0, 2.0, 3.0, 4.0);
vec3.negate();
expect(vec3.x, equals(-1.0));
expect(vec3.y, equals(-2.0));
expect(vec3.z, equals(-3.0));
expect(vec3.w, equals(-4.0));
}
void testVector3Equals() {
final v3 = Vector3(1.0, 2.0, 3.0);
expect(v3 == Vector3(1.0, 2.0, 3.0), isTrue);
expect(v3 == Vector3(0.0, 2.0, 3.0), isFalse);
expect(v3 == Vector3(1.0, 0.0, 3.0), isFalse);
expect(v3 == Vector3(1.0, 2.0, 0.0), isFalse);
expect(
Vector3(1.0, 2.0, 3.0).hashCode, equals(Vector3(1.0, 2.0, 3.0).hashCode));
}
void testVector3Reflect() {
var v = Vector3(5.0, 0.0, 0.0);
v.reflect(Vector3(-1.0, 0.0, 0.0));
expect(v.x, equals(-5.0));
expect(v.y, equals(0.0));
expect(v.y, equals(0.0));
v = Vector3(0.0, 5.0, 0.0);
v.reflect(Vector3(0.0, -1.0, 0.0));
expect(v.x, equals(0.0));
expect(v.y, equals(-5.0));
expect(v.z, equals(0.0));
v = Vector3(0.0, 0.0, 5.0);
v.reflect(Vector3(0.0, 0.0, -1.0));
expect(v.x, equals(0.0));
expect(v.y, equals(0.0));
expect(v.z, equals(-5.0));
v = Vector3(-5.0, 0.0, 0.0);
v.reflect(Vector3(1.0, 0.0, 0.0));
expect(v.x, equals(5.0));
expect(v.y, equals(0.0));
expect(v.y, equals(0.0));
v = Vector3(0.0, -5.0, 0.0);
v.reflect(Vector3(0.0, 1.0, 0.0));
expect(v.x, equals(0.0));
expect(v.y, equals(5.0));
expect(v.z, equals(0.0));
v = Vector3(0.0, 0.0, -5.0);
v.reflect(Vector3(0.0, 0.0, 1.0));
expect(v.x, equals(0.0));
expect(v.y, equals(0.0));
expect(v.z, equals(5.0));
v = Vector3(4.0, 4.0, 4.0);
v.reflect(Vector3(-1.0, -1.0, -1.0).normalized());
relativeTest(v.x, -4.0);
relativeTest(v.y, -4.0);
relativeTest(v.z, -4.0);
v = Vector3(-4.0, -4.0, -4.0);
v.reflect(Vector3(1.0, 1.0, 1.0).normalized());
relativeTest(v.x, 4.0);
relativeTest(v.y, 4.0);
relativeTest(v.z, 4.0);
v = Vector3(10.0, 20.0, 2.0);
v.reflect(Vector3(-10.0, -20.0, -2.0).normalized());
relativeTest(v.x, -10.0);
relativeTest(v.y, -20.0);
relativeTest(v.z, -2.0);
}
void testVector3Projection() {
final v = Vector3(1.0, 1.0, 1.0);
final a = 2.0 / 3.0;
final b = 1.0 / 3.0;
final m =
Matrix4(a, b, -b, 0.0, b, a, b, 0.0, -b, b, a, 0.0, 0.0, 0.0, 0.0, 1.0);
v.applyProjection(m);
relativeTest(v.x, a);
relativeTest(v.y, 4.0 / 3.0);
relativeTest(v.z, a);
}
void testVector3DistanceTo() {
final a = Vector3(1.0, 1.0, 1.0);
final b = Vector3(1.0, 3.0, 1.0);
final c = Vector3(1.0, 1.0, -1.0);
expect(a.distanceTo(b), equals(2.0));
expect(a.distanceTo(c), equals(2.0));
}
void testVector3DistanceToSquared() {
final a = Vector3(1.0, 1.0, 1.0);
final b = Vector3(1.0, 3.0, 1.0);
final c = Vector3(1.0, 1.0, -1.0);
expect(a.distanceToSquared(b), equals(4.0));
expect(a.distanceToSquared(c), equals(4.0));
}
void testVector3AngleTo() {
final v0 = Vector3(1.0, 0.0, 0.0);
final v1 = Vector3(0.0, 1.0, 0.0);
final v2 = Vector3(1.0, 1.0, 0.0);
final v3 = v2.normalized();
final tol = 1e-8;
expect(v0.angleTo(v0), equals(0.0));
expect(v0.angleTo(v1), equals(math.pi / 2.0));
expect(v0.angleTo(v2), closeTo(math.pi / 4.0, tol));
expect(v0.angleTo(v3), closeTo(math.pi / 4.0, tol));
}
void testVector3AngleToSigned() {
final v0 = Vector3(1.0, 0.0, 0.0);
final v1 = Vector3(0.0, 1.0, 0.0);
final n = Vector3(0.0, 0.0, 1.0);
expect(v0.angleToSigned(v0, n), equals(0.0));
expect(v0.angleToSigned(v1, n), equals(math.pi / 2.0));
expect(v1.angleToSigned(v0, n), equals(-math.pi / 2.0));
}
void testVector3Clamp() {
final x = 2.0, y = 3.0, z = 4.0;
final v0 = Vector3(x, y, z);
final v1 = Vector3(-x, -y, -z);
final v2 = Vector3(-2.0 * x, 2.0 * y, -2.0 * z)..clamp(v1, v0);
expect(v2.storage, orderedEquals(<double>[-x, y, -z]));
}
void testVector3ClampScalar() {
final x = 2.0;
final v0 = Vector3(-2.0 * x, 2.0 * x, -2.0 * x)..clampScalar(-x, x);
expect(v0.storage, orderedEquals(<double>[-x, x, -x]));
}
void testVector3Floor() {
final v0 = Vector3(-0.1, 0.1, -0.1)..floor();
final v1 = Vector3(-0.5, 0.5, -0.5)..floor();
final v2 = Vector3(-0.9, 0.9, -0.5)..floor();
expect(v0.storage, orderedEquals(<double>[-1.0, 0.0, -1.0]));
expect(v1.storage, orderedEquals(<double>[-1.0, 0.0, -1.0]));
expect(v2.storage, orderedEquals(<double>[-1.0, 0.0, -1.0]));
}
void testVector3Ceil() {
final v0 = Vector3(-0.1, 0.1, -0.1)..ceil();
final v1 = Vector3(-0.5, 0.5, -0.5)..ceil();
final v2 = Vector3(-0.9, 0.9, -0.9)..ceil();
expect(v0.storage, orderedEquals(<double>[0.0, 1.0, 0.0]));
expect(v1.storage, orderedEquals(<double>[0.0, 1.0, 0.0]));
expect(v2.storage, orderedEquals(<double>[0.0, 1.0, 0.0]));
}
void testVector3Round() {
final v0 = Vector3(-0.1, 0.1, -0.1)..round();
final v1 = Vector3(-0.5, 0.5, -0.5)..round();
final v2 = Vector3(-0.9, 0.9, -0.9)..round();
expect(v0.storage, orderedEquals(<double>[0.0, 0.0, 0.0]));
expect(v1.storage, orderedEquals(<double>[-1.0, 1.0, -1.0]));
expect(v2.storage, orderedEquals(<double>[-1.0, 1.0, -1.0]));
}
void testVector3RoundToZero() {
final v0 = Vector3(-0.1, 0.1, -0.1)..roundToZero();
final v1 = Vector3(-0.5, 0.5, -0.5)..roundToZero();
final v2 = Vector3(-0.9, 0.9, -0.9)..roundToZero();
final v3 = Vector3(-1.1, 1.1, -1.1)..roundToZero();
final v4 = Vector3(-1.5, 1.5, -1.5)..roundToZero();
final v5 = Vector3(-1.9, 1.9, -1.9)..roundToZero();
expect(v0.storage, orderedEquals(<double>[0.0, 0.0, 0.0]));
expect(v1.storage, orderedEquals(<double>[0.0, 0.0, 0.0]));
expect(v2.storage, orderedEquals(<double>[0.0, 0.0, 0.0]));
expect(v3.storage, orderedEquals(<double>[-1.0, 1.0, -1.0]));
expect(v4.storage, orderedEquals(<double>[-1.0, 1.0, -1.0]));
expect(v5.storage, orderedEquals(<double>[-1.0, 1.0, -1.0]));
}
void testVector3ApplyQuaternion() {
final q = Quaternion(0.0, 0.9238795292366128, 0.0, 0.38268342717215614);
final v = Vector3(0.417267069084370, 0.049654430325742, 0.753423475845592)
..applyQuaternion(q);
relativeTest(v,
Vector3(0.23769846558570862, 0.04965442791581154, -0.8278031349182129));
}
void main() {
group('Vector3', () {
test('dot product', testVector3DotProduct);
test('postmultiplication', testVector3Postmultiplication);
test('cross product', testVector3CrossProduct);
test('reflect', testVector3Reflect);
test('projection', testVector3Projection);
test('length', testVector3Length);
test('equals', testVector3Equals);
test('set length', testVector3SetLength);
test('Negate', testVector3Negate);
test('Constructor', testVector3Constructor);
test('add', testVector3Add);
test('min/max', testVector3MinMax);
test('mix', testVector3Mix);
test('distanceTo', testVector3DistanceTo);
test('distanceToSquared', testVector3DistanceToSquared);
test('angleTo', testVector3AngleTo);
test('angleToSinged', testVector3AngleToSigned);
test('instancing from Float32List', testVector3InstacinfFromFloat32List);
test('instancing from ByteBuffer', testVector3InstacingFromByteBuffer);
test('clamp', testVector3Clamp);
test('clampScalar', testVector3ClampScalar);
test('floor', testVector3Floor);
test('ceil', testVector3Ceil);
test('round', testVector3Round);
test('roundToZero', testVector3RoundToZero);
test('applyQuaternion', testVector3ApplyQuaternion);
});
}