Adding mapbox-gl branch

This commit is contained in:
Andreas Hocevar
2015-03-16 18:50:27 +01:00
parent 7985f030fa
commit 57ee7f52fd
3109 changed files with 943365 additions and 0 deletions
@@ -0,0 +1,111 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Supplies a Float32Array implementation that implements
* most of the Float32Array spec and that can be used when a built-in
* implementation is not available.
*
* Note that if no existing Float32Array implementation is found then
* this class and all its public properties are exported as Float32Array.
*
* Adding support for the other TypedArray classes here does not make sense
* since this vector math library only needs Float32Array.
*
*/
goog.provide('goog.vec.Float32Array');
/**
* Constructs a new Float32Array. The new array is initialized to all zeros.
*
* @param {goog.vec.Float32Array|Array|ArrayBuffer|number} p0
* The length of the array, or an array to initialize the contents of the
* new Float32Array.
* @constructor
* @final
*/
goog.vec.Float32Array = function(p0) {
this.length = /** @type {number} */ (p0.length || p0);
for (var i = 0; i < this.length; i++) {
this[i] = p0[i] || 0;
}
};
/**
* The number of bytes in an element (as defined by the Typed Array
* specification).
*
* @type {number}
*/
goog.vec.Float32Array.BYTES_PER_ELEMENT = 4;
/**
* The number of bytes in an element (as defined by the Typed Array
* specification).
*
* @type {number}
*/
goog.vec.Float32Array.prototype.BYTES_PER_ELEMENT = 4;
/**
* Sets elements of the array.
* @param {Array<number>|Float32Array} values The array of values.
* @param {number=} opt_offset The offset in this array to start.
*/
goog.vec.Float32Array.prototype.set = function(values, opt_offset) {
opt_offset = opt_offset || 0;
for (var i = 0; i < values.length && opt_offset + i < this.length; i++) {
this[opt_offset + i] = values[i];
}
};
/**
* Creates a string representation of this array.
* @return {string} The string version of this array.
* @override
*/
goog.vec.Float32Array.prototype.toString = Array.prototype.join;
/**
* Note that we cannot implement the subarray() or (deprecated) slice()
* methods properly since doing so would require being able to overload
* the [] operator which is not possible in javascript. So we leave
* them unimplemented. Any attempt to call these methods will just result
* in a javascript error since we leave them undefined.
*/
/**
* If no existing Float32Array implementation is found then we export
* goog.vec.Float32Array as Float32Array.
*/
if (typeof Float32Array == 'undefined') {
goog.exportProperty(goog.vec.Float32Array, 'BYTES_PER_ELEMENT',
goog.vec.Float32Array.BYTES_PER_ELEMENT);
goog.exportProperty(goog.vec.Float32Array.prototype, 'BYTES_PER_ELEMENT',
goog.vec.Float32Array.prototype.BYTES_PER_ELEMENT);
goog.exportProperty(goog.vec.Float32Array.prototype, 'set',
goog.vec.Float32Array.prototype.set);
goog.exportProperty(goog.vec.Float32Array.prototype, 'toString',
goog.vec.Float32Array.prototype.toString);
goog.exportSymbol('Float32Array', goog.vec.Float32Array);
}
@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Float32Array</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testConstructorInitializesElementsToZero() {
var f = new goog.vec.Float32Array(3);
assertEquals(3, f.length);
assertEquals(0, f[0]);
assertEquals(0, f[1]);
assertEquals(0, f[2]);
assertEquals(4, f.BYTES_PER_ELEMENT);
assertEquals(4, goog.vec.Float32Array.BYTES_PER_ELEMENT);
}
function testConstructorWithArrayAsArgument() {
var f0 = new goog.vec.Float32Array([0, 0, 1, 0]);
var f1 = new goog.vec.Float32Array(4);
f1[0] = 0;
f1[1] = 0;
f1[2] = 1;
f1[3] = 0;
assertObjectEquals(f0, f1);
}
function testSet() {
var f0 = new goog.vec.Float32Array(4);
var f1 = new goog.vec.Float32Array(4);
f0.set([1, 2, 3, 4]);
f1[0] = 1;
f1[1] = 2;
f1[2] = 3;
f1[3] = 4;
assertObjectEquals(f0, f1);
}
function testSetWithOffset() {
var f0 = new goog.vec.Float32Array(4);
var f1 = new goog.vec.Float32Array(4);
f0.set([5], 1);
f1[0] = 0;
f1[1] = 5;
f1[2] = 0;
f1[3] = 0;
assertObjectEquals(f0, f1);
}
function testToString() {
var f = new goog.vec.Float32Array([4, 3, 2, 1]);
assertEquals('4,3,2,1', f.toString());
}
</script>
</body>
@@ -0,0 +1,118 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Supplies a Float64Array implementation that implements
* most of the Float64Array spec and that can be used when a built-in
* implementation is not available.
*
* Note that if no existing Float64Array implementation is found then this
* class and all its public properties are exported as Float64Array.
*
* Adding support for the other TypedArray classes here does not make sense
* since this vector math library only needs Float32Array and Float64Array.
*
*/
goog.provide('goog.vec.Float64Array');
/**
* Constructs a new Float64Array. The new array is initialized to all zeros.
*
* @param {goog.vec.Float64Array|Array|ArrayBuffer|number} p0
* The length of the array, or an array to initialize the contents of the
* new Float64Array.
* @constructor
* @final
*/
goog.vec.Float64Array = function(p0) {
this.length = /** @type {number} */ (p0.length || p0);
for (var i = 0; i < this.length; i++) {
this[i] = p0[i] || 0;
}
};
/**
* The number of bytes in an element (as defined by the Typed Array
* specification).
*
* @type {number}
*/
goog.vec.Float64Array.BYTES_PER_ELEMENT = 8;
/**
* The number of bytes in an element (as defined by the Typed Array
* specification).
*
* @type {number}
*/
goog.vec.Float64Array.prototype.BYTES_PER_ELEMENT = 8;
/**
* Sets elements of the array.
* @param {Array<number>|Float64Array} values The array of values.
* @param {number=} opt_offset The offset in this array to start.
*/
goog.vec.Float64Array.prototype.set = function(values, opt_offset) {
opt_offset = opt_offset || 0;
for (var i = 0; i < values.length && opt_offset + i < this.length; i++) {
this[opt_offset + i] = values[i];
}
};
/**
* Creates a string representation of this array.
* @return {string} The string version of this array.
* @override
*/
goog.vec.Float64Array.prototype.toString = Array.prototype.join;
/**
* Note that we cannot implement the subarray() or (deprecated) slice()
* methods properly since doing so would require being able to overload
* the [] operator which is not possible in javascript. So we leave
* them unimplemented. Any attempt to call these methods will just result
* in a javascript error since we leave them undefined.
*/
/**
* If no existing Float64Array implementation is found then we export
* goog.vec.Float64Array as Float64Array.
*/
if (typeof Float64Array == 'undefined') {
try {
goog.exportProperty(goog.vec.Float64Array, 'BYTES_PER_ELEMENT',
goog.vec.Float64Array.BYTES_PER_ELEMENT);
} catch (float64ArrayError) {
// Do nothing. This code is in place to fix b/7225850, in which an error
// is incorrectly thrown for Google TV on an old Chrome.
// TODO(user): remove after that version is retired.
}
goog.exportProperty(goog.vec.Float64Array.prototype, 'BYTES_PER_ELEMENT',
goog.vec.Float64Array.prototype.BYTES_PER_ELEMENT);
goog.exportProperty(goog.vec.Float64Array.prototype, 'set',
goog.vec.Float64Array.prototype.set);
goog.exportProperty(goog.vec.Float64Array.prototype, 'toString',
goog.vec.Float64Array.prototype.toString);
goog.exportSymbol('Float64Array', goog.vec.Float64Array);
}
@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Float64Array</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float64Array');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testConstructorInitializesElementsToZero() {
var f = new goog.vec.Float64Array(3);
assertEquals(3, f.length);
assertEquals(0, f[0]);
assertEquals(0, f[1]);
assertEquals(0, f[2]);
assertEquals(8, f.BYTES_PER_ELEMENT);
assertEquals(8, goog.vec.Float64Array.BYTES_PER_ELEMENT);
}
function testConstructorWithArrayAsArgument() {
var f0 = new goog.vec.Float64Array([0, 0, 1, 0]);
var f1 = new goog.vec.Float64Array(4);
f1[0] = 0;
f1[1] = 0;
f1[2] = 1;
f1[3] = 0;
assertObjectEquals(f0, f1);
}
function testSet() {
var f0 = new goog.vec.Float64Array(4);
var f1 = new goog.vec.Float64Array(4);
f0.set([1, 2, 3, 4]);
f1[0] = 1;
f1[1] = 2;
f1[2] = 3;
f1[3] = 4;
assertObjectEquals(f0, f1);
}
function testSetWithOffset() {
var f0 = new goog.vec.Float64Array(4);
var f1 = new goog.vec.Float64Array(4);
f0.set([5], 1);
f1[0] = 0;
f1[1] = 5;
f1[2] = 0;
f1[3] = 0;
assertObjectEquals(f0, f1);
}
function testToString() {
var f = new goog.vec.Float64Array([4, 3, 2, 1]);
assertEquals('4,3,2,1', f.toString());
}
</script>
</body>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,465 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Mat3</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Mat3');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
var randomMat3 = goog.vec.Mat3.createFloat32FromValues(
0.8025078773498535,
0.7559120655059814,
0.15274643898010254,
0.19196106493473053,
0.0890120416879654,
0.15422114729881287,
0.09754583984613419,
0.44862601161003113,
0.9196512699127197);
function testDeprecatedConstructor() {
var m0 = goog.vec.Mat3.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
var m1 = goog.vec.Mat3.createFromArray([1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
var m2 = goog.vec.Mat3.createFromArray(m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m2);
var m3 = goog.vec.Mat3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m3);
var m4 = goog.vec.Mat3.createIdentity();
assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], m4);
}
function testConstructor() {
var m0 = goog.vec.Mat3.createFloat32();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
var m1 = goog.vec.Mat3.createFloat32FromArray([1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
var m2 = goog.vec.Mat3.createFloat32FromArray(m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m2);
var m3 = goog.vec.Mat3.createFloat32FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m3);
var m4 = goog.vec.Mat3.createFloat32Identity();
assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], m4);
var n0 = goog.vec.Mat3.createFloat64();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], n0);
var n1 = goog.vec.Mat3.createFloat64FromArray([1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], n1);
var n2 = goog.vec.Mat3.createFloat64FromArray(n1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], n1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], n2);
var n3 = goog.vec.Mat3.createFloat64FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], n3);
var n4 = goog.vec.Mat3.createFloat64Identity();
assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], n4);
}
function testSet() {
var m0 = goog.vec.Mat3.createFloat32();
var m1 = goog.vec.Mat3.createFromArray([1, 2, 3, 4, 5, 6, 7, 8, 9]);
goog.vec.Mat3.setFromArray(m0, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
goog.vec.Mat3.setFromValues(m0, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 10], m0);
}
function testSetDiagonal() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.setDiagonalValues(m0, 1, 2, 3);
assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], m0);
goog.vec.Mat3.setDiagonal(m0, [4, 5, 6]);
assertElementsEquals([4, 0, 0, 0, 5, 0, 0, 0, 6], m0);
}
function testSetGetColumn() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.setColumn(m0, 0, [1, 2, 3]);
goog.vec.Mat3.setColumn(m0, 1, [4, 5, 6]);
goog.vec.Mat3.setColumn(m0, 2, [7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
var v0 = [0, 0, 0];
goog.vec.Mat3.getColumn(m0, 0, v0);
assertElementsEquals([1, 2, 3], v0);
goog.vec.Mat3.getColumn(m0, 1, v0);
assertElementsEquals([4, 5, 6], v0);
goog.vec.Mat3.getColumn(m0, 2, v0);
assertElementsEquals([7, 8, 9], v0);
}
function testSetGetColumns() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.setColumns(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
var v0 = [0, 0, 0], v1 = [0, 0, 0], v2 = [0, 0, 0];
goog.vec.Mat3.getColumns(m0, v0, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([7, 8, 9], v2);
}
function testSetGetRow() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.setRow(m0, 0, [1, 2, 3]);
goog.vec.Mat3.setRow(m0, 1, [4, 5, 6]);
goog.vec.Mat3.setRow(m0, 2, [7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
var v0 = [0, 0, 0];
goog.vec.Mat3.getRow(m0, 0, v0);
assertElementsEquals([1, 2, 3], v0);
goog.vec.Mat3.getRow(m0, 1, v0);
assertElementsEquals([4, 5, 6], v0);
goog.vec.Mat3.getRow(m0, 2, v0);
assertElementsEquals([7, 8, 9], v0);
}
function testSetGetRows() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.setRows(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
var v0 = [0, 0, 0], v1 = [0, 0, 0], v2 = [0, 0, 0];
goog.vec.Mat3.getRows(m0, v0, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([7, 8, 9], v2);
}
function testSetRowMajorArray() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.setFromRowMajorArray(
m0, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
}
function testMakeZero() {
var m0 = goog.vec.Mat3.createFromArray([1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
goog.vec.Mat3.makeZero(m0);
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
}
function testMakeIdentity() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.makeIdentity(m0);
assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], m0);
}
function testSetGetElement() {
var m0 = goog.vec.Mat3.createFloat32();
for (var r = 0; r < 3; r++) {
for (var c = 0; c < 3; c++) {
var value = c * 3 + r + 1;
goog.vec.Mat3.setElement(m0, r, c, value);
assertEquals(value, goog.vec.Mat3.getElement(m0, r, c));
}
}
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
}
function testAddMat() {
var m0 = goog.vec.Mat3.createFloat32FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Mat3.createFloat32FromValues(3, 4, 5, 6, 7, 8, 9, 1, 2);
var m2 = goog.vec.Mat3.create();
goog.vec.Mat3.addMat(m0, m1, m2);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m2);
goog.vec.Mat3.addMat(m0, m1, m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m0);
}
function testSubMat() {
var m0 = goog.vec.Mat3.createFloat32FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Mat3.createFloat32FromValues(3, 4, 5, 6, 7, 8, 9, 1, 2);
var m2 = goog.vec.Mat3.create();
goog.vec.Mat3.subMat(m0, m1, m2);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([-2, -2, -2, -2, -2, -2, -2, 7, 7], m2);
goog.vec.Mat3.subMat(m1, m0, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([2, 2, 2, 2, 2, 2, 2, -7, -7], m1);
}
function testMultScalar() {
var m0 = goog.vec.Mat3.createFloat32FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.multScalar(m0, 5, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m1);
goog.vec.Mat3.multScalar(m0, 5, m0);
assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m0);
}
function testMultMat() {
var m0 = goog.vec.Mat3.createFloat32FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Mat3.createFloat32FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m2 = goog.vec.Mat3.create();
goog.vec.Mat3.multMat(m0, m1, m2);
assertElementsEquals([30, 36, 42, 66, 81, 96, 102, 126, 150], m2);
goog.vec.Mat3.addMat(m0, m1, m1);
goog.vec.Mat3.multMat(m0, m1, m1);
assertElementsEquals([60, 72, 84, 132, 162, 192, 204, 252, 300], m1);
}
function testTranspose() {
var m0 = goog.vec.Mat3.createFloat32FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.transpose(m0, m1);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m1);
goog.vec.Mat3.transpose(m1, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
}
function testInvert() {
var m0 = goog.vec.Mat3.createFloat32FromValues(1, 1, 1, 1, 1, 1, 1, 1, 1);
assertFalse(goog.vec.Mat3.invert(m0, m0));
assertElementsEquals([1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.Mat3.setFromValues(m0, 1, 2, 3, 1, 3, 4, 3, 4, 5);
assertTrue(goog.vec.Mat3.invert(m0, m0));
assertElementsEquals([0.5, -1.0, 0.5, -3.5, 2.0, 0.5, 2.5, -1.0, -0.5], m0);
goog.vec.Mat3.makeScale(m0, .01, .01, .01);
assertTrue(goog.vec.Mat3.invert(m0, m0));
var m1 = goog.vec.Mat3.create();
goog.vec.Mat3.makeScale(m1, 100, 100, 100);
assertElementsEquals(m1, m0);
}
function testEquals() {
var m0 = goog.vec.Mat3.createFloat32FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Mat3.createFromArray(m0);
assertTrue(goog.vec.Mat3.equals(m0, m1));
assertTrue(goog.vec.Mat3.equals(m1, m0));
for (var i = 0; i < 9; i++) {
m1[i] = 15;
assertFalse(goog.vec.Mat3.equals(m0, m1));
assertFalse(goog.vec.Mat3.equals(m1, m0));
m1[i] = i + 1;
}
}
function testMultVec3() {
var m0 = goog.vec.Mat3.createFloat32FromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.Mat3.multVec3(m0, v0, v1);
assertElementsEquals([30, 36, 42], v1);
goog.vec.Mat3.multVec3(m0, v0, v0);
assertElementsEquals([30, 36, 42], v0);
}
function testSetValues() {
var a0 = goog.vec.Mat3.createFloat32();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
goog.vec.Mat3.setFromValues(a0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a0);
var a1 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.setDiagonalValues(a1, 1, 2, 3);
assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], a1);
goog.vec.Mat3.setColumnValues(a1, 0, 2, 3, 4);
goog.vec.Mat3.setColumnValues(a1, 1, 5, 6, 7);
goog.vec.Mat3.setColumnValues(a1, 2, 8, 9, 1);
assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 1], a1);
goog.vec.Mat3.setRowValues(a1, 0, 1, 4, 7);
goog.vec.Mat3.setRowValues(a1, 1, 2, 5, 8);
goog.vec.Mat3.setRowValues(a1, 2, 3, 6, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a1);
}
function testMakeTranslate() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.makeTranslate(m0, 3, 4);
assertElementsEquals([1, 0, 0, 0, 1, 0, 3, 4, 1], m0);
}
function testMakeScale() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.makeScale(m0, 3, 4, 5);
assertElementsEquals([3, 0, 0, 0, 4, 0, 0, 0, 5], m0);
}
function testMakeRotate() {
var m0 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.makeRotate(m0, Math.PI / 2, 0, 0, 1);
var v0 = [0, 1, 0, -1, 0, 0, 0, 0, 1];
assertElementsRoughlyEqual(m0, v0, goog.vec.EPSILON);
var m1 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.makeRotate(m1, -Math.PI / 4, 0, 0, 1);
goog.vec.Mat3.multMat(m0, m1, m1);
var v1 = [0.7071068, 0.7071068, 0, -0.7071068, 0.7071068, 0, 0, 0, 1];
assertElementsRoughlyEqual(m1, v1, goog.vec.EPSILON);
}
function testMakeRotateX() {
var m0 = goog.vec.Mat3.createFloat32();
var m1 = goog.vec.Mat3.createFloat32()
goog.vec.Mat3.makeRotateX(m0, Math.PI / 7);
goog.vec.Mat3.makeRotate(m1, Math.PI / 7, 1, 0, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateY() {
var m0 = goog.vec.Mat3.createFloat32();
var m1 = goog.vec.Mat3.createFloat32()
goog.vec.Mat3.makeRotateY(m0, Math.PI / 7);
goog.vec.Mat3.makeRotate(m1, Math.PI / 7, 0, 1, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateZ() {
var m0 = goog.vec.Mat3.createFloat32();
var m1 = goog.vec.Mat3.createFloat32()
goog.vec.Mat3.makeRotateZ(m0, Math.PI / 7);
goog.vec.Mat3.makeRotate(m1, Math.PI / 7, 0, 0, 1);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotate() {
var m0 = goog.vec.Mat3.createIdentity();
goog.vec.Mat3.rotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, -1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
goog.vec.Mat3.rotate(m0, -Math.PI / 4, 0, 0, 1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0,
-0.7071068, 0.7071068, 0,
0, 0, 1],
m0, goog.vec.EPSILON);
}
function testRotateX() {
var m0 = goog.vec.Mat3.createFloat32();
var m1 = goog.vec.Mat3.createFloat32FromArray(randomMat3)
goog.vec.Mat3.makeRotateX(m0, Math.PI / 7);
goog.vec.Mat3.multMat(m1, m0, m0);
goog.vec.Mat3.rotateX(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateY() {
var m0 = goog.vec.Mat3.createFloat32();
var m1 = goog.vec.Mat3.createFloat32FromArray(randomMat3)
goog.vec.Mat3.makeRotateY(m0, Math.PI / 7);
goog.vec.Mat3.multMat(m1, m0, m0);
goog.vec.Mat3.rotateY(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateZ() {
var m0 = goog.vec.Mat3.createFloat32();
var m1 = goog.vec.Mat3.createFloat32FromArray(randomMat3)
goog.vec.Mat3.makeRotateZ(m0, Math.PI / 7);
goog.vec.Mat3.multMat(m1, m0, m0);
goog.vec.Mat3.rotateZ(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeEulerZXZ() {
var m0 = goog.vec.Mat3.createFloat32();
var roll = 0.200982 * 2 * Math.PI;
var tilt = 0.915833 * Math.PI;
var yaw = 0.839392 * 2 * Math.PI;
goog.vec.Mat3.makeRotate(m0, roll, 0, 0, 1);
goog.vec.Mat3.rotate(m0, tilt, 1, 0, 0);
goog.vec.Mat3.rotate(m0, yaw, 0, 0, 1);
var m1 = goog.vec.Mat3.createFloat32();
goog.vec.Mat3.makeEulerZXZ(m1, roll, tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.Mat3.toEulerZXZ(m0, euler);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
// Test negative tilt now.
goog.vec.Mat3.makeRotate(m0, roll, 0, 0, 1);
goog.vec.Mat3.rotate(m0, -tilt, 1, 0, 0);
goog.vec.Mat3.rotate(m0, yaw, 0, 0, 1);
goog.vec.Mat3.makeEulerZXZ(m1, roll, -tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.Mat3.toEulerZXZ(m0, euler, true);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(-tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
}
function testEulerZXZExtrema() {
var m0 = goog.vec.Mat3.createFloat32FromArray(
[1, 0, 0, 0, 0, -1, 0, 1, 0]);
var m1 = goog.vec.Mat3.createFloat32FromArray(
[0, 0, 0, 0, 0, 0, 0, 0, 0]);
var euler = [0, 0, 0];
goog.vec.Mat3.toEulerZXZ(m0, euler);
assertElementsRoughlyEqual(
[Math.PI, Math.PI / 2, Math.PI], euler, goog.vec.EPSILON);
goog.vec.Mat3.makeEulerZXZ(m1, euler[0], euler[1], euler[2]);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
</script>
</body>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,432 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to mat3f_test.html by running: //
// swap_type.sh mat3d_test.html > mat3f_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.mat3d</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.mat3d');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
var randommat3d = goog.vec.mat3d.setFromValues(goog.vec.mat3d.create(),
0.8025078773498535,
0.7559120655059814,
0.15274643898010254,
0.19196106493473053,
0.0890120416879654,
0.15422114729881287,
0.09754583984613419,
0.44862601161003113,
0.9196512699127197);
function testCreate() {
var m = goog.vec.mat3d.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m);
}
function testSet() {
var m0 = goog.vec.mat3d.create();
var m1 = goog.vec.mat3d.setFromArray(
goog.vec.mat3d.create(), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
goog.vec.mat3d.setFromArray(m0, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
goog.vec.mat3d.setFromValues(m0, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 10], m0);
}
function testSetDiagonal() {
var m0 = goog.vec.mat3d.create();
goog.vec.mat3d.setDiagonalValues(m0, 1, 2, 3);
assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], m0);
goog.vec.mat3d.setDiagonal(m0, [4, 5, 6]);
assertElementsEquals([4, 0, 0, 0, 5, 0, 0, 0, 6], m0);
}
function testSetGetColumn() {
var m0 = goog.vec.mat3d.create();
goog.vec.mat3d.setColumn(m0, 0, [1, 2, 3]);
goog.vec.mat3d.setColumn(m0, 1, [4, 5, 6]);
goog.vec.mat3d.setColumn(m0, 2, [7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
var v0 = [0, 0, 0];
goog.vec.mat3d.getColumn(m0, 0, v0);
assertElementsEquals([1, 2, 3], v0);
goog.vec.mat3d.getColumn(m0, 1, v0);
assertElementsEquals([4, 5, 6], v0);
goog.vec.mat3d.getColumn(m0, 2, v0);
assertElementsEquals([7, 8, 9], v0);
}
function testSetGetColumns() {
var m0 = goog.vec.mat3d.create();
goog.vec.mat3d.setColumns(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
var v0 = [0, 0, 0], v1 = [0, 0, 0], v2 = [0, 0, 0];
goog.vec.mat3d.getColumns(m0, v0, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([7, 8, 9], v2);
}
function testSetGetRow() {
var m0 = goog.vec.mat3d.create();
goog.vec.mat3d.setRow(m0, 0, [1, 2, 3]);
goog.vec.mat3d.setRow(m0, 1, [4, 5, 6]);
goog.vec.mat3d.setRow(m0, 2, [7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
var v0 = [0, 0, 0];
goog.vec.mat3d.getRow(m0, 0, v0);
assertElementsEquals([1, 2, 3], v0);
goog.vec.mat3d.getRow(m0, 1, v0);
assertElementsEquals([4, 5, 6], v0);
goog.vec.mat3d.getRow(m0, 2, v0);
assertElementsEquals([7, 8, 9], v0);
}
function testSetGetRows() {
var m0 = goog.vec.mat3d.create();
goog.vec.mat3d.setRows(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
var v0 = [0, 0, 0], v1 = [0, 0, 0], v2 = [0, 0, 0];
goog.vec.mat3d.getRows(m0, v0, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([7, 8, 9], v2);
}
function testMakeZero() {
var m0 = goog.vec.mat3d.setFromArray(
goog.vec.mat3d.create(), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
goog.vec.mat3d.makeZero(m0);
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
}
function testMakeIdentity() {
var m0 = goog.vec.mat3d.create();
goog.vec.mat3d.makeIdentity(m0);
assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], m0);
}
function testSetGetElement() {
var m0 = goog.vec.mat3d.create();
for (var r = 0; r < 3; r++) {
for (var c = 0; c < 3; c++) {
var value = c * 3 + r + 1;
goog.vec.mat3d.setElement(m0, r, c, value);
assertEquals(value, goog.vec.mat3d.getElement(m0, r, c));
}
}
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
}
function testAddMat() {
var m0 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 3, 4, 5, 6, 7, 8, 9, 1, 2);
var m2 = goog.vec.mat3d.create();
goog.vec.mat3d.addMat(m0, m1, m2);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m2);
goog.vec.mat3d.addMat(m0, m1, m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m0);
}
function testSubMat() {
var m0 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 3, 4, 5, 6, 7, 8, 9, 1, 2);
var m2 = goog.vec.mat3d.create();
goog.vec.mat3d.subMat(m0, m1, m2);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([-2, -2, -2, -2, -2, -2, -2, 7, 7], m2);
goog.vec.mat3d.subMat(m1, m0, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([2, 2, 2, 2, 2, 2, 2, -7, -7], m1);
}
function testMultScalar() {
var m0 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3d.create();
goog.vec.mat3d.multScalar(m0, 5, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m1);
goog.vec.mat3d.multScalar(m0, 5, m0);
assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m0);
}
function testMultMat() {
var m0 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m2 = goog.vec.mat3d.create();
goog.vec.mat3d.multMat(m0, m1, m2);
assertElementsEquals([30, 36, 42, 66, 81, 96, 102, 126, 150], m2);
goog.vec.mat3d.addMat(m0, m1, m1);
goog.vec.mat3d.multMat(m0, m1, m1);
assertElementsEquals([60, 72, 84, 132, 162, 192, 204, 252, 300], m1);
}
function testTranspose() {
var m0 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3d.create();
goog.vec.mat3d.transpose(m0, m1);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m1);
goog.vec.mat3d.transpose(m1, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
}
function testInvert() {
var m0 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertFalse(goog.vec.mat3d.invert(m0, m0));
assertElementsEquals([1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.mat3d.setFromValues(m0, 1, 2, 3, 1, 3, 4, 3, 4, 5);
assertTrue(goog.vec.mat3d.invert(m0, m0));
assertElementsEquals([0.5, -1.0, 0.5, -3.5, 2.0, 0.5, 2.5, -1.0, -0.5], m0);
goog.vec.mat3d.makeScale(m0, .01, .01, .01);
assertTrue(goog.vec.mat3d.invert(m0, m0));
var m1 = goog.vec.mat3d.create();
goog.vec.mat3d.makeScale(m1, 100, 100, 100);
assertElementsEquals(m1, m0);
}
function testEquals() {
var m0 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3d.setFromArray(goog.vec.mat3d.create(), m0);
assertTrue(goog.vec.mat3d.equals(m0, m1));
assertTrue(goog.vec.mat3d.equals(m1, m0));
for (var i = 0; i < 9; i++) {
m1[i] = 15;
assertFalse(goog.vec.mat3d.equals(m0, m1));
assertFalse(goog.vec.mat3d.equals(m1, m0));
m1[i] = i + 1;
}
}
function testMultVec3() {
var m0 = goog.vec.mat3d.setFromValues(
goog.vec.mat3d.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.mat3d.multVec3(m0, v0, v1);
assertElementsEquals([30, 36, 42], v1);
goog.vec.mat3d.multVec3(m0, v0, v0);
assertElementsEquals([30, 36, 42], v0);
}
function testSetValues() {
var a0 = goog.vec.mat3d.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
goog.vec.mat3d.setFromValues(a0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a0);
var a1 = goog.vec.mat3d.create();
goog.vec.mat3d.setDiagonalValues(a1, 1, 2, 3);
assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], a1);
goog.vec.mat3d.setColumnValues(a1, 0, 2, 3, 4);
goog.vec.mat3d.setColumnValues(a1, 1, 5, 6, 7);
goog.vec.mat3d.setColumnValues(a1, 2, 8, 9, 1);
assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 1], a1);
goog.vec.mat3d.setRowValues(a1, 0, 1, 4, 7);
goog.vec.mat3d.setRowValues(a1, 1, 2, 5, 8);
goog.vec.mat3d.setRowValues(a1, 2, 3, 6, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a1);
}
function testMakeTranslate() {
var m0 = goog.vec.mat3d.create();
goog.vec.mat3d.makeTranslate(m0, 3, 4);
assertElementsEquals([1, 0, 0, 0, 1, 0, 3, 4, 1], m0);
}
function testMakeScale() {
var m0 = goog.vec.mat3d.create();
goog.vec.mat3d.makeScale(m0, 3, 4, 5);
assertElementsEquals([3, 0, 0, 0, 4, 0, 0, 0, 5], m0);
}
function testMakeRotate() {
var m0 = goog.vec.mat3d.create();
goog.vec.mat3d.makeRotate(m0, Math.PI / 2, 0, 0, 1);
var v0 = [0, 1, 0, -1, 0, 0, 0, 0, 1];
assertElementsRoughlyEqual(m0, v0, goog.vec.EPSILON);
var m1 = goog.vec.mat3d.create();
goog.vec.mat3d.makeRotate(m1, -Math.PI / 4, 0, 0, 1);
goog.vec.mat3d.multMat(m0, m1, m1);
var v1 = [0.7071068, 0.7071068, 0, -0.7071068, 0.7071068, 0, 0, 0, 1];
assertElementsRoughlyEqual(m1, v1, goog.vec.EPSILON);
}
function testMakeRotateX() {
var m0 = goog.vec.mat3d.create();
var m1 = goog.vec.mat3d.create()
goog.vec.mat3d.makeRotateX(m0, Math.PI / 7);
goog.vec.mat3d.makeRotate(m1, Math.PI / 7, 1, 0, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateY() {
var m0 = goog.vec.mat3d.create();
var m1 = goog.vec.mat3d.create()
goog.vec.mat3d.makeRotateY(m0, Math.PI / 7);
goog.vec.mat3d.makeRotate(m1, Math.PI / 7, 0, 1, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateZ() {
var m0 = goog.vec.mat3d.create();
var m1 = goog.vec.mat3d.create()
goog.vec.mat3d.makeRotateZ(m0, Math.PI / 7);
goog.vec.mat3d.makeRotate(m1, Math.PI / 7, 0, 0, 1);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotate() {
var m0 = goog.vec.mat3d.makeIdentity(goog.vec.mat3d.create());
goog.vec.mat3d.rotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, -1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
goog.vec.mat3d.rotate(m0, -Math.PI / 4, 0, 0, 1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0,
-0.7071068, 0.7071068, 0,
0, 0, 1],
m0, goog.vec.EPSILON);
}
function testRotateX() {
var m0 = goog.vec.mat3d.create();
var m1 = goog.vec.mat3d.setFromArray(goog.vec.mat3d.create(), randommat3d);
goog.vec.mat3d.makeRotateX(m0, Math.PI / 7);
goog.vec.mat3d.multMat(m1, m0, m0);
goog.vec.mat3d.rotateX(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateY() {
var m0 = goog.vec.mat3d.create();
var m1 = goog.vec.mat3d.setFromArray(goog.vec.mat3d.create(), randommat3d);
goog.vec.mat3d.makeRotateY(m0, Math.PI / 7);
goog.vec.mat3d.multMat(m1, m0, m0);
goog.vec.mat3d.rotateY(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateZ() {
var m0 = goog.vec.mat3d.create();
var m1 = goog.vec.mat3d.setFromArray(goog.vec.mat3d.create(), randommat3d);
goog.vec.mat3d.makeRotateZ(m0, Math.PI / 7);
goog.vec.mat3d.multMat(m1, m0, m0);
goog.vec.mat3d.rotateZ(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeEulerZXZ() {
var m0 = goog.vec.mat3d.create();
var roll = 0.200982 * 2 * Math.PI;
var tilt = 0.915833 * Math.PI;
var yaw = 0.839392 * 2 * Math.PI;
goog.vec.mat3d.makeRotate(m0, roll, 0, 0, 1);
goog.vec.mat3d.rotate(m0, tilt, 1, 0, 0);
goog.vec.mat3d.rotate(m0, yaw, 0, 0, 1);
var m1 = goog.vec.mat3d.create();
goog.vec.mat3d.makeEulerZXZ(m1, roll, tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.mat3d.toEulerZXZ(m0, euler);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
// Test negative tilt now.
goog.vec.mat3d.makeRotate(m0, roll, 0, 0, 1);
goog.vec.mat3d.rotate(m0, -tilt, 1, 0, 0);
goog.vec.mat3d.rotate(m0, yaw, 0, 0, 1);
goog.vec.mat3d.makeEulerZXZ(m1, roll, -tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.mat3d.toEulerZXZ(m0, euler, true);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(-tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
}
function testEulerZXZExtrema() {
var m0 = goog.vec.mat3d.setFromArray(goog.vec.mat3d.create(),
[1, 0, 0, 0, 0, -1, 0, 1, 0]);
var m1 = goog.vec.mat3d.setFromArray(goog.vec.mat3d.create(),
[0, 0, 0, 0, 0, 0, 0, 0, 0]);
var euler = [0, 0, 0];
goog.vec.mat3d.toEulerZXZ(m0, euler);
assertElementsRoughlyEqual(
[Math.PI, Math.PI / 2, Math.PI], euler, goog.vec.EPSILON);
goog.vec.mat3d.makeEulerZXZ(m1, euler[0], euler[1], euler[2]);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
</script>
</body>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,432 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to mat3d_test.html by running: //
// swap_type.sh mat3f_test.html > mat3d_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.mat3f</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.mat3f');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
var randommat3f = goog.vec.mat3f.setFromValues(goog.vec.mat3f.create(),
0.8025078773498535,
0.7559120655059814,
0.15274643898010254,
0.19196106493473053,
0.0890120416879654,
0.15422114729881287,
0.09754583984613419,
0.44862601161003113,
0.9196512699127197);
function testCreate() {
var m = goog.vec.mat3f.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m);
}
function testSet() {
var m0 = goog.vec.mat3f.create();
var m1 = goog.vec.mat3f.setFromArray(
goog.vec.mat3f.create(), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
goog.vec.mat3f.setFromArray(m0, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
goog.vec.mat3f.setFromValues(m0, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 10], m0);
}
function testSetDiagonal() {
var m0 = goog.vec.mat3f.create();
goog.vec.mat3f.setDiagonalValues(m0, 1, 2, 3);
assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], m0);
goog.vec.mat3f.setDiagonal(m0, [4, 5, 6]);
assertElementsEquals([4, 0, 0, 0, 5, 0, 0, 0, 6], m0);
}
function testSetGetColumn() {
var m0 = goog.vec.mat3f.create();
goog.vec.mat3f.setColumn(m0, 0, [1, 2, 3]);
goog.vec.mat3f.setColumn(m0, 1, [4, 5, 6]);
goog.vec.mat3f.setColumn(m0, 2, [7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
var v0 = [0, 0, 0];
goog.vec.mat3f.getColumn(m0, 0, v0);
assertElementsEquals([1, 2, 3], v0);
goog.vec.mat3f.getColumn(m0, 1, v0);
assertElementsEquals([4, 5, 6], v0);
goog.vec.mat3f.getColumn(m0, 2, v0);
assertElementsEquals([7, 8, 9], v0);
}
function testSetGetColumns() {
var m0 = goog.vec.mat3f.create();
goog.vec.mat3f.setColumns(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
var v0 = [0, 0, 0], v1 = [0, 0, 0], v2 = [0, 0, 0];
goog.vec.mat3f.getColumns(m0, v0, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([7, 8, 9], v2);
}
function testSetGetRow() {
var m0 = goog.vec.mat3f.create();
goog.vec.mat3f.setRow(m0, 0, [1, 2, 3]);
goog.vec.mat3f.setRow(m0, 1, [4, 5, 6]);
goog.vec.mat3f.setRow(m0, 2, [7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
var v0 = [0, 0, 0];
goog.vec.mat3f.getRow(m0, 0, v0);
assertElementsEquals([1, 2, 3], v0);
goog.vec.mat3f.getRow(m0, 1, v0);
assertElementsEquals([4, 5, 6], v0);
goog.vec.mat3f.getRow(m0, 2, v0);
assertElementsEquals([7, 8, 9], v0);
}
function testSetGetRows() {
var m0 = goog.vec.mat3f.create();
goog.vec.mat3f.setRows(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
var v0 = [0, 0, 0], v1 = [0, 0, 0], v2 = [0, 0, 0];
goog.vec.mat3f.getRows(m0, v0, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([7, 8, 9], v2);
}
function testMakeZero() {
var m0 = goog.vec.mat3f.setFromArray(
goog.vec.mat3f.create(), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
goog.vec.mat3f.makeZero(m0);
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
}
function testMakeIdentity() {
var m0 = goog.vec.mat3f.create();
goog.vec.mat3f.makeIdentity(m0);
assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], m0);
}
function testSetGetElement() {
var m0 = goog.vec.mat3f.create();
for (var r = 0; r < 3; r++) {
for (var c = 0; c < 3; c++) {
var value = c * 3 + r + 1;
goog.vec.mat3f.setElement(m0, r, c, value);
assertEquals(value, goog.vec.mat3f.getElement(m0, r, c));
}
}
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
}
function testAddMat() {
var m0 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 3, 4, 5, 6, 7, 8, 9, 1, 2);
var m2 = goog.vec.mat3f.create();
goog.vec.mat3f.addMat(m0, m1, m2);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m2);
goog.vec.mat3f.addMat(m0, m1, m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m0);
}
function testSubMat() {
var m0 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 3, 4, 5, 6, 7, 8, 9, 1, 2);
var m2 = goog.vec.mat3f.create();
goog.vec.mat3f.subMat(m0, m1, m2);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([-2, -2, -2, -2, -2, -2, -2, 7, 7], m2);
goog.vec.mat3f.subMat(m1, m0, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([2, 2, 2, 2, 2, 2, 2, -7, -7], m1);
}
function testMultScalar() {
var m0 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3f.create();
goog.vec.mat3f.multScalar(m0, 5, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m1);
goog.vec.mat3f.multScalar(m0, 5, m0);
assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m0);
}
function testMultMat() {
var m0 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m2 = goog.vec.mat3f.create();
goog.vec.mat3f.multMat(m0, m1, m2);
assertElementsEquals([30, 36, 42, 66, 81, 96, 102, 126, 150], m2);
goog.vec.mat3f.addMat(m0, m1, m1);
goog.vec.mat3f.multMat(m0, m1, m1);
assertElementsEquals([60, 72, 84, 132, 162, 192, 204, 252, 300], m1);
}
function testTranspose() {
var m0 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3f.create();
goog.vec.mat3f.transpose(m0, m1);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m1);
goog.vec.mat3f.transpose(m1, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
}
function testInvert() {
var m0 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertFalse(goog.vec.mat3f.invert(m0, m0));
assertElementsEquals([1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.mat3f.setFromValues(m0, 1, 2, 3, 1, 3, 4, 3, 4, 5);
assertTrue(goog.vec.mat3f.invert(m0, m0));
assertElementsEquals([0.5, -1.0, 0.5, -3.5, 2.0, 0.5, 2.5, -1.0, -0.5], m0);
goog.vec.mat3f.makeScale(m0, .01, .01, .01);
assertTrue(goog.vec.mat3f.invert(m0, m0));
var m1 = goog.vec.mat3f.create();
goog.vec.mat3f.makeScale(m1, 100, 100, 100);
assertElementsEquals(m1, m0);
}
function testEquals() {
var m0 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.mat3f.setFromArray(goog.vec.mat3f.create(), m0);
assertTrue(goog.vec.mat3f.equals(m0, m1));
assertTrue(goog.vec.mat3f.equals(m1, m0));
for (var i = 0; i < 9; i++) {
m1[i] = 15;
assertFalse(goog.vec.mat3f.equals(m0, m1));
assertFalse(goog.vec.mat3f.equals(m1, m0));
m1[i] = i + 1;
}
}
function testMultVec3() {
var m0 = goog.vec.mat3f.setFromValues(
goog.vec.mat3f.create(), 1, 2, 3, 4, 5, 6, 7, 8, 9);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.mat3f.multVec3(m0, v0, v1);
assertElementsEquals([30, 36, 42], v1);
goog.vec.mat3f.multVec3(m0, v0, v0);
assertElementsEquals([30, 36, 42], v0);
}
function testSetValues() {
var a0 = goog.vec.mat3f.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
goog.vec.mat3f.setFromValues(a0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a0);
var a1 = goog.vec.mat3f.create();
goog.vec.mat3f.setDiagonalValues(a1, 1, 2, 3);
assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], a1);
goog.vec.mat3f.setColumnValues(a1, 0, 2, 3, 4);
goog.vec.mat3f.setColumnValues(a1, 1, 5, 6, 7);
goog.vec.mat3f.setColumnValues(a1, 2, 8, 9, 1);
assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 1], a1);
goog.vec.mat3f.setRowValues(a1, 0, 1, 4, 7);
goog.vec.mat3f.setRowValues(a1, 1, 2, 5, 8);
goog.vec.mat3f.setRowValues(a1, 2, 3, 6, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a1);
}
function testMakeTranslate() {
var m0 = goog.vec.mat3f.create();
goog.vec.mat3f.makeTranslate(m0, 3, 4);
assertElementsEquals([1, 0, 0, 0, 1, 0, 3, 4, 1], m0);
}
function testMakeScale() {
var m0 = goog.vec.mat3f.create();
goog.vec.mat3f.makeScale(m0, 3, 4, 5);
assertElementsEquals([3, 0, 0, 0, 4, 0, 0, 0, 5], m0);
}
function testMakeRotate() {
var m0 = goog.vec.mat3f.create();
goog.vec.mat3f.makeRotate(m0, Math.PI / 2, 0, 0, 1);
var v0 = [0, 1, 0, -1, 0, 0, 0, 0, 1];
assertElementsRoughlyEqual(m0, v0, goog.vec.EPSILON);
var m1 = goog.vec.mat3f.create();
goog.vec.mat3f.makeRotate(m1, -Math.PI / 4, 0, 0, 1);
goog.vec.mat3f.multMat(m0, m1, m1);
var v1 = [0.7071068, 0.7071068, 0, -0.7071068, 0.7071068, 0, 0, 0, 1];
assertElementsRoughlyEqual(m1, v1, goog.vec.EPSILON);
}
function testMakeRotateX() {
var m0 = goog.vec.mat3f.create();
var m1 = goog.vec.mat3f.create()
goog.vec.mat3f.makeRotateX(m0, Math.PI / 7);
goog.vec.mat3f.makeRotate(m1, Math.PI / 7, 1, 0, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateY() {
var m0 = goog.vec.mat3f.create();
var m1 = goog.vec.mat3f.create()
goog.vec.mat3f.makeRotateY(m0, Math.PI / 7);
goog.vec.mat3f.makeRotate(m1, Math.PI / 7, 0, 1, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateZ() {
var m0 = goog.vec.mat3f.create();
var m1 = goog.vec.mat3f.create()
goog.vec.mat3f.makeRotateZ(m0, Math.PI / 7);
goog.vec.mat3f.makeRotate(m1, Math.PI / 7, 0, 0, 1);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotate() {
var m0 = goog.vec.mat3f.makeIdentity(goog.vec.mat3f.create());
goog.vec.mat3f.rotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, -1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
goog.vec.mat3f.rotate(m0, -Math.PI / 4, 0, 0, 1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0,
-0.7071068, 0.7071068, 0,
0, 0, 1],
m0, goog.vec.EPSILON);
}
function testRotateX() {
var m0 = goog.vec.mat3f.create();
var m1 = goog.vec.mat3f.setFromArray(goog.vec.mat3f.create(), randommat3f);
goog.vec.mat3f.makeRotateX(m0, Math.PI / 7);
goog.vec.mat3f.multMat(m1, m0, m0);
goog.vec.mat3f.rotateX(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateY() {
var m0 = goog.vec.mat3f.create();
var m1 = goog.vec.mat3f.setFromArray(goog.vec.mat3f.create(), randommat3f);
goog.vec.mat3f.makeRotateY(m0, Math.PI / 7);
goog.vec.mat3f.multMat(m1, m0, m0);
goog.vec.mat3f.rotateY(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateZ() {
var m0 = goog.vec.mat3f.create();
var m1 = goog.vec.mat3f.setFromArray(goog.vec.mat3f.create(), randommat3f);
goog.vec.mat3f.makeRotateZ(m0, Math.PI / 7);
goog.vec.mat3f.multMat(m1, m0, m0);
goog.vec.mat3f.rotateZ(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeEulerZXZ() {
var m0 = goog.vec.mat3f.create();
var roll = 0.200982 * 2 * Math.PI;
var tilt = 0.915833 * Math.PI;
var yaw = 0.839392 * 2 * Math.PI;
goog.vec.mat3f.makeRotate(m0, roll, 0, 0, 1);
goog.vec.mat3f.rotate(m0, tilt, 1, 0, 0);
goog.vec.mat3f.rotate(m0, yaw, 0, 0, 1);
var m1 = goog.vec.mat3f.create();
goog.vec.mat3f.makeEulerZXZ(m1, roll, tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.mat3f.toEulerZXZ(m0, euler);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
// Test negative tilt now.
goog.vec.mat3f.makeRotate(m0, roll, 0, 0, 1);
goog.vec.mat3f.rotate(m0, -tilt, 1, 0, 0);
goog.vec.mat3f.rotate(m0, yaw, 0, 0, 1);
goog.vec.mat3f.makeEulerZXZ(m1, roll, -tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.mat3f.toEulerZXZ(m0, euler, true);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(-tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
}
function testEulerZXZExtrema() {
var m0 = goog.vec.mat3f.setFromArray(goog.vec.mat3f.create(),
[1, 0, 0, 0, 0, -1, 0, 1, 0]);
var m1 = goog.vec.mat3f.setFromArray(goog.vec.mat3f.create(),
[0, 0, 0, 0, 0, 0, 0, 0, 0]);
var euler = [0, 0, 0];
goog.vec.mat3f.toEulerZXZ(m0, euler);
assertElementsRoughlyEqual(
[Math.PI, Math.PI / 2, Math.PI], euler, goog.vec.EPSILON);
goog.vec.mat3f.makeEulerZXZ(m1, euler[0], euler[1], euler[2]);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
</script>
</body>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,781 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Mat4</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Mat4');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
var randomMat4 = goog.vec.Mat4.createFloat32FromValues(
0.8025078773498535,
0.7559120655059814,
0.15274643898010254,
0.19196106493473053,
0.0890120416879654,
0.15422114729881287,
0.09754583984613419,
0.44862601161003113,
0.9196512699127197,
0.5310639142990112,
0.8962187170982361,
0.280601441860199,
0.594650387763977,
0.4134795069694519,
0.06632178276777267,
0.8837796449661255);
function testDeprecatedConstructor() {
var m0 = goog.vec.Mat4.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
var m1 = goog.vec.Mat4.createFromArray(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
var m2 = goog.vec.Mat4.clone(m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m2);
var m3 = goog.vec.Mat4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m3);
var m4 = goog.vec.Mat4.createIdentity();
assertElementsEquals([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], m4);
}
function testConstructor() {
var m0 = goog.vec.Mat4.createFloat32();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
var m1 = goog.vec.Mat4.createFloat32FromArray(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
var m2 = goog.vec.Mat4.clone(m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m2);
var m3 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m3);
var m4 = goog.vec.Mat4.createIdentity();
assertElementsEquals([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], m4);
}
function testSet() {
var m0 = goog.vec.Mat4.createFloat32();
var m1 = goog.vec.Mat4.createFloat32FromArray(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
goog.vec.Mat4.setFromArray(m0, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
goog.vec.Mat4.setFromValues(
m0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
assertElementsEquals(
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], m0);
}
function testSetDiagonal() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.setDiagonalValues(m0, 1, 2, 3, 4);
assertElementsEquals(
[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], m0);
goog.vec.Mat4.setDiagonal(m0, [4, 5, 6, 7]);
assertElementsEquals(
[4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0, 7], m0);
}
function testGetDiagonal() {
var v0 = goog.vec.Vec4.create();
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.setFromArray(
m0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
goog.vec.Mat4.getDiagonal(m0, v0);
assertElementsEquals([0, 5, 10, 15], v0);
goog.vec.Vec4.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.Mat4.getDiagonal(m0, v0, 1);
assertElementsEquals([4, 9, 14, 0], v0);
goog.vec.Vec4.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.Mat4.getDiagonal(m0, v0, 2);
assertElementsEquals([8, 13, 0, 0], v0);
goog.vec.Vec4.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.Mat4.getDiagonal(m0, v0, 3);
assertElementsEquals([12, 0, 0, 0], v0);
goog.vec.Vec4.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.Mat4.getDiagonal(m0, v0, 4);
assertElementsEquals([0, 0, 0, 0], v0);
goog.vec.Vec4.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.Mat4.getDiagonal(m0, v0, -1);
assertElementsEquals([1, 6, 11, 0], v0);
goog.vec.Vec4.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.Mat4.getDiagonal(m0, v0, -2);
assertElementsEquals([2, 7, 0, 0], v0);
goog.vec.Vec4.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.Mat4.getDiagonal(m0, v0, -3);
assertElementsEquals([3, 0, 0, 0], v0);
goog.vec.Vec4.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.Mat4.getDiagonal(m0, v0, -4);
assertElementsEquals([0, 0, 0, 0], v0);
}
function testSetGetColumn() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.setColumn(m0, 0, [1, 2, 3, 4]);
goog.vec.Mat4.setColumn(m0, 1, [5, 6, 7, 8]);
goog.vec.Mat4.setColumn(m0, 2, [9, 10, 11, 12]);
goog.vec.Mat4.setColumn(m0, 3, [13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
var v0 = [0, 0, 0, 0];
goog.vec.Mat4.getColumn(m0, 0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.Mat4.getColumn(m0, 1, v0);
assertElementsEquals([5, 6, 7, 8], v0);
goog.vec.Mat4.getColumn(m0, 2, v0);
assertElementsEquals([9, 10, 11, 12], v0);
goog.vec.Mat4.getColumn(m0, 3, v0);
assertElementsEquals([13, 14, 15, 16], v0);
}
function testSetGetColumns() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.setColumns(
m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
goog.vec.Mat4.getColumns(m0, v0, v1, v2, v3);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([9, 10, 11, 12], v2);
assertElementsEquals([13, 14, 15, 16], v3);
}
function testSetGetRow() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.setRow(m0, 0, [1, 2, 3, 4]);
goog.vec.Mat4.setRow(m0, 1, [5, 6, 7, 8]);
goog.vec.Mat4.setRow(m0, 2, [9, 10, 11, 12]);
goog.vec.Mat4.setRow(m0, 3, [13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
var v0 = [0, 0, 0, 0];
goog.vec.Mat4.getRow(m0, 0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.Mat4.getRow(m0, 1, v0);
assertElementsEquals([5, 6, 7, 8], v0);
goog.vec.Mat4.getRow(m0, 2, v0);
assertElementsEquals([9, 10, 11, 12], v0);
goog.vec.Mat4.getRow(m0, 3, v0);
assertElementsEquals([13, 14, 15, 16], v0);
}
function testSetGetRows() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.setRows(
m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
goog.vec.Mat4.getRows(m0, v0, v1, v2, v3);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([9, 10, 11, 12], v2);
assertElementsEquals([13, 14, 15, 16], v3);
}
function testSetRowMajorArray() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.setFromRowMajorArray(
m0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
}
function testMakeZero() {
var m0 = goog.vec.Mat4.createFloat32FromArray(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
goog.vec.Mat4.makeZero(m0);
assertElementsEquals(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
}
function testMakeIdentity() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeIdentity(m0);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], m0);
}
function testSetGetElement() {
var m0 = goog.vec.Mat4.createFloat32();
for (var r = 0; r < 4; r++) {
for (var c = 0; c < 4; c++) {
var value = c * 4 + r + 1;
goog.vec.Mat4.setElement(m0, r, c, value);
assertEquals(value, goog.vec.Mat4.getElement(m0, r, c));
}
}
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
}
function testAddMat() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Mat4.createFloat32FromValues(
9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
var m2 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.addMat(m0, m1, m2);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m2);
goog.vec.Mat4.addMat(m0, m1, m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m0);
}
function testSubMat() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Mat4.createFloat32FromValues(
9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
var m2 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.subMat(m0, m1, m2);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[-8, -8, -8, -8, -8, -8, -8, -8, 8, 8, 8, 8, 8, 8, 8, 8], m2);
goog.vec.Mat4.subMat(m1, m0, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[8, 8, 8, 8, 8, 8, 8, 8, -8, -8, -8, -8, -8, -8, -8, -8], m1);
}
function testMultScalar() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.multScalar(m0, 2, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32], m1);
goog.vec.Mat4.multScalar(m0, 5, m0);
assertElementsEquals(
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80], m0);
}
function testMultMat() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m2 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.multMat(m0, m1, m2);
assertElementsEquals(
[90, 100, 110, 120, 202, 228, 254, 280,
314, 356, 398, 440, 426, 484, 542, 600], m2);
goog.vec.Mat4.multScalar(m1, 2, m1);
goog.vec.Mat4.multMat(m1, m0, m1);
assertElementsEquals(
[180, 200, 220, 240, 404, 456, 508, 560,
628, 712, 796, 880, 852, 968, 1084, 1200], m1);
}
function testTranspose() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.transpose(m0, m1);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m1);
goog.vec.Mat4.transpose(m1, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
}
function testDeterminant() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertEquals(0, goog.vec.Mat4.determinant(m0));
assertElementsEquals(
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.Mat4.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
assertEquals(160, goog.vec.Mat4.determinant(m0));
assertElementsEquals(
[1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3], m0);
}
function testInvert() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertFalse(goog.vec.Mat4.invert(m0, m0));
assertElementsEquals(
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.Mat4.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
assertTrue(goog.vec.Mat4.invert(m0, m0));
assertElementsRoughlyEqual(
[-0.225, 0.025, 0.025, 0.275, 0.025, 0.025, 0.275, -0.225,
0.025, 0.275, -0.225, 0.025, 0.275, -0.225, 0.025, 0.025], m0,
goog.vec.EPSILON);
goog.vec.Mat4.makeScale(m0, .01, .01, .01);
assertTrue(goog.vec.Mat4.invert(m0, m0));
var m1 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeScale(m1, 100, 100, 100);
assertElementsEquals(m1, m0);
}
function testEquals() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Mat4.clone(m0);
assertTrue(goog.vec.Mat4.equals(m0, m1));
assertTrue(goog.vec.Mat4.equals(m1, m0));
for (var i = 0; i < 16; i++) {
m1[i] = 18;
assertFalse(goog.vec.Mat4.equals(m0, m1));
assertFalse(goog.vec.Mat4.equals(m1, m0));
m1[i] = i + 1;
}
}
function testMultVec3() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.Mat4.multVec3(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([51, 58, 65], v1);
goog.vec.Mat4.multVec3(m0, v0, v0);
assertElementsEquals([51, 58, 65], v0);
}
function testMultVec3NoTranslate() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.Mat4.multVec3NoTranslate(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([38, 44, 50], v1);
goog.vec.Mat4.multVec3NoTranslate(m0, v0, v0);
assertElementsEquals([38, 44, 50], v0);
}
function testMultVec3Projective() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
var invw = 1 / 72;
goog.vec.Mat4.multVec3Projective(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals(
[51 * invw, 58 * invw, 65 * invw], v1);
goog.vec.Mat4.multVec3Projective(m0, v0, v0);
assertElementsEquals(
[51 * invw, 58 * invw, 65 * invw], v0);
}
function testMultVec4() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3, 4];
var v1 = [0, 0, 0, 0];
goog.vec.Mat4.multVec4(m0, v0, v1);
assertElementsEquals([90, 100, 110, 120], v1);
goog.vec.Mat4.multVec4(m0, v0, v0);
assertElementsEquals([90, 100, 110, 120], v0);
}
function testSetValues() {
var a0 = goog.vec.Mat4.createFloat32();
assertElementsEquals(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
a0 = goog.vec.Mat4.createFloat32FromArray(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a0);
var a1 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.setDiagonalValues(a1, 1, 2, 3, 4);
assertElementsEquals(
[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], a1);
goog.vec.Mat4.setColumnValues(a1, 0, 2, 3, 4, 5);
goog.vec.Mat4.setColumnValues(a1, 1, 6, 7, 8, 9);
goog.vec.Mat4.setColumnValues(a1, 2, 10, 11, 12, 13);
goog.vec.Mat4.setColumnValues(a1, 3, 14, 15, 16, 1);
assertElementsEquals(
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1], a1);
goog.vec.Mat4.setRowValues(a1, 0, 1, 5, 9, 13);
goog.vec.Mat4.setRowValues(a1, 1, 2, 6, 10, 14);
goog.vec.Mat4.setRowValues(a1, 2, 3, 7, 11, 15);
goog.vec.Mat4.setRowValues(a1, 3, 4, 8, 12, 16);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a1);
}
function testMakeTranslate() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeTranslate(m0, 3, 4, 5);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
}
function testMakeScale() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeScale(m0, 3, 4, 5);
assertElementsEquals(
[3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
}
function testMakeRotate() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeRotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
var m1 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeRotate(m1, -Math.PI / 4, 0, 0, 1);
goog.vec.Mat4.multMat(m0, m1, m1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0, 0,
-0.7071068, 0.7071068, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1],
m1, goog.vec.EPSILON);
}
function testMakeRotateX() {
var m0 = goog.vec.Mat4.createFloat32();
var m1 = goog.vec.Mat4.createFloat32()
goog.vec.Mat4.makeRotateX(m0, Math.PI / 7);
goog.vec.Mat4.makeRotate(m1, Math.PI / 7, 1, 0, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateY() {
var m0 = goog.vec.Mat4.createFloat32();
var m1 = goog.vec.Mat4.createFloat32()
goog.vec.Mat4.makeRotateY(m0, Math.PI / 7);
goog.vec.Mat4.makeRotate(m1, Math.PI / 7, 0, 1, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateZ() {
var m0 = goog.vec.Mat4.createFloat32();
var m1 = goog.vec.Mat4.createFloat32()
goog.vec.Mat4.makeRotateZ(m0, Math.PI / 7);
goog.vec.Mat4.makeRotate(m1, Math.PI / 7, 0, 0, 1);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testTranslate() {
var m0 = goog.vec.Mat4.createIdentity();
goog.vec.Mat4.translate(m0, 3, 4, 5);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
goog.vec.Mat4.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
var m1 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeTranslate(m1, 5, 6, 7);
var m2 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.multMat(m0, m1, m2);
goog.vec.Mat4.translate(m0, 5, 6, 7);
assertElementsEquals(m2, m0);
}
function testScale() {
var m0 = goog.vec.Mat4.createIdentity();
goog.vec.Mat4.scale(m0, 3, 4, 5);
assertElementsEquals([3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
}
function testRotate() {
var m0 = goog.vec.Mat4.createIdentity();
goog.vec.Mat4.rotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
goog.vec.Mat4.rotate(m0, -Math.PI / 4, 0, 0, 1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0, 0,
-0.7071068, 0.7071068, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1],
m0, goog.vec.EPSILON);
}
function testRotateX() {
var m0 = goog.vec.Mat4.createFloat32();
var m1 = goog.vec.Mat4.createFloat32FromArray(randomMat4)
goog.vec.Mat4.makeRotateX(m0, Math.PI / 7);
goog.vec.Mat4.multMat(m1, m0, m0);
goog.vec.Mat4.rotateX(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateY() {
var m0 = goog.vec.Mat4.createFloat32();
var m1 = goog.vec.Mat4.createFloat32FromArray(randomMat4)
goog.vec.Mat4.makeRotateY(m0, Math.PI / 7);
goog.vec.Mat4.multMat(m1, m0, m0);
goog.vec.Mat4.rotateY(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateZ() {
var m0 = goog.vec.Mat4.createFloat32();
var m1 = goog.vec.Mat4.createFloat32FromArray(randomMat4)
goog.vec.Mat4.makeRotateZ(m0, Math.PI / 7);
goog.vec.Mat4.multMat(m1, m0, m0);
goog.vec.Mat4.rotateZ(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testGetTranslation() {
var mat = goog.vec.Mat4.createFloat32FromArray(randomMat4);
var translation = goog.vec.Vec3.createFloat32();
goog.vec.Mat4.getTranslation(mat, translation);
assertElementsRoughlyEqual(
[0.59465038776, 0.413479506969, 0.0663217827677],
translation, goog.vec.EPSILON);
}
function testMakeFrustum() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeFrustum(m0, -1, 2, -2, 1, .1, 1.1);
assertElementsRoughlyEqual(
[0.06666666, 0, 0, 0,
0, 0.06666666, 0, 0,
0.33333333, -0.33333333, -1.2, -1,
0, 0, -0.22, 0], m0, goog.vec.EPSILON);
}
function testMakePerspective() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makePerspective(m0, 90 * Math.PI / 180, 2, 0.1, 1.1);
assertElementsRoughlyEqual(
[0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1.2, -1, 0, 0, -0.22, 0],
m0, goog.vec.EPSILON);
}
function testMakeOrtho() {
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeOrtho(m0, -1, 2, -2, 1, 0.1, 1.1);
assertElementsRoughlyEqual(
[0.6666666, 0, 0, 0,
0, 0.6666666, 0, 0,
0, 0, -2, 0,
-0.333333, 0.3333333, -1.2, 1], m0, goog.vec.EPSILON);
}
function testMakeEulerZXZ() {
var m0 = goog.vec.Mat4.createFloat32();
var roll = 0.200982 * 2 * Math.PI;
var tilt = 0.915833 * Math.PI;
var yaw = 0.839392 * 2 * Math.PI;
goog.vec.Mat4.makeRotate(m0, roll, 0, 0, 1);
goog.vec.Mat4.rotate(m0, tilt, 1, 0, 0);
goog.vec.Mat4.rotate(m0, yaw, 0, 0, 1);
var m1 = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeEulerZXZ(m1, roll, tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.Mat4.toEulerZXZ(m0, euler);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
// Test negative tilt now.
goog.vec.Mat4.makeRotate(m0, roll, 0, 0, 1);
goog.vec.Mat4.rotate(m0, -tilt, 1, 0, 0);
goog.vec.Mat4.rotate(m0, yaw, 0, 0, 1);
goog.vec.Mat4.makeEulerZXZ(m1, roll, -tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.Mat4.toEulerZXZ(m0, euler, true);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(-tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
}
function testEulerZXZExtrema() {
var m0 = goog.vec.Mat4.createFloat32FromArray(
[1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1]);
var m1 = goog.vec.Mat4.createFloat32FromArray(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
var euler = [0, 0, 0];
goog.vec.Mat4.toEulerZXZ(m0, euler);
assertElementsRoughlyEqual(
[Math.PI, Math.PI / 2, Math.PI], euler, goog.vec.EPSILON);
goog.vec.Mat4.makeEulerZXZ(m1, euler[0], euler[1], euler[2]);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testLookAt() {
var viewMatrix = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeLookAt(
viewMatrix, [0, 0, 0], [1, 0, 0], [0, 1, 0]);
assertElementsRoughlyEqual(
[0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], viewMatrix,
goog.vec.EPSILON);
}
function testToLookAt() {
// This test does not use the default precision goog.vec.EPSILON due to
// precision issues in some browsers leading to flaky tests.
var EPSILON = 1e-4;
var eyeExp = [0, 0, 0];
var fwdExp = [1, 0, 0];
var upExp = [0, 1, 0];
var centerExp = [0, 0, 0];
goog.vec.Vec3.add(eyeExp, fwdExp, centerExp);
var view = goog.vec.Mat4.createFloat32();
goog.vec.Mat4.makeLookAt(view, eyeExp, centerExp, upExp);
var eyeRes = [0, 0, 0];
var fwdRes = [0, 0, 0];
var upRes = [0, 0, 0];
goog.vec.Mat4.toLookAt(view, eyeRes, fwdRes, upRes);
assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
assertElementsRoughlyEqual(upExp, upRes, EPSILON);
}
function testLookAtDecomposition() {
// This test does not use the default precision goog.vec.EPSILON due to
// precision issues in some browsers leading to flaky tests.
var EPSILON = 1e-4;
var viewExp = goog.vec.Mat4.createFloat32();
var viewRes = goog.vec.Mat4.createFloat32();
// Get a valid set of random vectors eye, forward, up by decomposing
// a random matrix into a set of lookAt vectors.
var tmp = goog.vec.Mat4.createFloat32FromArray(randomMat4);
var eyeExp = [0, 0, 0];
var fwdExp = [0, 0, 0];
var upExp = [0, 0, 0];
var centerExp = [0, 0, 0];
// Project the random matrix into a real modelview matrix.
goog.vec.Mat4.toLookAt(tmp, eyeExp, fwdExp, upExp);
goog.vec.Vec3.add(eyeExp, fwdExp, centerExp);
// Compute the expected modelview matrix from a set of valid random vectors.
goog.vec.Mat4.makeLookAt(viewExp, eyeExp, centerExp, upExp);
var eyeRes = [0, 0, 0];
var fwdRes = [0, 0, 0];
var upRes = [0, 0, 0];
var centerRes = [0, 0, 0];
goog.vec.Mat4.toLookAt(viewExp, eyeRes, fwdRes, upRes);
goog.vec.Vec3.add(eyeRes, fwdRes, centerRes);
goog.vec.Mat4.makeLookAt(viewRes, eyeRes, centerRes, upRes);
assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
assertElementsRoughlyEqual(upExp, upRes, EPSILON);
assertElementsRoughlyEqual(viewExp, viewRes, EPSILON);
}
</script>
</body>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,738 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to mat4f_test.html by running: //
// swap_type.sh mat4d_test.html > mat4f_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.mat4d</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.mat4d');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
var randommat4d = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
0.8025078773498535,
0.7559120655059814,
0.15274643898010254,
0.19196106493473053,
0.0890120416879654,
0.15422114729881287,
0.09754583984613419,
0.44862601161003113,
0.9196512699127197,
0.5310639142990112,
0.8962187170982361,
0.280601441860199,
0.594650387763977,
0.4134795069694519,
0.06632178276777267,
0.8837796449661255);
function testCreate() {
var m = goog.vec.mat4d.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m);
}
function testSet() {
var m0 = goog.vec.mat4d.create();
var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
goog.vec.mat4d.setFromArray(m0, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
goog.vec.mat4d.setFromValues(
m0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
assertElementsEquals(
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], m0);
}
function testSetDiagonal() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.setDiagonalValues(m0, 1, 2, 3, 4);
assertElementsEquals(
[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], m0);
goog.vec.mat4d.setDiagonal(m0, [4, 5, 6, 7]);
assertElementsEquals(
[4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0, 7], m0);
}
function testGetDiagonal() {
var v0 = goog.vec.vec4d.create();
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.setFromArray(
m0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
goog.vec.mat4d.getDiagonal(m0, v0);
assertElementsEquals([0, 5, 10, 15], v0);
goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4d.getDiagonal(m0, v0, 1);
assertElementsEquals([4, 9, 14, 0], v0);
goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4d.getDiagonal(m0, v0, 2);
assertElementsEquals([8, 13, 0, 0], v0);
goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4d.getDiagonal(m0, v0, 3);
assertElementsEquals([12, 0, 0, 0], v0);
goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4d.getDiagonal(m0, v0, 4);
assertElementsEquals([0, 0, 0, 0], v0);
goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4d.getDiagonal(m0, v0, -1);
assertElementsEquals([1, 6, 11, 0], v0);
goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4d.getDiagonal(m0, v0, -2);
assertElementsEquals([2, 7, 0, 0], v0);
goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4d.getDiagonal(m0, v0, -3);
assertElementsEquals([3, 0, 0, 0], v0);
goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4d.getDiagonal(m0, v0, -4);
assertElementsEquals([0, 0, 0, 0], v0);
}
function testSetGetColumn() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.setColumn(m0, 0, [1, 2, 3, 4]);
goog.vec.mat4d.setColumn(m0, 1, [5, 6, 7, 8]);
goog.vec.mat4d.setColumn(m0, 2, [9, 10, 11, 12]);
goog.vec.mat4d.setColumn(m0, 3, [13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
var v0 = [0, 0, 0, 0];
goog.vec.mat4d.getColumn(m0, 0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.mat4d.getColumn(m0, 1, v0);
assertElementsEquals([5, 6, 7, 8], v0);
goog.vec.mat4d.getColumn(m0, 2, v0);
assertElementsEquals([9, 10, 11, 12], v0);
goog.vec.mat4d.getColumn(m0, 3, v0);
assertElementsEquals([13, 14, 15, 16], v0);
}
function testSetGetColumns() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.setColumns(
m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
goog.vec.mat4d.getColumns(m0, v0, v1, v2, v3);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([9, 10, 11, 12], v2);
assertElementsEquals([13, 14, 15, 16], v3);
}
function testSetGetRow() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.setRow(m0, 0, [1, 2, 3, 4]);
goog.vec.mat4d.setRow(m0, 1, [5, 6, 7, 8]);
goog.vec.mat4d.setRow(m0, 2, [9, 10, 11, 12]);
goog.vec.mat4d.setRow(m0, 3, [13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
var v0 = [0, 0, 0, 0];
goog.vec.mat4d.getRow(m0, 0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.mat4d.getRow(m0, 1, v0);
assertElementsEquals([5, 6, 7, 8], v0);
goog.vec.mat4d.getRow(m0, 2, v0);
assertElementsEquals([9, 10, 11, 12], v0);
goog.vec.mat4d.getRow(m0, 3, v0);
assertElementsEquals([13, 14, 15, 16], v0);
}
function testSetGetRows() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.setRows(
m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
goog.vec.mat4d.getRows(m0, v0, v1, v2, v3);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([9, 10, 11, 12], v2);
assertElementsEquals([13, 14, 15, 16], v3);
}
function testMakeZero() {
var m0 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
goog.vec.mat4d.makeZero(m0);
assertElementsEquals(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
}
function testMakeIdentity() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.makeIdentity(m0);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], m0);
}
function testSetGetElement() {
var m0 = goog.vec.mat4d.create();
for (var r = 0; r < 4; r++) {
for (var c = 0; c < 4; c++) {
var value = c * 4 + r + 1;
goog.vec.mat4d.setElement(m0, r, c, value);
assertEquals(value, goog.vec.mat4d.getElement(m0, r, c));
}
}
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
}
function testAddMat() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
var m2 = goog.vec.mat4d.create();
goog.vec.mat4d.addMat(m0, m1, m2);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m2);
goog.vec.mat4d.addMat(m0, m1, m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m0);
}
function testSubMat() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
var m2 = goog.vec.mat4d.create();
goog.vec.mat4d.subMat(m0, m1, m2);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[-8, -8, -8, -8, -8, -8, -8, -8, 8, 8, 8, 8, 8, 8, 8, 8], m2);
goog.vec.mat4d.subMat(m1, m0, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[8, 8, 8, 8, 8, 8, 8, 8, -8, -8, -8, -8, -8, -8, -8, -8], m1);
}
function testMultScalar() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4d.create();
goog.vec.mat4d.multScalar(m0, 2, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32], m1);
goog.vec.mat4d.multScalar(m0, 5, m0);
assertElementsEquals(
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80], m0);
}
function testMultMat() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m2 = goog.vec.mat4d.create();
goog.vec.mat4d.multMat(m0, m1, m2);
assertElementsEquals(
[90, 100, 110, 120, 202, 228, 254, 280,
314, 356, 398, 440, 426, 484, 542, 600], m2);
goog.vec.mat4d.multScalar(m1, 2, m1);
goog.vec.mat4d.multMat(m1, m0, m1);
assertElementsEquals(
[180, 200, 220, 240, 404, 456, 508, 560,
628, 712, 796, 880, 852, 968, 1084, 1200], m1);
}
function testTranspose() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4d.create();
goog.vec.mat4d.transpose(m0, m1);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m1);
goog.vec.mat4d.transpose(m1, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
}
function testDeterminant() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertEquals(0, goog.vec.mat4d.determinant(m0));
assertElementsEquals(
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.mat4d.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
assertEquals(160, goog.vec.mat4d.determinant(m0));
assertElementsEquals(
[1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3], m0);
}
function testInvert() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertFalse(goog.vec.mat4d.invert(m0, m0));
assertElementsEquals(
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.mat4d.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
assertTrue(goog.vec.mat4d.invert(m0, m0));
assertElementsRoughlyEqual(
[-0.225, 0.025, 0.025, 0.275, 0.025, 0.025, 0.275, -0.225,
0.025, 0.275, -0.225, 0.025, 0.275, -0.225, 0.025, 0.025], m0,
goog.vec.EPSILON);
goog.vec.mat4d.makeScale(m0, .01, .01, .01);
assertTrue(goog.vec.mat4d.invert(m0, m0));
var m1 = goog.vec.mat4d.create();
goog.vec.mat4d.makeScale(m1, 100, 100, 100);
assertElementsEquals(m1, m0);
}
function testEquals() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4d.setFromMat4d(goog.vec.mat4d.create(), m0);
assertTrue(goog.vec.mat4d.equals(m0, m1));
assertTrue(goog.vec.mat4d.equals(m1, m0));
for (var i = 0; i < 16; i++) {
m1[i] = 18;
assertFalse(goog.vec.mat4d.equals(m0, m1));
assertFalse(goog.vec.mat4d.equals(m1, m0));
m1[i] = i + 1;
}
}
function testMultVec3() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.mat4d.multVec3(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([51, 58, 65], v1);
goog.vec.mat4d.multVec3(m0, v0, v0);
assertElementsEquals([51, 58, 65], v0);
}
function testMultVec3NoTranslate() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.mat4d.multVec3NoTranslate(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([38, 44, 50], v1);
goog.vec.mat4d.multVec3NoTranslate(m0, v0, v0);
assertElementsEquals([38, 44, 50], v0);
}
function testMultVec3Projective() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
var invw = 1 / 72;
goog.vec.mat4d.multVec3Projective(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals(
[51 * invw, 58 * invw, 65 * invw], v1);
goog.vec.mat4d.multVec3Projective(m0, v0, v0);
assertElementsEquals(
[51 * invw, 58 * invw, 65 * invw], v0);
}
function testMultVec4() {
var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3, 4];
var v1 = [0, 0, 0, 0];
goog.vec.mat4d.multVec4(m0, v0, v1);
assertElementsEquals([90, 100, 110, 120], v1);
goog.vec.mat4d.multVec4(m0, v0, v0);
assertElementsEquals([90, 100, 110, 120], v0);
}
function testSetValues() {
var a0 = goog.vec.mat4d.create();
assertElementsEquals(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
a0 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a0);
var a1 = goog.vec.mat4d.create();
goog.vec.mat4d.setDiagonalValues(a1, 1, 2, 3, 4);
assertElementsEquals(
[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], a1);
goog.vec.mat4d.setColumnValues(a1, 0, 2, 3, 4, 5);
goog.vec.mat4d.setColumnValues(a1, 1, 6, 7, 8, 9);
goog.vec.mat4d.setColumnValues(a1, 2, 10, 11, 12, 13);
goog.vec.mat4d.setColumnValues(a1, 3, 14, 15, 16, 1);
assertElementsEquals(
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1], a1);
goog.vec.mat4d.setRowValues(a1, 0, 1, 5, 9, 13);
goog.vec.mat4d.setRowValues(a1, 1, 2, 6, 10, 14);
goog.vec.mat4d.setRowValues(a1, 2, 3, 7, 11, 15);
goog.vec.mat4d.setRowValues(a1, 3, 4, 8, 12, 16);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a1);
}
function testMakeTranslate() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.makeTranslate(m0, 3, 4, 5);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
}
function testMakeScale() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.makeScale(m0, 3, 4, 5);
assertElementsEquals(
[3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
}
function testMakeRotate() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.makeRotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
var m1 = goog.vec.mat4d.create();
goog.vec.mat4d.makeRotate(m1, -Math.PI / 4, 0, 0, 1);
goog.vec.mat4d.multMat(m0, m1, m1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0, 0,
-0.7071068, 0.7071068, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1],
m1, goog.vec.EPSILON);
}
function testMakeRotateX() {
var m0 = goog.vec.mat4d.create();
var m1 = goog.vec.mat4d.create()
goog.vec.mat4d.makeRotateX(m0, Math.PI / 7);
goog.vec.mat4d.makeRotate(m1, Math.PI / 7, 1, 0, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateY() {
var m0 = goog.vec.mat4d.create();
var m1 = goog.vec.mat4d.create()
goog.vec.mat4d.makeRotateY(m0, Math.PI / 7);
goog.vec.mat4d.makeRotate(m1, Math.PI / 7, 0, 1, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateZ() {
var m0 = goog.vec.mat4d.create();
var m1 = goog.vec.mat4d.create()
goog.vec.mat4d.makeRotateZ(m0, Math.PI / 7);
goog.vec.mat4d.makeRotate(m1, Math.PI / 7, 0, 0, 1);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testTranslate() {
var m0 = goog.vec.mat4d.makeIdentity(goog.vec.mat4d.create());
goog.vec.mat4d.translate(m0, 3, 4, 5);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
goog.vec.mat4d.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
var m1 = goog.vec.mat4d.create();
goog.vec.mat4d.makeTranslate(m1, 5, 6, 7);
var m2 = goog.vec.mat4d.create();
goog.vec.mat4d.multMat(m0, m1, m2);
goog.vec.mat4d.translate(m0, 5, 6, 7);
assertElementsEquals(m2, m0);
}
function testScale() {
var m0 = goog.vec.mat4d.makeIdentity(goog.vec.mat4d.create());
goog.vec.mat4d.scale(m0, 3, 4, 5);
assertElementsEquals([3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
}
function testRotate() {
var m0 = goog.vec.mat4d.makeIdentity(goog.vec.mat4d.create());
goog.vec.mat4d.rotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
goog.vec.mat4d.rotate(m0, -Math.PI / 4, 0, 0, 1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0, 0,
-0.7071068, 0.7071068, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1],
m0, goog.vec.EPSILON);
}
function testRotateX() {
var m0 = goog.vec.mat4d.create();
var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d)
goog.vec.mat4d.makeRotateX(m0, Math.PI / 7);
goog.vec.mat4d.multMat(m1, m0, m0);
goog.vec.mat4d.rotateX(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateY() {
var m0 = goog.vec.mat4d.create();
var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d)
goog.vec.mat4d.makeRotateY(m0, Math.PI / 7);
goog.vec.mat4d.multMat(m1, m0, m0);
goog.vec.mat4d.rotateY(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateZ() {
var m0 = goog.vec.mat4d.create();
var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d)
goog.vec.mat4d.makeRotateZ(m0, Math.PI / 7);
goog.vec.mat4d.multMat(m1, m0, m0);
goog.vec.mat4d.rotateZ(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testGetTranslation() {
var mat = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d);
var translation = goog.vec.vec3d.create();
goog.vec.mat4d.getTranslation(mat, translation);
assertElementsRoughlyEqual(
[0.59465038776, 0.413479506969, 0.0663217827677],
translation, goog.vec.EPSILON);
}
function testMakeFrustum() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.makeFrustum(m0, -1, 2, -2, 1, .1, 1.1);
assertElementsRoughlyEqual(
[0.06666666, 0, 0, 0,
0, 0.06666666, 0, 0,
0.33333333, -0.33333333, -1.2, -1,
0, 0, -0.22, 0], m0, goog.vec.EPSILON);
}
function testMakePerspective() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.makePerspective(m0, 90 * Math.PI / 180, 2, 0.1, 1.1);
assertElementsRoughlyEqual(
[0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1.2, -1, 0, 0, -0.22, 0],
m0, goog.vec.EPSILON);
}
function testMakeOrtho() {
var m0 = goog.vec.mat4d.create();
goog.vec.mat4d.makeOrtho(m0, -1, 2, -2, 1, 0.1, 1.1);
assertElementsRoughlyEqual(
[0.6666666, 0, 0, 0,
0, 0.6666666, 0, 0,
0, 0, -2, 0,
-0.333333, 0.3333333, -1.2, 1], m0, goog.vec.EPSILON);
}
function testMakeEulerZXZ() {
var m0 = goog.vec.mat4d.create();
var roll = 0.200982 * 2 * Math.PI;
var tilt = 0.915833 * Math.PI;
var yaw = 0.839392 * 2 * Math.PI;
goog.vec.mat4d.makeRotate(m0, roll, 0, 0, 1);
goog.vec.mat4d.rotate(m0, tilt, 1, 0, 0);
goog.vec.mat4d.rotate(m0, yaw, 0, 0, 1);
var m1 = goog.vec.mat4d.create();
goog.vec.mat4d.makeEulerZXZ(m1, roll, tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.mat4d.toEulerZXZ(m0, euler);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
// Test negative tilt now.
goog.vec.mat4d.makeRotate(m0, roll, 0, 0, 1);
goog.vec.mat4d.rotate(m0, -tilt, 1, 0, 0);
goog.vec.mat4d.rotate(m0, yaw, 0, 0, 1);
goog.vec.mat4d.makeEulerZXZ(m1, roll, -tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.mat4d.toEulerZXZ(m0, euler, true);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(-tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
}
function testEulerZXZExtrema() {
var m0 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
[1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1]);
var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
var euler = [0, 0, 0];
goog.vec.mat4d.toEulerZXZ(m0, euler);
assertElementsRoughlyEqual(
[Math.PI, Math.PI / 2, Math.PI], euler, goog.vec.EPSILON);
goog.vec.mat4d.makeEulerZXZ(m1, euler[0], euler[1], euler[2]);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testLookAt() {
var viewMatrix = goog.vec.mat4d.create();
goog.vec.mat4d.makeLookAt(
viewMatrix, [0, 0, 0], [1, 0, 0], [0, 1, 0]);
assertElementsRoughlyEqual(
[0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], viewMatrix,
goog.vec.EPSILON);
}
function testToLookAt() {
// This test does not use the default precision goog.vec.EPSILON due to
// precision issues in some browsers leading to flaky tests.
var EPSILON = 1e-4;
var eyeExp = [0, 0, 0];
var fwdExp = [1, 0, 0];
var upExp = [0, 1, 0];
var centerExp = [0, 0, 0];
goog.vec.vec3d.add(eyeExp, fwdExp, centerExp);
var view = goog.vec.mat4d.create();
goog.vec.mat4d.makeLookAt(view, eyeExp, centerExp, upExp);
var eyeRes = [0, 0, 0];
var fwdRes = [0, 0, 0];
var upRes = [0, 0, 0];
goog.vec.mat4d.toLookAt(view, eyeRes, fwdRes, upRes);
assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
assertElementsRoughlyEqual(upExp, upRes, EPSILON);
}
function testLookAtDecomposition() {
// This test does not use the default precision goog.vec.EPSILON due to
// precision issues in some browsers leading to flaky tests.
var EPSILON = 1e-4;
var viewExp = goog.vec.mat4d.create();
var viewRes = goog.vec.mat4d.create();
// Get a valid set of random vectors eye, forward, up by decomposing
// a random matrix into a set of lookAt vectors.
var tmp = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d);
var eyeExp = [0, 0, 0];
var fwdExp = [0, 0, 0];
var upExp = [0, 0, 0];
var centerExp = [0, 0, 0];
// Project the random matrix into a real modelview matrix.
goog.vec.mat4d.toLookAt(tmp, eyeExp, fwdExp, upExp);
goog.vec.vec3d.add(eyeExp, fwdExp, centerExp);
// Compute the expected modelview matrix from a set of valid random vectors.
goog.vec.mat4d.makeLookAt(viewExp, eyeExp, centerExp, upExp);
var eyeRes = [0, 0, 0];
var fwdRes = [0, 0, 0];
var upRes = [0, 0, 0];
var centerRes = [0, 0, 0];
goog.vec.mat4d.toLookAt(viewExp, eyeRes, fwdRes, upRes);
goog.vec.vec3d.add(eyeRes, fwdRes, centerRes);
goog.vec.mat4d.makeLookAt(viewRes, eyeRes, centerRes, upRes);
assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
assertElementsRoughlyEqual(upExp, upRes, EPSILON);
assertElementsRoughlyEqual(viewExp, viewRes, EPSILON);
}
</script>
</body>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,738 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to mat4d_test.html by running: //
// swap_type.sh mat4f_test.html > mat4d_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.mat4f</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.mat4f');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
var randommat4f = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
0.8025078773498535,
0.7559120655059814,
0.15274643898010254,
0.19196106493473053,
0.0890120416879654,
0.15422114729881287,
0.09754583984613419,
0.44862601161003113,
0.9196512699127197,
0.5310639142990112,
0.8962187170982361,
0.280601441860199,
0.594650387763977,
0.4134795069694519,
0.06632178276777267,
0.8837796449661255);
function testCreate() {
var m = goog.vec.mat4f.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m);
}
function testSet() {
var m0 = goog.vec.mat4f.create();
var m1 = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(),
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
goog.vec.mat4f.setFromArray(m0, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
goog.vec.mat4f.setFromValues(
m0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
assertElementsEquals(
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], m0);
}
function testSetDiagonal() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.setDiagonalValues(m0, 1, 2, 3, 4);
assertElementsEquals(
[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], m0);
goog.vec.mat4f.setDiagonal(m0, [4, 5, 6, 7]);
assertElementsEquals(
[4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0, 7], m0);
}
function testGetDiagonal() {
var v0 = goog.vec.vec4f.create();
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.setFromArray(
m0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
goog.vec.mat4f.getDiagonal(m0, v0);
assertElementsEquals([0, 5, 10, 15], v0);
goog.vec.vec4f.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4f.getDiagonal(m0, v0, 1);
assertElementsEquals([4, 9, 14, 0], v0);
goog.vec.vec4f.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4f.getDiagonal(m0, v0, 2);
assertElementsEquals([8, 13, 0, 0], v0);
goog.vec.vec4f.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4f.getDiagonal(m0, v0, 3);
assertElementsEquals([12, 0, 0, 0], v0);
goog.vec.vec4f.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4f.getDiagonal(m0, v0, 4);
assertElementsEquals([0, 0, 0, 0], v0);
goog.vec.vec4f.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4f.getDiagonal(m0, v0, -1);
assertElementsEquals([1, 6, 11, 0], v0);
goog.vec.vec4f.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4f.getDiagonal(m0, v0, -2);
assertElementsEquals([2, 7, 0, 0], v0);
goog.vec.vec4f.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4f.getDiagonal(m0, v0, -3);
assertElementsEquals([3, 0, 0, 0], v0);
goog.vec.vec4f.setFromArray(v0, [0, 0, 0, 0]);
goog.vec.mat4f.getDiagonal(m0, v0, -4);
assertElementsEquals([0, 0, 0, 0], v0);
}
function testSetGetColumn() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.setColumn(m0, 0, [1, 2, 3, 4]);
goog.vec.mat4f.setColumn(m0, 1, [5, 6, 7, 8]);
goog.vec.mat4f.setColumn(m0, 2, [9, 10, 11, 12]);
goog.vec.mat4f.setColumn(m0, 3, [13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
var v0 = [0, 0, 0, 0];
goog.vec.mat4f.getColumn(m0, 0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.mat4f.getColumn(m0, 1, v0);
assertElementsEquals([5, 6, 7, 8], v0);
goog.vec.mat4f.getColumn(m0, 2, v0);
assertElementsEquals([9, 10, 11, 12], v0);
goog.vec.mat4f.getColumn(m0, 3, v0);
assertElementsEquals([13, 14, 15, 16], v0);
}
function testSetGetColumns() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.setColumns(
m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
goog.vec.mat4f.getColumns(m0, v0, v1, v2, v3);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([9, 10, 11, 12], v2);
assertElementsEquals([13, 14, 15, 16], v3);
}
function testSetGetRow() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.setRow(m0, 0, [1, 2, 3, 4]);
goog.vec.mat4f.setRow(m0, 1, [5, 6, 7, 8]);
goog.vec.mat4f.setRow(m0, 2, [9, 10, 11, 12]);
goog.vec.mat4f.setRow(m0, 3, [13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
var v0 = [0, 0, 0, 0];
goog.vec.mat4f.getRow(m0, 0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.mat4f.getRow(m0, 1, v0);
assertElementsEquals([5, 6, 7, 8], v0);
goog.vec.mat4f.getRow(m0, 2, v0);
assertElementsEquals([9, 10, 11, 12], v0);
goog.vec.mat4f.getRow(m0, 3, v0);
assertElementsEquals([13, 14, 15, 16], v0);
}
function testSetGetRows() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.setRows(
m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
goog.vec.mat4f.getRows(m0, v0, v1, v2, v3);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([9, 10, 11, 12], v2);
assertElementsEquals([13, 14, 15, 16], v3);
}
function testMakeZero() {
var m0 = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(),
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
goog.vec.mat4f.makeZero(m0);
assertElementsEquals(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
}
function testMakeIdentity() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.makeIdentity(m0);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], m0);
}
function testSetGetElement() {
var m0 = goog.vec.mat4f.create();
for (var r = 0; r < 4; r++) {
for (var c = 0; c < 4; c++) {
var value = c * 4 + r + 1;
goog.vec.mat4f.setElement(m0, r, c, value);
assertEquals(value, goog.vec.mat4f.getElement(m0, r, c));
}
}
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
}
function testAddMat() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
var m2 = goog.vec.mat4f.create();
goog.vec.mat4f.addMat(m0, m1, m2);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m2);
goog.vec.mat4f.addMat(m0, m1, m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m0);
}
function testSubMat() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
var m2 = goog.vec.mat4f.create();
goog.vec.mat4f.subMat(m0, m1, m2);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[-8, -8, -8, -8, -8, -8, -8, -8, 8, 8, 8, 8, 8, 8, 8, 8], m2);
goog.vec.mat4f.subMat(m1, m0, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[8, 8, 8, 8, 8, 8, 8, 8, -8, -8, -8, -8, -8, -8, -8, -8], m1);
}
function testMultScalar() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4f.create();
goog.vec.mat4f.multScalar(m0, 2, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32], m1);
goog.vec.mat4f.multScalar(m0, 5, m0);
assertElementsEquals(
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80], m0);
}
function testMultMat() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m2 = goog.vec.mat4f.create();
goog.vec.mat4f.multMat(m0, m1, m2);
assertElementsEquals(
[90, 100, 110, 120, 202, 228, 254, 280,
314, 356, 398, 440, 426, 484, 542, 600], m2);
goog.vec.mat4f.multScalar(m1, 2, m1);
goog.vec.mat4f.multMat(m1, m0, m1);
assertElementsEquals(
[180, 200, 220, 240, 404, 456, 508, 560,
628, 712, 796, 880, 852, 968, 1084, 1200], m1);
}
function testTranspose() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4f.create();
goog.vec.mat4f.transpose(m0, m1);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m1);
goog.vec.mat4f.transpose(m1, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
}
function testDeterminant() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertEquals(0, goog.vec.mat4f.determinant(m0));
assertElementsEquals(
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.mat4f.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
assertEquals(160, goog.vec.mat4f.determinant(m0));
assertElementsEquals(
[1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3], m0);
}
function testInvert() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertFalse(goog.vec.mat4f.invert(m0, m0));
assertElementsEquals(
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.mat4f.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
assertTrue(goog.vec.mat4f.invert(m0, m0));
assertElementsRoughlyEqual(
[-0.225, 0.025, 0.025, 0.275, 0.025, 0.025, 0.275, -0.225,
0.025, 0.275, -0.225, 0.025, 0.275, -0.225, 0.025, 0.025], m0,
goog.vec.EPSILON);
goog.vec.mat4f.makeScale(m0, .01, .01, .01);
assertTrue(goog.vec.mat4f.invert(m0, m0));
var m1 = goog.vec.mat4f.create();
goog.vec.mat4f.makeScale(m1, 100, 100, 100);
assertElementsEquals(m1, m0);
}
function testEquals() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.mat4f.setFromMat4f(goog.vec.mat4f.create(), m0);
assertTrue(goog.vec.mat4f.equals(m0, m1));
assertTrue(goog.vec.mat4f.equals(m1, m0));
for (var i = 0; i < 16; i++) {
m1[i] = 18;
assertFalse(goog.vec.mat4f.equals(m0, m1));
assertFalse(goog.vec.mat4f.equals(m1, m0));
m1[i] = i + 1;
}
}
function testMultVec3() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.mat4f.multVec3(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([51, 58, 65], v1);
goog.vec.mat4f.multVec3(m0, v0, v0);
assertElementsEquals([51, 58, 65], v0);
}
function testMultVec3NoTranslate() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.mat4f.multVec3NoTranslate(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([38, 44, 50], v1);
goog.vec.mat4f.multVec3NoTranslate(m0, v0, v0);
assertElementsEquals([38, 44, 50], v0);
}
function testMultVec3Projective() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
var invw = 1 / 72;
goog.vec.mat4f.multVec3Projective(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals(
[51 * invw, 58 * invw, 65 * invw], v1);
goog.vec.mat4f.multVec3Projective(m0, v0, v0);
assertElementsEquals(
[51 * invw, 58 * invw, 65 * invw], v0);
}
function testMultVec4() {
var m0 = goog.vec.mat4f.setFromValues(goog.vec.mat4f.create(),
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3, 4];
var v1 = [0, 0, 0, 0];
goog.vec.mat4f.multVec4(m0, v0, v1);
assertElementsEquals([90, 100, 110, 120], v1);
goog.vec.mat4f.multVec4(m0, v0, v0);
assertElementsEquals([90, 100, 110, 120], v0);
}
function testSetValues() {
var a0 = goog.vec.mat4f.create();
assertElementsEquals(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
a0 = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(),
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a0);
var a1 = goog.vec.mat4f.create();
goog.vec.mat4f.setDiagonalValues(a1, 1, 2, 3, 4);
assertElementsEquals(
[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], a1);
goog.vec.mat4f.setColumnValues(a1, 0, 2, 3, 4, 5);
goog.vec.mat4f.setColumnValues(a1, 1, 6, 7, 8, 9);
goog.vec.mat4f.setColumnValues(a1, 2, 10, 11, 12, 13);
goog.vec.mat4f.setColumnValues(a1, 3, 14, 15, 16, 1);
assertElementsEquals(
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1], a1);
goog.vec.mat4f.setRowValues(a1, 0, 1, 5, 9, 13);
goog.vec.mat4f.setRowValues(a1, 1, 2, 6, 10, 14);
goog.vec.mat4f.setRowValues(a1, 2, 3, 7, 11, 15);
goog.vec.mat4f.setRowValues(a1, 3, 4, 8, 12, 16);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a1);
}
function testMakeTranslate() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.makeTranslate(m0, 3, 4, 5);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
}
function testMakeScale() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.makeScale(m0, 3, 4, 5);
assertElementsEquals(
[3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
}
function testMakeRotate() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.makeRotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
var m1 = goog.vec.mat4f.create();
goog.vec.mat4f.makeRotate(m1, -Math.PI / 4, 0, 0, 1);
goog.vec.mat4f.multMat(m0, m1, m1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0, 0,
-0.7071068, 0.7071068, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1],
m1, goog.vec.EPSILON);
}
function testMakeRotateX() {
var m0 = goog.vec.mat4f.create();
var m1 = goog.vec.mat4f.create()
goog.vec.mat4f.makeRotateX(m0, Math.PI / 7);
goog.vec.mat4f.makeRotate(m1, Math.PI / 7, 1, 0, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateY() {
var m0 = goog.vec.mat4f.create();
var m1 = goog.vec.mat4f.create()
goog.vec.mat4f.makeRotateY(m0, Math.PI / 7);
goog.vec.mat4f.makeRotate(m1, Math.PI / 7, 0, 1, 0);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testMakeRotateZ() {
var m0 = goog.vec.mat4f.create();
var m1 = goog.vec.mat4f.create()
goog.vec.mat4f.makeRotateZ(m0, Math.PI / 7);
goog.vec.mat4f.makeRotate(m1, Math.PI / 7, 0, 0, 1);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testTranslate() {
var m0 = goog.vec.mat4f.makeIdentity(goog.vec.mat4f.create());
goog.vec.mat4f.translate(m0, 3, 4, 5);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
goog.vec.mat4f.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
var m1 = goog.vec.mat4f.create();
goog.vec.mat4f.makeTranslate(m1, 5, 6, 7);
var m2 = goog.vec.mat4f.create();
goog.vec.mat4f.multMat(m0, m1, m2);
goog.vec.mat4f.translate(m0, 5, 6, 7);
assertElementsEquals(m2, m0);
}
function testScale() {
var m0 = goog.vec.mat4f.makeIdentity(goog.vec.mat4f.create());
goog.vec.mat4f.scale(m0, 3, 4, 5);
assertElementsEquals([3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
}
function testRotate() {
var m0 = goog.vec.mat4f.makeIdentity(goog.vec.mat4f.create());
goog.vec.mat4f.rotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
goog.vec.mat4f.rotate(m0, -Math.PI / 4, 0, 0, 1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0, 0,
-0.7071068, 0.7071068, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1],
m0, goog.vec.EPSILON);
}
function testRotateX() {
var m0 = goog.vec.mat4f.create();
var m1 = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(), randommat4f)
goog.vec.mat4f.makeRotateX(m0, Math.PI / 7);
goog.vec.mat4f.multMat(m1, m0, m0);
goog.vec.mat4f.rotateX(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateY() {
var m0 = goog.vec.mat4f.create();
var m1 = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(), randommat4f)
goog.vec.mat4f.makeRotateY(m0, Math.PI / 7);
goog.vec.mat4f.multMat(m1, m0, m0);
goog.vec.mat4f.rotateY(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testRotateZ() {
var m0 = goog.vec.mat4f.create();
var m1 = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(), randommat4f)
goog.vec.mat4f.makeRotateZ(m0, Math.PI / 7);
goog.vec.mat4f.multMat(m1, m0, m0);
goog.vec.mat4f.rotateZ(m1, Math.PI / 7);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testGetTranslation() {
var mat = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(), randommat4f);
var translation = goog.vec.vec3f.create();
goog.vec.mat4f.getTranslation(mat, translation);
assertElementsRoughlyEqual(
[0.59465038776, 0.413479506969, 0.0663217827677],
translation, goog.vec.EPSILON);
}
function testMakeFrustum() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.makeFrustum(m0, -1, 2, -2, 1, .1, 1.1);
assertElementsRoughlyEqual(
[0.06666666, 0, 0, 0,
0, 0.06666666, 0, 0,
0.33333333, -0.33333333, -1.2, -1,
0, 0, -0.22, 0], m0, goog.vec.EPSILON);
}
function testMakePerspective() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.makePerspective(m0, 90 * Math.PI / 180, 2, 0.1, 1.1);
assertElementsRoughlyEqual(
[0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1.2, -1, 0, 0, -0.22, 0],
m0, goog.vec.EPSILON);
}
function testMakeOrtho() {
var m0 = goog.vec.mat4f.create();
goog.vec.mat4f.makeOrtho(m0, -1, 2, -2, 1, 0.1, 1.1);
assertElementsRoughlyEqual(
[0.6666666, 0, 0, 0,
0, 0.6666666, 0, 0,
0, 0, -2, 0,
-0.333333, 0.3333333, -1.2, 1], m0, goog.vec.EPSILON);
}
function testMakeEulerZXZ() {
var m0 = goog.vec.mat4f.create();
var roll = 0.200982 * 2 * Math.PI;
var tilt = 0.915833 * Math.PI;
var yaw = 0.839392 * 2 * Math.PI;
goog.vec.mat4f.makeRotate(m0, roll, 0, 0, 1);
goog.vec.mat4f.rotate(m0, tilt, 1, 0, 0);
goog.vec.mat4f.rotate(m0, yaw, 0, 0, 1);
var m1 = goog.vec.mat4f.create();
goog.vec.mat4f.makeEulerZXZ(m1, roll, tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.mat4f.toEulerZXZ(m0, euler);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
// Test negative tilt now.
goog.vec.mat4f.makeRotate(m0, roll, 0, 0, 1);
goog.vec.mat4f.rotate(m0, -tilt, 1, 0, 0);
goog.vec.mat4f.rotate(m0, yaw, 0, 0, 1);
goog.vec.mat4f.makeEulerZXZ(m1, roll, -tilt, yaw);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.mat4f.toEulerZXZ(m0, euler, true);
assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
assertRoughlyEquals(-tilt, euler[1], goog.vec.EPSILON);
assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
}
function testEulerZXZExtrema() {
var m0 = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(),
[1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1]);
var m1 = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(),
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
var euler = [0, 0, 0];
goog.vec.mat4f.toEulerZXZ(m0, euler);
assertElementsRoughlyEqual(
[Math.PI, Math.PI / 2, Math.PI], euler, goog.vec.EPSILON);
goog.vec.mat4f.makeEulerZXZ(m1, euler[0], euler[1], euler[2]);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testLookAt() {
var viewMatrix = goog.vec.mat4f.create();
goog.vec.mat4f.makeLookAt(
viewMatrix, [0, 0, 0], [1, 0, 0], [0, 1, 0]);
assertElementsRoughlyEqual(
[0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], viewMatrix,
goog.vec.EPSILON);
}
function testToLookAt() {
// This test does not use the default precision goog.vec.EPSILON due to
// precision issues in some browsers leading to flaky tests.
var EPSILON = 1e-4;
var eyeExp = [0, 0, 0];
var fwdExp = [1, 0, 0];
var upExp = [0, 1, 0];
var centerExp = [0, 0, 0];
goog.vec.vec3f.add(eyeExp, fwdExp, centerExp);
var view = goog.vec.mat4f.create();
goog.vec.mat4f.makeLookAt(view, eyeExp, centerExp, upExp);
var eyeRes = [0, 0, 0];
var fwdRes = [0, 0, 0];
var upRes = [0, 0, 0];
goog.vec.mat4f.toLookAt(view, eyeRes, fwdRes, upRes);
assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
assertElementsRoughlyEqual(upExp, upRes, EPSILON);
}
function testLookAtDecomposition() {
// This test does not use the default precision goog.vec.EPSILON due to
// precision issues in some browsers leading to flaky tests.
var EPSILON = 1e-4;
var viewExp = goog.vec.mat4f.create();
var viewRes = goog.vec.mat4f.create();
// Get a valid set of random vectors eye, forward, up by decomposing
// a random matrix into a set of lookAt vectors.
var tmp = goog.vec.mat4f.setFromArray(goog.vec.mat4f.create(), randommat4f);
var eyeExp = [0, 0, 0];
var fwdExp = [0, 0, 0];
var upExp = [0, 0, 0];
var centerExp = [0, 0, 0];
// Project the random matrix into a real modelview matrix.
goog.vec.mat4f.toLookAt(tmp, eyeExp, fwdExp, upExp);
goog.vec.vec3f.add(eyeExp, fwdExp, centerExp);
// Compute the expected modelview matrix from a set of valid random vectors.
goog.vec.mat4f.makeLookAt(viewExp, eyeExp, centerExp, upExp);
var eyeRes = [0, 0, 0];
var fwdRes = [0, 0, 0];
var upRes = [0, 0, 0];
var centerRes = [0, 0, 0];
goog.vec.mat4f.toLookAt(viewExp, eyeRes, fwdRes, upRes);
goog.vec.vec3f.add(eyeRes, fwdRes, centerRes);
goog.vec.mat4f.makeLookAt(viewRes, eyeRes, centerRes, upRes);
assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
assertElementsRoughlyEqual(upExp, upRes, EPSILON);
assertElementsRoughlyEqual(viewExp, viewRes, EPSILON);
}
</script>
</body>
@@ -0,0 +1,720 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview WARNING: DEPRECATED. Use Mat3 instead.
* Implements 3x3 matrices and their related functions which are
* compatible with WebGL. The API is structured to avoid unnecessary memory
* allocations. The last parameter will typically be the output vector and
* an object can be both an input and output parameter to all methods except
* where noted. Matrix operations follow the mathematical form when multiplying
* vectors as follows: resultVec = matrix * vec.
*
*/
goog.provide('goog.vec.Matrix3');
/**
* @typedef {goog.vec.ArrayType}
*/
goog.vec.Matrix3.Type;
/**
* Creates the array representation of a 3x3 matrix. The use of the array
* directly eliminates any overhead associated with the class representation
* defined above. The returned matrix is cleared to all zeros.
*
* @return {goog.vec.Matrix3.Type} The new, nine element array.
*/
goog.vec.Matrix3.create = function() {
return new Float32Array(9);
};
/**
* Creates the array representation of a 3x3 matrix. The use of the array
* directly eliminates any overhead associated with the class representation
* defined above. The returned matrix is initialized with the identity.
*
* @return {goog.vec.Matrix3.Type} The new, nine element array.
*/
goog.vec.Matrix3.createIdentity = function() {
var mat = goog.vec.Matrix3.create();
mat[0] = mat[4] = mat[8] = 1;
return mat;
};
/**
* Creates a 3x3 matrix initialized from the given array.
*
* @param {goog.vec.ArrayType} matrix The array containing the
* matrix values in column major order.
* @return {goog.vec.Matrix3.Type} The new, nine element array.
*/
goog.vec.Matrix3.createFromArray = function(matrix) {
var newMatrix = goog.vec.Matrix3.create();
goog.vec.Matrix3.setFromArray(newMatrix, matrix);
return newMatrix;
};
/**
* Creates a 3x3 matrix initialized from the given values.
*
* @param {number} v00 The values at (0, 0).
* @param {number} v10 The values at (1, 0).
* @param {number} v20 The values at (2, 0).
* @param {number} v01 The values at (0, 1).
* @param {number} v11 The values at (1, 1).
* @param {number} v21 The values at (2, 1).
* @param {number} v02 The values at (0, 2).
* @param {number} v12 The values at (1, 2).
* @param {number} v22 The values at (2, 2).
* @return {goog.vec.Matrix3.Type} The new, nine element array.
*/
goog.vec.Matrix3.createFromValues = function(
v00, v10, v20, v01, v11, v21, v02, v12, v22) {
var newMatrix = goog.vec.Matrix3.create();
goog.vec.Matrix3.setFromValues(
newMatrix, v00, v10, v20, v01, v11, v21, v02, v12, v22);
return newMatrix;
};
/**
* Creates a clone of a 3x3 matrix.
*
* @param {goog.vec.Matrix3.Type} matrix The source 3x3 matrix.
* @return {goog.vec.Matrix3.Type} The new 3x3 element matrix.
*/
goog.vec.Matrix3.clone =
goog.vec.Matrix3.createFromArray;
/**
* Retrieves the element at the requested row and column.
*
* @param {goog.vec.ArrayType} mat The matrix containing the
* value to retrieve.
* @param {number} row The row index.
* @param {number} column The column index.
* @return {number} The element value at the requested row, column indices.
*/
goog.vec.Matrix3.getElement = function(mat, row, column) {
return mat[row + column * 3];
};
/**
* Sets the element at the requested row and column.
*
* @param {goog.vec.ArrayType} mat The matrix containing the
* value to retrieve.
* @param {number} row The row index.
* @param {number} column The column index.
* @param {number} value The value to set at the requested row, column.
*/
goog.vec.Matrix3.setElement = function(mat, row, column, value) {
mat[row + column * 3] = value;
};
/**
* Initializes the matrix from the set of values. Note the values supplied are
* in column major order.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* values.
* @param {number} v00 The values at (0, 0).
* @param {number} v10 The values at (1, 0).
* @param {number} v20 The values at (2, 0).
* @param {number} v01 The values at (0, 1).
* @param {number} v11 The values at (1, 1).
* @param {number} v21 The values at (2, 1).
* @param {number} v02 The values at (0, 2).
* @param {number} v12 The values at (1, 2).
* @param {number} v22 The values at (2, 2).
*/
goog.vec.Matrix3.setFromValues = function(
mat, v00, v10, v20, v01, v11, v21, v02, v12, v22) {
mat[0] = v00;
mat[1] = v10;
mat[2] = v20;
mat[3] = v01;
mat[4] = v11;
mat[5] = v21;
mat[6] = v02;
mat[7] = v12;
mat[8] = v22;
};
/**
* Sets the matrix from the array of values stored in column major order.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* values.
* @param {goog.vec.ArrayType} values The column major ordered
* array of values to store in the matrix.
*/
goog.vec.Matrix3.setFromArray = function(mat, values) {
mat[0] = values[0];
mat[1] = values[1];
mat[2] = values[2];
mat[3] = values[3];
mat[4] = values[4];
mat[5] = values[5];
mat[6] = values[6];
mat[7] = values[7];
mat[8] = values[8];
};
/**
* Sets the matrix from the array of values stored in row major order.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* values.
* @param {goog.vec.ArrayType} values The row major ordered array
* of values to store in the matrix.
*/
goog.vec.Matrix3.setFromRowMajorArray = function(mat, values) {
mat[0] = values[0];
mat[1] = values[3];
mat[2] = values[6];
mat[3] = values[1];
mat[4] = values[4];
mat[5] = values[7];
mat[6] = values[2];
mat[7] = values[5];
mat[8] = values[8];
};
/**
* Sets the diagonal values of the matrix from the given values.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* values.
* @param {number} v00 The values for (0, 0).
* @param {number} v11 The values for (1, 1).
* @param {number} v22 The values for (2, 2).
*/
goog.vec.Matrix3.setDiagonalValues = function(mat, v00, v11, v22) {
mat[0] = v00;
mat[4] = v11;
mat[8] = v22;
};
/**
* Sets the diagonal values of the matrix from the given vector.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* values.
* @param {goog.vec.ArrayType} vec The vector containing the
* values.
*/
goog.vec.Matrix3.setDiagonal = function(mat, vec) {
mat[0] = vec[0];
mat[4] = vec[1];
mat[8] = vec[2];
};
/**
* Sets the specified column with the supplied values.
*
* @param {goog.vec.ArrayType} mat The matrix to recieve the
* values.
* @param {number} column The column index to set the values on.
* @param {number} v0 The value for row 0.
* @param {number} v1 The value for row 1.
* @param {number} v2 The value for row 2.
*/
goog.vec.Matrix3.setColumnValues = function(
mat, column, v0, v1, v2) {
var i = column * 3;
mat[i] = v0;
mat[i + 1] = v1;
mat[i + 2] = v2;
};
/**
* Sets the specified column with the value from the supplied array.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* values.
* @param {number} column The column index to set the values on.
* @param {goog.vec.ArrayType} vec The vector elements for the
* column.
*/
goog.vec.Matrix3.setColumn = function(mat, column, vec) {
var i = column * 3;
mat[i] = vec[0];
mat[i + 1] = vec[1];
mat[i + 2] = vec[2];
};
/**
* Retrieves the specified column from the matrix into the given vector
* array.
*
* @param {goog.vec.ArrayType} mat The matrix supplying the
* values.
* @param {number} column The column to get the values from.
* @param {goog.vec.ArrayType} vec The vector elements to receive
* the column.
*/
goog.vec.Matrix3.getColumn = function(mat, column, vec) {
var i = column * 3;
vec[0] = mat[i];
vec[1] = mat[i + 1];
vec[2] = mat[i + 2];
};
/**
* Sets the columns of the matrix from the set of vector elements.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* values.
* @param {goog.vec.ArrayType} vec0 The values for column 0.
* @param {goog.vec.ArrayType} vec1 The values for column 1.
* @param {goog.vec.ArrayType} vec2 The values for column 2.
*/
goog.vec.Matrix3.setColumns = function(
mat, vec0, vec1, vec2) {
goog.vec.Matrix3.setColumn(mat, 0, vec0);
goog.vec.Matrix3.setColumn(mat, 1, vec1);
goog.vec.Matrix3.setColumn(mat, 2, vec2);
};
/**
* Retrieves the column values from the given matrix into the given vector
* elements.
*
* @param {goog.vec.ArrayType} mat The matrix containing the
* columns to retrieve.
* @param {goog.vec.ArrayType} vec0 The vector elements to receive
* column 0.
* @param {goog.vec.ArrayType} vec1 The vector elements to receive
* column 1.
* @param {goog.vec.ArrayType} vec2 The vector elements to receive
* column 2.
*/
goog.vec.Matrix3.getColumns = function(
mat, vec0, vec1, vec2) {
goog.vec.Matrix3.getColumn(mat, 0, vec0);
goog.vec.Matrix3.getColumn(mat, 1, vec1);
goog.vec.Matrix3.getColumn(mat, 2, vec2);
};
/**
* Sets the row values from the supplied values.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* values.
* @param {number} row The index of the row to receive the values.
* @param {number} v0 The value for column 0.
* @param {number} v1 The value for column 1.
* @param {number} v2 The value for column 2.
*/
goog.vec.Matrix3.setRowValues = function(mat, row, v0, v1, v2) {
mat[row] = v0;
mat[row + 3] = v1;
mat[row + 6] = v2;
};
/**
* Sets the row values from the supplied vector.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* row values.
* @param {number} row The index of the row.
* @param {goog.vec.ArrayType} vec The vector containing the values.
*/
goog.vec.Matrix3.setRow = function(mat, row, vec) {
mat[row] = vec[0];
mat[row + 3] = vec[1];
mat[row + 6] = vec[2];
};
/**
* Retrieves the row values into the given vector.
*
* @param {goog.vec.ArrayType} mat The matrix supplying the
* values.
* @param {number} row The index of the row supplying the values.
* @param {goog.vec.ArrayType} vec The vector to receive the row.
*/
goog.vec.Matrix3.getRow = function(mat, row, vec) {
vec[0] = mat[row];
vec[1] = mat[row + 3];
vec[2] = mat[row + 6];
};
/**
* Sets the rows of the matrix from the supplied vectors.
*
* @param {goog.vec.ArrayType} mat The matrix to receive the
* values.
* @param {goog.vec.ArrayType} vec0 The values for row 0.
* @param {goog.vec.ArrayType} vec1 The values for row 1.
* @param {goog.vec.ArrayType} vec2 The values for row 2.
*/
goog.vec.Matrix3.setRows = function(
mat, vec0, vec1, vec2) {
goog.vec.Matrix3.setRow(mat, 0, vec0);
goog.vec.Matrix3.setRow(mat, 1, vec1);
goog.vec.Matrix3.setRow(mat, 2, vec2);
};
/**
* Retrieves the rows of the matrix into the supplied vectors.
*
* @param {goog.vec.ArrayType} mat The matrix to supplying
* the values.
* @param {goog.vec.ArrayType} vec0 The vector to receive row 0.
* @param {goog.vec.ArrayType} vec1 The vector to receive row 1.
* @param {goog.vec.ArrayType} vec2 The vector to receive row 2.
*/
goog.vec.Matrix3.getRows = function(
mat, vec0, vec1, vec2) {
goog.vec.Matrix3.getRow(mat, 0, vec0);
goog.vec.Matrix3.getRow(mat, 1, vec1);
goog.vec.Matrix3.getRow(mat, 2, vec2);
};
/**
* Clears the given matrix to zero.
*
* @param {goog.vec.ArrayType} mat The matrix to clear.
*/
goog.vec.Matrix3.setZero = function(mat) {
mat[0] = 0;
mat[1] = 0;
mat[2] = 0;
mat[3] = 0;
mat[4] = 0;
mat[5] = 0;
mat[6] = 0;
mat[7] = 0;
mat[8] = 0;
};
/**
* Sets the given matrix to the identity matrix.
*
* @param {goog.vec.ArrayType} mat The matrix to set.
*/
goog.vec.Matrix3.setIdentity = function(mat) {
mat[0] = 1;
mat[1] = 0;
mat[2] = 0;
mat[3] = 0;
mat[4] = 1;
mat[5] = 0;
mat[6] = 0;
mat[7] = 0;
mat[8] = 1;
};
/**
* Performs a per-component addition of the matrices mat0 and mat1, storing
* the result into resultMat.
*
* @param {goog.vec.ArrayType} mat0 The first addend.
* @param {goog.vec.ArrayType} mat1 The second addend.
* @param {goog.vec.ArrayType} resultMat The matrix to
* receive the results (may be either mat0 or mat1).
* @return {goog.vec.ArrayType} return resultMat so that operations can be
* chained together.
*/
goog.vec.Matrix3.add = function(mat0, mat1, resultMat) {
resultMat[0] = mat0[0] + mat1[0];
resultMat[1] = mat0[1] + mat1[1];
resultMat[2] = mat0[2] + mat1[2];
resultMat[3] = mat0[3] + mat1[3];
resultMat[4] = mat0[4] + mat1[4];
resultMat[5] = mat0[5] + mat1[5];
resultMat[6] = mat0[6] + mat1[6];
resultMat[7] = mat0[7] + mat1[7];
resultMat[8] = mat0[8] + mat1[8];
return resultMat;
};
/**
* Performs a per-component subtraction of the matrices mat0 and mat1,
* storing the result into resultMat.
*
* @param {goog.vec.ArrayType} mat0 The minuend.
* @param {goog.vec.ArrayType} mat1 The subtrahend.
* @param {goog.vec.ArrayType} resultMat The matrix to receive
* the results (may be either mat0 or mat1).
* @return {goog.vec.ArrayType} return resultMat so that operations can be
* chained together.
*/
goog.vec.Matrix3.subtract = function(mat0, mat1, resultMat) {
resultMat[0] = mat0[0] - mat1[0];
resultMat[1] = mat0[1] - mat1[1];
resultMat[2] = mat0[2] - mat1[2];
resultMat[3] = mat0[3] - mat1[3];
resultMat[4] = mat0[4] - mat1[4];
resultMat[5] = mat0[5] - mat1[5];
resultMat[6] = mat0[6] - mat1[6];
resultMat[7] = mat0[7] - mat1[7];
resultMat[8] = mat0[8] - mat1[8];
return resultMat;
};
/**
* Performs a component-wise multiplication of mat0 with the given scalar
* storing the result into resultMat.
*
* @param {goog.vec.ArrayType} mat0 The matrix to scale.
* @param {number} scalar The scalar value to multiple to each element of mat0.
* @param {goog.vec.ArrayType} resultMat The matrix to receive
* the results (may be mat0).
* @return {goog.vec.ArrayType} return resultMat so that operations can be
* chained together.
*/
goog.vec.Matrix3.scale = function(mat0, scalar, resultMat) {
resultMat[0] = mat0[0] * scalar;
resultMat[1] = mat0[1] * scalar;
resultMat[2] = mat0[2] * scalar;
resultMat[3] = mat0[3] * scalar;
resultMat[4] = mat0[4] * scalar;
resultMat[5] = mat0[5] * scalar;
resultMat[6] = mat0[6] * scalar;
resultMat[7] = mat0[7] * scalar;
resultMat[8] = mat0[8] * scalar;
return resultMat;
};
/**
* Multiplies the two matrices mat0 and mat1 using matrix multiplication,
* storing the result into resultMat.
*
* @param {goog.vec.ArrayType} mat0 The first (left hand) matrix.
* @param {goog.vec.ArrayType} mat1 The second (right hand)
* matrix.
* @param {goog.vec.ArrayType} resultMat The matrix to receive
* the results (may be either mat0 or mat1).
* @return {goog.vec.ArrayType} return resultMat so that operations can be
* chained together.
*/
goog.vec.Matrix3.multMat = function(mat0, mat1, resultMat) {
var a00 = mat0[0], a10 = mat0[1], a20 = mat0[2];
var a01 = mat0[3], a11 = mat0[4], a21 = mat0[5];
var a02 = mat0[6], a12 = mat0[7], a22 = mat0[8];
var b00 = mat1[0], b10 = mat1[1], b20 = mat1[2];
var b01 = mat1[3], b11 = mat1[4], b21 = mat1[5];
var b02 = mat1[6], b12 = mat1[7], b22 = mat1[8];
resultMat[0] = a00 * b00 + a01 * b10 + a02 * b20;
resultMat[1] = a10 * b00 + a11 * b10 + a12 * b20;
resultMat[2] = a20 * b00 + a21 * b10 + a22 * b20;
resultMat[3] = a00 * b01 + a01 * b11 + a02 * b21;
resultMat[4] = a10 * b01 + a11 * b11 + a12 * b21;
resultMat[5] = a20 * b01 + a21 * b11 + a22 * b21;
resultMat[6] = a00 * b02 + a01 * b12 + a02 * b22;
resultMat[7] = a10 * b02 + a11 * b12 + a12 * b22;
resultMat[8] = a20 * b02 + a21 * b12 + a22 * b22;
return resultMat;
};
/**
* Transposes the given matrix mat storing the result into resultMat.
* @param {goog.vec.ArrayType} mat The matrix to transpose.
* @param {goog.vec.ArrayType} resultMat The matrix to receive
* the results (may be mat).
* @return {goog.vec.ArrayType} return resultMat so that operations can be
* chained together.
*/
goog.vec.Matrix3.transpose = function(mat, resultMat) {
if (resultMat == mat) {
var a10 = mat[1], a20 = mat[2], a21 = mat[5];
resultMat[1] = mat[3];
resultMat[2] = mat[6];
resultMat[3] = a10;
resultMat[5] = mat[7];
resultMat[6] = a20;
resultMat[7] = a21;
} else {
resultMat[0] = mat[0];
resultMat[1] = mat[3];
resultMat[2] = mat[6];
resultMat[3] = mat[1];
resultMat[4] = mat[4];
resultMat[5] = mat[7];
resultMat[6] = mat[2];
resultMat[7] = mat[5];
resultMat[8] = mat[8];
}
return resultMat;
};
/**
* Computes the inverse of mat0 storing the result into resultMat. If the
* inverse is defined, this function returns true, false otherwise.
* @param {goog.vec.ArrayType} mat0 The matrix to invert.
* @param {goog.vec.ArrayType} resultMat The matrix to receive
* the result (may be mat0).
* @return {boolean} True if the inverse is defined. If false is returned,
* resultMat is not modified.
*/
goog.vec.Matrix3.invert = function(mat0, resultMat) {
var a00 = mat0[0], a10 = mat0[1], a20 = mat0[2];
var a01 = mat0[3], a11 = mat0[4], a21 = mat0[5];
var a02 = mat0[6], a12 = mat0[7], a22 = mat0[8];
var t00 = a11 * a22 - a12 * a21;
var t10 = a12 * a20 - a10 * a22;
var t20 = a10 * a21 - a11 * a20;
var det = a00 * t00 + a01 * t10 + a02 * t20;
if (det == 0) {
return false;
}
var idet = 1 / det;
resultMat[0] = t00 * idet;
resultMat[3] = (a02 * a21 - a01 * a22) * idet;
resultMat[6] = (a01 * a12 - a02 * a11) * idet;
resultMat[1] = t10 * idet;
resultMat[4] = (a00 * a22 - a02 * a20) * idet;
resultMat[7] = (a02 * a10 - a00 * a12) * idet;
resultMat[2] = t20 * idet;
resultMat[5] = (a01 * a20 - a00 * a21) * idet;
resultMat[8] = (a00 * a11 - a01 * a10) * idet;
return true;
};
/**
* Returns true if the components of mat0 are equal to the components of mat1.
*
* @param {goog.vec.ArrayType} mat0 The first matrix.
* @param {goog.vec.ArrayType} mat1 The second matrix.
* @return {boolean} True if the the two matrices are equivalent.
*/
goog.vec.Matrix3.equals = function(mat0, mat1) {
return mat0.length == mat1.length &&
mat0[0] == mat1[0] && mat0[1] == mat1[1] && mat0[2] == mat1[2] &&
mat0[3] == mat1[3] && mat0[4] == mat1[4] && mat0[5] == mat1[5] &&
mat0[6] == mat1[6] && mat0[7] == mat1[7] && mat0[8] == mat1[8];
};
/**
* Transforms the given vector with the given matrix storing the resulting,
* transformed matrix into resultVec.
*
* @param {goog.vec.ArrayType} mat The matrix supplying the
* transformation.
* @param {goog.vec.ArrayType} vec The vector to transform.
* @param {goog.vec.ArrayType} resultVec The vector to
* receive the results (may be vec).
* @return {goog.vec.ArrayType} return resultVec so that operations can be
* chained together.
*/
goog.vec.Matrix3.multVec3 = function(mat, vec, resultVec) {
var x = vec[0], y = vec[1], z = vec[2];
resultVec[0] = x * mat[0] + y * mat[3] + z * mat[6];
resultVec[1] = x * mat[1] + y * mat[4] + z * mat[7];
resultVec[2] = x * mat[2] + y * mat[5] + z * mat[8];
return resultVec;
};
/**
* Initializes the given 3x3 matrix as a translation matrix with x and y
* translation values.
*
* @param {goog.vec.ArrayType} mat The 3x3 (9-element) matrix
* array to receive the new translation matrix.
* @param {number} x The translation along the x axis.
* @param {number} y The translation along the y axis.
*/
goog.vec.Matrix3.makeTranslate = function(mat, x, y) {
goog.vec.Matrix3.setIdentity(mat);
goog.vec.Matrix3.setColumnValues(mat, 2, x, y, 1);
};
/**
* Initializes the given 3x3 matrix as a scale matrix with x, y and z scale
* factors.
* @param {goog.vec.ArrayType} mat The 3x3 (9-element) matrix
* array to receive the new scale matrix.
* @param {number} x The scale along the x axis.
* @param {number} y The scale along the y axis.
* @param {number} z The scale along the z axis.
*/
goog.vec.Matrix3.makeScale = function(mat, x, y, z) {
goog.vec.Matrix3.setIdentity(mat);
goog.vec.Matrix3.setDiagonalValues(mat, x, y, z);
};
/**
* Initializes the given 3x3 matrix as a rotation matrix with the given rotation
* angle about the axis defined by the vector (ax, ay, az).
* @param {goog.vec.ArrayType} mat The 3x3 (9-element) matrix
* array to receive the new scale matrix.
* @param {number} angle The rotation angle in radians.
* @param {number} ax The x component of the rotation axis.
* @param {number} ay The y component of the rotation axis.
* @param {number} az The z component of the rotation axis.
*/
goog.vec.Matrix3.makeAxisAngleRotate = function(
mat, angle, ax, ay, az) {
var c = Math.cos(angle);
var d = 1 - c;
var s = Math.sin(angle);
goog.vec.Matrix3.setFromValues(mat,
ax * ax * d + c,
ax * ay * d + az * s,
ax * az * d - ay * s,
ax * ay * d - az * s,
ay * ay * d + c,
ay * az * d + ax * s,
ax * az * d + ay * s,
ay * az * d - ax * s,
az * az * d + c);
};
@@ -0,0 +1,301 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Vec3</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.Matrix3');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testConstructor() {
var m0 = goog.vec.Matrix3.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
var m1 = goog.vec.Matrix3.createFromArray([1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
var m2 = goog.vec.Matrix3.createFromArray(m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m2);
var m3 = goog.vec.Matrix3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m3);
var m4 = goog.vec.Matrix3.createIdentity();
assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], m4);
}
function testSet() {
var m0 = goog.vec.Matrix3.create();
var m1 = goog.vec.Matrix3.createFromArray([1, 2, 3, 4, 5, 6, 7, 8, 9]);
goog.vec.Matrix3.setFromArray(m0, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
goog.vec.Matrix3.setFromValues(m0, 2, 3, 4, 5, 6, 7, 8, 9, 10);
assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 10], m0);
}
function testSetDiagonal() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.setDiagonalValues(m0, 1, 2, 3);
assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], m0);
goog.vec.Matrix3.setDiagonal(m0, [4, 5, 6]);
assertElementsEquals([4, 0, 0, 0, 5, 0, 0, 0, 6], m0);
}
function testSetGetColumn() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.setColumn(m0, 0, [1, 2, 3]);
goog.vec.Matrix3.setColumn(m0, 1, [4, 5, 6]);
goog.vec.Matrix3.setColumn(m0, 2, [7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
var v0 = [0, 0, 0];
goog.vec.Matrix3.getColumn(m0, 0, v0);
assertElementsEquals([1, 2, 3], v0);
goog.vec.Matrix3.getColumn(m0, 1, v0);
assertElementsEquals([4, 5, 6], v0);
goog.vec.Matrix3.getColumn(m0, 2, v0);
assertElementsEquals([7, 8, 9], v0);
}
function testSetGetColumns() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.setColumns(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
var v0 = [0, 0, 0], v1 = [0, 0, 0], v2 = [0, 0, 0];
goog.vec.Matrix3.getColumns(m0, v0, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([7, 8, 9], v2);
}
function testSetGetRow() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.setRow(m0, 0, [1, 2, 3]);
goog.vec.Matrix3.setRow(m0, 1, [4, 5, 6]);
goog.vec.Matrix3.setRow(m0, 2, [7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
var v0 = [0, 0, 0];
goog.vec.Matrix3.getRow(m0, 0, v0);
assertElementsEquals([1, 2, 3], v0);
goog.vec.Matrix3.getRow(m0, 1, v0);
assertElementsEquals([4, 5, 6], v0);
goog.vec.Matrix3.getRow(m0, 2, v0);
assertElementsEquals([7, 8, 9], v0);
}
function testSetGetRows() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.setRows(m0, [1, 2, 3], [4, 5, 6], [7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
var v0 = [0, 0, 0], v1 = [0, 0, 0], v2 = [0, 0, 0];
goog.vec.Matrix3.getRows(m0, v0, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([7, 8, 9], v2);
}
function testSetRowMajorArray() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.setFromRowMajorArray(
m0, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m0);
}
function testSetZero() {
var m0 = goog.vec.Matrix3.createFromArray([1, 2, 3, 4, 5, 6, 7, 8, 9]);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
goog.vec.Matrix3.setZero(m0);
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
}
function testSetIdentity() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.setIdentity(m0);
assertElementsEquals([1, 0, 0, 0, 1, 0, 0, 0, 1], m0);
}
function testSetGetElement() {
var m0 = goog.vec.Matrix3.create();
for (var r = 0; r < 3; r++) {
for (var c = 0; c < 3; c++) {
var value = c * 3 + r + 1;
goog.vec.Matrix3.setElement(m0, r, c, value);
assertEquals(value, goog.vec.Matrix3.getElement(m0, r, c));
}
}
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
}
function testAdd() {
var m0 = goog.vec.Matrix3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Matrix3.createFromValues(3, 4, 5, 6, 7, 8, 9, 1, 2);
var m2 = goog.vec.Matrix3.create();
goog.vec.Matrix3.add(m0, m1, m2);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m2);
goog.vec.Matrix3.add(m0, m1, m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([4, 6, 8, 10, 12, 14, 16, 9, 11], m0);
}
function testSubtract() {
var m0 = goog.vec.Matrix3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Matrix3.createFromValues(3, 4, 5, 6, 7, 8, 9, 1, 2);
var m2 = goog.vec.Matrix3.create();
goog.vec.Matrix3.subtract(m0, m1, m2);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([3, 4, 5, 6, 7, 8, 9, 1, 2], m1);
assertElementsEquals([-2, -2, -2, -2, -2, -2, -2, 7, 7], m2);
goog.vec.Matrix3.subtract(m1, m0, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([2, 2, 2, 2, 2, 2, 2, -7, -7], m1);
}
function testScale() {
var m0 = goog.vec.Matrix3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Matrix3.create();
goog.vec.Matrix3.scale(m0, 5, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m0);
assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m1);
goog.vec.Matrix3.scale(m0, 5, m0);
assertElementsEquals([5, 10, 15, 20, 25, 30, 35, 40, 45], m0);
}
function testMultMat() {
var m0 = goog.vec.Matrix3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Matrix3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m2 = goog.vec.Matrix3.create();
goog.vec.Matrix3.multMat(m0, m1, m2);
assertElementsEquals([30, 36, 42, 66, 81, 96, 102, 126, 150], m2);
goog.vec.Matrix3.add(m0, m1, m1);
goog.vec.Matrix3.multMat(m0, m1, m1);
assertElementsEquals([60, 72, 84, 132, 162, 192, 204, 252, 300], m1);
}
function testTranspose() {
var m0 = goog.vec.Matrix3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Matrix3.create();
goog.vec.Matrix3.transpose(m0, m1);
assertElementsEquals([1, 4, 7, 2, 5, 8, 3, 6, 9], m1);
goog.vec.Matrix3.transpose(m1, m1);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], m1);
}
function testInvert() {
var m0 = goog.vec.Matrix3.createFromValues(1, 1, 1, 1, 1, 1, 1, 1, 1);
assertFalse(goog.vec.Matrix3.invert(m0, m0));
assertElementsEquals([1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.Matrix3.setFromValues(m0, 1, 2, 3, 1, 3, 4, 3, 4, 5);
assertTrue(goog.vec.Matrix3.invert(m0, m0));
assertElementsEquals([0.5, -1.0, 0.5, -3.5, 2.0, 0.5, 2.5, -1.0, -0.5], m0);
goog.vec.Matrix3.makeScale(m0, .01, .01, .01);
assertTrue(goog.vec.Matrix3.invert(m0, m0));
var m1 = goog.vec.Matrix3.create();
goog.vec.Matrix3.makeScale(m1, 100, 100, 100);
assertElementsEquals(m1, m0);
}
function testEquals() {
var m0 = goog.vec.Matrix3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var m1 = goog.vec.Matrix3.createFromArray(m0);
assertTrue(goog.vec.Matrix3.equals(m0, m1));
assertTrue(goog.vec.Matrix3.equals(m1, m0));
for (var i = 0; i < 9; i++) {
m1[i] = 15;
assertFalse(goog.vec.Matrix3.equals(m0, m1));
assertFalse(goog.vec.Matrix3.equals(m1, m0));
m1[i] = i + 1;
}
}
function testMultVec3() {
var m0 = goog.vec.Matrix3.createFromValues(1, 2, 3, 4, 5, 6, 7, 8, 9);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.Matrix3.multVec3(m0, v0, v1);
assertElementsEquals([30, 36, 42], v1);
goog.vec.Matrix3.multVec3(m0, v0, v0);
assertElementsEquals([30, 36, 42], v0);
}
function testSetValues() {
var a0 = goog.vec.Matrix3.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
goog.vec.Matrix3.setFromValues(a0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a0);
var a1 = goog.vec.Matrix3.create();
goog.vec.Matrix3.setDiagonalValues(a1, 1, 2, 3);
assertElementsEquals([1, 0, 0, 0, 2, 0, 0, 0, 3], a1);
goog.vec.Matrix3.setColumnValues(a1, 0, 2, 3, 4);
goog.vec.Matrix3.setColumnValues(a1, 1, 5, 6, 7);
goog.vec.Matrix3.setColumnValues(a1, 2, 8, 9, 1);
assertElementsEquals([2, 3, 4, 5, 6, 7, 8, 9, 1], a1);
goog.vec.Matrix3.setRowValues(a1, 0, 1, 4, 7);
goog.vec.Matrix3.setRowValues(a1, 1, 2, 5, 8);
goog.vec.Matrix3.setRowValues(a1, 2, 3, 6, 9);
assertElementsEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a1);
}
function testMakeTranslate() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.makeTranslate(m0, 3, 4);
assertElementsEquals([1, 0, 0, 0, 1, 0, 3, 4, 1], m0);
}
function testMakeScale() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.makeScale(m0, 3, 4, 5);
assertElementsEquals([3, 0, 0, 0, 4, 0, 0, 0, 5], m0);
}
function testMakeRotate() {
var m0 = goog.vec.Matrix3.create();
goog.vec.Matrix3.makeAxisAngleRotate(m0, Math.PI / 2, 0, 0, 1);
var v0 = [0, 1, 0, -1, 0, 0, 0, 0, 1];
for (var i = 0; i < 9; ++i) {
assertTrue(Math.abs(m0[i] - v0[i]) < 1e-6);
}
var m1 = goog.vec.Matrix3.create();
goog.vec.Matrix3.makeAxisAngleRotate(m1, -Math.PI / 4, 0, 0, 1);
goog.vec.Matrix3.multMat(m0, m1, m1);
var v1 = [0.7071068, 0.7071068, 0, -0.7071068, 0.7071068, 0, 0, 0, 1];
for (var i = 0; i < 9; ++i) {
assertTrue(Math.abs(m1[i] - v1[i]) < 1e-6);
}
}
</script>
</body>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,626 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Matrix4</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.Matrix4');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testConstructor() {
var m0 = goog.vec.Matrix4.create();
assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
var m1 = goog.vec.Matrix4.createFromArray(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
var m2 = goog.vec.Matrix4.clone(m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m2);
var m3 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m3);
var m4 = goog.vec.Matrix4.createIdentity();
assertElementsEquals([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], m4);
}
function testSet() {
var m0 = goog.vec.Matrix4.create();
var m1 = goog.vec.Matrix4.createFromArray(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
goog.vec.Matrix4.setFromArray(m0, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
goog.vec.Matrix4.setFromValues(
m0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
assertElementsEquals(
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], m0);
}
function testSetDiagonal() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.setDiagonalValues(m0, 1, 2, 3, 4);
assertElementsEquals(
[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], m0);
goog.vec.Matrix4.setDiagonal(m0, [4, 5, 6, 7]);
assertElementsEquals(
[4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0, 7], m0);
}
function testSetGetColumn() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.setColumn(m0, 0, [1, 2, 3, 4]);
goog.vec.Matrix4.setColumn(m0, 1, [5, 6, 7, 8]);
goog.vec.Matrix4.setColumn(m0, 2, [9, 10, 11, 12]);
goog.vec.Matrix4.setColumn(m0, 3, [13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
var v0 = [0, 0, 0, 0];
goog.vec.Matrix4.getColumn(m0, 0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.Matrix4.getColumn(m0, 1, v0);
assertElementsEquals([5, 6, 7, 8], v0);
goog.vec.Matrix4.getColumn(m0, 2, v0);
assertElementsEquals([9, 10, 11, 12], v0);
goog.vec.Matrix4.getColumn(m0, 3, v0);
assertElementsEquals([13, 14, 15, 16], v0);
}
function testSetGetColumns() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.setColumns(
m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
goog.vec.Matrix4.getColumns(m0, v0, v1, v2, v3);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([9, 10, 11, 12], v2);
assertElementsEquals([13, 14, 15, 16], v3);
}
function testSetGetRow() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.setRow(m0, 0, [1, 2, 3, 4]);
goog.vec.Matrix4.setRow(m0, 1, [5, 6, 7, 8]);
goog.vec.Matrix4.setRow(m0, 2, [9, 10, 11, 12]);
goog.vec.Matrix4.setRow(m0, 3, [13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
var v0 = [0, 0, 0, 0];
goog.vec.Matrix4.getRow(m0, 0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.Matrix4.getRow(m0, 1, v0);
assertElementsEquals([5, 6, 7, 8], v0);
goog.vec.Matrix4.getRow(m0, 2, v0);
assertElementsEquals([9, 10, 11, 12], v0);
goog.vec.Matrix4.getRow(m0, 3, v0);
assertElementsEquals([13, 14, 15, 16], v0);
}
function testSetGetRows() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.setRows(
m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
goog.vec.Matrix4.getRows(m0, v0, v1, v2, v3);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([9, 10, 11, 12], v2);
assertElementsEquals([13, 14, 15, 16], v3);
}
function testSetRowMajorArray() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.setFromRowMajorArray(
m0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
}
function testSetZero() {
var m0 = goog.vec.Matrix4.createFromArray(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
goog.vec.Matrix4.setZero(m0);
assertElementsEquals(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
}
function testSetIdentity() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.setIdentity(m0);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], m0);
}
function testSetGetElement() {
var m0 = goog.vec.Matrix4.create();
for (var r = 0; r < 4; r++) {
for (var c = 0; c < 4; c++) {
var value = c * 4 + r + 1;
goog.vec.Matrix4.setElement(m0, r, c, value);
assertEquals(value, goog.vec.Matrix4.getElement(m0, r, c));
}
}
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
}
function testAdd() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Matrix4.createFromValues(
9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
var m2 = goog.vec.Matrix4.create();
goog.vec.Matrix4.add(m0, m1, m2);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m2);
goog.vec.Matrix4.add(m0, m1, m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m0);
}
function testSubtract() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Matrix4.createFromValues(
9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
var m2 = goog.vec.Matrix4.create();
goog.vec.Matrix4.subtract(m0, m1, m2);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
assertElementsEquals(
[-8, -8, -8, -8, -8, -8, -8, -8, 8, 8, 8, 8, 8, 8, 8, 8], m2);
goog.vec.Matrix4.subtract(m1, m0, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[8, 8, 8, 8, 8, 8, 8, 8, -8, -8, -8, -8, -8, -8, -8, -8], m1);
}
function testScale() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Matrix4.create();
goog.vec.Matrix4.scale(m0, 2, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
assertElementsEquals(
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32], m1);
goog.vec.Matrix4.scale(m0, 5, m0);
assertElementsEquals(
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80], m0);
}
function testMultMat() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m2 = goog.vec.Matrix4.create();
goog.vec.Matrix4.multMat(m0, m1, m2);
assertElementsEquals(
[90, 100, 110, 120, 202, 228, 254, 280,
314, 356, 398, 440, 426, 484, 542, 600], m2);
goog.vec.Matrix4.scale(m1, 2, m1);
goog.vec.Matrix4.multMat(m1, m0, m1);
assertElementsEquals(
[180, 200, 220, 240, 404, 456, 508, 560,
628, 712, 796, 880, 852, 968, 1084, 1200], m1);
}
function testTranspose() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Matrix4.create();
goog.vec.Matrix4.transpose(m0, m1);
assertElementsEquals(
[1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m1);
goog.vec.Matrix4.transpose(m1, m1);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
}
function testDeterminant() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertEquals(0, goog.vec.Matrix4.determinant(m0));
assertElementsEquals(
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.Matrix4.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
assertEquals(160, goog.vec.Matrix4.determinant(m0));
assertElementsEquals(
[1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3], m0);
}
function testInvert() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
assertFalse(goog.vec.Matrix4.invert(m0, m0));
assertElementsEquals(
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
goog.vec.Matrix4.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
assertTrue(goog.vec.Matrix4.invert(m0, m0));
assertElementsRoughlyEqual(
[-0.225, 0.025, 0.025, 0.275, 0.025, 0.025, 0.275, -0.225,
0.025, 0.275, -0.225, 0.025, 0.275, -0.225, 0.025, 0.025], m0,
goog.vec.EPSILON);
goog.vec.Matrix4.makeScale(m0, .01, .01, .01);
assertTrue(goog.vec.Matrix4.invert(m0, m0));
var m1 = goog.vec.Matrix4.create();
goog.vec.Matrix4.makeScale(m1, 100, 100, 100);
assertElementsEquals(m1, m0);
}
function testEquals() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var m1 = goog.vec.Matrix4.clone(m0);
assertTrue(goog.vec.Matrix4.equals(m0, m1));
assertTrue(goog.vec.Matrix4.equals(m1, m0));
for (var i = 0; i < 16; i++) {
m1[i] = 18;
assertFalse(goog.vec.Matrix4.equals(m0, m1));
assertFalse(goog.vec.Matrix4.equals(m1, m0));
m1[i] = i + 1;
}
}
function testMultVec3() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.Matrix4.multVec3(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([51, 58, 65], v1);
goog.vec.Matrix4.multVec3(m0, v0, v0);
assertElementsEquals([51, 58, 65], v0);
v0 = [1, 2, 3];
goog.vec.Matrix4.multVec3ToArray(m0, v0, v0);
assertElementsEquals([51, 58, 65], v0);
}
function testMultVec3NoTranslate() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
goog.vec.Matrix4.multVec3NoTranslate(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([38, 44, 50], v1);
goog.vec.Matrix4.multVec3NoTranslate(m0, v0, v0);
assertElementsEquals([38, 44, 50], v0);
}
function testMultVec3Projective() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3];
var v1 = [0, 0, 0];
var invw = 1 / 72;
goog.vec.Matrix4.multVec3Projective(m0, v0, v1);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals(
[51 * invw, 58 * invw, 65 * invw], v1);
goog.vec.Matrix4.multVec3Projective(m0, v0, v0);
assertElementsEquals(
[51 * invw, 58 * invw, 65 * invw], v0);
}
function testMultVec4() {
var m0 = goog.vec.Matrix4.createFromValues(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
var v0 = [1, 2, 3, 4];
var v1 = [0, 0, 0, 0];
goog.vec.Matrix4.multVec4(m0, v0, v1);
assertElementsEquals([90, 100, 110, 120], v1);
goog.vec.Matrix4.multVec4(m0, v0, v0);
assertElementsEquals([90, 100, 110, 120], v0);
var v0 = [1, 2, 3, 4];
goog.vec.Matrix4.multVec4ToArray(m0, v0, v0);
assertElementsEquals([90, 100, 110, 120], v0);
}
function testSetValues() {
var a0 = goog.vec.Matrix4.create();
assertElementsEquals(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
a0 = goog.vec.Matrix4.createFromArray(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a0);
var a1 = goog.vec.Matrix4.create();
goog.vec.Matrix4.setDiagonalValues(a1, 1, 2, 3, 4);
assertElementsEquals(
[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], a1);
goog.vec.Matrix4.setColumnValues(a1, 0, 2, 3, 4, 5);
goog.vec.Matrix4.setColumnValues(a1, 1, 6, 7, 8, 9);
goog.vec.Matrix4.setColumnValues(a1, 2, 10, 11, 12, 13);
goog.vec.Matrix4.setColumnValues(a1, 3, 14, 15, 16, 1);
assertElementsEquals(
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1], a1);
goog.vec.Matrix4.setRowValues(a1, 0, 1, 5, 9, 13);
goog.vec.Matrix4.setRowValues(a1, 1, 2, 6, 10, 14);
goog.vec.Matrix4.setRowValues(a1, 2, 3, 7, 11, 15);
goog.vec.Matrix4.setRowValues(a1, 3, 4, 8, 12, 16);
assertElementsEquals(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a1);
}
function testMakeTranslate() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.makeTranslate(m0, 3, 4, 5);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
}
function testMakeScale() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.makeScale(m0, 3, 4, 5);
assertElementsEquals(
[3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
}
function testMakeRotate() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.makeAxisAngleRotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
var m1 = goog.vec.Matrix4.create();
goog.vec.Matrix4.makeAxisAngleRotate(m1, -Math.PI / 4, 0, 0, 1);
goog.vec.Matrix4.multMat(m0, m1, m1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0, 0,
-0.7071068, 0.7071068, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1],
m1, goog.vec.EPSILON);
}
function testApplyTranslate() {
var m0 = goog.vec.Matrix4.createIdentity();
goog.vec.Matrix4.applyTranslate(m0, 3, 4, 5);
assertElementsEquals(
[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
goog.vec.Matrix4.setFromValues(
m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
var m1 = goog.vec.Matrix4.create();
goog.vec.Matrix4.makeTranslate(m1, 5, 6, 7);
var m2 = goog.vec.Matrix4.create();
goog.vec.Matrix4.multMat(m0, m1, m2);
goog.vec.Matrix4.applyTranslate(m0, 5, 6, 7);
assertElementsEquals(m2, m0);
}
function testApplyScale() {
var m0 = goog.vec.Matrix4.createIdentity();
goog.vec.Matrix4.applyScale(m0, 3, 4, 5);
assertElementsEquals([3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
}
function testApplyRotate() {
var m0 = goog.vec.Matrix4.createIdentity();
goog.vec.Matrix4.applyRotate(m0, Math.PI / 2, 0, 0, 1);
assertElementsRoughlyEqual(
[0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
m0, goog.vec.EPSILON);
goog.vec.Matrix4.applyRotate(m0, -Math.PI / 4, 0, 0, 1);
assertElementsRoughlyEqual(
[0.7071068, 0.7071068, 0, 0,
-0.7071068, 0.7071068, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1],
m0, goog.vec.EPSILON);
}
function testMakeFrustum() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.makeFrustum(m0, -1, 2, -2, 1, .1, 1.1);
assertElementsRoughlyEqual(
[0.06666666, 0, 0, 0,
0, 0.06666666, 0, 0,
0.33333333, -0.33333333, -1.2, -1,
0, 0, -0.22, 0], m0, goog.vec.EPSILON);
}
function testMakePerspective() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.makePerspective(m0, 90 * Math.PI / 180, 2, 0.1, 1.1);
assertElementsRoughlyEqual(
[0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1.2, -1, 0, 0, -0.22, 0],
m0, goog.vec.EPSILON);
}
function testMakeOrtho() {
var m0 = goog.vec.Matrix4.create();
goog.vec.Matrix4.makeOrtho(m0, -1, 2, -2, 1, 0.1, 1.1);
assertElementsRoughlyEqual(
[0.6666666, 0, 0, 0,
0, 0.6666666, 0, 0,
0, 0, -2, 0,
-0.333333, 0.3333333, -1.2, 1], m0, goog.vec.EPSILON);
}
function testEulerZXZ() {
var m0 = goog.vec.Matrix4.create();
var roll = Math.random() * 2 * Math.PI;
var tilt = -Math.random() * Math.PI / 2;
var pan = Math.random() * 2 * Math.PI;
goog.vec.Matrix4.makeAxisAngleRotate(m0, roll, 0, 0, 1);
goog.vec.Matrix4.applyRotate(m0, tilt, 1, 0, 0);
goog.vec.Matrix4.applyRotate(m0, pan, 0, 0, 1);
var m1 = goog.vec.Matrix4.create();
goog.vec.Matrix4.fromEulerZXZ(m1, roll, tilt, pan);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
var euler = [0, 0, 0];
goog.vec.Matrix4.toEulerZXZ(m0, euler);
// Bring them to their range.
euler[0] = (euler[0] + Math.PI * 2) % (Math.PI * 2);
euler[1] = (euler[1] - Math.PI * 2) % (Math.PI * 2);
euler[2] = (euler[2] + Math.PI * 2) % (Math.PI * 2);
assertElementsRoughlyEqual([roll, tilt, pan], euler, goog.vec.EPSILON);
}
function testEulerZXZExtrema() {
var m0 = goog.vec.Matrix4.createFromArray(
[1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1]);
var m1 = goog.vec.Matrix4.createFromArray(
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
var euler = [0, 0, 0];
goog.vec.Matrix4.toEulerZXZ(m0, euler);
assertElementsRoughlyEqual([0, -Math.PI / 2, 0], euler, goog.vec.EPSILON);
goog.vec.Matrix4.fromEulerZXZ(m1, euler[0], euler[1], euler[2]);
assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
}
function testLookAt() {
var viewMatrix = goog.vec.Matrix4.create();
goog.vec.Matrix4.lookAt(
viewMatrix, [0, 0, 0], [1, 0, 0], [0, 1, 0]);
assertElementsRoughlyEqual(
[0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], viewMatrix,
goog.vec.EPSILON);
}
function testToLookAt() {
// This test does not use the default precision goog.vec.EPSILON due to
// precision issues in some browsers leading to flaky tests.
var EPSILON = 1e-4;
var eyeExp = [0, 0, 0];
var fwdExp = [1, 0, 0];
var upExp = [0, 1, 0];
var centerExp = [0, 0, 0];
goog.vec.Vec3.add(eyeExp, fwdExp, centerExp);
var view = goog.vec.Matrix4.create();
goog.vec.Matrix4.lookAt(view, eyeExp, centerExp, upExp);
var eyeRes = [0, 0, 0];
var fwdRes = [0, 0, 0];
var upRes = [0, 0, 0];
goog.vec.Matrix4.toLookAt(view, eyeRes, fwdRes, upRes);
assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
assertElementsRoughlyEqual(upExp, upRes, EPSILON);
}
function testLookAtDecomposition() {
// This test does not use the default precision goog.vec.EPSILON due to
// precision issues in some browsers, which leads to flaky tests.
var EPSILON = 1e-4;
var viewExp = goog.vec.Matrix4.create();
var viewRes = goog.vec.Matrix4.create();
var tmp = goog.vec.Matrix4.create();
// Get a valid set of random vectors eye, forward, up by decomposing
// a random matrix into a set of lookAt vectors.
for (var i = 0; i < tmp.length; i++)
tmp[i] = Math.random();
var eyeExp = [0, 0, 0];
var fwdExp = [0, 0, 0];
var upExp = [0, 0, 0];
var centerExp = [0, 0, 0];
// Project the random matrix into a real modelview matrix.
goog.vec.Matrix4.toLookAt(tmp, eyeExp, fwdExp, upExp);
goog.vec.Vec3.add(eyeExp, fwdExp, centerExp);
// Compute the expected modelview matrix from a set of valid random vectors.
goog.vec.Matrix4.lookAt(viewExp, eyeExp, centerExp, upExp);
var eyeRes = [0, 0, 0];
var fwdRes = [0, 0, 0];
var upRes = [0, 0, 0];
var centerRes = [0, 0, 0];
goog.vec.Matrix4.toLookAt(viewExp, eyeRes, fwdRes, upRes);
goog.vec.Vec3.add(eyeRes, fwdRes, centerRes);
goog.vec.Matrix4.lookAt(viewRes, eyeRes, centerRes, upRes);
assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
assertElementsRoughlyEqual(upExp, upRes, EPSILON);
assertElementsRoughlyEqual(viewExp, viewRes, EPSILON);
}
</script>
</body>
@@ -0,0 +1,458 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Implements quaternions and their conversion functions. In this
* implementation, quaternions are represented as 4 element vectors with the
* first 3 elements holding the imaginary components and the 4th element holding
* the real component.
*
*/
goog.provide('goog.vec.Quaternion');
goog.require('goog.vec');
goog.require('goog.vec.Vec3');
goog.require('goog.vec.Vec4');
/** @typedef {goog.vec.Float32} */ goog.vec.Quaternion.Float32;
/** @typedef {goog.vec.Float64} */ goog.vec.Quaternion.Float64;
/** @typedef {goog.vec.Number} */ goog.vec.Quaternion.Number;
/** @typedef {goog.vec.AnyType} */ goog.vec.Quaternion.AnyType;
/**
* Creates a Float32 quaternion, initialized to zero.
*
* @return {!goog.vec.Quaternion.Float32} The new quaternion.
*/
goog.vec.Quaternion.createFloat32 = goog.vec.Vec4.createFloat32;
/**
* Creates a Float64 quaternion, initialized to zero.
*
* @return {goog.vec.Quaternion.Float64} The new quaternion.
*/
goog.vec.Quaternion.createFloat64 = goog.vec.Vec4.createFloat64;
/**
* Creates a Number quaternion, initialized to zero.
*
* @return {goog.vec.Quaternion.Number} The new quaternion.
*/
goog.vec.Quaternion.createNumber = goog.vec.Vec4.createNumber;
/**
* Creates a new Float32 quaternion initialized with the values from the
* supplied array.
*
* @param {goog.vec.AnyType} vec The source 4 element array.
* @return {!goog.vec.Quaternion.Float32} The new quaternion.
*/
goog.vec.Quaternion.createFloat32FromArray =
goog.vec.Vec4.createFloat32FromArray;
/**
* Creates a new Float64 quaternion initialized with the values from the
* supplied array.
*
* @param {goog.vec.AnyType} vec The source 4 element array.
* @return {!goog.vec.Quaternion.Float64} The new quaternion.
*/
goog.vec.Quaternion.createFloat64FromArray =
goog.vec.Vec4.createFloat64FromArray;
/**
* Creates a new Float32 quaternion initialized with the supplied values.
*
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @param {number} v3 The value for element at index 3.
* @return {!goog.vec.Quaternion.Float32} The new quaternion.
*/
goog.vec.Quaternion.createFloat32FromValues =
goog.vec.Vec4.createFloat32FromValues;
/**
* Creates a new Float64 quaternion initialized with the supplied values.
*
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @param {number} v3 The value for element at index 3.
* @return {!goog.vec.Quaternion.Float64} The new quaternion.
*/
goog.vec.Quaternion.createFloat64FromValues =
goog.vec.Vec4.createFloat64FromValues;
/**
* Creates a clone of the given Float32 quaternion.
*
* @param {goog.vec.Quaternion.Float32} q The source quaternion.
* @return {goog.vec.Quaternion.Float32} The new quaternion.
*/
goog.vec.Quaternion.cloneFloat32 = goog.vec.Vec4.cloneFloat32;
/**
* Creates a clone of the given Float64 quaternion.
*
* @param {goog.vec.Quaternion.Float64} q The source quaternion.
* @return {goog.vec.Quaternion.Float64} The new quaternion.
*/
goog.vec.Quaternion.cloneFloat64 = goog.vec.Vec4.cloneFloat64;
/**
* Initializes the quaternion with the given values.
*
* @param {goog.vec.Quaternion.AnyType} q The quaternion to receive
* the values.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @param {number} v3 The value for element at index 3.
* @return {!goog.vec.Vec4.AnyType} return q so that operations can be
* chained together.
*/
goog.vec.Quaternion.setFromValues = goog.vec.Vec4.setFromValues;
/**
* Initializes the quaternion with the given array of values.
*
* @param {goog.vec.Quaternion.AnyType} q The quaternion to receive
* the values.
* @param {goog.vec.AnyType} values The array of values.
* @return {!goog.vec.Quaternion.AnyType} return q so that operations can be
* chained together.
*/
goog.vec.Quaternion.setFromArray = goog.vec.Vec4.setFromArray;
/**
* Adds the two quaternions.
*
* @param {goog.vec.Quaternion.AnyType} quat0 The first addend.
* @param {goog.vec.Quaternion.AnyType} quat1 The second addend.
* @param {goog.vec.Quaternion.AnyType} resultQuat The quaternion to
* receive the result. May be quat0 or quat1.
*/
goog.vec.Quaternion.add = goog.vec.Vec4.add;
/**
* Negates a quaternion, storing the result into resultQuat.
*
* @param {goog.vec.Quaternion.AnyType} quat0 The quaternion to negate.
* @param {goog.vec.Quaternion.AnyType} resultQuat The quaternion to
* receive the result. May be quat0.
*/
goog.vec.Quaternion.negate = goog.vec.Vec4.negate;
/**
* Multiplies each component of quat0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.Quaternion.AnyType} quat0 The source quaternion.
* @param {number} scalar The value to multiply with each component of quat0.
* @param {goog.vec.Quaternion.AnyType} resultQuat The quaternion to
* receive the result. May be quat0.
*/
goog.vec.Quaternion.scale = goog.vec.Vec4.scale;
/**
* Returns the square magnitude of the given quaternion.
*
* @param {goog.vec.Quaternion.AnyType} quat0 The quaternion.
* @return {number} The magnitude of the quaternion.
*/
goog.vec.Quaternion.magnitudeSquared =
goog.vec.Vec4.magnitudeSquared;
/**
* Returns the magnitude of the given quaternion.
*
* @param {goog.vec.Quaternion.AnyType} quat0 The quaternion.
* @return {number} The magnitude of the quaternion.
*/
goog.vec.Quaternion.magnitude =
goog.vec.Vec4.magnitude;
/**
* Normalizes the given quaternion storing the result into resultVec.
*
* @param {goog.vec.Quaternion.AnyType} quat0 The quaternion to
* normalize.
* @param {goog.vec.Quaternion.AnyType} resultQuat The quaternion to
* receive the result. May be quat0.
*/
goog.vec.Quaternion.normalize = goog.vec.Vec4.normalize;
/**
* Computes the dot (scalar) product of two quaternions.
*
* @param {goog.vec.Quaternion.AnyType} q0 The first quaternion.
* @param {goog.vec.Quaternion.AnyType} q1 The second quaternion.
* @return {number} The scalar product.
*/
goog.vec.Quaternion.dot = goog.vec.Vec4.dot;
/**
* Computes the conjugate of the quaternion in quat storing the result into
* resultQuat.
*
* @param {goog.vec.Quaternion.AnyType} quat The source quaternion.
* @param {goog.vec.Quaternion.AnyType} resultQuat The quaternion to
* receive the result.
* @return {!goog.vec.Quaternion.AnyType} Return q so that
* operations can be chained together.
*/
goog.vec.Quaternion.conjugate = function(quat, resultQuat) {
resultQuat[0] = -quat[0];
resultQuat[1] = -quat[1];
resultQuat[2] = -quat[2];
resultQuat[3] = quat[3];
return resultQuat;
};
/**
* Concatenates the two quaternions storing the result into resultQuat.
*
* @param {goog.vec.Quaternion.AnyType} quat0 The first quaternion.
* @param {goog.vec.Quaternion.AnyType} quat1 The second quaternion.
* @param {goog.vec.Quaternion.AnyType} resultQuat The quaternion to
* receive the result.
* @return {!goog.vec.Quaternion.AnyType} Return q so that
* operations can be chained together.
*/
goog.vec.Quaternion.concat = function(quat0, quat1, resultQuat) {
var x0 = quat0[0], y0 = quat0[1], z0 = quat0[2], w0 = quat0[3];
var x1 = quat1[0], y1 = quat1[1], z1 = quat1[2], w1 = quat1[3];
resultQuat[0] = w0 * x1 + x0 * w1 + y0 * z1 - z0 * y1;
resultQuat[1] = w0 * y1 - x0 * z1 + y0 * w1 + z0 * x1;
resultQuat[2] = w0 * z1 + x0 * y1 - y0 * x1 + z0 * w1;
resultQuat[3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
return resultQuat;
};
/**
* Generates a unit quaternion from the given angle-axis rotation pair.
* The rotation axis is not required to be a unit vector, but should
* have non-zero length. The angle should be specified in radians.
*
* @param {number} angle The angle (in radians) to rotate about the axis.
* @param {goog.vec.Quaternion.AnyType} axis Unit vector specifying the
* axis of rotation.
* @param {goog.vec.Quaternion.AnyType} quat Unit quaternion to store the
* result.
* @return {goog.vec.Quaternion.AnyType} Return q so that
* operations can be chained together.
*/
goog.vec.Quaternion.fromAngleAxis = function(angle, axis, quat) {
// Normalize the axis of rotation.
goog.vec.Vec3.normalize(axis, axis);
var halfAngle = 0.5 * angle;
var sin = Math.sin(halfAngle);
goog.vec.Quaternion.setFromValues(
quat, sin * axis[0], sin * axis[1], sin * axis[2], Math.cos(halfAngle));
// Normalize the resulting quaternion.
goog.vec.Quaternion.normalize(quat, quat);
return quat;
};
/**
* Generates an angle-axis rotation pair from a unit quaternion.
* The quaternion is assumed to be of unit length. The calculated
* values are returned via the passed 'axis' object and the 'angle'
* number returned by the function itself. The returned rotation axis
* is a non-zero length unit vector, and the returned angle is in
* radians in the range of [-PI, +PI].
*
* @param {goog.vec.Quaternion.AnyType} quat Unit quaternion to convert.
* @param {goog.vec.Quaternion.AnyType} axis Vector to store the returned
* rotation axis.
* @return {number} angle Angle (in radians) to rotate about 'axis'.
* The range of the returned angle is [-PI, +PI].
*/
goog.vec.Quaternion.toAngleAxis = function(quat, axis) {
var angle = 2 * Math.acos(quat[3]);
var magnitude = Math.min(Math.max(1 - quat[3] * quat[3], 0), 1);
if (magnitude < goog.vec.EPSILON) {
// This is nearly an identity rotation, so just use a fixed +X axis.
goog.vec.Vec3.setFromValues(axis, 1, 0, 0);
} else {
// Compute the proper rotation axis.
goog.vec.Vec3.setFromValues(axis, quat[0], quat[1], quat[2]);
// Make sure the rotation axis is of unit length.
goog.vec.Vec3.normalize(axis, axis);
}
// Adjust the range of the returned angle to [-PI, +PI].
if (angle > Math.PI) {
angle -= 2 * Math.PI;
}
return angle;
};
/**
* Generates the quaternion from the given rotation matrix.
*
* @param {goog.vec.Quaternion.AnyType} matrix The source matrix.
* @param {goog.vec.Quaternion.AnyType} quat The resulting quaternion.
* @return {!goog.vec.Quaternion.AnyType} Return q so that
* operations can be chained together.
*/
goog.vec.Quaternion.fromRotationMatrix4 = function(matrix, quat) {
var sx = matrix[0], sy = matrix[5], sz = matrix[10];
quat[3] = Math.sqrt(Math.max(0, 1 + sx + sy + sz)) / 2;
quat[0] = Math.sqrt(Math.max(0, 1 + sx - sy - sz)) / 2;
quat[1] = Math.sqrt(Math.max(0, 1 - sx + sy - sz)) / 2;
quat[2] = Math.sqrt(Math.max(0, 1 - sx - sy + sz)) / 2;
quat[0] = (matrix[6] - matrix[9] < 0) != (quat[0] < 0) ? -quat[0] : quat[0];
quat[1] = (matrix[8] - matrix[2] < 0) != (quat[1] < 0) ? -quat[1] : quat[1];
quat[2] = (matrix[1] - matrix[4] < 0) != (quat[2] < 0) ? -quat[2] : quat[2];
return quat;
};
/**
* Generates the rotation matrix from the given quaternion.
*
* @param {goog.vec.Quaternion.AnyType} quat The source quaternion.
* @param {goog.vec.AnyType} matrix The resulting matrix.
* @return {!goog.vec.AnyType} Return resulting matrix so that
* operations can be chained together.
*/
goog.vec.Quaternion.toRotationMatrix4 = function(quat, matrix) {
var x = quat[0], y = quat[1], z = quat[2], w = quat[3];
var x2 = 2 * x, y2 = 2 * y, z2 = 2 * z;
var wx = x2 * w;
var wy = y2 * w;
var wz = z2 * w;
var xx = x2 * x;
var xy = y2 * x;
var xz = z2 * x;
var yy = y2 * y;
var yz = z2 * y;
var zz = z2 * z;
matrix[0] = 1 - (yy + zz);
matrix[1] = xy + wz;
matrix[2] = xz - wy;
matrix[3] = 0;
matrix[4] = xy - wz;
matrix[5] = 1 - (xx + zz);
matrix[6] = yz + wx;
matrix[7] = 0;
matrix[8] = xz + wy;
matrix[9] = yz - wx;
matrix[10] = 1 - (xx + yy);
matrix[11] = 0;
matrix[12] = 0;
matrix[13] = 0;
matrix[14] = 0;
matrix[15] = 1;
return matrix;
};
/**
* Computes the spherical linear interpolated value from the given quaternions
* q0 and q1 according to the coefficient t. The resulting quaternion is stored
* in resultQuat.
*
* @param {goog.vec.Quaternion.AnyType} q0 The first quaternion.
* @param {goog.vec.Quaternion.AnyType} q1 The second quaternion.
* @param {number} t The interpolating coefficient.
* @param {goog.vec.Quaternion.AnyType} resultQuat The quaternion to
* receive the result.
* @return {goog.vec.Quaternion.AnyType} Return q so that
* operations can be chained together.
*/
goog.vec.Quaternion.slerp = function(q0, q1, t, resultQuat) {
// Compute the dot product between q0 and q1 (cos of the angle between q0 and
// q1). If it's outside the interval [-1,1], then the arccos is not defined.
// The usual reason for this is that q0 and q1 are colinear. In this case
// the angle between the two is zero, so just return q1.
var cosVal = goog.vec.Quaternion.dot(q0, q1);
if (cosVal > 1 || cosVal < -1) {
goog.vec.Vec4.setFromArray(resultQuat, q1);
return resultQuat;
}
// Quaternions are a double cover on the space of rotations. That is, q and -q
// represent the same rotation. Thus we have two possibilities when
// interpolating between q0 and q1: going the short way or the long way. We
// prefer the short way since that is the likely expectation from users.
var factor = 1;
if (cosVal < 0) {
factor = -1;
cosVal = -cosVal;
}
// Compute the angle between q0 and q1. If it's very small, then just return
// q1 to avoid a very large denominator below.
var angle = Math.acos(cosVal);
if (angle <= goog.vec.EPSILON) {
goog.vec.Vec4.setFromArray(resultQuat, q1);
return resultQuat;
}
// Compute the coefficients and interpolate.
var invSinVal = 1 / Math.sin(angle);
var c0 = Math.sin((1 - t) * angle) * invSinVal;
var c1 = factor * Math.sin(t * angle) * invSinVal;
resultQuat[0] = q0[0] * c0 + q1[0] * c1;
resultQuat[1] = q0[1] * c0 + q1[1] * c1;
resultQuat[2] = q0[2] * c0 + q1[2] * c1;
resultQuat[3] = q0[3] * c0 + q1[3] * c1;
return resultQuat;
};
/**
* Compute the simple linear interpolation of the two quaternions q0 and q1
* according to the coefficient t. The resulting quaternion is stored in
* resultVec.
*
* @param {goog.vec.Quaternion.AnyType} q0 The first quaternion.
* @param {goog.vec.Quaternion.AnyType} q1 The second quaternion.
* @param {number} t The interpolation factor.
* @param {goog.vec.Quaternion.AnyType} resultQuat The quaternion to
* receive the results (may be q0 or q1).
*/
goog.vec.Quaternion.nlerp = goog.vec.Vec4.lerp;
@@ -0,0 +1,195 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Quaternion</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.Mat4');
goog.require('goog.vec.Quaternion');
goog.require('goog.vec.Vec3');
goog.require('goog.vec.Vec4');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testConjugate() {
var q0 = goog.vec.Quaternion.createFloat32FromValues(1, 2, 3, 4);
var q1 = goog.vec.Quaternion.createFloat32();
goog.vec.Quaternion.conjugate(q0, q1);
assertElementsEquals([1, 2, 3, 4], q0);
assertElementsEquals([-1, -2, -3, 4], q1);
goog.vec.Quaternion.conjugate(q1, q1);
assertElementsEquals([1, 2, 3, 4], q1);
}
function testConcat() {
var q0 = goog.vec.Quaternion.createFloat32FromValues(1, 2, 3, 4);
var q1 = goog.vec.Quaternion.createFloat32FromValues(2, 3, 4, 5);
var q2 = goog.vec.Quaternion.createFloat32();
goog.vec.Quaternion.concat(q0, q1, q2);
assertElementsEquals([12, 24, 30, 0], q2);
goog.vec.Quaternion.concat(q0, q1, q0);
assertElementsEquals([12, 24, 30, 0], q0);
}
function testSlerp() {
var q0 = goog.vec.Quaternion.createFloat32FromValues(1, 2, 3, 4);
var q1 = goog.vec.Quaternion.createFloat32FromValues(5, -6, 7, -8);
var q2 = goog.vec.Quaternion.createFloat32();
goog.vec.Quaternion.slerp(q0, q1, 0, q2);
assertElementsEquals([5, -6, 7, -8], q2);
goog.vec.Quaternion.normalize(q0, q0);
goog.vec.Quaternion.normalize(q1, q1);
goog.vec.Quaternion.slerp(q0, q0, .5, q2);
assertElementsEquals(q0, q2);
goog.vec.Quaternion.slerp(q0, q1, 0, q2);
assertElementsEquals(q0, q2);
goog.vec.Quaternion.slerp(q0, q1, 1, q2);
if (q1[3] * q2[3] < 0) {
goog.vec.Quaternion.negate(q2, q2);
}
assertElementsEquals(q1, q2);
goog.vec.Quaternion.slerp(q0, q1, .3, q2);
assertElementsRoughlyEqual(
[-0.000501537327541, 0.4817612034640, 0.2398775270769, 0.842831337398],
q2, goog.vec.EPSILON);
goog.vec.Quaternion.slerp(q0, q1, .5, q2);
assertElementsRoughlyEqual(
[-0.1243045421171, 0.51879732466, 0.0107895780990, 0.845743047108],
q2, goog.vec.EPSILON);
goog.vec.Quaternion.slerp(q0, q1, .8, q0);
assertElementsRoughlyEqual(
[-0.291353561485, 0.506925588797, -0.3292443285721, 0.741442999653],
q0, goog.vec.EPSILON);
}
function testToRotMatrix() {
var q0 = goog.vec.Quaternion.createFloat32FromValues(
0.22094256606638, 0.53340203646030,
0.64777022739548, 0.497051689967954);
var m0 = goog.vec.Mat4.createFloat32();
goog.vec.Quaternion.toRotationMatrix4(q0, m0);
assertElementsRoughlyEqual(
[-0.408248, 0.8796528, -0.244016935, 0,
-0.4082482, 0.06315623, 0.9106836, 0,
0.8164965, 0.47140452, 0.3333333, 0,
0, 0, 0, 1],
m0, goog.vec.EPSILON);
}
function testFromRotMatrix() {
var m0 = goog.vec.Mat4.createFloat32FromValues(
-0.408248, 0.8796528, -0.244016935, 0,
-0.4082482, 0.06315623, 0.9106836, 0,
0.8164965, 0.47140452, 0.3333333, 0,
0, 0, 0, 1);
var q0 = goog.vec.Quaternion.createFloat32();
goog.vec.Quaternion.fromRotationMatrix4(m0, q0);
assertElementsRoughlyEqual(
[0.22094256606638, 0.53340203646030,
0.64777022739548, 0.497051689967954],
q0, goog.vec.EPSILON);
}
function testToAngleAxis() {
// Test the identity rotation.
var q0 = goog.vec.Quaternion.createFloat32FromValues(0, 0, 0, 1);
var axis = goog.vec.Vec3.createFloat32();
var angle = goog.vec.Quaternion.toAngleAxis(q0, axis);
assertRoughlyEquals(0.0, angle, goog.vec.EPSILON);
assertElementsRoughlyEqual([1, 0, 0], axis, goog.vec.EPSILON);
// Check equivalent representations of the same rotation.
goog.vec.Quaternion.setFromValues(
q0, -0.288675032, 0.622008682, -0.17254543, 0.70710678);
angle = goog.vec.Quaternion.toAngleAxis(q0, axis);
assertRoughlyEquals(Math.PI / 2, angle, goog.vec.EPSILON);
assertElementsRoughlyEqual([-0.408248, 0.8796528, -0.244016],
axis, goog.vec.EPSILON);
// The polar opposite unit quaternion is the same rotation, so we
// check that the negated quaternion yields the negated angle and axis.
goog.vec.Quaternion.negate(q0, q0);
angle = goog.vec.Quaternion.toAngleAxis(q0, axis);
assertRoughlyEquals(-Math.PI / 2, angle, goog.vec.EPSILON);
assertElementsRoughlyEqual([0.408248, -0.8796528, 0.244016],
axis, goog.vec.EPSILON);
// Verify that the inverse rotation yields the inverse axis.
goog.vec.Quaternion.conjugate(q0, q0);
angle = goog.vec.Quaternion.toAngleAxis(q0, axis);
assertRoughlyEquals(-Math.PI / 2, angle, goog.vec.EPSILON);
assertElementsRoughlyEqual([-0.408248, 0.8796528, -0.244016],
axis, goog.vec.EPSILON);
}
function testFromAngleAxis() {
// Test identity rotation (zero angle or multiples of TWO_PI).
var angle = 0.0;
var axis = goog.vec.Vec3.createFloat32FromValues(-0.408248, 0.8796528,
-0.244016);
var q0 = goog.vec.Quaternion.createFloat32();
goog.vec.Quaternion.fromAngleAxis(angle, axis, q0);
assertElementsRoughlyEqual([0, 0, 0, 1], q0, goog.vec.EPSILON);
angle = 4 * Math.PI;
goog.vec.Quaternion.fromAngleAxis(angle, axis, q0);
assertElementsRoughlyEqual([0, 0, 0, 1], q0, goog.vec.EPSILON);
// General test of various rotations around axes of different lengths.
angle = Math.PI / 2;
goog.vec.Quaternion.fromAngleAxis(angle, axis, q0);
assertElementsRoughlyEqual(
[-0.288675032, 0.622008682, -0.17254543, 0.70710678],
q0, goog.vec.EPSILON);
// Angle multiples of TWO_PI with a scaled axis should be the same.
angle += 4 * Math.PI;
goog.vec.Vec3.scale(axis, 7.0, axis);
goog.vec.Quaternion.fromAngleAxis(angle, axis, q0);
assertElementsRoughlyEqual(
[-0.288675032, 0.622008682, -0.17254543, 0.70710678],
q0, goog.vec.EPSILON);
goog.vec.Vec3.setFromValues(axis, 1, 5, 8);
goog.vec.Quaternion.fromAngleAxis(angle, axis, q0);
assertElementsRoughlyEqual(
[0.074535599, 0.372677996, 0.596284794, 0.70710678],
q0, goog.vec.EPSILON);
// Check equivalent representations of the same rotation.
angle = Math.PI / 5;
goog.vec.Vec3.setFromValues(axis, 5, -2, -10);
goog.vec.Quaternion.fromAngleAxis(angle, axis, q0);
assertElementsRoughlyEqual(
[0.136037146, -0.0544148586, -0.27207429, 0.951056516],
q0, goog.vec.EPSILON);
// The negated angle and axis should yield the same rotation.
angle = -Math.PI / 5;
goog.vec.Vec3.negate(axis, axis);
goog.vec.Quaternion.fromAngleAxis(angle, axis, q0);
assertElementsRoughlyEqual(
[0.136037146, -0.0544148586, -0.27207429, 0.951056516],
q0, goog.vec.EPSILON);
}
</script>
</body>
@@ -0,0 +1,95 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Implements a 3D ray that are compatible with WebGL.
* Each element is a float64 in case high precision is required.
* The API is structured to avoid unnecessary memory allocations.
* The last parameter will typically be the output vector and an
* object can be both an input and output parameter to all methods
* except where noted.
*
*/
goog.provide('goog.vec.Ray');
goog.require('goog.vec.Vec3');
/**
* Constructs a new ray with an optional origin and direction. If not specified,
* the default is [0, 0, 0].
* @param {goog.vec.Vec3.AnyType=} opt_origin The optional origin.
* @param {goog.vec.Vec3.AnyType=} opt_dir The optional direction.
* @constructor
* @final
*/
goog.vec.Ray = function(opt_origin, opt_dir) {
/**
* @type {goog.vec.Vec3.Float64}
*/
this.origin = goog.vec.Vec3.createFloat64();
if (opt_origin) {
goog.vec.Vec3.setFromArray(this.origin, opt_origin);
}
/**
* @type {goog.vec.Vec3.Float64}
*/
this.dir = goog.vec.Vec3.createFloat64();
if (opt_dir) {
goog.vec.Vec3.setFromArray(this.dir, opt_dir);
}
};
/**
* Sets the origin and direction of the ray.
* @param {goog.vec.AnyType} origin The new origin.
* @param {goog.vec.AnyType} dir The new direction.
*/
goog.vec.Ray.prototype.set = function(origin, dir) {
goog.vec.Vec3.setFromArray(this.origin, origin);
goog.vec.Vec3.setFromArray(this.dir, dir);
};
/**
* Sets the origin of the ray.
* @param {goog.vec.AnyType} origin the new origin.
*/
goog.vec.Ray.prototype.setOrigin = function(origin) {
goog.vec.Vec3.setFromArray(this.origin, origin);
};
/**
* Sets the direction of the ray.
* @param {goog.vec.AnyType} dir The new direction.
*/
goog.vec.Ray.prototype.setDir = function(dir) {
goog.vec.Vec3.setFromArray(this.dir, dir);
};
/**
* Returns true if this ray is equal to the other ray.
* @param {goog.vec.Ray} other The other ray.
* @return {boolean} True if this ray is equal to the other ray.
*/
goog.vec.Ray.prototype.equals = function(other) {
return other != null &&
goog.vec.Vec3.equals(this.origin, other.origin) &&
goog.vec.Vec3.equals(this.dir, other.dir);
};
@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Ray</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.Ray');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testConstructor() {
var new_ray = new goog.vec.Ray();
assertElementsEquals([0, 0, 0], new_ray.origin);
assertElementsEquals([0, 0, 0], new_ray.dir);
new_ray = new goog.vec.Ray([1, 2, 3], [4, 5, 6]);
assertElementsEquals([1, 2, 3], new_ray.origin);
assertElementsEquals([4, 5, 6], new_ray.dir);
}
function testSet() {
var new_ray = new goog.vec.Ray();
new_ray.set([2, 3, 4], [5, 6, 7]);
assertElementsEquals([2, 3, 4], new_ray.origin);
assertElementsEquals([5, 6, 7], new_ray.dir);
}
function testSetOrigin() {
var new_ray = new goog.vec.Ray();
new_ray.setOrigin([1, 2, 3]);
assertElementsEquals([1, 2, 3], new_ray.origin);
assertElementsEquals([0, 0, 0], new_ray.dir);
}
function testSetDir() {
var new_ray = new goog.vec.Ray();
new_ray.setDir([2, 3, 4]);
assertElementsEquals([0, 0, 0], new_ray.origin);
assertElementsEquals([2, 3, 4], new_ray.dir);
}
function testEquals() {
var r0 = new goog.vec.Ray([1, 2, 3], [4, 5, 6]);
var r1 = new goog.vec.Ray([5, 2, 3], [4, 5, 6]);
assertFalse(r0.equals(r1));
assertFalse(r0.equals(null));
assertTrue(r1.equals(r1));
r1.setOrigin(r0.origin);
assertTrue(r1.equals(r0));
assertTrue(r0.equals(r1));
}
</script>
</body>
@@ -0,0 +1,73 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Supplies global data types and constants for the vector math
* library.
*/
goog.provide('goog.vec');
goog.provide('goog.vec.AnyType');
goog.provide('goog.vec.ArrayType');
goog.provide('goog.vec.Float32');
goog.provide('goog.vec.Float64');
goog.provide('goog.vec.Number');
/**
* On platforms that don't have native Float32Array or Float64Array support we
* use a javascript implementation so that this math library can be used on all
* platforms.
* @suppress {extraRequire}
*/
goog.require('goog.vec.Float32Array');
/** @suppress {extraRequire} */
goog.require('goog.vec.Float64Array');
// All vector and matrix operations are based upon arrays of numbers using
// either Float32Array, Float64Array, or a standard Javascript Array of
// Numbers.
/** @typedef {!Float32Array} */
goog.vec.Float32;
/** @typedef {!Float64Array} */
goog.vec.Float64;
/** @typedef {!Array<number>} */
goog.vec.Number;
/** @typedef {!goog.vec.Float32|!goog.vec.Float64|!goog.vec.Number} */
goog.vec.AnyType;
/**
* @deprecated Use AnyType.
* @typedef {!Float32Array|!Array<number>}
*/
goog.vec.ArrayType;
/**
* For graphics work, 6 decimal places of accuracy are typically all that is
* required.
*
* @type {number}
* @const
*/
goog.vec.EPSILON = 1e-6;
@@ -0,0 +1,439 @@
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Definition of 2 element vectors. This follows the same design
* patterns as Vec3 and Vec4.
*
*/
goog.provide('goog.vec.Vec2');
/** @suppress {extraRequire} */
goog.require('goog.vec');
/** @typedef {goog.vec.Float32} */ goog.vec.Vec2.Float32;
/** @typedef {goog.vec.Float64} */ goog.vec.Vec2.Float64;
/** @typedef {goog.vec.Number} */ goog.vec.Vec2.Number;
/** @typedef {goog.vec.AnyType} */ goog.vec.Vec2.AnyType;
/**
* Creates a 2 element vector of Float32. The array is initialized to zero.
*
* @return {!goog.vec.Vec2.Float32} The new 2 element array.
*/
goog.vec.Vec2.createFloat32 = function() {
return new Float32Array(2);
};
/**
* Creates a 2 element vector of Float64. The array is initialized to zero.
*
* @return {!goog.vec.Vec2.Float64} The new 2 element array.
*/
goog.vec.Vec2.createFloat64 = function() {
return new Float64Array(2);
};
/**
* Creates a 2 element vector of Number. The array is initialized to zero.
*
* @return {!goog.vec.Vec2.Number} The new 2 element array.
*/
goog.vec.Vec2.createNumber = function() {
var a = new Array(2);
goog.vec.Vec2.setFromValues(a, 0, 0);
return a;
};
/**
* Creates a new 2 element FLoat32 vector initialized with the value from the
* given array.
*
* @param {goog.vec.Vec2.AnyType} vec The source 2 element array.
* @return {!goog.vec.Vec2.Float32} The new 2 element array.
*/
goog.vec.Vec2.createFloat32FromArray = function(vec) {
var newVec = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.setFromArray(newVec, vec);
return newVec;
};
/**
* Creates a new 2 element Float32 vector initialized with the supplied values.
*
* @param {number} vec0 The value for element at index 0.
* @param {number} vec1 The value for element at index 1.
* @return {!goog.vec.Vec2.Float32} The new vector.
*/
goog.vec.Vec2.createFloat32FromValues = function(vec0, vec1) {
var a = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.setFromValues(a, vec0, vec1);
return a;
};
/**
* Creates a clone of the given 2 element Float32 vector.
*
* @param {goog.vec.Vec2.Float32} vec The source 2 element vector.
* @return {!goog.vec.Vec2.Float32} The new cloned vector.
*/
goog.vec.Vec2.cloneFloat32 = goog.vec.Vec2.createFloat32FromArray;
/**
* Creates a new 2 element Float64 vector initialized with the value from the
* given array.
*
* @param {goog.vec.Vec2.AnyType} vec The source 2 element array.
* @return {!goog.vec.Vec2.Float64} The new 2 element array.
*/
goog.vec.Vec2.createFloat64FromArray = function(vec) {
var newVec = goog.vec.Vec2.createFloat64();
goog.vec.Vec2.setFromArray(newVec, vec);
return newVec;
};
/**
* Creates a new 2 element Float64 vector initialized with the supplied values.
*
* @param {number} vec0 The value for element at index 0.
* @param {number} vec1 The value for element at index 1.
* @return {!goog.vec.Vec2.Float64} The new vector.
*/
goog.vec.Vec2.createFloat64FromValues = function(vec0, vec1) {
var vec = goog.vec.Vec2.createFloat64();
goog.vec.Vec2.setFromValues(vec, vec0, vec1);
return vec;
};
/**
* Creates a clone of the given 2 element vector.
*
* @param {goog.vec.Vec2.Float64} vec The source 2 element vector.
* @return {!goog.vec.Vec2.Float64} The new cloned vector.
*/
goog.vec.Vec2.cloneFloat64 = goog.vec.Vec2.createFloat64FromArray;
/**
* Initializes the vector with the given values.
*
* @param {goog.vec.Vec2.AnyType} vec The vector to receive the values.
* @param {number} vec0 The value for element at index 0.
* @param {number} vec1 The value for element at index 1.
* @return {!goog.vec.Vec2.AnyType} Return vec so that operations can be
* chained together.
*/
goog.vec.Vec2.setFromValues = function(vec, vec0, vec1) {
vec[0] = vec0;
vec[1] = vec1;
return vec;
};
/**
* Initializes the vector with the given array of values.
*
* @param {goog.vec.Vec2.AnyType} vec The vector to receive the
* values.
* @param {goog.vec.Vec2.AnyType} values The array of values.
* @return {!goog.vec.Vec2.AnyType} Return vec so that operations can be
* chained together.
*/
goog.vec.Vec2.setFromArray = function(vec, values) {
vec[0] = values[0];
vec[1] = values[1];
return vec;
};
/**
* Performs a component-wise addition of vec0 and vec1 together storing the
* result into resultVec.
*
* @param {goog.vec.Vec2.AnyType} vec0 The first addend.
* @param {goog.vec.Vec2.AnyType} vec1 The second addend.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.add = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] + vec1[0];
resultVec[1] = vec0[1] + vec1[1];
return resultVec;
};
/**
* Performs a component-wise subtraction of vec1 from vec0 storing the
* result into resultVec.
*
* @param {goog.vec.Vec2.AnyType} vec0 The minuend.
* @param {goog.vec.Vec2.AnyType} vec1 The subtrahend.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.subtract = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] - vec1[0];
resultVec[1] = vec0[1] - vec1[1];
return resultVec;
};
/**
* Negates vec0, storing the result into resultVec.
*
* @param {goog.vec.Vec2.AnyType} vec0 The vector to negate.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.negate = function(vec0, resultVec) {
resultVec[0] = -vec0[0];
resultVec[1] = -vec0[1];
return resultVec;
};
/**
* Takes the absolute value of each component of vec0 storing the result in
* resultVec.
*
* @param {goog.vec.Vec2.AnyType} vec0 The source vector.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the result.
* May be vec0.
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.abs = function(vec0, resultVec) {
resultVec[0] = Math.abs(vec0[0]);
resultVec[1] = Math.abs(vec0[1]);
return resultVec;
};
/**
* Multiplies each component of vec0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.Vec2.AnyType} vec0 The source vector.
* @param {number} scalar The value to multiply with each component of vec0.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.scale = function(vec0, scalar, resultVec) {
resultVec[0] = vec0[0] * scalar;
resultVec[1] = vec0[1] * scalar;
return resultVec;
};
/**
* Returns the magnitudeSquared of the given vector.
*
* @param {goog.vec.Vec2.AnyType} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.Vec2.magnitudeSquared = function(vec0) {
var x = vec0[0], y = vec0[1];
return x * x + y * y;
};
/**
* Returns the magnitude of the given vector.
*
* @param {goog.vec.Vec2.AnyType} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.Vec2.magnitude = function(vec0) {
var x = vec0[0], y = vec0[1];
return Math.sqrt(x * x + y * y);
};
/**
* Normalizes the given vector storing the result into resultVec.
*
* @param {goog.vec.Vec2.AnyType} vec0 The vector to normalize.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.normalize = function(vec0, resultVec) {
var ilen = 1 / goog.vec.Vec2.magnitude(vec0);
resultVec[0] = vec0[0] * ilen;
resultVec[1] = vec0[1] * ilen;
return resultVec;
};
/**
* Returns the scalar product of vectors vec0 and vec1.
*
* @param {goog.vec.Vec2.AnyType} vec0 The first vector.
* @param {goog.vec.Vec2.AnyType} vec1 The second vector.
* @return {number} The scalar product.
*/
goog.vec.Vec2.dot = function(vec0, vec1) {
return vec0[0] * vec1[0] + vec0[1] * vec1[1];
};
/**
* Returns the squared distance between two points.
*
* @param {goog.vec.Vec2.AnyType} vec0 First point.
* @param {goog.vec.Vec2.AnyType} vec1 Second point.
* @return {number} The squared distance between the points.
*/
goog.vec.Vec2.distanceSquared = function(vec0, vec1) {
var x = vec0[0] - vec1[0];
var y = vec0[1] - vec1[1];
return x * x + y * y;
};
/**
* Returns the distance between two points.
*
* @param {goog.vec.Vec2.AnyType} vec0 First point.
* @param {goog.vec.Vec2.AnyType} vec1 Second point.
* @return {number} The distance between the points.
*/
goog.vec.Vec2.distance = function(vec0, vec1) {
return Math.sqrt(goog.vec.Vec2.distanceSquared(vec0, vec1));
};
/**
* Returns a unit vector pointing from one point to another.
* If the input points are equal then the result will be all zeros.
*
* @param {goog.vec.Vec2.AnyType} vec0 Origin point.
* @param {goog.vec.Vec2.AnyType} vec1 Target point.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the
* results (may be vec0 or vec1).
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.direction = function(vec0, vec1, resultVec) {
var x = vec1[0] - vec0[0];
var y = vec1[1] - vec0[1];
var d = Math.sqrt(x * x + y * y);
if (d) {
d = 1 / d;
resultVec[0] = x * d;
resultVec[1] = y * d;
} else {
resultVec[0] = resultVec[1] = 0;
}
return resultVec;
};
/**
* Linearly interpolate from vec0 to vec1 according to f. The value of f should
* be in the range [0..1] otherwise the results are undefined.
*
* @param {goog.vec.Vec2.AnyType} vec0 The first vector.
* @param {goog.vec.Vec2.AnyType} vec1 The second vector.
* @param {number} f The interpolation factor.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the
* results (may be vec0 or vec1).
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.lerp = function(vec0, vec1, f, resultVec) {
var x = vec0[0], y = vec0[1];
resultVec[0] = (vec1[0] - x) * f + x;
resultVec[1] = (vec1[1] - y) * f + y;
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the larger values in resultVec.
*
* @param {goog.vec.Vec2.AnyType} vec0 The source vector.
* @param {goog.vec.Vec2.AnyType|number} limit The limit vector or scalar.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.max = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.max(vec0[0], limit);
resultVec[1] = Math.max(vec0[1], limit);
} else {
resultVec[0] = Math.max(vec0[0], limit[0]);
resultVec[1] = Math.max(vec0[1], limit[1]);
}
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the smaller values in resultVec.
*
* @param {goog.vec.Vec2.AnyType} vec0 The source vector.
* @param {goog.vec.Vec2.AnyType|number} limit The limit vector or scalar.
* @param {goog.vec.Vec2.AnyType} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.Vec2.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec2.min = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.min(vec0[0], limit);
resultVec[1] = Math.min(vec0[1], limit);
} else {
resultVec[0] = Math.min(vec0[0], limit[0]);
resultVec[1] = Math.min(vec0[1], limit[1]);
}
return resultVec;
};
/**
* Returns true if the components of vec0 are equal to the components of vec1.
*
* @param {goog.vec.Vec2.AnyType} vec0 The first vector.
* @param {goog.vec.Vec2.AnyType} vec1 The second vector.
* @return {boolean} True if the vectors are equal, false otherwise.
*/
goog.vec.Vec2.equals = function(vec0, vec1) {
return vec0.length == vec1.length &&
vec0[0] == vec1[0] && vec0[1] == vec1[1];
};
@@ -0,0 +1,254 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2012 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Vec2</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.Vec2');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testConstructor() {
var v = goog.vec.Vec2.createFloat32();
assertElementsEquals(0, v[0]);
assertEquals(0, v[1]);
assertElementsEquals([0, 0], goog.vec.Vec2.createFloat32());
goog.vec.Vec2.setFromValues(v, 1, 2);
assertElementsEquals([1, 2], v);
var w = goog.vec.Vec2.createFloat64();
assertElementsEquals(0, w[0]);
assertEquals(0, w[1]);
assertElementsEquals([0, 0], goog.vec.Vec2.createFloat64());
goog.vec.Vec2.setFromValues(w, 1, 2);
assertElementsEquals([1, 2], w);
}
function testSet() {
var v = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.setFromValues(v, 1, 2);
assertElementsEquals([1, 2], v);
goog.vec.Vec2.setFromArray(v, [4, 5]);
assertElementsEquals([4, 5], v);
var w = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.setFromValues(w, 1, 2);
assertElementsEquals([1, 2], w);
goog.vec.Vec2.setFromArray(w, [4, 5]);
assertElementsEquals([4, 5], w);
}
function testAdd() {
var v0 = goog.vec.Vec2.createFloat32FromArray([1, 2]);
var v1 = goog.vec.Vec2.createFloat32FromArray([4, 5]);
var v2 = goog.vec.Vec2.cloneFloat32(v0);
goog.vec.Vec2.add(v2, v1, v2);
assertElementsEquals([1, 2], v0);
assertElementsEquals([4, 5], v1);
assertElementsEquals([5, 7], v2);
goog.vec.Vec2.add(goog.vec.Vec2.add(v0, v1, v2), v0, v2);
assertElementsEquals([6, 9], v2);
}
function testSubtract() {
var v0 = goog.vec.Vec2.createFloat32FromArray([1, 2]);
var v1 = goog.vec.Vec2.createFloat32FromArray([4, 5]);
var v2 = goog.vec.Vec2.cloneFloat32(v0);
goog.vec.Vec2.subtract(v2, v1, v2);
assertElementsEquals([1, 2], v0);
assertElementsEquals([4, 5], v1);
assertElementsEquals([-3, -3], v2);
goog.vec.Vec2.setFromValues(v2, 0, 0, 0);
goog.vec.Vec2.subtract(v1, v0, v2);
assertElementsEquals([3, 3], v2);
v2 = goog.vec.Vec2.cloneFloat32(v0);
goog.vec.Vec2.subtract(v2, v1, v2);
assertElementsEquals([-3, -3], v2);
goog.vec.Vec2.subtract(goog.vec.Vec2.subtract(v1, v0, v2), v0, v2);
assertElementsEquals([2, 1], v2);
}
function testNegate() {
var v0 = goog.vec.Vec2.createFloat32FromArray([1, 2]);
var v1 = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.negate(v0, v1);
assertElementsEquals([-1, -2], v1);
assertElementsEquals([1, 2], v0);
goog.vec.Vec2.negate(v0, v0);
assertElementsEquals([-1, -2], v0);
}
function testAbs() {
var v0 = goog.vec.Vec2.createFloat32FromValues(-1, -2);
var v1 = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.abs(v0, v1);
assertElementsEquals([1, 2], v1);
assertElementsEquals([-1, -2], v0);
goog.vec.Vec2.abs(v0, v0);
assertElementsEquals([1, 2], v0);
}
function testScale() {
var v0 = goog.vec.Vec2.createFloat32FromArray([1, 2]);
var v1 = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.scale(v0, 4, v1);
assertElementsEquals([4, 8], v1);
assertElementsEquals([1, 2], v0);
goog.vec.Vec2.setFromArray(v1, v0);
goog.vec.Vec2.scale(v1, 5, v1);
assertElementsEquals([5, 10], v1);
}
function testMagnitudeSquared() {
var v0 = goog.vec.Vec2.createFloat32FromArray([1, 2]);
assertEquals(5, goog.vec.Vec2.magnitudeSquared(v0));
}
function testMagnitude() {
var v0 = goog.vec.Vec2.createFloat32FromArray([1, 2]);
assertEquals(Math.sqrt(5), goog.vec.Vec2.magnitude(v0));
}
function testNormalize() {
var v0 = goog.vec.Vec2.createFloat32FromArray([2, 3]);
var v1 = goog.vec.Vec2.createFloat32();
var v2 = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.scale(
v0, 1 / goog.vec.Vec2.magnitude(v0), v2);
goog.vec.Vec2.normalize(v0, v1);
assertElementsEquals(v2, v1);
assertElementsEquals([2, 3], v0);
goog.vec.Vec2.setFromArray(v1, v0);
goog.vec.Vec2.normalize(v1, v1);
assertElementsEquals(v2, v1);
}
function testDot() {
var v0 = goog.vec.Vec2.createFloat32FromArray([1, 2]);
var v1 = goog.vec.Vec2.createFloat32FromArray([4, 5]);
assertEquals(14, goog.vec.Vec2.dot(v0, v1));
assertEquals(14, goog.vec.Vec2.dot(v1, v0));
}
function testDistanceSquared() {
var v0 = goog.vec.Vec2.createFloat32FromValues(1, 2);
var v1 = goog.vec.Vec2.createFloat32FromValues(1, 2);
assertEquals(0, goog.vec.Vec2.distanceSquared(v0, v1));
goog.vec.Vec2.setFromValues(v0, 1, 2);
goog.vec.Vec2.setFromValues(v1, -1, -2);
assertEquals(20, goog.vec.Vec2.distanceSquared(v0, v1));
}
function testDistance() {
var v0 = goog.vec.Vec2.createFloat32FromValues(1, 2);
var v1 = goog.vec.Vec2.createFloat32FromValues(1, 2);
assertEquals(0, goog.vec.Vec2.distance(v0, v1));
goog.vec.Vec2.setFromValues(v0, 2, 3);
goog.vec.Vec2.setFromValues(v1, -2, 0);
assertEquals(5, goog.vec.Vec2.distance(v0, v1));
}
function testDirection() {
var v0 = goog.vec.Vec2.createFloat32FromValues(1, 2);
var v1 = goog.vec.Vec2.createFloat32FromValues(1, 2);
var dirVec = goog.vec.Vec2.createFloat32FromValues(4, 5);
goog.vec.Vec2.direction(v0, v1, dirVec);
assertElementsEquals([0, 0], dirVec);
goog.vec.Vec2.setFromValues(v0, 0, 0);
goog.vec.Vec2.setFromValues(v1, 1, 0);
goog.vec.Vec2.direction(v0, v1, dirVec);
assertElementsEquals([1, 0], dirVec);
goog.vec.Vec2.setFromValues(v0, 1, 1);
goog.vec.Vec2.setFromValues(v1, 0, 0);
goog.vec.Vec2.direction(v0, v1, dirVec);
assertElementsRoughlyEqual(
[-0.707106781, -0.707106781],
dirVec, goog.vec.EPSILON);
}
function testLerp() {
var v0 = goog.vec.Vec2.createFloat32FromValues(1, 2);
var v1 = goog.vec.Vec2.createFloat32FromValues(10, 20);
var v2 = goog.vec.Vec2.cloneFloat32(v0);
goog.vec.Vec2.lerp(v2, v1, 0, v2);
assertElementsEquals([1, 2], v2);
goog.vec.Vec2.lerp(v2, v1, 1, v2);
assertElementsEquals([10, 20], v2);
goog.vec.Vec2.lerp(v0, v1, .5, v2);
assertElementsEquals([5.5, 11], v2);
}
function testMax() {
var v0 = goog.vec.Vec2.createFloat32FromValues(10, 20);
var v1 = goog.vec.Vec2.createFloat32FromValues(5, 25);
var v2 = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.max(v0, v1, v2);
assertElementsEquals([10, 25], v2);
goog.vec.Vec2.max(v1, v0, v1);
assertElementsEquals([10, 25], v1);
goog.vec.Vec2.max(v2, 20, v2);
assertElementsEquals([20, 25], v2);
}
function testMin() {
var v0 = goog.vec.Vec2.createFloat32FromValues(10, 20);
var v1 = goog.vec.Vec2.createFloat32FromValues(5, 25);
var v2 = goog.vec.Vec2.createFloat32();
goog.vec.Vec2.min(v0, v1, v2);
assertElementsEquals([5, 20], v2);
goog.vec.Vec2.min(v1, v0, v1);
assertElementsEquals([5, 20], v1);
goog.vec.Vec2.min(v2, 10, v2);
assertElementsEquals([5, 10], v2);
}
function testEquals() {
var v0 = goog.vec.Vec2.createFloat32FromValues(1, 2);
var v1 = goog.vec.Vec2.cloneFloat32(v0);
assertElementsEquals(v0, v1);
v1[0] = 4;
assertFalse(goog.vec.Vec2.equals(v0, v1));
v1 = goog.vec.Vec2.cloneFloat32(v0);
v1[1] = 4;
assertFalse(goog.vec.Vec2.equals(v0, v1));
}
</script>
</body>
@@ -0,0 +1,424 @@
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec2f.js by running: //
// swap_type.sh vec2d.js > vec2f.js //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
/**
* @fileoverview Provides functions for operating on 2 element double (64bit)
* vectors.
*
* The last parameter will typically be the output object and an object
* can be both an input and output parameter to all methods except where
* noted.
*
* See the README for notes about the design and structure of the API
* (especially related to performance).
*
*/
goog.provide('goog.vec.vec2d');
goog.provide('goog.vec.vec2d.Type');
/** @suppress {extraRequire} */
goog.require('goog.vec');
/** @typedef {goog.vec.Float64} */ goog.vec.vec2d.Type;
/**
* Creates a vec2d with all elements initialized to zero.
*
* @return {!goog.vec.vec2d.Type} The new vec2d.
*/
goog.vec.vec2d.create = function() {
return new Float64Array(2);
};
/**
* Initializes the vector with the given values.
*
* @param {goog.vec.vec2d.Type} vec The vector to receive the values.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @return {!goog.vec.vec2d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec2d.setFromValues = function(vec, v0, v1) {
vec[0] = v0;
vec[1] = v1;
return vec;
};
/**
* Initializes vec2d vec from vec2d src.
*
* @param {goog.vec.vec2d.Type} vec The destination vector.
* @param {goog.vec.vec2d.Type} src The source vector.
* @return {!goog.vec.vec2d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec2d.setFromVec2d = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
return vec;
};
/**
* Initializes vec2d vec from vec2f src (typed as a Float32Array to
* avoid circular goog.requires).
*
* @param {goog.vec.vec2d.Type} vec The destination vector.
* @param {Float32Array} src The source vector.
* @return {!goog.vec.vec2d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec2d.setFromVec2f = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
return vec;
};
/**
* Initializes vec2d vec from Array src.
*
* @param {goog.vec.vec2d.Type} vec The destination vector.
* @param {Array<number>} src The source vector.
* @return {!goog.vec.vec2d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec2d.setFromArray = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
return vec;
};
/**
* Performs a component-wise addition of vec0 and vec1 together storing the
* result into resultVec.
*
* @param {goog.vec.vec2d.Type} vec0 The first addend.
* @param {goog.vec.vec2d.Type} vec1 The second addend.
* @param {goog.vec.vec2d.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.add = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] + vec1[0];
resultVec[1] = vec0[1] + vec1[1];
return resultVec;
};
/**
* Performs a component-wise subtraction of vec1 from vec0 storing the
* result into resultVec.
*
* @param {goog.vec.vec2d.Type} vec0 The minuend.
* @param {goog.vec.vec2d.Type} vec1 The subtrahend.
* @param {goog.vec.vec2d.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.subtract = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] - vec1[0];
resultVec[1] = vec0[1] - vec1[1];
return resultVec;
};
/**
* Multiplies each component of vec0 with the matching element of vec0
* storing the products into resultVec.
*
* @param {!goog.vec.vec2d.Type} vec0 The first vector.
* @param {!goog.vec.vec2d.Type} vec1 The second vector.
* @param {!goog.vec.vec2d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.componentMultiply = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] * vec1[0];
resultVec[1] = vec0[1] * vec1[1];
return resultVec;
};
/**
* Divides each component of vec0 with the matching element of vec0
* storing the divisor into resultVec.
*
* @param {!goog.vec.vec2d.Type} vec0 The first vector.
* @param {!goog.vec.vec2d.Type} vec1 The second vector.
* @param {!goog.vec.vec2d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.componentDivide = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] / vec1[0];
resultVec[1] = vec0[1] / vec1[1];
return resultVec;
};
/**
* Negates vec0, storing the result into resultVec.
*
* @param {goog.vec.vec2d.Type} vec0 The vector to negate.
* @param {goog.vec.vec2d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.negate = function(vec0, resultVec) {
resultVec[0] = -vec0[0];
resultVec[1] = -vec0[1];
return resultVec;
};
/**
* Takes the absolute value of each component of vec0 storing the result in
* resultVec.
*
* @param {goog.vec.vec2d.Type} vec0 The source vector.
* @param {goog.vec.vec2d.Type} resultVec The vector to receive the result.
* May be vec0.
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.abs = function(vec0, resultVec) {
resultVec[0] = Math.abs(vec0[0]);
resultVec[1] = Math.abs(vec0[1]);
return resultVec;
};
/**
* Multiplies each component of vec0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.vec2d.Type} vec0 The source vector.
* @param {number} scalar The value to multiply with each component of vec0.
* @param {goog.vec.vec2d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.scale = function(vec0, scalar, resultVec) {
resultVec[0] = vec0[0] * scalar;
resultVec[1] = vec0[1] * scalar;
return resultVec;
};
/**
* Returns the magnitudeSquared of the given vector.
*
* @param {goog.vec.vec2d.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec2d.magnitudeSquared = function(vec0) {
var x = vec0[0], y = vec0[1];
return x * x + y * y;
};
/**
* Returns the magnitude of the given vector.
*
* @param {goog.vec.vec2d.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec2d.magnitude = function(vec0) {
var x = vec0[0], y = vec0[1];
return Math.sqrt(x * x + y * y);
};
/**
* Normalizes the given vector storing the result into resultVec.
*
* @param {goog.vec.vec2d.Type} vec0 The vector to normalize.
* @param {goog.vec.vec2d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.normalize = function(vec0, resultVec) {
var x = vec0[0], y = vec0[1];
var ilen = 1 / Math.sqrt(x * x + y * y);
resultVec[0] = x * ilen;
resultVec[1] = y * ilen;
return resultVec;
};
/**
* Returns the scalar product of vectors vec0 and vec1.
*
* @param {goog.vec.vec2d.Type} vec0 The first vector.
* @param {goog.vec.vec2d.Type} vec1 The second vector.
* @return {number} The scalar product.
*/
goog.vec.vec2d.dot = function(vec0, vec1) {
return vec0[0] * vec1[0] + vec0[1] * vec1[1];
};
/**
* Returns the squared distance between two points.
*
* @param {goog.vec.vec2d.Type} vec0 First point.
* @param {goog.vec.vec2d.Type} vec1 Second point.
* @return {number} The squared distance between the points.
*/
goog.vec.vec2d.distanceSquared = function(vec0, vec1) {
var x = vec0[0] - vec1[0];
var y = vec0[1] - vec1[1];
return x * x + y * y;
};
/**
* Returns the distance between two points.
*
* @param {goog.vec.vec2d.Type} vec0 First point.
* @param {goog.vec.vec2d.Type} vec1 Second point.
* @return {number} The distance between the points.
*/
goog.vec.vec2d.distance = function(vec0, vec1) {
return Math.sqrt(goog.vec.vec2d.distanceSquared(vec0, vec1));
};
/**
* Returns a unit vector pointing from one point to another.
* If the input points are equal then the result will be all zeros.
*
* @param {goog.vec.vec2d.Type} vec0 Origin point.
* @param {goog.vec.vec2d.Type} vec1 Target point.
* @param {goog.vec.vec2d.Type} resultVec The vector to receive the
* results (may be vec0 or vec1).
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.direction = function(vec0, vec1, resultVec) {
var x = vec1[0] - vec0[0];
var y = vec1[1] - vec0[1];
var d = Math.sqrt(x * x + y * y);
if (d) {
d = 1 / d;
resultVec[0] = x * d;
resultVec[1] = y * d;
} else {
resultVec[0] = resultVec[1] = 0;
}
return resultVec;
};
/**
* Linearly interpolate from vec0 to vec1 according to f. The value of f should
* be in the range [0..1] otherwise the results are undefined.
*
* @param {goog.vec.vec2d.Type} vec0 The first vector.
* @param {goog.vec.vec2d.Type} vec1 The second vector.
* @param {number} f The interpolation factor.
* @param {goog.vec.vec2d.Type} resultVec The vector to receive the
* results (may be vec0 or vec1).
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.lerp = function(vec0, vec1, f, resultVec) {
var x = vec0[0], y = vec0[1];
resultVec[0] = (vec1[0] - x) * f + x;
resultVec[1] = (vec1[1] - y) * f + y;
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the larger values in resultVec.
*
* @param {goog.vec.vec2d.Type} vec0 The source vector.
* @param {goog.vec.vec2d.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec2d.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.max = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.max(vec0[0], limit);
resultVec[1] = Math.max(vec0[1], limit);
} else {
resultVec[0] = Math.max(vec0[0], limit[0]);
resultVec[1] = Math.max(vec0[1], limit[1]);
}
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the smaller values in resultVec.
*
* @param {goog.vec.vec2d.Type} vec0 The source vector.
* @param {goog.vec.vec2d.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec2d.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec2d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2d.min = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.min(vec0[0], limit);
resultVec[1] = Math.min(vec0[1], limit);
} else {
resultVec[0] = Math.min(vec0[0], limit[0]);
resultVec[1] = Math.min(vec0[1], limit[1]);
}
return resultVec;
};
/**
* Returns true if the components of vec0 are equal to the components of vec1.
*
* @param {goog.vec.vec2d.Type} vec0 The first vector.
* @param {goog.vec.vec2d.Type} vec1 The second vector.
* @return {boolean} True if the vectors are equal, false otherwise.
*/
goog.vec.vec2d.equals = function(vec0, vec1) {
return vec0.length == vec1.length &&
vec0[0] == vec1[0] && vec0[1] == vec1[1];
};
@@ -0,0 +1,282 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec2f_test.html by running: //
// swap_type.sh vec2d_test.html > vec2f_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.vec2d</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float64Array');
goog.require('goog.vec.vec2d');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testCreate() {
var v = goog.vec.vec2d.create();
assertElementsEquals([0, 0], v);
}
function testSet() {
var v = goog.vec.vec2d.create();
goog.vec.vec2d.setFromValues(v, 1, 2);
assertElementsEquals([1, 2], v);
goog.vec.vec2d.setFromArray(v, [4, 5]);
assertElementsEquals([4, 5], v);
var w = goog.vec.vec2d.create();
goog.vec.vec2d.setFromValues(w, 1, 2);
assertElementsEquals([1, 2], w);
goog.vec.vec2d.setFromArray(w, [4, 5]);
assertElementsEquals([4, 5], w);
}
function testAdd() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [1, 2]);
var v1 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [4, 5]);
var v2 = goog.vec.vec2d.setFromVec2d(goog.vec.vec2d.create(), v0);
goog.vec.vec2d.add(v2, v1, v2);
assertElementsEquals([1, 2], v0);
assertElementsEquals([4, 5], v1);
assertElementsEquals([5, 7], v2);
goog.vec.vec2d.add(goog.vec.vec2d.add(v0, v1, v2), v0, v2);
assertElementsEquals([6, 9], v2);
}
function testSubtract() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [1, 2]);
var v1 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [4, 5]);
var v2 = goog.vec.vec2d.setFromVec2d(goog.vec.vec2d.create(), v0);
goog.vec.vec2d.subtract(v2, v1, v2);
assertElementsEquals([1, 2], v0);
assertElementsEquals([4, 5], v1);
assertElementsEquals([-3, -3], v2);
goog.vec.vec2d.setFromValues(v2, 0, 0);
goog.vec.vec2d.subtract(v1, v0, v2);
assertElementsEquals([3, 3], v2);
v2 = goog.vec.vec2d.setFromVec2d(goog.vec.vec2d.create(), v0);
goog.vec.vec2d.subtract(v2, v1, v2);
assertElementsEquals([-3, -3], v2);
goog.vec.vec2d.subtract(goog.vec.vec2d.subtract(v1, v0, v2), v0, v2);
assertElementsEquals([2, 1], v2);
}
function testMultiply() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [1, 2]);
var v1 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [4, 5]);
var v2 = goog.vec.vec2d.setFromVec2d(goog.vec.vec2d.create(), v0);
goog.vec.vec2d.componentMultiply(v2, v1, v2);
assertElementsEquals([1, 2], v0);
assertElementsEquals([4, 5], v1);
assertElementsEquals([4, 10], v2);
goog.vec.vec2d.componentMultiply(goog.vec.vec2d.componentMultiply(v0, v1, v2), v0, v2);
assertElementsEquals([4, 20], v2);
}
function testDivide() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [1, 2]);
var v1 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [4, 5]);
var v2 = goog.vec.vec2d.setFromVec2d(goog.vec.vec2d.create(), v0);
goog.vec.vec2d.componentDivide(v2, v1, v2);
assertElementsRoughlyEqual([1, 2], v0, 10e-5);
assertElementsRoughlyEqual([4, 5], v1, 10e-5);
assertElementsRoughlyEqual([.25, .4], v2, 10e-5);
goog.vec.vec2d.setFromValues(v2, 0, 0);
goog.vec.vec2d.componentDivide(v1, v0, v2);
assertElementsRoughlyEqual([4, 2.5], v2, 10e-5);
v2 = goog.vec.vec2d.setFromVec2d(goog.vec.vec2d.create(), v0);
goog.vec.vec2d.componentDivide(v2, v1, v2);
assertElementsRoughlyEqual([.25, .4], v2, 10e-5);
goog.vec.vec2d.componentDivide(goog.vec.vec2d.componentDivide(v1, v0, v2), v0, v2);
assertElementsRoughlyEqual([4, 1.25], v2, 10e-5);
}
function testNegate() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [1, 2]);
var v1 = goog.vec.vec2d.create();
goog.vec.vec2d.negate(v0, v1);
assertElementsEquals([-1, -2], v1);
assertElementsEquals([1, 2], v0);
goog.vec.vec2d.negate(v0, v0);
assertElementsEquals([-1, -2], v0);
}
function testAbs() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [-1, -2]);
var v1 = goog.vec.vec2d.create();
goog.vec.vec2d.abs(v0, v1);
assertElementsEquals([1, 2], v1);
assertElementsEquals([-1, -2], v0);
goog.vec.vec2d.abs(v0, v0);
assertElementsEquals([1, 2], v0);
}
function testScale() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [1, 2]);
var v1 = goog.vec.vec2d.create();
goog.vec.vec2d.scale(v0, 4, v1);
assertElementsEquals([4, 8], v1);
assertElementsEquals([1, 2], v0);
goog.vec.vec2d.setFromArray(v1, v0);
goog.vec.vec2d.scale(v1, 5, v1);
assertElementsEquals([5, 10], v1);
}
function testMagnitudeSquared() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [1, 2]);
assertEquals(5, goog.vec.vec2d.magnitudeSquared(v0));
}
function testMagnitude() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [1, 2]);
assertEquals(Math.sqrt(5), goog.vec.vec2d.magnitude(v0));
}
function testNormalize() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [2, 3]);
var v1 = goog.vec.vec2d.create();
var v2 = goog.vec.vec2d.create();
goog.vec.vec2d.scale(
v0, 1 / goog.vec.vec2d.magnitude(v0), v2);
goog.vec.vec2d.normalize(v0, v1);
assertElementsEquals(v2, v1);
assertElementsEquals([2, 3], v0);
goog.vec.vec2d.setFromArray(v1, v0);
goog.vec.vec2d.normalize(v1, v1);
assertElementsEquals(v2, v1);
}
function testDot() {
var v0 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [1, 2]);
var v1 = goog.vec.vec2d.setFromArray(goog.vec.vec2d.create(), [4, 5]);
assertEquals(14, goog.vec.vec2d.dot(v0, v1));
assertEquals(14, goog.vec.vec2d.dot(v1, v0));
}
function testDistanceSquared() {
var v0 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 1, 2);
var v1 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 1, 2);
assertEquals(0, goog.vec.vec2d.distanceSquared(v0, v1));
goog.vec.vec2d.setFromValues(v0, 1, 2);
goog.vec.vec2d.setFromValues(v1, -1, -2);
assertEquals(20, goog.vec.vec2d.distanceSquared(v0, v1));
}
function testDistance() {
var v0 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 1, 2);
var v1 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 1, 2);
assertEquals(0, goog.vec.vec2d.distance(v0, v1));
goog.vec.vec2d.setFromValues(v0, 2, 3);
goog.vec.vec2d.setFromValues(v1, -2, 0);
assertEquals(5, goog.vec.vec2d.distance(v0, v1));
}
function testDirection() {
var v0 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 1, 2);
var v1 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 1, 2);
var dirVec = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 4, 5);
goog.vec.vec2d.direction(v0, v1, dirVec);
assertElementsEquals([0, 0], dirVec);
goog.vec.vec2d.setFromValues(v0, 0, 0);
goog.vec.vec2d.setFromValues(v1, 1, 0);
goog.vec.vec2d.direction(v0, v1, dirVec);
assertElementsEquals([1, 0], dirVec);
goog.vec.vec2d.setFromValues(v0, 1, 1);
goog.vec.vec2d.setFromValues(v1, 0, 0);
goog.vec.vec2d.direction(v0, v1, dirVec);
assertElementsRoughlyEqual(
[-0.707106781, -0.707106781],
dirVec, goog.vec.EPSILON);
}
function testLerp() {
var v0 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 1, 2);
var v1 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 10, 20);
var v2 = goog.vec.vec2d.setFromVec2d(goog.vec.vec2d.create(), v0);
goog.vec.vec2d.lerp(v2, v1, 0, v2);
assertElementsEquals([1, 2], v2);
goog.vec.vec2d.lerp(v2, v1, 1, v2);
assertElementsEquals([10, 20], v2);
goog.vec.vec2d.lerp(v0, v1, .5, v2);
assertElementsEquals([5.5, 11], v2);
}
function testMax() {
var v0 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 10, 20);
var v1 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 5, 25);
var v2 = goog.vec.vec2d.create();
goog.vec.vec2d.max(v0, v1, v2);
assertElementsEquals([10, 25], v2);
goog.vec.vec2d.max(v1, v0, v1);
assertElementsEquals([10, 25], v1);
goog.vec.vec2d.max(v2, 20, v2);
assertElementsEquals([20, 25], v2);
}
function testMin() {
var v0 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 10, 20);
var v1 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 5, 25);
var v2 = goog.vec.vec2d.create();
goog.vec.vec2d.min(v0, v1, v2);
assertElementsEquals([5, 20], v2);
goog.vec.vec2d.min(v1, v0, v1);
assertElementsEquals([5, 20], v1);
goog.vec.vec2d.min(v2, 10, v2);
assertElementsEquals([5, 10], v2);
}
function testEquals() {
var v0 = goog.vec.vec2d.setFromValues(goog.vec.vec2d.create(), 1, 2);
var v1 = goog.vec.vec2d.setFromVec2d(goog.vec.vec2d.create(), v0);
assertElementsEquals(v0, v1);
v1[0] = 4;
assertFalse(goog.vec.vec2d.equals(v0, v1));
v1 = goog.vec.vec2d.setFromVec2d(goog.vec.vec2d.create(), v0);
v1[1] = 4;
assertFalse(goog.vec.vec2d.equals(v0, v1));
}
</script>
</body>
@@ -0,0 +1,424 @@
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec2d.js by running: //
// swap_type.sh vec2f.js > vec2d.js //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
/**
* @fileoverview Provides functions for operating on 2 element float (32bit)
* vectors.
*
* The last parameter will typically be the output object and an object
* can be both an input and output parameter to all methods except where
* noted.
*
* See the README for notes about the design and structure of the API
* (especially related to performance).
*
*/
goog.provide('goog.vec.vec2f');
goog.provide('goog.vec.vec2f.Type');
/** @suppress {extraRequire} */
goog.require('goog.vec');
/** @typedef {goog.vec.Float32} */ goog.vec.vec2f.Type;
/**
* Creates a vec2f with all elements initialized to zero.
*
* @return {!goog.vec.vec2f.Type} The new vec2f.
*/
goog.vec.vec2f.create = function() {
return new Float32Array(2);
};
/**
* Initializes the vector with the given values.
*
* @param {goog.vec.vec2f.Type} vec The vector to receive the values.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @return {!goog.vec.vec2f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec2f.setFromValues = function(vec, v0, v1) {
vec[0] = v0;
vec[1] = v1;
return vec;
};
/**
* Initializes vec2f vec from vec2f src.
*
* @param {goog.vec.vec2f.Type} vec The destination vector.
* @param {goog.vec.vec2f.Type} src The source vector.
* @return {!goog.vec.vec2f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec2f.setFromVec2f = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
return vec;
};
/**
* Initializes vec2f vec from vec2d src (typed as a Float64Array to
* avoid circular goog.requires).
*
* @param {goog.vec.vec2f.Type} vec The destination vector.
* @param {Float64Array} src The source vector.
* @return {!goog.vec.vec2f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec2f.setFromVec2d = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
return vec;
};
/**
* Initializes vec2f vec from Array src.
*
* @param {goog.vec.vec2f.Type} vec The destination vector.
* @param {Array<number>} src The source vector.
* @return {!goog.vec.vec2f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec2f.setFromArray = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
return vec;
};
/**
* Performs a component-wise addition of vec0 and vec1 together storing the
* result into resultVec.
*
* @param {goog.vec.vec2f.Type} vec0 The first addend.
* @param {goog.vec.vec2f.Type} vec1 The second addend.
* @param {goog.vec.vec2f.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.add = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] + vec1[0];
resultVec[1] = vec0[1] + vec1[1];
return resultVec;
};
/**
* Performs a component-wise subtraction of vec1 from vec0 storing the
* result into resultVec.
*
* @param {goog.vec.vec2f.Type} vec0 The minuend.
* @param {goog.vec.vec2f.Type} vec1 The subtrahend.
* @param {goog.vec.vec2f.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.subtract = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] - vec1[0];
resultVec[1] = vec0[1] - vec1[1];
return resultVec;
};
/**
* Multiplies each component of vec0 with the matching element of vec0
* storing the products into resultVec.
*
* @param {!goog.vec.vec2f.Type} vec0 The first vector.
* @param {!goog.vec.vec2f.Type} vec1 The second vector.
* @param {!goog.vec.vec2f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.componentMultiply = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] * vec1[0];
resultVec[1] = vec0[1] * vec1[1];
return resultVec;
};
/**
* Divides each component of vec0 with the matching element of vec0
* storing the divisor into resultVec.
*
* @param {!goog.vec.vec2f.Type} vec0 The first vector.
* @param {!goog.vec.vec2f.Type} vec1 The second vector.
* @param {!goog.vec.vec2f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.componentDivide = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] / vec1[0];
resultVec[1] = vec0[1] / vec1[1];
return resultVec;
};
/**
* Negates vec0, storing the result into resultVec.
*
* @param {goog.vec.vec2f.Type} vec0 The vector to negate.
* @param {goog.vec.vec2f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.negate = function(vec0, resultVec) {
resultVec[0] = -vec0[0];
resultVec[1] = -vec0[1];
return resultVec;
};
/**
* Takes the absolute value of each component of vec0 storing the result in
* resultVec.
*
* @param {goog.vec.vec2f.Type} vec0 The source vector.
* @param {goog.vec.vec2f.Type} resultVec The vector to receive the result.
* May be vec0.
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.abs = function(vec0, resultVec) {
resultVec[0] = Math.abs(vec0[0]);
resultVec[1] = Math.abs(vec0[1]);
return resultVec;
};
/**
* Multiplies each component of vec0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.vec2f.Type} vec0 The source vector.
* @param {number} scalar The value to multiply with each component of vec0.
* @param {goog.vec.vec2f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.scale = function(vec0, scalar, resultVec) {
resultVec[0] = vec0[0] * scalar;
resultVec[1] = vec0[1] * scalar;
return resultVec;
};
/**
* Returns the magnitudeSquared of the given vector.
*
* @param {goog.vec.vec2f.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec2f.magnitudeSquared = function(vec0) {
var x = vec0[0], y = vec0[1];
return x * x + y * y;
};
/**
* Returns the magnitude of the given vector.
*
* @param {goog.vec.vec2f.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec2f.magnitude = function(vec0) {
var x = vec0[0], y = vec0[1];
return Math.sqrt(x * x + y * y);
};
/**
* Normalizes the given vector storing the result into resultVec.
*
* @param {goog.vec.vec2f.Type} vec0 The vector to normalize.
* @param {goog.vec.vec2f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.normalize = function(vec0, resultVec) {
var x = vec0[0], y = vec0[1];
var ilen = 1 / Math.sqrt(x * x + y * y);
resultVec[0] = x * ilen;
resultVec[1] = y * ilen;
return resultVec;
};
/**
* Returns the scalar product of vectors vec0 and vec1.
*
* @param {goog.vec.vec2f.Type} vec0 The first vector.
* @param {goog.vec.vec2f.Type} vec1 The second vector.
* @return {number} The scalar product.
*/
goog.vec.vec2f.dot = function(vec0, vec1) {
return vec0[0] * vec1[0] + vec0[1] * vec1[1];
};
/**
* Returns the squared distance between two points.
*
* @param {goog.vec.vec2f.Type} vec0 First point.
* @param {goog.vec.vec2f.Type} vec1 Second point.
* @return {number} The squared distance between the points.
*/
goog.vec.vec2f.distanceSquared = function(vec0, vec1) {
var x = vec0[0] - vec1[0];
var y = vec0[1] - vec1[1];
return x * x + y * y;
};
/**
* Returns the distance between two points.
*
* @param {goog.vec.vec2f.Type} vec0 First point.
* @param {goog.vec.vec2f.Type} vec1 Second point.
* @return {number} The distance between the points.
*/
goog.vec.vec2f.distance = function(vec0, vec1) {
return Math.sqrt(goog.vec.vec2f.distanceSquared(vec0, vec1));
};
/**
* Returns a unit vector pointing from one point to another.
* If the input points are equal then the result will be all zeros.
*
* @param {goog.vec.vec2f.Type} vec0 Origin point.
* @param {goog.vec.vec2f.Type} vec1 Target point.
* @param {goog.vec.vec2f.Type} resultVec The vector to receive the
* results (may be vec0 or vec1).
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.direction = function(vec0, vec1, resultVec) {
var x = vec1[0] - vec0[0];
var y = vec1[1] - vec0[1];
var d = Math.sqrt(x * x + y * y);
if (d) {
d = 1 / d;
resultVec[0] = x * d;
resultVec[1] = y * d;
} else {
resultVec[0] = resultVec[1] = 0;
}
return resultVec;
};
/**
* Linearly interpolate from vec0 to vec1 according to f. The value of f should
* be in the range [0..1] otherwise the results are undefined.
*
* @param {goog.vec.vec2f.Type} vec0 The first vector.
* @param {goog.vec.vec2f.Type} vec1 The second vector.
* @param {number} f The interpolation factor.
* @param {goog.vec.vec2f.Type} resultVec The vector to receive the
* results (may be vec0 or vec1).
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.lerp = function(vec0, vec1, f, resultVec) {
var x = vec0[0], y = vec0[1];
resultVec[0] = (vec1[0] - x) * f + x;
resultVec[1] = (vec1[1] - y) * f + y;
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the larger values in resultVec.
*
* @param {goog.vec.vec2f.Type} vec0 The source vector.
* @param {goog.vec.vec2f.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec2f.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.max = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.max(vec0[0], limit);
resultVec[1] = Math.max(vec0[1], limit);
} else {
resultVec[0] = Math.max(vec0[0], limit[0]);
resultVec[1] = Math.max(vec0[1], limit[1]);
}
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the smaller values in resultVec.
*
* @param {goog.vec.vec2f.Type} vec0 The source vector.
* @param {goog.vec.vec2f.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec2f.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec2f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec2f.min = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.min(vec0[0], limit);
resultVec[1] = Math.min(vec0[1], limit);
} else {
resultVec[0] = Math.min(vec0[0], limit[0]);
resultVec[1] = Math.min(vec0[1], limit[1]);
}
return resultVec;
};
/**
* Returns true if the components of vec0 are equal to the components of vec1.
*
* @param {goog.vec.vec2f.Type} vec0 The first vector.
* @param {goog.vec.vec2f.Type} vec1 The second vector.
* @return {boolean} True if the vectors are equal, false otherwise.
*/
goog.vec.vec2f.equals = function(vec0, vec1) {
return vec0.length == vec1.length &&
vec0[0] == vec1[0] && vec0[1] == vec1[1];
};
@@ -0,0 +1,282 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec2d_test.html by running: //
// swap_type.sh vec2f_test.html > vec2d_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.vec2f</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.vec2f');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testCreate() {
var v = goog.vec.vec2f.create();
assertElementsEquals([0, 0], v);
}
function testSet() {
var v = goog.vec.vec2f.create();
goog.vec.vec2f.setFromValues(v, 1, 2);
assertElementsEquals([1, 2], v);
goog.vec.vec2f.setFromArray(v, [4, 5]);
assertElementsEquals([4, 5], v);
var w = goog.vec.vec2f.create();
goog.vec.vec2f.setFromValues(w, 1, 2);
assertElementsEquals([1, 2], w);
goog.vec.vec2f.setFromArray(w, [4, 5]);
assertElementsEquals([4, 5], w);
}
function testAdd() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [1, 2]);
var v1 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [4, 5]);
var v2 = goog.vec.vec2f.setFromVec2f(goog.vec.vec2f.create(), v0);
goog.vec.vec2f.add(v2, v1, v2);
assertElementsEquals([1, 2], v0);
assertElementsEquals([4, 5], v1);
assertElementsEquals([5, 7], v2);
goog.vec.vec2f.add(goog.vec.vec2f.add(v0, v1, v2), v0, v2);
assertElementsEquals([6, 9], v2);
}
function testSubtract() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [1, 2]);
var v1 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [4, 5]);
var v2 = goog.vec.vec2f.setFromVec2f(goog.vec.vec2f.create(), v0);
goog.vec.vec2f.subtract(v2, v1, v2);
assertElementsEquals([1, 2], v0);
assertElementsEquals([4, 5], v1);
assertElementsEquals([-3, -3], v2);
goog.vec.vec2f.setFromValues(v2, 0, 0);
goog.vec.vec2f.subtract(v1, v0, v2);
assertElementsEquals([3, 3], v2);
v2 = goog.vec.vec2f.setFromVec2f(goog.vec.vec2f.create(), v0);
goog.vec.vec2f.subtract(v2, v1, v2);
assertElementsEquals([-3, -3], v2);
goog.vec.vec2f.subtract(goog.vec.vec2f.subtract(v1, v0, v2), v0, v2);
assertElementsEquals([2, 1], v2);
}
function testMultiply() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [1, 2]);
var v1 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [4, 5]);
var v2 = goog.vec.vec2f.setFromVec2f(goog.vec.vec2f.create(), v0);
goog.vec.vec2f.componentMultiply(v2, v1, v2);
assertElementsEquals([1, 2], v0);
assertElementsEquals([4, 5], v1);
assertElementsEquals([4, 10], v2);
goog.vec.vec2f.componentMultiply(goog.vec.vec2f.componentMultiply(v0, v1, v2), v0, v2);
assertElementsEquals([4, 20], v2);
}
function testDivide() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [1, 2]);
var v1 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [4, 5]);
var v2 = goog.vec.vec2f.setFromVec2f(goog.vec.vec2f.create(), v0);
goog.vec.vec2f.componentDivide(v2, v1, v2);
assertElementsRoughlyEqual([1, 2], v0, 10e-5);
assertElementsRoughlyEqual([4, 5], v1, 10e-5);
assertElementsRoughlyEqual([.25, .4], v2, 10e-5);
goog.vec.vec2f.setFromValues(v2, 0, 0);
goog.vec.vec2f.componentDivide(v1, v0, v2);
assertElementsRoughlyEqual([4, 2.5], v2, 10e-5);
v2 = goog.vec.vec2f.setFromVec2f(goog.vec.vec2f.create(), v0);
goog.vec.vec2f.componentDivide(v2, v1, v2);
assertElementsRoughlyEqual([.25, .4], v2, 10e-5);
goog.vec.vec2f.componentDivide(goog.vec.vec2f.componentDivide(v1, v0, v2), v0, v2);
assertElementsRoughlyEqual([4, 1.25], v2, 10e-5);
}
function testNegate() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [1, 2]);
var v1 = goog.vec.vec2f.create();
goog.vec.vec2f.negate(v0, v1);
assertElementsEquals([-1, -2], v1);
assertElementsEquals([1, 2], v0);
goog.vec.vec2f.negate(v0, v0);
assertElementsEquals([-1, -2], v0);
}
function testAbs() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [-1, -2]);
var v1 = goog.vec.vec2f.create();
goog.vec.vec2f.abs(v0, v1);
assertElementsEquals([1, 2], v1);
assertElementsEquals([-1, -2], v0);
goog.vec.vec2f.abs(v0, v0);
assertElementsEquals([1, 2], v0);
}
function testScale() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [1, 2]);
var v1 = goog.vec.vec2f.create();
goog.vec.vec2f.scale(v0, 4, v1);
assertElementsEquals([4, 8], v1);
assertElementsEquals([1, 2], v0);
goog.vec.vec2f.setFromArray(v1, v0);
goog.vec.vec2f.scale(v1, 5, v1);
assertElementsEquals([5, 10], v1);
}
function testMagnitudeSquared() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [1, 2]);
assertEquals(5, goog.vec.vec2f.magnitudeSquared(v0));
}
function testMagnitude() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [1, 2]);
assertEquals(Math.sqrt(5), goog.vec.vec2f.magnitude(v0));
}
function testNormalize() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [2, 3]);
var v1 = goog.vec.vec2f.create();
var v2 = goog.vec.vec2f.create();
goog.vec.vec2f.scale(
v0, 1 / goog.vec.vec2f.magnitude(v0), v2);
goog.vec.vec2f.normalize(v0, v1);
assertElementsEquals(v2, v1);
assertElementsEquals([2, 3], v0);
goog.vec.vec2f.setFromArray(v1, v0);
goog.vec.vec2f.normalize(v1, v1);
assertElementsEquals(v2, v1);
}
function testDot() {
var v0 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [1, 2]);
var v1 = goog.vec.vec2f.setFromArray(goog.vec.vec2f.create(), [4, 5]);
assertEquals(14, goog.vec.vec2f.dot(v0, v1));
assertEquals(14, goog.vec.vec2f.dot(v1, v0));
}
function testDistanceSquared() {
var v0 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 1, 2);
var v1 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 1, 2);
assertEquals(0, goog.vec.vec2f.distanceSquared(v0, v1));
goog.vec.vec2f.setFromValues(v0, 1, 2);
goog.vec.vec2f.setFromValues(v1, -1, -2);
assertEquals(20, goog.vec.vec2f.distanceSquared(v0, v1));
}
function testDistance() {
var v0 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 1, 2);
var v1 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 1, 2);
assertEquals(0, goog.vec.vec2f.distance(v0, v1));
goog.vec.vec2f.setFromValues(v0, 2, 3);
goog.vec.vec2f.setFromValues(v1, -2, 0);
assertEquals(5, goog.vec.vec2f.distance(v0, v1));
}
function testDirection() {
var v0 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 1, 2);
var v1 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 1, 2);
var dirVec = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 4, 5);
goog.vec.vec2f.direction(v0, v1, dirVec);
assertElementsEquals([0, 0], dirVec);
goog.vec.vec2f.setFromValues(v0, 0, 0);
goog.vec.vec2f.setFromValues(v1, 1, 0);
goog.vec.vec2f.direction(v0, v1, dirVec);
assertElementsEquals([1, 0], dirVec);
goog.vec.vec2f.setFromValues(v0, 1, 1);
goog.vec.vec2f.setFromValues(v1, 0, 0);
goog.vec.vec2f.direction(v0, v1, dirVec);
assertElementsRoughlyEqual(
[-0.707106781, -0.707106781],
dirVec, goog.vec.EPSILON);
}
function testLerp() {
var v0 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 1, 2);
var v1 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 10, 20);
var v2 = goog.vec.vec2f.setFromVec2f(goog.vec.vec2f.create(), v0);
goog.vec.vec2f.lerp(v2, v1, 0, v2);
assertElementsEquals([1, 2], v2);
goog.vec.vec2f.lerp(v2, v1, 1, v2);
assertElementsEquals([10, 20], v2);
goog.vec.vec2f.lerp(v0, v1, .5, v2);
assertElementsEquals([5.5, 11], v2);
}
function testMax() {
var v0 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 10, 20);
var v1 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 5, 25);
var v2 = goog.vec.vec2f.create();
goog.vec.vec2f.max(v0, v1, v2);
assertElementsEquals([10, 25], v2);
goog.vec.vec2f.max(v1, v0, v1);
assertElementsEquals([10, 25], v1);
goog.vec.vec2f.max(v2, 20, v2);
assertElementsEquals([20, 25], v2);
}
function testMin() {
var v0 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 10, 20);
var v1 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 5, 25);
var v2 = goog.vec.vec2f.create();
goog.vec.vec2f.min(v0, v1, v2);
assertElementsEquals([5, 20], v2);
goog.vec.vec2f.min(v1, v0, v1);
assertElementsEquals([5, 20], v1);
goog.vec.vec2f.min(v2, 10, v2);
assertElementsEquals([5, 10], v2);
}
function testEquals() {
var v0 = goog.vec.vec2f.setFromValues(goog.vec.vec2f.create(), 1, 2);
var v1 = goog.vec.vec2f.setFromVec2f(goog.vec.vec2f.create(), v0);
assertElementsEquals(v0, v1);
v1[0] = 4;
assertFalse(goog.vec.vec2f.equals(v0, v1));
v1 = goog.vec.vec2f.setFromVec2f(goog.vec.vec2f.create(), v0);
v1[1] = 4;
assertFalse(goog.vec.vec2f.equals(v0, v1));
}
</script>
</body>
@@ -0,0 +1,542 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Supplies 3 element vectors that are compatible with WebGL.
* Each element is a float32 since that is typically the desired size of a
* 3-vector in the GPU. The API is structured to avoid unnecessary memory
* allocations. The last parameter will typically be the output vector and
* an object can be both an input and output parameter to all methods except
* where noted.
*
*/
goog.provide('goog.vec.Vec3');
/** @suppress {extraRequire} */
goog.require('goog.vec');
/** @typedef {goog.vec.Float32} */ goog.vec.Vec3.Float32;
/** @typedef {goog.vec.Float64} */ goog.vec.Vec3.Float64;
/** @typedef {goog.vec.Number} */ goog.vec.Vec3.Number;
/** @typedef {goog.vec.AnyType} */ goog.vec.Vec3.AnyType;
// The following two types are deprecated - use the above types instead.
/** @typedef {Float32Array} */ goog.vec.Vec3.Type;
/** @typedef {goog.vec.ArrayType} */ goog.vec.Vec3.Vec3Like;
/**
* Creates a 3 element vector of Float32. The array is initialized to zero.
*
* @return {!goog.vec.Vec3.Float32} The new 3 element array.
*/
goog.vec.Vec3.createFloat32 = function() {
return new Float32Array(3);
};
/**
* Creates a 3 element vector of Float64. The array is initialized to zero.
*
* @return {!goog.vec.Vec3.Float64} The new 3 element array.
*/
goog.vec.Vec3.createFloat64 = function() {
return new Float64Array(3);
};
/**
* Creates a 3 element vector of Number. The array is initialized to zero.
*
* @return {!goog.vec.Vec3.Number} The new 3 element array.
*/
goog.vec.Vec3.createNumber = function() {
var a = new Array(3);
goog.vec.Vec3.setFromValues(a, 0, 0, 0);
return a;
};
/**
* Creates a 3 element vector of Float32Array. The array is initialized to zero.
*
* @deprecated Use createFloat32.
* @return {!goog.vec.Vec3.Type} The new 3 element array.
*/
goog.vec.Vec3.create = function() {
return new Float32Array(3);
};
/**
* Creates a new 3 element FLoat32 vector initialized with the value from the
* given array.
*
* @param {goog.vec.Vec3.AnyType} vec The source 3 element array.
* @return {!goog.vec.Vec3.Float32} The new 3 element array.
*/
goog.vec.Vec3.createFloat32FromArray = function(vec) {
var newVec = goog.vec.Vec3.createFloat32();
goog.vec.Vec3.setFromArray(newVec, vec);
return newVec;
};
/**
* Creates a new 3 element Float32 vector initialized with the supplied values.
*
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @return {!goog.vec.Vec3.Float32} The new vector.
*/
goog.vec.Vec3.createFloat32FromValues = function(v0, v1, v2) {
var a = goog.vec.Vec3.createFloat32();
goog.vec.Vec3.setFromValues(a, v0, v1, v2);
return a;
};
/**
* Creates a clone of the given 3 element Float32 vector.
*
* @param {goog.vec.Vec3.Float32} vec The source 3 element vector.
* @return {!goog.vec.Vec3.Float32} The new cloned vector.
*/
goog.vec.Vec3.cloneFloat32 = goog.vec.Vec3.createFloat32FromArray;
/**
* Creates a new 3 element Float64 vector initialized with the value from the
* given array.
*
* @param {goog.vec.Vec3.AnyType} vec The source 3 element array.
* @return {!goog.vec.Vec3.Float64} The new 3 element array.
*/
goog.vec.Vec3.createFloat64FromArray = function(vec) {
var newVec = goog.vec.Vec3.createFloat64();
goog.vec.Vec3.setFromArray(newVec, vec);
return newVec;
};
/**
* Creates a new 3 element Float64 vector initialized with the supplied values.
*
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @return {!goog.vec.Vec3.Float64} The new vector.
*/
goog.vec.Vec3.createFloat64FromValues = function(v0, v1, v2) {
var vec = goog.vec.Vec3.createFloat64();
goog.vec.Vec3.setFromValues(vec, v0, v1, v2);
return vec;
};
/**
* Creates a clone of the given 3 element vector.
*
* @param {goog.vec.Vec3.Float64} vec The source 3 element vector.
* @return {!goog.vec.Vec3.Float64} The new cloned vector.
*/
goog.vec.Vec3.cloneFloat64 = goog.vec.Vec3.createFloat64FromArray;
/**
* Creates a new 3 element vector initialized with the value from the given
* array.
*
* @deprecated Use createFloat32FromArray.
* @param {goog.vec.Vec3.Vec3Like} vec The source 3 element array.
* @return {!goog.vec.Vec3.Type} The new 3 element array.
*/
goog.vec.Vec3.createFromArray = function(vec) {
var newVec = goog.vec.Vec3.create();
goog.vec.Vec3.setFromArray(newVec, vec);
return newVec;
};
/**
* Creates a new 3 element vector initialized with the supplied values.
*
* @deprecated Use createFloat32FromValues.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @return {!goog.vec.Vec3.Type} The new vector.
*/
goog.vec.Vec3.createFromValues = function(v0, v1, v2) {
var vec = goog.vec.Vec3.create();
goog.vec.Vec3.setFromValues(vec, v0, v1, v2);
return vec;
};
/**
* Creates a clone of the given 3 element vector.
*
* @deprecated Use cloneFloat32.
* @param {goog.vec.Vec3.Vec3Like} vec The source 3 element vector.
* @return {!goog.vec.Vec3.Type} The new cloned vector.
*/
goog.vec.Vec3.clone = function(vec) {
var newVec = goog.vec.Vec3.create();
goog.vec.Vec3.setFromArray(newVec, vec);
return newVec;
};
/**
* Initializes the vector with the given values.
*
* @param {goog.vec.Vec3.AnyType} vec The vector to receive the values.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @return {!goog.vec.Vec3.AnyType} Return vec so that operations can be
* chained together.
*/
goog.vec.Vec3.setFromValues = function(vec, v0, v1, v2) {
vec[0] = v0;
vec[1] = v1;
vec[2] = v2;
return vec;
};
/**
* Initializes the vector with the given array of values.
*
* @param {goog.vec.Vec3.AnyType} vec The vector to receive the
* values.
* @param {goog.vec.Vec3.AnyType} values The array of values.
* @return {!goog.vec.Vec3.AnyType} Return vec so that operations can be
* chained together.
*/
goog.vec.Vec3.setFromArray = function(vec, values) {
vec[0] = values[0];
vec[1] = values[1];
vec[2] = values[2];
return vec;
};
/**
* Performs a component-wise addition of vec0 and vec1 together storing the
* result into resultVec.
*
* @param {goog.vec.Vec3.AnyType} vec0 The first addend.
* @param {goog.vec.Vec3.AnyType} vec1 The second addend.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.add = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] + vec1[0];
resultVec[1] = vec0[1] + vec1[1];
resultVec[2] = vec0[2] + vec1[2];
return resultVec;
};
/**
* Performs a component-wise subtraction of vec1 from vec0 storing the
* result into resultVec.
*
* @param {goog.vec.Vec3.AnyType} vec0 The minuend.
* @param {goog.vec.Vec3.AnyType} vec1 The subtrahend.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.subtract = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] - vec1[0];
resultVec[1] = vec0[1] - vec1[1];
resultVec[2] = vec0[2] - vec1[2];
return resultVec;
};
/**
* Negates vec0, storing the result into resultVec.
*
* @param {goog.vec.Vec3.AnyType} vec0 The vector to negate.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.negate = function(vec0, resultVec) {
resultVec[0] = -vec0[0];
resultVec[1] = -vec0[1];
resultVec[2] = -vec0[2];
return resultVec;
};
/**
* Takes the absolute value of each component of vec0 storing the result in
* resultVec.
*
* @param {goog.vec.Vec3.AnyType} vec0 The source vector.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the result.
* May be vec0.
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.abs = function(vec0, resultVec) {
resultVec[0] = Math.abs(vec0[0]);
resultVec[1] = Math.abs(vec0[1]);
resultVec[2] = Math.abs(vec0[2]);
return resultVec;
};
/**
* Multiplies each component of vec0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.Vec3.AnyType} vec0 The source vector.
* @param {number} scalar The value to multiply with each component of vec0.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.scale = function(vec0, scalar, resultVec) {
resultVec[0] = vec0[0] * scalar;
resultVec[1] = vec0[1] * scalar;
resultVec[2] = vec0[2] * scalar;
return resultVec;
};
/**
* Returns the magnitudeSquared of the given vector.
*
* @param {goog.vec.Vec3.AnyType} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.Vec3.magnitudeSquared = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2];
return x * x + y * y + z * z;
};
/**
* Returns the magnitude of the given vector.
*
* @param {goog.vec.Vec3.AnyType} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.Vec3.magnitude = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2];
return Math.sqrt(x * x + y * y + z * z);
};
/**
* Normalizes the given vector storing the result into resultVec.
*
* @param {goog.vec.Vec3.AnyType} vec0 The vector to normalize.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.normalize = function(vec0, resultVec) {
var ilen = 1 / goog.vec.Vec3.magnitude(vec0);
resultVec[0] = vec0[0] * ilen;
resultVec[1] = vec0[1] * ilen;
resultVec[2] = vec0[2] * ilen;
return resultVec;
};
/**
* Returns the scalar product of vectors v0 and v1.
*
* @param {goog.vec.Vec3.AnyType} v0 The first vector.
* @param {goog.vec.Vec3.AnyType} v1 The second vector.
* @return {number} The scalar product.
*/
goog.vec.Vec3.dot = function(v0, v1) {
return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
};
/**
* Computes the vector (cross) product of v0 and v1 storing the result into
* resultVec.
*
* @param {goog.vec.Vec3.AnyType} v0 The first vector.
* @param {goog.vec.Vec3.AnyType} v1 The second vector.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the
* results. May be either v0 or v1.
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.cross = function(v0, v1, resultVec) {
var x0 = v0[0], y0 = v0[1], z0 = v0[2];
var x1 = v1[0], y1 = v1[1], z1 = v1[2];
resultVec[0] = y0 * z1 - z0 * y1;
resultVec[1] = z0 * x1 - x0 * z1;
resultVec[2] = x0 * y1 - y0 * x1;
return resultVec;
};
/**
* Returns the squared distance between two points.
*
* @param {goog.vec.Vec3.AnyType} vec0 First point.
* @param {goog.vec.Vec3.AnyType} vec1 Second point.
* @return {number} The squared distance between the points.
*/
goog.vec.Vec3.distanceSquared = function(vec0, vec1) {
var x = vec0[0] - vec1[0];
var y = vec0[1] - vec1[1];
var z = vec0[2] - vec1[2];
return x * x + y * y + z * z;
};
/**
* Returns the distance between two points.
*
* @param {goog.vec.Vec3.AnyType} vec0 First point.
* @param {goog.vec.Vec3.AnyType} vec1 Second point.
* @return {number} The distance between the points.
*/
goog.vec.Vec3.distance = function(vec0, vec1) {
return Math.sqrt(goog.vec.Vec3.distanceSquared(vec0, vec1));
};
/**
* Returns a unit vector pointing from one point to another.
* If the input points are equal then the result will be all zeros.
*
* @param {goog.vec.Vec3.AnyType} vec0 Origin point.
* @param {goog.vec.Vec3.AnyType} vec1 Target point.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the
* results (may be vec0 or vec1).
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.direction = function(vec0, vec1, resultVec) {
var x = vec1[0] - vec0[0];
var y = vec1[1] - vec0[1];
var z = vec1[2] - vec0[2];
var d = Math.sqrt(x * x + y * y + z * z);
if (d) {
d = 1 / d;
resultVec[0] = x * d;
resultVec[1] = y * d;
resultVec[2] = z * d;
} else {
resultVec[0] = resultVec[1] = resultVec[2] = 0;
}
return resultVec;
};
/**
* Linearly interpolate from vec0 to v1 according to f. The value of f should be
* in the range [0..1] otherwise the results are undefined.
*
* @param {goog.vec.Vec3.AnyType} v0 The first vector.
* @param {goog.vec.Vec3.AnyType} v1 The second vector.
* @param {number} f The interpolation factor.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the
* results (may be v0 or v1).
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.lerp = function(v0, v1, f, resultVec) {
var x = v0[0], y = v0[1], z = v0[2];
resultVec[0] = (v1[0] - x) * f + x;
resultVec[1] = (v1[1] - y) * f + y;
resultVec[2] = (v1[2] - z) * f + z;
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the larger values in resultVec.
*
* @param {goog.vec.Vec3.AnyType} vec0 The source vector.
* @param {goog.vec.Vec3.AnyType|number} limit The limit vector or scalar.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.max = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.max(vec0[0], limit);
resultVec[1] = Math.max(vec0[1], limit);
resultVec[2] = Math.max(vec0[2], limit);
} else {
resultVec[0] = Math.max(vec0[0], limit[0]);
resultVec[1] = Math.max(vec0[1], limit[1]);
resultVec[2] = Math.max(vec0[2], limit[2]);
}
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the smaller values in resultVec.
*
* @param {goog.vec.Vec3.AnyType} vec0 The source vector.
* @param {goog.vec.Vec3.AnyType|number} limit The limit vector or scalar.
* @param {goog.vec.Vec3.AnyType} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.Vec3.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec3.min = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.min(vec0[0], limit);
resultVec[1] = Math.min(vec0[1], limit);
resultVec[2] = Math.min(vec0[2], limit);
} else {
resultVec[0] = Math.min(vec0[0], limit[0]);
resultVec[1] = Math.min(vec0[1], limit[1]);
resultVec[2] = Math.min(vec0[2], limit[2]);
}
return resultVec;
};
/**
* Returns true if the components of v0 are equal to the components of v1.
*
* @param {goog.vec.Vec3.AnyType} v0 The first vector.
* @param {goog.vec.Vec3.AnyType} v1 The second vector.
* @return {boolean} True if the vectors are equal, false otherwise.
*/
goog.vec.Vec3.equals = function(v0, v1) {
return v0.length == v1.length &&
v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2];
};
@@ -0,0 +1,296 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Vec3</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.Vec3');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testDeprecatedConstructor() {
var v = goog.vec.Vec3.create();
assertElementsEquals(0, v[0]);
assertEquals(0, v[1]);
assertEquals(0, v[2]);
assertElementsEquals([0, 0, 0], goog.vec.Vec3.create());
assertElementsEquals([1, 2, 3], goog.vec.Vec3.createFromValues(1, 2, 3));
assertElementsEquals([1, 2, 3], goog.vec.Vec3.createFromArray([1, 2, 3]));
v = goog.vec.Vec3.createFromValues(1, 2, 3);
assertElementsEquals([1, 2, 3], goog.vec.Vec3.clone(v));
}
function testConstructor() {
var v = goog.vec.Vec3.createFloat32();
assertElementsEquals(0, v[0]);
assertEquals(0, v[1]);
assertEquals(0, v[2]);
assertElementsEquals([0, 0, 0], goog.vec.Vec3.createFloat32());
goog.vec.Vec3.setFromValues(v, 1, 2, 3);
assertElementsEquals([1, 2, 3], v);
var w = goog.vec.Vec3.createFloat64();
assertElementsEquals(0, w[0]);
assertEquals(0, w[1]);
assertEquals(0, w[2]);
assertElementsEquals([0, 0, 0], goog.vec.Vec3.createFloat64());
goog.vec.Vec3.setFromValues(w, 1, 2, 3);
assertElementsEquals([1, 2, 3], w);
}
function testSet() {
var v = goog.vec.Vec3.createFloat32();
goog.vec.Vec3.setFromValues(v, 1, 2, 3);
assertElementsEquals([1, 2, 3], v);
goog.vec.Vec3.setFromArray(v, [4, 5, 6]);
assertElementsEquals([4, 5, 6], v);
var w = goog.vec.Vec3.createFloat32();
goog.vec.Vec3.setFromValues(w, 1, 2, 3);
assertElementsEquals([1, 2, 3], w);
goog.vec.Vec3.setFromArray(w, [4, 5, 6]);
assertElementsEquals([4, 5, 6], w);
}
function testAdd() {
var v0 = goog.vec.Vec3.createFloat32FromArray([1, 2, 3]);
var v1 = goog.vec.Vec3.createFloat32FromArray([4, 5, 6]);
var v2 = goog.vec.Vec3.cloneFloat32(v0);
goog.vec.Vec3.add(v2, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([5, 7, 9], v2);
goog.vec.Vec3.add(goog.vec.Vec3.add(v0, v1, v2), v0, v2);
assertElementsEquals([6, 9, 12], v2);
}
function testSubtract() {
var v0 = goog.vec.Vec3.createFloat32FromArray([1, 2, 3]);
var v1 = goog.vec.Vec3.createFloat32FromArray([4, 5, 6]);
var v2 = goog.vec.Vec3.cloneFloat32(v0);
goog.vec.Vec3.subtract(v2, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([-3, -3, -3], v2);
goog.vec.Vec3.setFromValues(v2, 0, 0, 0);
goog.vec.Vec3.subtract(v1, v0, v2);
assertElementsEquals([3, 3, 3], v2);
v2 = goog.vec.Vec3.cloneFloat32(v0);
goog.vec.Vec3.subtract(v2, v1, v2);
assertElementsEquals([-3, -3, -3], v2);
goog.vec.Vec3.subtract(goog.vec.Vec3.subtract(v1, v0, v2), v0, v2);
assertElementsEquals([2, 1, 0], v2);
}
function testNegate() {
var v0 = goog.vec.Vec3.createFloat32FromArray([1, 2, 3]);
var v1 = goog.vec.Vec3.createFloat32();
goog.vec.Vec3.negate(v0, v1);
assertElementsEquals([-1, -2, -3], v1);
assertElementsEquals([1, 2, 3], v0);
goog.vec.Vec3.negate(v0, v0);
assertElementsEquals([-1, -2, -3], v0);
}
function testAbs() {
var v0 = goog.vec.Vec3.createFloat32FromValues(-1, -2, -3);
var v1 = goog.vec.Vec3.createFloat32();
goog.vec.Vec3.abs(v0, v1);
assertElementsEquals([1, 2, 3], v1);
assertElementsEquals([-1, -2, -3], v0);
goog.vec.Vec3.abs(v0, v0);
assertElementsEquals([1, 2, 3], v0);
}
function testScale() {
var v0 = goog.vec.Vec3.createFloat32FromArray([1, 2, 3]);
var v1 = goog.vec.Vec3.createFloat32();
goog.vec.Vec3.scale(v0, 4, v1);
assertElementsEquals([4, 8, 12], v1);
assertElementsEquals([1, 2, 3], v0);
goog.vec.Vec3.setFromArray(v1, v0);
goog.vec.Vec3.scale(v1, 5, v1);
assertElementsEquals([5, 10, 15], v1);
}
function testMagnitudeSquared() {
var v0 = goog.vec.Vec3.createFloat32FromArray([1, 2, 3]);
assertEquals(14, goog.vec.Vec3.magnitudeSquared(v0));
}
function testMagnitude() {
var v0 = goog.vec.Vec3.createFloat32FromArray([1, 2, 3]);
assertEquals(Math.sqrt(14), goog.vec.Vec3.magnitude(v0));
}
function testNormalize() {
var v0 = goog.vec.Vec3.createFloat32FromArray([2, 3, 4]);
var v1 = goog.vec.Vec3.create();
var v2 = goog.vec.Vec3.create();
goog.vec.Vec3.scale(
v0, 1 / goog.vec.Vec3.magnitude(v0), v2);
goog.vec.Vec3.normalize(v0, v1);
assertElementsEquals(v2, v1);
assertElementsEquals([2, 3, 4], v0);
goog.vec.Vec3.setFromArray(v1, v0);
goog.vec.Vec3.normalize(v1, v1);
assertElementsEquals(v2, v1);
}
function testDot() {
var v0 = goog.vec.Vec3.createFloat32FromArray([1, 2, 3]);
var v1 = goog.vec.Vec3.createFloat32FromArray([4, 5, 6]);
assertEquals(32, goog.vec.Vec3.dot(v0, v1));
assertEquals(32, goog.vec.Vec3.dot(v1, v0));
}
function testCross() {
var v0 = goog.vec.Vec3.createFloat32FromArray([1, 2, 3]);
var v1 = goog.vec.Vec3.createFloat32FromArray([4, 5, 6]);
var crossVec = goog.vec.Vec3.create();
goog.vec.Vec3.cross(v0, v1, crossVec);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([-3, 6, -3], crossVec);
goog.vec.Vec3.setFromArray(crossVec, v1);
goog.vec.Vec3.cross(crossVec, v0, crossVec);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([3, -6, 3], crossVec);
goog.vec.Vec3.cross(v0, v0, v0);
assertElementsEquals([0, 0, 0], v0);
}
function testDistanceSquared() {
var v0 = goog.vec.Vec3.createFloat32FromValues(1, 2, 3);
var v1 = goog.vec.Vec3.createFloat32FromValues(1, 2, 3);
assertEquals(0, goog.vec.Vec3.distanceSquared(v0, v1));
goog.vec.Vec3.setFromValues(v0, 1, 2, 3);
goog.vec.Vec3.setFromValues(v1, -1, -2, -1);
assertEquals(36, goog.vec.Vec3.distanceSquared(v0, v1));
}
function testDistance() {
var v0 = goog.vec.Vec3.createFloat32FromValues(1, 2, 3);
var v1 = goog.vec.Vec3.createFloat32FromValues(1, 2, 3);
assertEquals(0, goog.vec.Vec3.distance(v0, v1));
goog.vec.Vec3.setFromValues(v0, 1, 2, 3);
goog.vec.Vec3.setFromValues(v1, -1, -2, -1);
assertEquals(6, goog.vec.Vec3.distance(v0, v1));
}
function testDirection() {
var v0 = goog.vec.Vec3.createFloat32FromValues(1, 2, 3);
var v1 = goog.vec.Vec3.createFloat32FromValues(1, 2, 3);
var dirVec = goog.vec.Vec3.createFloat32FromValues(4, 5, 6);
goog.vec.Vec3.direction(v0, v1, dirVec);
assertElementsEquals([0, 0, 0], dirVec);
goog.vec.Vec3.setFromValues(v0, 0, 0, 0);
goog.vec.Vec3.setFromValues(v1, 1, 0, 0);
goog.vec.Vec3.direction(v0, v1, dirVec);
assertElementsEquals([1, 0, 0], dirVec);
goog.vec.Vec3.setFromValues(v0, 1, 1, 1);
goog.vec.Vec3.setFromValues(v1, 0, 0, 0);
goog.vec.Vec3.direction(v0, v1, dirVec);
assertElementsRoughlyEqual(
[-0.5773502588272095, -0.5773502588272095, -0.5773502588272095],
dirVec, goog.vec.EPSILON);
}
function testLerp() {
var v0 = goog.vec.Vec3.createFloat32FromValues(1, 2, 3);
var v1 = goog.vec.Vec3.createFloat32FromValues(10, 20, 30);
var v2 = goog.vec.Vec3.cloneFloat32(v0);
goog.vec.Vec3.lerp(v2, v1, 0, v2);
assertElementsEquals([1, 2, 3], v2);
goog.vec.Vec3.lerp(v2, v1, 1, v2);
assertElementsEquals([10, 20, 30], v2);
goog.vec.Vec3.lerp(v0, v1, .5, v2);
assertElementsEquals([5.5, 11, 16.5], v2);
}
function testMax() {
var v0 = goog.vec.Vec3.createFloat32FromValues(10, 20, 30);
var v1 = goog.vec.Vec3.createFloat32FromValues(5, 25, 35);
var v2 = goog.vec.Vec3.createFloat32();
goog.vec.Vec3.max(v0, v1, v2);
assertElementsEquals([10, 25, 35], v2);
goog.vec.Vec3.max(v1, v0, v1);
assertElementsEquals([10, 25, 35], v1);
goog.vec.Vec3.max(v2, 20, v2);
assertElementsEquals([20, 25, 35], v2);
}
function testMin() {
var v0 = goog.vec.Vec3.createFloat32FromValues(10, 20, 30);
var v1 = goog.vec.Vec3.createFloat32FromValues(5, 25, 35);
var v2 = goog.vec.Vec3.createFloat32();
goog.vec.Vec3.min(v0, v1, v2);
assertElementsEquals([5, 20, 30], v2);
goog.vec.Vec3.min(v1, v0, v1);
assertElementsEquals([5, 20, 30], v1);
goog.vec.Vec3.min(v2, 20, v2);
assertElementsEquals([5, 20, 20], v2);
}
function testEquals() {
var v0 = goog.vec.Vec3.createFloat32FromValues(1, 2, 3);
var v1 = goog.vec.Vec3.cloneFloat32(v0);
assertElementsEquals(v0, v1);
v1[0] = 4;
assertFalse(goog.vec.Vec3.equals(v0, v1));
v1 = goog.vec.Vec3.cloneFloat32(v0);
v1[1] = 4;
assertFalse(goog.vec.Vec3.equals(v0, v1));
v1 = goog.vec.Vec3.cloneFloat32(v0);
v1[2] = 4;
assertFalse(goog.vec.Vec3.equals(v0, v1));
}
</script>
</body>
@@ -0,0 +1,426 @@
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec3f.js by running: //
// swap_type.sh vec3d.js > vec3f.js //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
/**
* @fileoverview Provides functions for operating on 3 element double (64bit)
* vectors.
*
* The last parameter will typically be the output object and an object
* can be both an input and output parameter to all methods except where
* noted.
*
* See the README for notes about the design and structure of the API
* (especially related to performance).
*
*/
goog.provide('goog.vec.vec3d');
goog.provide('goog.vec.vec3d.Type');
/** @suppress {extraRequire} */
goog.require('goog.vec');
/** @typedef {goog.vec.Float64} */ goog.vec.vec3d.Type;
/**
* Creates a vec3d with all elements initialized to zero.
*
* @return {!goog.vec.vec3d.Type} The new vec3d.
*/
goog.vec.vec3d.create = function() {
return new Float64Array(3);
};
/**
* Initializes the vector with the given values.
*
* @param {goog.vec.vec3d.Type} vec The vector to receive the values.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @return {!goog.vec.vec3d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec3d.setFromValues = function(vec, v0, v1, v2) {
vec[0] = v0;
vec[1] = v1;
vec[2] = v2;
return vec;
};
/**
* Initializes vec3d vec from vec3d src.
*
* @param {goog.vec.vec3d.Type} vec The destination vector.
* @param {goog.vec.vec3d.Type} src The source vector.
* @return {!goog.vec.vec3d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec3d.setFromVec3d = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
return vec;
};
/**
* Initializes vec3d vec from vec3f src (typed as a Float32Array to
* avoid circular goog.requires).
*
* @param {goog.vec.vec3d.Type} vec The destination vector.
* @param {Float32Array} src The source vector.
* @return {!goog.vec.vec3d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec3d.setFromVec3f = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
return vec;
};
/**
* Initializes vec3d vec from Array src.
*
* @param {goog.vec.vec3d.Type} vec The destination vector.
* @param {Array<number>} src The source vector.
* @return {!goog.vec.vec3d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec3d.setFromArray = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
return vec;
};
/**
* Performs a component-wise addition of vec0 and vec1 together storing the
* result into resultVec.
*
* @param {goog.vec.vec3d.Type} vec0 The first addend.
* @param {goog.vec.vec3d.Type} vec1 The second addend.
* @param {goog.vec.vec3d.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.add = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] + vec1[0];
resultVec[1] = vec0[1] + vec1[1];
resultVec[2] = vec0[2] + vec1[2];
return resultVec;
};
/**
* Performs a component-wise subtraction of vec1 from vec0 storing the
* result into resultVec.
*
* @param {goog.vec.vec3d.Type} vec0 The minuend.
* @param {goog.vec.vec3d.Type} vec1 The subtrahend.
* @param {goog.vec.vec3d.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.subtract = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] - vec1[0];
resultVec[1] = vec0[1] - vec1[1];
resultVec[2] = vec0[2] - vec1[2];
return resultVec;
};
/**
* Negates vec0, storing the result into resultVec.
*
* @param {goog.vec.vec3d.Type} vec0 The vector to negate.
* @param {goog.vec.vec3d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.negate = function(vec0, resultVec) {
resultVec[0] = -vec0[0];
resultVec[1] = -vec0[1];
resultVec[2] = -vec0[2];
return resultVec;
};
/**
* Takes the absolute value of each component of vec0 storing the result in
* resultVec.
*
* @param {goog.vec.vec3d.Type} vec0 The source vector.
* @param {goog.vec.vec3d.Type} resultVec The vector to receive the result.
* May be vec0.
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.abs = function(vec0, resultVec) {
resultVec[0] = Math.abs(vec0[0]);
resultVec[1] = Math.abs(vec0[1]);
resultVec[2] = Math.abs(vec0[2]);
return resultVec;
};
/**
* Multiplies each component of vec0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.vec3d.Type} vec0 The source vector.
* @param {number} scalar The value to multiply with each component of vec0.
* @param {goog.vec.vec3d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.scale = function(vec0, scalar, resultVec) {
resultVec[0] = vec0[0] * scalar;
resultVec[1] = vec0[1] * scalar;
resultVec[2] = vec0[2] * scalar;
return resultVec;
};
/**
* Returns the magnitudeSquared of the given vector.
*
* @param {goog.vec.vec3d.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec3d.magnitudeSquared = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2];
return x * x + y * y + z * z;
};
/**
* Returns the magnitude of the given vector.
*
* @param {goog.vec.vec3d.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec3d.magnitude = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2];
return Math.sqrt(x * x + y * y + z * z);
};
/**
* Normalizes the given vector storing the result into resultVec.
*
* @param {goog.vec.vec3d.Type} vec0 The vector to normalize.
* @param {goog.vec.vec3d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.normalize = function(vec0, resultVec) {
var x = vec0[0], y = vec0[1], z = vec0[2];
var ilen = 1 / Math.sqrt(x * x + y * y + z * z);
resultVec[0] = x * ilen;
resultVec[1] = y * ilen;
resultVec[2] = z * ilen;
return resultVec;
};
/**
* Returns the scalar product of vectors v0 and v1.
*
* @param {goog.vec.vec3d.Type} v0 The first vector.
* @param {goog.vec.vec3d.Type} v1 The second vector.
* @return {number} The scalar product.
*/
goog.vec.vec3d.dot = function(v0, v1) {
return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
};
/**
* Computes the vector (cross) product of v0 and v1 storing the result into
* resultVec.
*
* @param {goog.vec.vec3d.Type} v0 The first vector.
* @param {goog.vec.vec3d.Type} v1 The second vector.
* @param {goog.vec.vec3d.Type} resultVec The vector to receive the
* results. May be either v0 or v1.
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.cross = function(v0, v1, resultVec) {
var x0 = v0[0], y0 = v0[1], z0 = v0[2];
var x1 = v1[0], y1 = v1[1], z1 = v1[2];
resultVec[0] = y0 * z1 - z0 * y1;
resultVec[1] = z0 * x1 - x0 * z1;
resultVec[2] = x0 * y1 - y0 * x1;
return resultVec;
};
/**
* Returns the squared distance between two points.
*
* @param {goog.vec.vec3d.Type} vec0 First point.
* @param {goog.vec.vec3d.Type} vec1 Second point.
* @return {number} The squared distance between the points.
*/
goog.vec.vec3d.distanceSquared = function(vec0, vec1) {
var x = vec0[0] - vec1[0];
var y = vec0[1] - vec1[1];
var z = vec0[2] - vec1[2];
return x * x + y * y + z * z;
};
/**
* Returns the distance between two points.
*
* @param {goog.vec.vec3d.Type} vec0 First point.
* @param {goog.vec.vec3d.Type} vec1 Second point.
* @return {number} The distance between the points.
*/
goog.vec.vec3d.distance = function(vec0, vec1) {
return Math.sqrt(goog.vec.vec3d.distanceSquared(vec0, vec1));
};
/**
* Returns a unit vector pointing from one point to another.
* If the input points are equal then the result will be all zeros.
*
* @param {goog.vec.vec3d.Type} vec0 Origin point.
* @param {goog.vec.vec3d.Type} vec1 Target point.
* @param {goog.vec.vec3d.Type} resultVec The vector to receive the
* results (may be vec0 or vec1).
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.direction = function(vec0, vec1, resultVec) {
var x = vec1[0] - vec0[0];
var y = vec1[1] - vec0[1];
var z = vec1[2] - vec0[2];
var d = Math.sqrt(x * x + y * y + z * z);
if (d) {
d = 1 / d;
resultVec[0] = x * d;
resultVec[1] = y * d;
resultVec[2] = z * d;
} else {
resultVec[0] = resultVec[1] = resultVec[2] = 0;
}
return resultVec;
};
/**
* Linearly interpolate from vec0 to v1 according to f. The value of f should be
* in the range [0..1] otherwise the results are undefined.
*
* @param {goog.vec.vec3d.Type} v0 The first vector.
* @param {goog.vec.vec3d.Type} v1 The second vector.
* @param {number} f The interpolation factor.
* @param {goog.vec.vec3d.Type} resultVec The vector to receive the
* results (may be v0 or v1).
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.lerp = function(v0, v1, f, resultVec) {
var x = v0[0], y = v0[1], z = v0[2];
resultVec[0] = (v1[0] - x) * f + x;
resultVec[1] = (v1[1] - y) * f + y;
resultVec[2] = (v1[2] - z) * f + z;
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the larger values in resultVec.
*
* @param {goog.vec.vec3d.Type} vec0 The source vector.
* @param {goog.vec.vec3d.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec3d.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.max = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.max(vec0[0], limit);
resultVec[1] = Math.max(vec0[1], limit);
resultVec[2] = Math.max(vec0[2], limit);
} else {
resultVec[0] = Math.max(vec0[0], limit[0]);
resultVec[1] = Math.max(vec0[1], limit[1]);
resultVec[2] = Math.max(vec0[2], limit[2]);
}
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the smaller values in resultVec.
*
* @param {goog.vec.vec3d.Type} vec0 The source vector.
* @param {goog.vec.vec3d.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec3d.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec3d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3d.min = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.min(vec0[0], limit);
resultVec[1] = Math.min(vec0[1], limit);
resultVec[2] = Math.min(vec0[2], limit);
} else {
resultVec[0] = Math.min(vec0[0], limit[0]);
resultVec[1] = Math.min(vec0[1], limit[1]);
resultVec[2] = Math.min(vec0[2], limit[2]);
}
return resultVec;
};
/**
* Returns true if the components of v0 are equal to the components of v1.
*
* @param {goog.vec.vec3d.Type} v0 The first vector.
* @param {goog.vec.vec3d.Type} v1 The second vector.
* @return {boolean} True if the vectors are equal, false otherwise.
*/
goog.vec.vec3d.equals = function(v0, v1) {
return v0.length == v1.length &&
v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2];
};
@@ -0,0 +1,270 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec3f_test.html by running: //
// swap_type.sh vec3d_test.html > vec3f_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.vec3d</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float64Array');
goog.require('goog.vec.vec3d');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testCreate() {
var v = goog.vec.vec3d.create();
assertElementsEquals([0, 0, 0], v);
}
function testSet() {
var v = goog.vec.vec3d.create();
goog.vec.vec3d.setFromValues(v, 1, 2, 3);
assertElementsEquals([1, 2, 3], v);
goog.vec.vec3d.setFromArray(v, [4, 5, 6]);
assertElementsEquals([4, 5, 6], v);
var w = goog.vec.vec3d.create();
goog.vec.vec3d.setFromValues(w, 1, 2, 3);
assertElementsEquals([1, 2, 3], w);
goog.vec.vec3d.setFromArray(w, [4, 5, 6]);
assertElementsEquals([4, 5, 6], w);
}
function testAdd() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [1, 2, 3]);
var v1 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [4, 5, 6]);
var v2 = goog.vec.vec3d.setFromVec3d(goog.vec.vec3d.create(), v0);
goog.vec.vec3d.add(v2, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([5, 7, 9], v2);
goog.vec.vec3d.add(goog.vec.vec3d.add(v0, v1, v2), v0, v2);
assertElementsEquals([6, 9, 12], v2);
}
function testSubtract() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [1, 2, 3]);
var v1 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [4, 5, 6]);
var v2 = goog.vec.vec3d.setFromVec3d(goog.vec.vec3d.create(), v0);
goog.vec.vec3d.subtract(v2, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([-3, -3, -3], v2);
goog.vec.vec3d.setFromValues(v2, 0, 0, 0);
goog.vec.vec3d.subtract(v1, v0, v2);
assertElementsEquals([3, 3, 3], v2);
v2 = goog.vec.vec3d.setFromVec3d(goog.vec.vec3d.create(), v0);
goog.vec.vec3d.subtract(v2, v1, v2);
assertElementsEquals([-3, -3, -3], v2);
goog.vec.vec3d.subtract(goog.vec.vec3d.subtract(v1, v0, v2), v0, v2);
assertElementsEquals([2, 1, 0], v2);
}
function testNegate() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [1, 2, 3]);
var v1 = goog.vec.vec3d.create();
goog.vec.vec3d.negate(v0, v1);
assertElementsEquals([-1, -2, -3], v1);
assertElementsEquals([1, 2, 3], v0);
goog.vec.vec3d.negate(v0, v0);
assertElementsEquals([-1, -2, -3], v0);
}
function testAbs() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [-1, -2, -3]);
var v1 = goog.vec.vec3d.create();
goog.vec.vec3d.abs(v0, v1);
assertElementsEquals([1, 2, 3], v1);
assertElementsEquals([-1, -2, -3], v0);
goog.vec.vec3d.abs(v0, v0);
assertElementsEquals([1, 2, 3], v0);
}
function testScale() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [1, 2, 3]);
var v1 = goog.vec.vec3d.create();
goog.vec.vec3d.scale(v0, 4, v1);
assertElementsEquals([4, 8, 12], v1);
assertElementsEquals([1, 2, 3], v0);
goog.vec.vec3d.setFromArray(v1, v0);
goog.vec.vec3d.scale(v1, 5, v1);
assertElementsEquals([5, 10, 15], v1);
}
function testMagnitudeSquared() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [1, 2, 3]);
assertEquals(14, goog.vec.vec3d.magnitudeSquared(v0));
}
function testMagnitude() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [1, 2, 3]);
assertEquals(Math.sqrt(14), goog.vec.vec3d.magnitude(v0));
}
function testNormalize() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [2, 3, 4]);
var v1 = goog.vec.vec3d.create();
var v2 = goog.vec.vec3d.create();
goog.vec.vec3d.scale(
v0, 1 / goog.vec.vec3d.magnitude(v0), v2);
goog.vec.vec3d.normalize(v0, v1);
assertElementsEquals(v2, v1);
assertElementsEquals([2, 3, 4], v0);
goog.vec.vec3d.setFromArray(v1, v0);
goog.vec.vec3d.normalize(v1, v1);
assertElementsEquals(v2, v1);
}
function testDot() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [1, 2, 3]);
var v1 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [4, 5, 6]);
assertEquals(32, goog.vec.vec3d.dot(v0, v1));
assertEquals(32, goog.vec.vec3d.dot(v1, v0));
}
function testCross() {
var v0 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [1, 2, 3]);
var v1 = goog.vec.vec3d.setFromArray(goog.vec.vec3d.create(), [4, 5, 6]);
var crossVec = goog.vec.vec3d.create();
goog.vec.vec3d.cross(v0, v1, crossVec);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([-3, 6, -3], crossVec);
goog.vec.vec3d.setFromArray(crossVec, v1);
goog.vec.vec3d.cross(crossVec, v0, crossVec);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([3, -6, 3], crossVec);
goog.vec.vec3d.cross(v0, v0, v0);
assertElementsEquals([0, 0, 0], v0);
}
function testDistanceSquared() {
var v0 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 1, 2, 3);
var v1 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 1, 2, 3);
assertEquals(0, goog.vec.vec3d.distanceSquared(v0, v1));
goog.vec.vec3d.setFromValues(v0, 1, 2, 3);
goog.vec.vec3d.setFromValues(v1, -1, -2, -1);
assertEquals(36, goog.vec.vec3d.distanceSquared(v0, v1));
}
function testDistance() {
var v0 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 1, 2, 3);
var v1 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 1, 2, 3);
assertEquals(0, goog.vec.vec3d.distance(v0, v1));
goog.vec.vec3d.setFromValues(v0, 1, 2, 3);
goog.vec.vec3d.setFromValues(v1, -1, -2, -1);
assertEquals(6, goog.vec.vec3d.distance(v0, v1));
}
function testDirection() {
var v0 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 1, 2, 3);
var v1 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 1, 2, 3);
var dirVec = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 4, 5, 6);
goog.vec.vec3d.direction(v0, v1, dirVec);
assertElementsEquals([0, 0, 0], dirVec);
goog.vec.vec3d.setFromValues(v0, 0, 0, 0);
goog.vec.vec3d.setFromValues(v1, 1, 0, 0);
goog.vec.vec3d.direction(v0, v1, dirVec);
assertElementsEquals([1, 0, 0], dirVec);
goog.vec.vec3d.setFromValues(v0, 1, 1, 1);
goog.vec.vec3d.setFromValues(v1, 0, 0, 0);
goog.vec.vec3d.direction(v0, v1, dirVec);
assertElementsRoughlyEqual(
[-0.5773502588272095, -0.5773502588272095, -0.5773502588272095],
dirVec, goog.vec.EPSILON);
}
function testLerp() {
var v0 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 1, 2, 3);
var v1 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 10, 20, 30);
var v2 = goog.vec.vec3d.setFromVec3d(goog.vec.vec3d.create(), v0);
goog.vec.vec3d.lerp(v2, v1, 0, v2);
assertElementsEquals([1, 2, 3], v2);
goog.vec.vec3d.lerp(v2, v1, 1, v2);
assertElementsEquals([10, 20, 30], v2);
goog.vec.vec3d.lerp(v0, v1, .5, v2);
assertElementsEquals([5.5, 11, 16.5], v2);
}
function testMax() {
var v0 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 10, 20, 30);
var v1 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 5, 25, 35);
var v2 = goog.vec.vec3d.create();
goog.vec.vec3d.max(v0, v1, v2);
assertElementsEquals([10, 25, 35], v2);
goog.vec.vec3d.max(v1, v0, v1);
assertElementsEquals([10, 25, 35], v1);
goog.vec.vec3d.max(v2, 20, v2);
assertElementsEquals([20, 25, 35], v2);
}
function testMin() {
var v0 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 10, 20, 30);
var v1 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 5, 25, 35);
var v2 = goog.vec.vec3d.create();
goog.vec.vec3d.min(v0, v1, v2);
assertElementsEquals([5, 20, 30], v2);
goog.vec.vec3d.min(v1, v0, v1);
assertElementsEquals([5, 20, 30], v1);
goog.vec.vec3d.min(v2, 20, v2);
assertElementsEquals([5, 20, 20], v2);
}
function testEquals() {
var v0 = goog.vec.vec3d.setFromValues(goog.vec.vec3d.create(), 1, 2, 3);
var v1 = goog.vec.vec3d.setFromVec3d(goog.vec.vec3d.create(), v0);
assertElementsEquals(v0, v1);
v1[0] = 4;
assertFalse(goog.vec.vec3d.equals(v0, v1));
v1 = goog.vec.vec3d.setFromVec3d(goog.vec.vec3d.create(), v0);
v1[1] = 4;
assertFalse(goog.vec.vec3d.equals(v0, v1));
v1 = goog.vec.vec3d.setFromVec3d(goog.vec.vec3d.create(), v0);
v1[2] = 4;
assertFalse(goog.vec.vec3d.equals(v0, v1));
}
</script>
</body>
@@ -0,0 +1,426 @@
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec3d.js by running: //
// swap_type.sh vec3f.js > vec3d.js //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
/**
* @fileoverview Provides functions for operating on 3 element float (32bit)
* vectors.
*
* The last parameter will typically be the output object and an object
* can be both an input and output parameter to all methods except where
* noted.
*
* See the README for notes about the design and structure of the API
* (especially related to performance).
*
*/
goog.provide('goog.vec.vec3f');
goog.provide('goog.vec.vec3f.Type');
/** @suppress {extraRequire} */
goog.require('goog.vec');
/** @typedef {goog.vec.Float32} */ goog.vec.vec3f.Type;
/**
* Creates a vec3f with all elements initialized to zero.
*
* @return {!goog.vec.vec3f.Type} The new vec3f.
*/
goog.vec.vec3f.create = function() {
return new Float32Array(3);
};
/**
* Initializes the vector with the given values.
*
* @param {goog.vec.vec3f.Type} vec The vector to receive the values.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @return {!goog.vec.vec3f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec3f.setFromValues = function(vec, v0, v1, v2) {
vec[0] = v0;
vec[1] = v1;
vec[2] = v2;
return vec;
};
/**
* Initializes vec3f vec from vec3f src.
*
* @param {goog.vec.vec3f.Type} vec The destination vector.
* @param {goog.vec.vec3f.Type} src The source vector.
* @return {!goog.vec.vec3f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec3f.setFromVec3f = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
return vec;
};
/**
* Initializes vec3f vec from vec3d src (typed as a Float64Array to
* avoid circular goog.requires).
*
* @param {goog.vec.vec3f.Type} vec The destination vector.
* @param {Float64Array} src The source vector.
* @return {!goog.vec.vec3f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec3f.setFromVec3d = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
return vec;
};
/**
* Initializes vec3f vec from Array src.
*
* @param {goog.vec.vec3f.Type} vec The destination vector.
* @param {Array<number>} src The source vector.
* @return {!goog.vec.vec3f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec3f.setFromArray = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
return vec;
};
/**
* Performs a component-wise addition of vec0 and vec1 together storing the
* result into resultVec.
*
* @param {goog.vec.vec3f.Type} vec0 The first addend.
* @param {goog.vec.vec3f.Type} vec1 The second addend.
* @param {goog.vec.vec3f.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.add = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] + vec1[0];
resultVec[1] = vec0[1] + vec1[1];
resultVec[2] = vec0[2] + vec1[2];
return resultVec;
};
/**
* Performs a component-wise subtraction of vec1 from vec0 storing the
* result into resultVec.
*
* @param {goog.vec.vec3f.Type} vec0 The minuend.
* @param {goog.vec.vec3f.Type} vec1 The subtrahend.
* @param {goog.vec.vec3f.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.subtract = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] - vec1[0];
resultVec[1] = vec0[1] - vec1[1];
resultVec[2] = vec0[2] - vec1[2];
return resultVec;
};
/**
* Negates vec0, storing the result into resultVec.
*
* @param {goog.vec.vec3f.Type} vec0 The vector to negate.
* @param {goog.vec.vec3f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.negate = function(vec0, resultVec) {
resultVec[0] = -vec0[0];
resultVec[1] = -vec0[1];
resultVec[2] = -vec0[2];
return resultVec;
};
/**
* Takes the absolute value of each component of vec0 storing the result in
* resultVec.
*
* @param {goog.vec.vec3f.Type} vec0 The source vector.
* @param {goog.vec.vec3f.Type} resultVec The vector to receive the result.
* May be vec0.
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.abs = function(vec0, resultVec) {
resultVec[0] = Math.abs(vec0[0]);
resultVec[1] = Math.abs(vec0[1]);
resultVec[2] = Math.abs(vec0[2]);
return resultVec;
};
/**
* Multiplies each component of vec0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.vec3f.Type} vec0 The source vector.
* @param {number} scalar The value to multiply with each component of vec0.
* @param {goog.vec.vec3f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.scale = function(vec0, scalar, resultVec) {
resultVec[0] = vec0[0] * scalar;
resultVec[1] = vec0[1] * scalar;
resultVec[2] = vec0[2] * scalar;
return resultVec;
};
/**
* Returns the magnitudeSquared of the given vector.
*
* @param {goog.vec.vec3f.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec3f.magnitudeSquared = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2];
return x * x + y * y + z * z;
};
/**
* Returns the magnitude of the given vector.
*
* @param {goog.vec.vec3f.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec3f.magnitude = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2];
return Math.sqrt(x * x + y * y + z * z);
};
/**
* Normalizes the given vector storing the result into resultVec.
*
* @param {goog.vec.vec3f.Type} vec0 The vector to normalize.
* @param {goog.vec.vec3f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.normalize = function(vec0, resultVec) {
var x = vec0[0], y = vec0[1], z = vec0[2];
var ilen = 1 / Math.sqrt(x * x + y * y + z * z);
resultVec[0] = x * ilen;
resultVec[1] = y * ilen;
resultVec[2] = z * ilen;
return resultVec;
};
/**
* Returns the scalar product of vectors v0 and v1.
*
* @param {goog.vec.vec3f.Type} v0 The first vector.
* @param {goog.vec.vec3f.Type} v1 The second vector.
* @return {number} The scalar product.
*/
goog.vec.vec3f.dot = function(v0, v1) {
return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
};
/**
* Computes the vector (cross) product of v0 and v1 storing the result into
* resultVec.
*
* @param {goog.vec.vec3f.Type} v0 The first vector.
* @param {goog.vec.vec3f.Type} v1 The second vector.
* @param {goog.vec.vec3f.Type} resultVec The vector to receive the
* results. May be either v0 or v1.
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.cross = function(v0, v1, resultVec) {
var x0 = v0[0], y0 = v0[1], z0 = v0[2];
var x1 = v1[0], y1 = v1[1], z1 = v1[2];
resultVec[0] = y0 * z1 - z0 * y1;
resultVec[1] = z0 * x1 - x0 * z1;
resultVec[2] = x0 * y1 - y0 * x1;
return resultVec;
};
/**
* Returns the squared distance between two points.
*
* @param {goog.vec.vec3f.Type} vec0 First point.
* @param {goog.vec.vec3f.Type} vec1 Second point.
* @return {number} The squared distance between the points.
*/
goog.vec.vec3f.distanceSquared = function(vec0, vec1) {
var x = vec0[0] - vec1[0];
var y = vec0[1] - vec1[1];
var z = vec0[2] - vec1[2];
return x * x + y * y + z * z;
};
/**
* Returns the distance between two points.
*
* @param {goog.vec.vec3f.Type} vec0 First point.
* @param {goog.vec.vec3f.Type} vec1 Second point.
* @return {number} The distance between the points.
*/
goog.vec.vec3f.distance = function(vec0, vec1) {
return Math.sqrt(goog.vec.vec3f.distanceSquared(vec0, vec1));
};
/**
* Returns a unit vector pointing from one point to another.
* If the input points are equal then the result will be all zeros.
*
* @param {goog.vec.vec3f.Type} vec0 Origin point.
* @param {goog.vec.vec3f.Type} vec1 Target point.
* @param {goog.vec.vec3f.Type} resultVec The vector to receive the
* results (may be vec0 or vec1).
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.direction = function(vec0, vec1, resultVec) {
var x = vec1[0] - vec0[0];
var y = vec1[1] - vec0[1];
var z = vec1[2] - vec0[2];
var d = Math.sqrt(x * x + y * y + z * z);
if (d) {
d = 1 / d;
resultVec[0] = x * d;
resultVec[1] = y * d;
resultVec[2] = z * d;
} else {
resultVec[0] = resultVec[1] = resultVec[2] = 0;
}
return resultVec;
};
/**
* Linearly interpolate from vec0 to v1 according to f. The value of f should be
* in the range [0..1] otherwise the results are undefined.
*
* @param {goog.vec.vec3f.Type} v0 The first vector.
* @param {goog.vec.vec3f.Type} v1 The second vector.
* @param {number} f The interpolation factor.
* @param {goog.vec.vec3f.Type} resultVec The vector to receive the
* results (may be v0 or v1).
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.lerp = function(v0, v1, f, resultVec) {
var x = v0[0], y = v0[1], z = v0[2];
resultVec[0] = (v1[0] - x) * f + x;
resultVec[1] = (v1[1] - y) * f + y;
resultVec[2] = (v1[2] - z) * f + z;
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the larger values in resultVec.
*
* @param {goog.vec.vec3f.Type} vec0 The source vector.
* @param {goog.vec.vec3f.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec3f.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.max = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.max(vec0[0], limit);
resultVec[1] = Math.max(vec0[1], limit);
resultVec[2] = Math.max(vec0[2], limit);
} else {
resultVec[0] = Math.max(vec0[0], limit[0]);
resultVec[1] = Math.max(vec0[1], limit[1]);
resultVec[2] = Math.max(vec0[2], limit[2]);
}
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the smaller values in resultVec.
*
* @param {goog.vec.vec3f.Type} vec0 The source vector.
* @param {goog.vec.vec3f.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec3f.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec3f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec3f.min = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.min(vec0[0], limit);
resultVec[1] = Math.min(vec0[1], limit);
resultVec[2] = Math.min(vec0[2], limit);
} else {
resultVec[0] = Math.min(vec0[0], limit[0]);
resultVec[1] = Math.min(vec0[1], limit[1]);
resultVec[2] = Math.min(vec0[2], limit[2]);
}
return resultVec;
};
/**
* Returns true if the components of v0 are equal to the components of v1.
*
* @param {goog.vec.vec3f.Type} v0 The first vector.
* @param {goog.vec.vec3f.Type} v1 The second vector.
* @return {boolean} True if the vectors are equal, false otherwise.
*/
goog.vec.vec3f.equals = function(v0, v1) {
return v0.length == v1.length &&
v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2];
};
@@ -0,0 +1,270 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec3d_test.html by running: //
// swap_type.sh vec3f_test.html > vec3d_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.vec3f</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.vec3f');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testCreate() {
var v = goog.vec.vec3f.create();
assertElementsEquals([0, 0, 0], v);
}
function testSet() {
var v = goog.vec.vec3f.create();
goog.vec.vec3f.setFromValues(v, 1, 2, 3);
assertElementsEquals([1, 2, 3], v);
goog.vec.vec3f.setFromArray(v, [4, 5, 6]);
assertElementsEquals([4, 5, 6], v);
var w = goog.vec.vec3f.create();
goog.vec.vec3f.setFromValues(w, 1, 2, 3);
assertElementsEquals([1, 2, 3], w);
goog.vec.vec3f.setFromArray(w, [4, 5, 6]);
assertElementsEquals([4, 5, 6], w);
}
function testAdd() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [1, 2, 3]);
var v1 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [4, 5, 6]);
var v2 = goog.vec.vec3f.setFromVec3f(goog.vec.vec3f.create(), v0);
goog.vec.vec3f.add(v2, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([5, 7, 9], v2);
goog.vec.vec3f.add(goog.vec.vec3f.add(v0, v1, v2), v0, v2);
assertElementsEquals([6, 9, 12], v2);
}
function testSubtract() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [1, 2, 3]);
var v1 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [4, 5, 6]);
var v2 = goog.vec.vec3f.setFromVec3f(goog.vec.vec3f.create(), v0);
goog.vec.vec3f.subtract(v2, v1, v2);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([-3, -3, -3], v2);
goog.vec.vec3f.setFromValues(v2, 0, 0, 0);
goog.vec.vec3f.subtract(v1, v0, v2);
assertElementsEquals([3, 3, 3], v2);
v2 = goog.vec.vec3f.setFromVec3f(goog.vec.vec3f.create(), v0);
goog.vec.vec3f.subtract(v2, v1, v2);
assertElementsEquals([-3, -3, -3], v2);
goog.vec.vec3f.subtract(goog.vec.vec3f.subtract(v1, v0, v2), v0, v2);
assertElementsEquals([2, 1, 0], v2);
}
function testNegate() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [1, 2, 3]);
var v1 = goog.vec.vec3f.create();
goog.vec.vec3f.negate(v0, v1);
assertElementsEquals([-1, -2, -3], v1);
assertElementsEquals([1, 2, 3], v0);
goog.vec.vec3f.negate(v0, v0);
assertElementsEquals([-1, -2, -3], v0);
}
function testAbs() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [-1, -2, -3]);
var v1 = goog.vec.vec3f.create();
goog.vec.vec3f.abs(v0, v1);
assertElementsEquals([1, 2, 3], v1);
assertElementsEquals([-1, -2, -3], v0);
goog.vec.vec3f.abs(v0, v0);
assertElementsEquals([1, 2, 3], v0);
}
function testScale() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [1, 2, 3]);
var v1 = goog.vec.vec3f.create();
goog.vec.vec3f.scale(v0, 4, v1);
assertElementsEquals([4, 8, 12], v1);
assertElementsEquals([1, 2, 3], v0);
goog.vec.vec3f.setFromArray(v1, v0);
goog.vec.vec3f.scale(v1, 5, v1);
assertElementsEquals([5, 10, 15], v1);
}
function testMagnitudeSquared() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [1, 2, 3]);
assertEquals(14, goog.vec.vec3f.magnitudeSquared(v0));
}
function testMagnitude() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [1, 2, 3]);
assertEquals(Math.sqrt(14), goog.vec.vec3f.magnitude(v0));
}
function testNormalize() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [2, 3, 4]);
var v1 = goog.vec.vec3f.create();
var v2 = goog.vec.vec3f.create();
goog.vec.vec3f.scale(
v0, 1 / goog.vec.vec3f.magnitude(v0), v2);
goog.vec.vec3f.normalize(v0, v1);
assertElementsEquals(v2, v1);
assertElementsEquals([2, 3, 4], v0);
goog.vec.vec3f.setFromArray(v1, v0);
goog.vec.vec3f.normalize(v1, v1);
assertElementsEquals(v2, v1);
}
function testDot() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [1, 2, 3]);
var v1 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [4, 5, 6]);
assertEquals(32, goog.vec.vec3f.dot(v0, v1));
assertEquals(32, goog.vec.vec3f.dot(v1, v0));
}
function testCross() {
var v0 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [1, 2, 3]);
var v1 = goog.vec.vec3f.setFromArray(goog.vec.vec3f.create(), [4, 5, 6]);
var crossVec = goog.vec.vec3f.create();
goog.vec.vec3f.cross(v0, v1, crossVec);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([-3, 6, -3], crossVec);
goog.vec.vec3f.setFromArray(crossVec, v1);
goog.vec.vec3f.cross(crossVec, v0, crossVec);
assertElementsEquals([1, 2, 3], v0);
assertElementsEquals([4, 5, 6], v1);
assertElementsEquals([3, -6, 3], crossVec);
goog.vec.vec3f.cross(v0, v0, v0);
assertElementsEquals([0, 0, 0], v0);
}
function testDistanceSquared() {
var v0 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 1, 2, 3);
var v1 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 1, 2, 3);
assertEquals(0, goog.vec.vec3f.distanceSquared(v0, v1));
goog.vec.vec3f.setFromValues(v0, 1, 2, 3);
goog.vec.vec3f.setFromValues(v1, -1, -2, -1);
assertEquals(36, goog.vec.vec3f.distanceSquared(v0, v1));
}
function testDistance() {
var v0 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 1, 2, 3);
var v1 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 1, 2, 3);
assertEquals(0, goog.vec.vec3f.distance(v0, v1));
goog.vec.vec3f.setFromValues(v0, 1, 2, 3);
goog.vec.vec3f.setFromValues(v1, -1, -2, -1);
assertEquals(6, goog.vec.vec3f.distance(v0, v1));
}
function testDirection() {
var v0 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 1, 2, 3);
var v1 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 1, 2, 3);
var dirVec = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 4, 5, 6);
goog.vec.vec3f.direction(v0, v1, dirVec);
assertElementsEquals([0, 0, 0], dirVec);
goog.vec.vec3f.setFromValues(v0, 0, 0, 0);
goog.vec.vec3f.setFromValues(v1, 1, 0, 0);
goog.vec.vec3f.direction(v0, v1, dirVec);
assertElementsEquals([1, 0, 0], dirVec);
goog.vec.vec3f.setFromValues(v0, 1, 1, 1);
goog.vec.vec3f.setFromValues(v1, 0, 0, 0);
goog.vec.vec3f.direction(v0, v1, dirVec);
assertElementsRoughlyEqual(
[-0.5773502588272095, -0.5773502588272095, -0.5773502588272095],
dirVec, goog.vec.EPSILON);
}
function testLerp() {
var v0 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 1, 2, 3);
var v1 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 10, 20, 30);
var v2 = goog.vec.vec3f.setFromVec3f(goog.vec.vec3f.create(), v0);
goog.vec.vec3f.lerp(v2, v1, 0, v2);
assertElementsEquals([1, 2, 3], v2);
goog.vec.vec3f.lerp(v2, v1, 1, v2);
assertElementsEquals([10, 20, 30], v2);
goog.vec.vec3f.lerp(v0, v1, .5, v2);
assertElementsEquals([5.5, 11, 16.5], v2);
}
function testMax() {
var v0 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 10, 20, 30);
var v1 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 5, 25, 35);
var v2 = goog.vec.vec3f.create();
goog.vec.vec3f.max(v0, v1, v2);
assertElementsEquals([10, 25, 35], v2);
goog.vec.vec3f.max(v1, v0, v1);
assertElementsEquals([10, 25, 35], v1);
goog.vec.vec3f.max(v2, 20, v2);
assertElementsEquals([20, 25, 35], v2);
}
function testMin() {
var v0 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 10, 20, 30);
var v1 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 5, 25, 35);
var v2 = goog.vec.vec3f.create();
goog.vec.vec3f.min(v0, v1, v2);
assertElementsEquals([5, 20, 30], v2);
goog.vec.vec3f.min(v1, v0, v1);
assertElementsEquals([5, 20, 30], v1);
goog.vec.vec3f.min(v2, 20, v2);
assertElementsEquals([5, 20, 20], v2);
}
function testEquals() {
var v0 = goog.vec.vec3f.setFromValues(goog.vec.vec3f.create(), 1, 2, 3);
var v1 = goog.vec.vec3f.setFromVec3f(goog.vec.vec3f.create(), v0);
assertElementsEquals(v0, v1);
v1[0] = 4;
assertFalse(goog.vec.vec3f.equals(v0, v1));
v1 = goog.vec.vec3f.setFromVec3f(goog.vec.vec3f.create(), v0);
v1[1] = 4;
assertFalse(goog.vec.vec3f.equals(v0, v1));
v1 = goog.vec.vec3f.setFromVec3f(goog.vec.vec3f.create(), v0);
v1[2] = 4;
assertFalse(goog.vec.vec3f.equals(v0, v1));
}
</script>
</body>
@@ -0,0 +1,479 @@
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Supplies 4 element vectors that are compatible with WebGL.
* Each element is a float32 since that is typically the desired size of a
* 4-vector in the GPU. The API is structured to avoid unnecessary memory
* allocations. The last parameter will typically be the output vector and
* an object can be both an input and output parameter to all methods except
* where noted.
*
*/
goog.provide('goog.vec.Vec4');
/** @suppress {extraRequire} */
goog.require('goog.vec');
/** @typedef {goog.vec.Float32} */ goog.vec.Vec4.Float32;
/** @typedef {goog.vec.Float64} */ goog.vec.Vec4.Float64;
/** @typedef {goog.vec.Number} */ goog.vec.Vec4.Number;
/** @typedef {goog.vec.AnyType} */ goog.vec.Vec4.AnyType;
// The following two types are deprecated - use the above types instead.
/** @typedef {Float32Array} */ goog.vec.Vec4.Type;
/** @typedef {goog.vec.ArrayType} */ goog.vec.Vec4.Vec4Like;
/**
* Creates a 4 element vector of Float32. The array is initialized to zero.
*
* @return {!goog.vec.Vec4.Float32} The new 3 element array.
*/
goog.vec.Vec4.createFloat32 = function() {
return new Float32Array(4);
};
/**
* Creates a 4 element vector of Float64. The array is initialized to zero.
*
* @return {!goog.vec.Vec4.Float64} The new 4 element array.
*/
goog.vec.Vec4.createFloat64 = function() {
return new Float64Array(4);
};
/**
* Creates a 4 element vector of Number. The array is initialized to zero.
*
* @return {!goog.vec.Vec4.Number} The new 4 element array.
*/
goog.vec.Vec4.createNumber = function() {
var v = new Array(4);
goog.vec.Vec4.setFromValues(v, 0, 0, 0, 0);
return v;
};
/**
* Creates a 4 element vector of Float32Array. The array is initialized to zero.
*
* @deprecated Use createFloat32.
* @return {!goog.vec.Vec4.Type} The new 4 element array.
*/
goog.vec.Vec4.create = function() {
return new Float32Array(4);
};
/**
* Creates a new 4 element vector initialized with the value from the given
* array.
*
* @deprecated Use createFloat32FromArray.
* @param {goog.vec.Vec4.Vec4Like} vec The source 4 element array.
* @return {!goog.vec.Vec4.Type} The new 4 element array.
*/
goog.vec.Vec4.createFromArray = function(vec) {
var newVec = goog.vec.Vec4.create();
goog.vec.Vec4.setFromArray(newVec, vec);
return newVec;
};
/**
* Creates a new 4 element FLoat32 vector initialized with the value from the
* given array.
*
* @param {goog.vec.Vec4.AnyType} vec The source 3 element array.
* @return {!goog.vec.Vec4.Float32} The new 3 element array.
*/
goog.vec.Vec4.createFloat32FromArray = function(vec) {
var newVec = goog.vec.Vec4.createFloat32();
goog.vec.Vec4.setFromArray(newVec, vec);
return newVec;
};
/**
* Creates a new 4 element Float32 vector initialized with the supplied values.
*
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @param {number} v3 The value for element at index 3.
* @return {!goog.vec.Vec4.Float32} The new vector.
*/
goog.vec.Vec4.createFloat32FromValues = function(v0, v1, v2, v3) {
var vec = goog.vec.Vec4.createFloat32();
goog.vec.Vec4.setFromValues(vec, v0, v1, v2, v3);
return vec;
};
/**
* Creates a clone of the given 4 element Float32 vector.
*
* @param {goog.vec.Vec4.Float32} vec The source 3 element vector.
* @return {!goog.vec.Vec4.Float32} The new cloned vector.
*/
goog.vec.Vec4.cloneFloat32 = goog.vec.Vec4.createFloat32FromArray;
/**
* Creates a new 4 element Float64 vector initialized with the value from the
* given array.
*
* @param {goog.vec.Vec4.AnyType} vec The source 4 element array.
* @return {!goog.vec.Vec4.Float64} The new 4 element array.
*/
goog.vec.Vec4.createFloat64FromArray = function(vec) {
var newVec = goog.vec.Vec4.createFloat64();
goog.vec.Vec4.setFromArray(newVec, vec);
return newVec;
};
/**
* Creates a new 4 element Float64 vector initialized with the supplied values.
*
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @param {number} v3 The value for element at index 3.
* @return {!goog.vec.Vec4.Float64} The new vector.
*/
goog.vec.Vec4.createFloat64FromValues = function(v0, v1, v2, v3) {
var vec = goog.vec.Vec4.createFloat64();
goog.vec.Vec4.setFromValues(vec, v0, v1, v2, v3);
return vec;
};
/**
* Creates a clone of the given 4 element vector.
*
* @param {goog.vec.Vec4.Float64} vec The source 4 element vector.
* @return {!goog.vec.Vec4.Float64} The new cloned vector.
*/
goog.vec.Vec4.cloneFloat64 = goog.vec.Vec4.createFloat64FromArray;
/**
* Creates a new 4 element vector initialized with the supplied values.
*
* @deprecated Use createFloat32FromValues.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @param {number} v3 The value for element at index 3.
* @return {!goog.vec.Vec4.Type} The new vector.
*/
goog.vec.Vec4.createFromValues = function(v0, v1, v2, v3) {
var vec = goog.vec.Vec4.create();
goog.vec.Vec4.setFromValues(vec, v0, v1, v2, v3);
return vec;
};
/**
* Creates a clone of the given 4 element vector.
*
* @deprecated Use cloneFloat32.
* @param {goog.vec.Vec4.Vec4Like} vec The source 4 element vector.
* @return {!goog.vec.Vec4.Type} The new cloned vector.
*/
goog.vec.Vec4.clone = goog.vec.Vec4.createFromArray;
/**
* Initializes the vector with the given values.
*
* @param {goog.vec.Vec4.AnyType} vec The vector to receive the values.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @param {number} v3 The value for element at index 3.
* @return {!goog.vec.Vec4.AnyType} Return vec so that operations can be
* chained together.
*/
goog.vec.Vec4.setFromValues = function(vec, v0, v1, v2, v3) {
vec[0] = v0;
vec[1] = v1;
vec[2] = v2;
vec[3] = v3;
return vec;
};
/**
* Initializes the vector with the given array of values.
*
* @param {goog.vec.Vec4.AnyType} vec The vector to receive the
* values.
* @param {goog.vec.Vec4.AnyType} values The array of values.
* @return {!goog.vec.Vec4.AnyType} Return vec so that operations can be
* chained together.
*/
goog.vec.Vec4.setFromArray = function(vec, values) {
vec[0] = values[0];
vec[1] = values[1];
vec[2] = values[2];
vec[3] = values[3];
return vec;
};
/**
* Performs a component-wise addition of vec0 and vec1 together storing the
* result into resultVec.
*
* @param {goog.vec.Vec4.AnyType} vec0 The first addend.
* @param {goog.vec.Vec4.AnyType} vec1 The second addend.
* @param {goog.vec.Vec4.AnyType} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec4.add = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] + vec1[0];
resultVec[1] = vec0[1] + vec1[1];
resultVec[2] = vec0[2] + vec1[2];
resultVec[3] = vec0[3] + vec1[3];
return resultVec;
};
/**
* Performs a component-wise subtraction of vec1 from vec0 storing the
* result into resultVec.
*
* @param {goog.vec.Vec4.AnyType} vec0 The minuend.
* @param {goog.vec.Vec4.AnyType} vec1 The subtrahend.
* @param {goog.vec.Vec4.AnyType} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec4.subtract = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] - vec1[0];
resultVec[1] = vec0[1] - vec1[1];
resultVec[2] = vec0[2] - vec1[2];
resultVec[3] = vec0[3] - vec1[3];
return resultVec;
};
/**
* Negates vec0, storing the result into resultVec.
*
* @param {goog.vec.Vec4.AnyType} vec0 The vector to negate.
* @param {goog.vec.Vec4.AnyType} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec4.negate = function(vec0, resultVec) {
resultVec[0] = -vec0[0];
resultVec[1] = -vec0[1];
resultVec[2] = -vec0[2];
resultVec[3] = -vec0[3];
return resultVec;
};
/**
* Takes the absolute value of each component of vec0 storing the result in
* resultVec.
*
* @param {goog.vec.Vec4.AnyType} vec0 The source vector.
* @param {goog.vec.Vec4.AnyType} resultVec The vector to receive the result.
* May be vec0.
* @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec4.abs = function(vec0, resultVec) {
resultVec[0] = Math.abs(vec0[0]);
resultVec[1] = Math.abs(vec0[1]);
resultVec[2] = Math.abs(vec0[2]);
resultVec[3] = Math.abs(vec0[3]);
return resultVec;
};
/**
* Multiplies each component of vec0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.Vec4.AnyType} vec0 The source vector.
* @param {number} scalar The value to multiply with each component of vec0.
* @param {goog.vec.Vec4.AnyType} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec4.scale = function(vec0, scalar, resultVec) {
resultVec[0] = vec0[0] * scalar;
resultVec[1] = vec0[1] * scalar;
resultVec[2] = vec0[2] * scalar;
resultVec[3] = vec0[3] * scalar;
return resultVec;
};
/**
* Returns the magnitudeSquared of the given vector.
*
* @param {goog.vec.Vec4.AnyType} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.Vec4.magnitudeSquared = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2], w = vec0[3];
return x * x + y * y + z * z + w * w;
};
/**
* Returns the magnitude of the given vector.
*
* @param {goog.vec.Vec4.AnyType} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.Vec4.magnitude = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2], w = vec0[3];
return Math.sqrt(x * x + y * y + z * z + w * w);
};
/**
* Normalizes the given vector storing the result into resultVec.
*
* @param {goog.vec.Vec4.AnyType} vec0 The vector to normalize.
* @param {goog.vec.Vec4.AnyType} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec4.normalize = function(vec0, resultVec) {
var ilen = 1 / goog.vec.Vec4.magnitude(vec0);
resultVec[0] = vec0[0] * ilen;
resultVec[1] = vec0[1] * ilen;
resultVec[2] = vec0[2] * ilen;
resultVec[3] = vec0[3] * ilen;
return resultVec;
};
/**
* Returns the scalar product of vectors v0 and v1.
*
* @param {goog.vec.Vec4.AnyType} v0 The first vector.
* @param {goog.vec.Vec4.AnyType} v1 The second vector.
* @return {number} The scalar product.
*/
goog.vec.Vec4.dot = function(v0, v1) {
return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2] + v0[3] * v1[3];
};
/**
* Linearly interpolate from v0 to v1 according to f. The value of f should be
* in the range [0..1] otherwise the results are undefined.
*
* @param {goog.vec.Vec4.AnyType} v0 The first vector.
* @param {goog.vec.Vec4.AnyType} v1 The second vector.
* @param {number} f The interpolation factor.
* @param {goog.vec.Vec4.AnyType} resultVec The vector to receive the
* results (may be v0 or v1).
* @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec4.lerp = function(v0, v1, f, resultVec) {
var x = v0[0], y = v0[1], z = v0[2], w = v0[3];
resultVec[0] = (v1[0] - x) * f + x;
resultVec[1] = (v1[1] - y) * f + y;
resultVec[2] = (v1[2] - z) * f + z;
resultVec[3] = (v1[3] - w) * f + w;
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the larger values in resultVec.
*
* @param {goog.vec.Vec4.AnyType} vec0 The source vector.
* @param {goog.vec.Vec4.AnyType|number} limit The limit vector or scalar.
* @param {goog.vec.Vec4.AnyType} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec4.max = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.max(vec0[0], limit);
resultVec[1] = Math.max(vec0[1], limit);
resultVec[2] = Math.max(vec0[2], limit);
resultVec[3] = Math.max(vec0[3], limit);
} else {
resultVec[0] = Math.max(vec0[0], limit[0]);
resultVec[1] = Math.max(vec0[1], limit[1]);
resultVec[2] = Math.max(vec0[2], limit[2]);
resultVec[3] = Math.max(vec0[3], limit[3]);
}
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the smaller values in resultVec.
*
* @param {goog.vec.Vec4.AnyType} vec0 The source vector.
* @param {goog.vec.Vec4.AnyType|number} limit The limit vector or scalar.
* @param {goog.vec.Vec4.AnyType} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.Vec4.AnyType} Return resultVec so that operations can be
* chained together.
*/
goog.vec.Vec4.min = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.min(vec0[0], limit);
resultVec[1] = Math.min(vec0[1], limit);
resultVec[2] = Math.min(vec0[2], limit);
resultVec[3] = Math.min(vec0[3], limit);
} else {
resultVec[0] = Math.min(vec0[0], limit[0]);
resultVec[1] = Math.min(vec0[1], limit[1]);
resultVec[2] = Math.min(vec0[2], limit[2]);
resultVec[3] = Math.min(vec0[3], limit[3]);
}
return resultVec;
};
/**
* Returns true if the components of v0 are equal to the components of v1.
*
* @param {goog.vec.Vec4.AnyType} v0 The first vector.
* @param {goog.vec.Vec4.AnyType} v1 The second vector.
* @return {boolean} True if the vectors are equal, false otherwise.
*/
goog.vec.Vec4.equals = function(v0, v1) {
return v0.length == v1.length &&
v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2] && v0[3] == v1[3];
};
@@ -0,0 +1,230 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.Vec4</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.Vec4');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testDeprecatedConstructor() {
assertElementsEquals([0, 0, 0, 0], goog.vec.Vec4.create());
assertElementsEquals([1, 2, 3, 4],
goog.vec.Vec4.createFromValues(1, 2, 3, 4));
assertElementsEquals([1, 2, 3, 4],
goog.vec.Vec4.createFromArray([1, 2, 3, 4]));
var v = goog.vec.Vec4.createFromValues(1, 2, 3, 4);
assertElementsEquals([1, 2, 3, 4], goog.vec.Vec4.clone(v));
}
function testConstructor() {
assertElementsEquals([0, 0, 0, 0], goog.vec.Vec4.createFloat32());
assertElementsEquals([1, 2, 3, 4],
goog.vec.Vec4.createFloat32FromValues(1, 2, 3, 4));
assertElementsEquals([1, 2, 3, 4],
goog.vec.Vec4.createFloat32FromArray([1, 2, 3, 4]));
var v = goog.vec.Vec4.createFloat32FromValues(1, 2, 3, 4);
assertElementsEquals([1, 2, 3, 4], goog.vec.Vec4.cloneFloat32(v));
assertElementsEquals([0, 0, 0, 0], goog.vec.Vec4.createFloat64());
assertElementsEquals([1, 2, 3, 4],
goog.vec.Vec4.createFloat64FromValues(1, 2, 3, 4));
assertElementsEquals([1, 2, 3, 4],
goog.vec.Vec4.createFloat64FromArray([1, 2, 3, 4]));
var w = goog.vec.Vec4.createFloat64FromValues(1, 2, 3, 4);
assertElementsEquals([1, 2, 3, 4], goog.vec.Vec4.cloneFloat64(w));
}
function testSet() {
var v = goog.vec.Vec4.createFloat32();
goog.vec.Vec4.setFromValues(v, 1, 2, 3, 4);
assertElementsEquals([1, 2, 3, 4], v);
goog.vec.Vec4.setFromArray(v, [4, 5, 6, 7]);
assertElementsEquals([4, 5, 6, 7], v);
}
function testAdd() {
var v0 = goog.vec.Vec4.createFloat32FromArray([1, 2, 3, 4]);
var v1 = goog.vec.Vec4.createFloat32FromArray([5, 6, 7, 8]);
var v2 = goog.vec.Vec4.cloneFloat32(v0);
goog.vec.Vec4.add(v2, v1, v2);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([6, 8, 10, 12], v2);
goog.vec.Vec4.add(goog.vec.Vec4.add(v0, v1, v2), v0, v2);
assertElementsEquals([7, 10, 13, 16], v2);
}
function testSubtract() {
var v0 = goog.vec.Vec4.createFloat32FromArray([4, 3, 2, 1]);
var v1 = goog.vec.Vec4.createFloat32FromArray([5, 6, 7, 8]);
var v2 = goog.vec.Vec4.cloneFloat32(v0);
goog.vec.Vec4.subtract(v2, v1, v2);
assertElementsEquals([4, 3, 2, 1], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([-1, -3, -5, -7], v2);
goog.vec.Vec4.setFromValues(v2, 0, 0, 0, 0);
goog.vec.Vec4.subtract(v1, v0, v2);
assertElementsEquals([1, 3, 5, 7], v2);
goog.vec.Vec4.subtract(goog.vec.Vec4.subtract(v1, v0, v2), v0, v2);
assertElementsEquals([-3, 0, 3, 6], v2);
}
function testNegate() {
var v0 = goog.vec.Vec4.createFloat32FromArray([1, 2, 3, 4]);
var v1 = goog.vec.Vec4.createFloat32();
goog.vec.Vec4.negate(v0, v1);
assertElementsEquals([-1, -2, -3, -4], v1);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.Vec4.negate(v0, v0);
assertElementsEquals([-1, -2, -3, -4], v0);
}
function testAbs() {
var v0 = goog.vec.Vec4.createFloat32FromValues(-1, -2, -3, -4);
var v1 = goog.vec.Vec4.createFloat32();
goog.vec.Vec4.abs(v0, v1);
assertElementsEquals([1, 2, 3, 4], v1);
assertElementsEquals([-1, -2, -3, -4], v0);
goog.vec.Vec4.abs(v0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
}
function testScale() {
var v0 = goog.vec.Vec4.createFloat32FromArray([1, 2, 3, 4]);
var v1 = goog.vec.Vec4.createFloat32();
goog.vec.Vec4.scale(v0, 4, v1);
assertElementsEquals([4, 8, 12, 16], v1);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.Vec4.setFromArray(v1, v0);
goog.vec.Vec4.scale(v1, 5, v1);
assertElementsEquals([5, 10, 15, 20], v1);
}
function testMagnitudeSquared() {
var v0 = goog.vec.Vec4.createFloat32FromArray([1, 2, 3, 4]);
assertEquals(30, goog.vec.Vec4.magnitudeSquared(v0));
}
function testMagnitude() {
var v0 = goog.vec.Vec4.createFloat32FromArray([1, 2, 3, 4]);
assertEquals(Math.sqrt(30), goog.vec.Vec4.magnitude(v0));
}
function testNormalize() {
var v0 = goog.vec.Vec4.createFloat32FromArray([2, 3, 4, 5]);
var v1 = goog.vec.Vec4.createFloat32();
var v2 = goog.vec.Vec4.createFloat32();
goog.vec.Vec4.scale(v0, 1 / goog.vec.Vec4.magnitude(v0), v2);
goog.vec.Vec4.normalize(v0, v1);
assertElementsEquals(v2, v1);
assertElementsEquals([2, 3, 4, 5], v0);
goog.vec.Vec4.setFromArray(v1, v0);
goog.vec.Vec4.normalize(v1, v1);
assertElementsEquals(v2, v1);
}
function testDot() {
var v0 = goog.vec.Vec4.createFloat32FromArray([1, 2, 3, 4]);
var v1 = goog.vec.Vec4.createFloat32FromArray([5, 6, 7, 8]);
assertEquals(70, goog.vec.Vec4.dot(v0, v1));
assertEquals(70, goog.vec.Vec4.dot(v1, v0));
}
function testLerp() {
var v0 = goog.vec.Vec4.createFloat32FromValues(1, 2, 3, 4);
var v1 = goog.vec.Vec4.createFloat32FromValues(10, 20, 30, 40);
var v2 = goog.vec.Vec4.cloneFloat32(v0);
goog.vec.Vec4.lerp(v2, v1, 0, v2);
assertElementsEquals([1, 2, 3, 4], v2);
goog.vec.Vec4.lerp(v2, v1, 1, v2);
assertElementsEquals([10, 20, 30, 40], v2);
goog.vec.Vec4.lerp(v0, v1, .5, v2);
assertElementsEquals([5.5, 11, 16.5, 22], v2);
}
function testMax() {
var v0 = goog.vec.Vec4.createFloat32FromValues(10, 20, 30, 40);
var v1 = goog.vec.Vec4.createFloat32FromValues(5, 25, 35, 30);
var v2 = goog.vec.Vec4.createFloat32();
goog.vec.Vec4.max(v0, v1, v2);
assertElementsEquals([10, 25, 35, 40], v2);
goog.vec.Vec4.max(v1, v0, v1);
assertElementsEquals([10, 25, 35, 40], v1);
goog.vec.Vec4.max(v2, 20, v2);
assertElementsEquals([20, 25, 35, 40], v2);
}
function testMin() {
var v0 = goog.vec.Vec4.createFloat32FromValues(10, 20, 30, 40);
var v1 = goog.vec.Vec4.createFloat32FromValues(5, 25, 35, 30);
var v2 = goog.vec.Vec4.createFloat32();
goog.vec.Vec4.min(v0, v1, v2);
assertElementsEquals([5, 20, 30, 30], v2);
goog.vec.Vec4.min(v1, v0, v1);
assertElementsEquals([5, 20, 30, 30], v1);
goog.vec.Vec4.min(v2, 20, v2);
assertElementsEquals([5, 20, 20, 20], v2);
}
function testEquals() {
var v0 = goog.vec.Vec4.createFloat32FromValues(1, 2, 3, 4);
var v1 = goog.vec.Vec4.cloneFloat32(v0);
assertElementsEquals(v0, v1);
v1[0] = 5;
assertFalse(goog.vec.Vec4.equals(v0, v1));
v1 = goog.vec.Vec4.cloneFloat32(v0);
v1[1] = 5;
assertFalse(goog.vec.Vec4.equals(v0, v1));
v1 = goog.vec.Vec4.cloneFloat32(v0);
v1[2] = 5;
assertFalse(goog.vec.Vec4.equals(v0, v1));
v1 = goog.vec.Vec4.cloneFloat32(v0);
v1[3] = 5;
assertFalse(goog.vec.Vec4.equals(v0, v1));
}
</script>
</body>
@@ -0,0 +1,366 @@
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec4f.js by running: //
// swap_type.sh vec4d.js > vec4f.js //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
/**
* @fileoverview Provides functions for operating on 4 element double (64bit)
* vectors.
*
* The last parameter will typically be the output object and an object
* can be both an input and output parameter to all methods except where
* noted.
*
* See the README for notes about the design and structure of the API
* (especially related to performance).
*
*/
goog.provide('goog.vec.vec4d');
goog.provide('goog.vec.vec4d.Type');
/** @suppress {extraRequire} */
goog.require('goog.vec');
/** @typedef {goog.vec.Float64} */ goog.vec.vec4d.Type;
/**
* Creates a vec4d with all elements initialized to zero.
*
* @return {!goog.vec.vec4d.Type} The new vec4d.
*/
goog.vec.vec4d.create = function() {
return new Float64Array(4);
};
/**
* Initializes the vector with the given values.
*
* @param {goog.vec.vec4d.Type} vec The vector to receive the values.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @param {number} v3 The value for element at index 3.
* @return {!goog.vec.vec4d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec4d.setFromValues = function(vec, v0, v1, v2, v3) {
vec[0] = v0;
vec[1] = v1;
vec[2] = v2;
vec[3] = v3;
return vec;
};
/**
* Initializes vec4d vec from vec4d src.
*
* @param {goog.vec.vec4d.Type} vec The destination vector.
* @param {goog.vec.vec4d.Type} src The source vector.
* @return {!goog.vec.vec4d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec4d.setFromVec4d = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
vec[3] = src[3];
return vec;
};
/**
* Initializes vec4d vec from vec4f src (typed as a Float32Array to
* avoid circular goog.requires).
*
* @param {goog.vec.vec4d.Type} vec The destination vector.
* @param {Float32Array} src The source vector.
* @return {!goog.vec.vec4d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec4d.setFromVec4f = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
vec[3] = src[3];
return vec;
};
/**
* Initializes vec4d vec from Array src.
*
* @param {goog.vec.vec4d.Type} vec The destination vector.
* @param {Array<number>} src The source vector.
* @return {!goog.vec.vec4d.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec4d.setFromArray = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
vec[3] = src[3];
return vec;
};
/**
* Performs a component-wise addition of vec0 and vec1 together storing the
* result into resultVec.
*
* @param {goog.vec.vec4d.Type} vec0 The first addend.
* @param {goog.vec.vec4d.Type} vec1 The second addend.
* @param {goog.vec.vec4d.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4d.add = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] + vec1[0];
resultVec[1] = vec0[1] + vec1[1];
resultVec[2] = vec0[2] + vec1[2];
resultVec[3] = vec0[3] + vec1[3];
return resultVec;
};
/**
* Performs a component-wise subtraction of vec1 from vec0 storing the
* result into resultVec.
*
* @param {goog.vec.vec4d.Type} vec0 The minuend.
* @param {goog.vec.vec4d.Type} vec1 The subtrahend.
* @param {goog.vec.vec4d.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4d.subtract = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] - vec1[0];
resultVec[1] = vec0[1] - vec1[1];
resultVec[2] = vec0[2] - vec1[2];
resultVec[3] = vec0[3] - vec1[3];
return resultVec;
};
/**
* Negates vec0, storing the result into resultVec.
*
* @param {goog.vec.vec4d.Type} vec0 The vector to negate.
* @param {goog.vec.vec4d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4d.negate = function(vec0, resultVec) {
resultVec[0] = -vec0[0];
resultVec[1] = -vec0[1];
resultVec[2] = -vec0[2];
resultVec[3] = -vec0[3];
return resultVec;
};
/**
* Takes the absolute value of each component of vec0 storing the result in
* resultVec.
*
* @param {goog.vec.vec4d.Type} vec0 The source vector.
* @param {goog.vec.vec4d.Type} resultVec The vector to receive the result.
* May be vec0.
* @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4d.abs = function(vec0, resultVec) {
resultVec[0] = Math.abs(vec0[0]);
resultVec[1] = Math.abs(vec0[1]);
resultVec[2] = Math.abs(vec0[2]);
resultVec[3] = Math.abs(vec0[3]);
return resultVec;
};
/**
* Multiplies each component of vec0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.vec4d.Type} vec0 The source vector.
* @param {number} scalar The value to multiply with each component of vec0.
* @param {goog.vec.vec4d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4d.scale = function(vec0, scalar, resultVec) {
resultVec[0] = vec0[0] * scalar;
resultVec[1] = vec0[1] * scalar;
resultVec[2] = vec0[2] * scalar;
resultVec[3] = vec0[3] * scalar;
return resultVec;
};
/**
* Returns the magnitudeSquared of the given vector.
*
* @param {goog.vec.vec4d.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec4d.magnitudeSquared = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2], w = vec0[3];
return x * x + y * y + z * z + w * w;
};
/**
* Returns the magnitude of the given vector.
*
* @param {goog.vec.vec4d.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec4d.magnitude = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2], w = vec0[3];
return Math.sqrt(x * x + y * y + z * z + w * w);
};
/**
* Normalizes the given vector storing the result into resultVec.
*
* @param {goog.vec.vec4d.Type} vec0 The vector to normalize.
* @param {goog.vec.vec4d.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4d.normalize = function(vec0, resultVec) {
var x = vec0[0], y = vec0[1], z = vec0[2], w = vec0[3];
var ilen = 1 / Math.sqrt(x * x + y * y + z * z + w * w);
resultVec[0] = x * ilen;
resultVec[1] = y * ilen;
resultVec[2] = z * ilen;
resultVec[3] = w * ilen;
return resultVec;
};
/**
* Returns the scalar product of vectors v0 and v1.
*
* @param {goog.vec.vec4d.Type} v0 The first vector.
* @param {goog.vec.vec4d.Type} v1 The second vector.
* @return {number} The scalar product.
*/
goog.vec.vec4d.dot = function(v0, v1) {
return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2] + v0[3] * v1[3];
};
/**
* Linearly interpolate from v0 to v1 according to f. The value of f should be
* in the range [0..1] otherwise the results are undefined.
*
* @param {goog.vec.vec4d.Type} v0 The first vector.
* @param {goog.vec.vec4d.Type} v1 The second vector.
* @param {number} f The interpolation factor.
* @param {goog.vec.vec4d.Type} resultVec The vector to receive the
* results (may be v0 or v1).
* @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4d.lerp = function(v0, v1, f, resultVec) {
var x = v0[0], y = v0[1], z = v0[2], w = v0[3];
resultVec[0] = (v1[0] - x) * f + x;
resultVec[1] = (v1[1] - y) * f + y;
resultVec[2] = (v1[2] - z) * f + z;
resultVec[3] = (v1[3] - w) * f + w;
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the larger values in resultVec.
*
* @param {goog.vec.vec4d.Type} vec0 The source vector.
* @param {goog.vec.vec4d.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec4d.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4d.max = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.max(vec0[0], limit);
resultVec[1] = Math.max(vec0[1], limit);
resultVec[2] = Math.max(vec0[2], limit);
resultVec[3] = Math.max(vec0[3], limit);
} else {
resultVec[0] = Math.max(vec0[0], limit[0]);
resultVec[1] = Math.max(vec0[1], limit[1]);
resultVec[2] = Math.max(vec0[2], limit[2]);
resultVec[3] = Math.max(vec0[3], limit[3]);
}
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the smaller values in resultVec.
*
* @param {goog.vec.vec4d.Type} vec0 The source vector.
* @param {goog.vec.vec4d.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec4d.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec4d.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4d.min = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.min(vec0[0], limit);
resultVec[1] = Math.min(vec0[1], limit);
resultVec[2] = Math.min(vec0[2], limit);
resultVec[3] = Math.min(vec0[3], limit);
} else {
resultVec[0] = Math.min(vec0[0], limit[0]);
resultVec[1] = Math.min(vec0[1], limit[1]);
resultVec[2] = Math.min(vec0[2], limit[2]);
resultVec[3] = Math.min(vec0[3], limit[3]);
}
return resultVec;
};
/**
* Returns true if the components of v0 are equal to the components of v1.
*
* @param {goog.vec.vec4d.Type} v0 The first vector.
* @param {goog.vec.vec4d.Type} v1 The second vector.
* @return {boolean} True if the vectors are equal, false otherwise.
*/
goog.vec.vec4d.equals = function(v0, v1) {
return v0.length == v1.length &&
v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2] && v0[3] == v1[3];
};
@@ -0,0 +1,206 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec4f_test.html by running: //
// swap_type.sh vec4d_test.html > vec4f_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.vec4d</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float64Array');
goog.require('goog.vec.vec4d');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testCreate() {
var v = goog.vec.vec4d.create();
assertElementsEquals([0, 0, 0, 0], v);
}
function testSet() {
var v = goog.vec.vec4d.create();
goog.vec.vec4d.setFromValues(v, 1, 2, 3, 4);
assertElementsEquals([1, 2, 3, 4], v);
goog.vec.vec4d.setFromArray(v, [4, 5, 6, 7]);
assertElementsEquals([4, 5, 6, 7], v);
}
function testAdd() {
var v0 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [1, 2, 3, 4]);
var v1 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [5, 6, 7, 8]);
var v2 = goog.vec.vec4d.setFromVec4d(goog.vec.vec4d.create(), v0);
goog.vec.vec4d.add(v2, v1, v2);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([6, 8, 10, 12], v2);
goog.vec.vec4d.add(goog.vec.vec4d.add(v0, v1, v2), v0, v2);
assertElementsEquals([7, 10, 13, 16], v2);
}
function testSubtract() {
var v0 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [4, 3, 2, 1]);
var v1 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [5, 6, 7, 8]);
var v2 = goog.vec.vec4d.setFromVec4d(goog.vec.vec4d.create(), v0);
goog.vec.vec4d.subtract(v2, v1, v2);
assertElementsEquals([4, 3, 2, 1], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([-1, -3, -5, -7], v2);
goog.vec.vec4d.setFromValues(v2, 0, 0, 0, 0);
goog.vec.vec4d.subtract(v1, v0, v2);
assertElementsEquals([1, 3, 5, 7], v2);
goog.vec.vec4d.subtract(goog.vec.vec4d.subtract(v1, v0, v2), v0, v2);
assertElementsEquals([-3, 0, 3, 6], v2);
}
function testNegate() {
var v0 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [1, 2, 3, 4]);
var v1 = goog.vec.vec4d.create();
goog.vec.vec4d.negate(v0, v1);
assertElementsEquals([-1, -2, -3, -4], v1);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.vec4d.negate(v0, v0);
assertElementsEquals([-1, -2, -3, -4], v0);
}
function testAbs() {
var v0 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [-1, -2, -3, -4]);
var v1 = goog.vec.vec4d.create();
goog.vec.vec4d.abs(v0, v1);
assertElementsEquals([1, 2, 3, 4], v1);
assertElementsEquals([-1, -2, -3, -4], v0);
goog.vec.vec4d.abs(v0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
}
function testScale() {
var v0 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [1, 2, 3, 4]);
var v1 = goog.vec.vec4d.create();
goog.vec.vec4d.scale(v0, 4, v1);
assertElementsEquals([4, 8, 12, 16], v1);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.vec4d.setFromArray(v1, v0);
goog.vec.vec4d.scale(v1, 5, v1);
assertElementsEquals([5, 10, 15, 20], v1);
}
function testMagnitudeSquared() {
var v0 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [1, 2, 3, 4]);
assertEquals(30, goog.vec.vec4d.magnitudeSquared(v0));
}
function testMagnitude() {
var v0 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [1, 2, 3, 4]);
assertEquals(Math.sqrt(30), goog.vec.vec4d.magnitude(v0));
}
function testNormalize() {
var v0 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [2, 3, 4, 5]);
var v1 = goog.vec.vec4d.create();
var v2 = goog.vec.vec4d.create();
goog.vec.vec4d.scale(v0, 1 / goog.vec.vec4d.magnitude(v0), v2);
goog.vec.vec4d.normalize(v0, v1);
assertElementsEquals(v2, v1);
assertElementsEquals([2, 3, 4, 5], v0);
goog.vec.vec4d.setFromArray(v1, v0);
goog.vec.vec4d.normalize(v1, v1);
assertElementsEquals(v2, v1);
}
function testDot() {
var v0 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [1, 2, 3, 4]);
var v1 = goog.vec.vec4d.setFromArray(goog.vec.vec4d.create(), [5, 6, 7, 8]);
assertEquals(70, goog.vec.vec4d.dot(v0, v1));
assertEquals(70, goog.vec.vec4d.dot(v1, v0));
}
function testLerp() {
var v0 = goog.vec.vec4d.setFromValues(goog.vec.vec4d.create(), 1, 2, 3, 4);
var v1 = goog.vec.vec4d.setFromValues(goog.vec.vec4d.create(), 10, 20, 30, 40);
var v2 = goog.vec.vec4d.setFromVec4d(goog.vec.vec4d.create(), v0);
goog.vec.vec4d.lerp(v2, v1, 0, v2);
assertElementsEquals([1, 2, 3, 4], v2);
goog.vec.vec4d.lerp(v2, v1, 1, v2);
assertElementsEquals([10, 20, 30, 40], v2);
goog.vec.vec4d.lerp(v0, v1, .5, v2);
assertElementsEquals([5.5, 11, 16.5, 22], v2);
}
function testMax() {
var v0 = goog.vec.vec4d.setFromValues(goog.vec.vec4d.create(), 10, 20, 30, 40);
var v1 = goog.vec.vec4d.setFromValues(goog.vec.vec4d.create(), 5, 25, 35, 30);
var v2 = goog.vec.vec4d.create();
goog.vec.vec4d.max(v0, v1, v2);
assertElementsEquals([10, 25, 35, 40], v2);
goog.vec.vec4d.max(v1, v0, v1);
assertElementsEquals([10, 25, 35, 40], v1);
goog.vec.vec4d.max(v2, 20, v2);
assertElementsEquals([20, 25, 35, 40], v2);
}
function testMin() {
var v0 = goog.vec.vec4d.setFromValues(goog.vec.vec4d.create(), 10, 20, 30, 40);
var v1 = goog.vec.vec4d.setFromValues(goog.vec.vec4d.create(), 5, 25, 35, 30);
var v2 = goog.vec.vec4d.create();
goog.vec.vec4d.min(v0, v1, v2);
assertElementsEquals([5, 20, 30, 30], v2);
goog.vec.vec4d.min(v1, v0, v1);
assertElementsEquals([5, 20, 30, 30], v1);
goog.vec.vec4d.min(v2, 20, v2);
assertElementsEquals([5, 20, 20, 20], v2);
}
function testEquals() {
var v0 = goog.vec.vec4d.setFromValues(goog.vec.vec4d.create(), 1, 2, 3, 4);
var v1 = goog.vec.vec4d.setFromVec4d(goog.vec.vec4d.create(), v0);
assertElementsEquals(v0, v1);
v1[0] = 5;
assertFalse(goog.vec.vec4d.equals(v0, v1));
v1 = goog.vec.vec4d.setFromVec4d(goog.vec.vec4d.create(), v0);
v1[1] = 5;
assertFalse(goog.vec.vec4d.equals(v0, v1));
v1 = goog.vec.vec4d.setFromVec4d(goog.vec.vec4d.create(), v0);
v1[2] = 5;
assertFalse(goog.vec.vec4d.equals(v0, v1));
v1 = goog.vec.vec4d.setFromVec4d(goog.vec.vec4d.create(), v0);
v1[3] = 5;
assertFalse(goog.vec.vec4d.equals(v0, v1));
}
</script>
</body>
@@ -0,0 +1,366 @@
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec4d.js by running: //
// swap_type.sh vec4f.js > vec4d.js //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
/**
* @fileoverview Provides functions for operating on 4 element float (32bit)
* vectors.
*
* The last parameter will typically be the output object and an object
* can be both an input and output parameter to all methods except where
* noted.
*
* See the README for notes about the design and structure of the API
* (especially related to performance).
*
*/
goog.provide('goog.vec.vec4f');
goog.provide('goog.vec.vec4f.Type');
/** @suppress {extraRequire} */
goog.require('goog.vec');
/** @typedef {goog.vec.Float32} */ goog.vec.vec4f.Type;
/**
* Creates a vec4f with all elements initialized to zero.
*
* @return {!goog.vec.vec4f.Type} The new vec4f.
*/
goog.vec.vec4f.create = function() {
return new Float32Array(4);
};
/**
* Initializes the vector with the given values.
*
* @param {goog.vec.vec4f.Type} vec The vector to receive the values.
* @param {number} v0 The value for element at index 0.
* @param {number} v1 The value for element at index 1.
* @param {number} v2 The value for element at index 2.
* @param {number} v3 The value for element at index 3.
* @return {!goog.vec.vec4f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec4f.setFromValues = function(vec, v0, v1, v2, v3) {
vec[0] = v0;
vec[1] = v1;
vec[2] = v2;
vec[3] = v3;
return vec;
};
/**
* Initializes vec4f vec from vec4f src.
*
* @param {goog.vec.vec4f.Type} vec The destination vector.
* @param {goog.vec.vec4f.Type} src The source vector.
* @return {!goog.vec.vec4f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec4f.setFromVec4f = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
vec[3] = src[3];
return vec;
};
/**
* Initializes vec4f vec from vec4d src (typed as a Float64Array to
* avoid circular goog.requires).
*
* @param {goog.vec.vec4f.Type} vec The destination vector.
* @param {Float64Array} src The source vector.
* @return {!goog.vec.vec4f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec4f.setFromVec4d = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
vec[3] = src[3];
return vec;
};
/**
* Initializes vec4f vec from Array src.
*
* @param {goog.vec.vec4f.Type} vec The destination vector.
* @param {Array<number>} src The source vector.
* @return {!goog.vec.vec4f.Type} Return vec so that operations can be
* chained together.
*/
goog.vec.vec4f.setFromArray = function(vec, src) {
vec[0] = src[0];
vec[1] = src[1];
vec[2] = src[2];
vec[3] = src[3];
return vec;
};
/**
* Performs a component-wise addition of vec0 and vec1 together storing the
* result into resultVec.
*
* @param {goog.vec.vec4f.Type} vec0 The first addend.
* @param {goog.vec.vec4f.Type} vec1 The second addend.
* @param {goog.vec.vec4f.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4f.add = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] + vec1[0];
resultVec[1] = vec0[1] + vec1[1];
resultVec[2] = vec0[2] + vec1[2];
resultVec[3] = vec0[3] + vec1[3];
return resultVec;
};
/**
* Performs a component-wise subtraction of vec1 from vec0 storing the
* result into resultVec.
*
* @param {goog.vec.vec4f.Type} vec0 The minuend.
* @param {goog.vec.vec4f.Type} vec1 The subtrahend.
* @param {goog.vec.vec4f.Type} resultVec The vector to
* receive the result. May be vec0 or vec1.
* @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4f.subtract = function(vec0, vec1, resultVec) {
resultVec[0] = vec0[0] - vec1[0];
resultVec[1] = vec0[1] - vec1[1];
resultVec[2] = vec0[2] - vec1[2];
resultVec[3] = vec0[3] - vec1[3];
return resultVec;
};
/**
* Negates vec0, storing the result into resultVec.
*
* @param {goog.vec.vec4f.Type} vec0 The vector to negate.
* @param {goog.vec.vec4f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4f.negate = function(vec0, resultVec) {
resultVec[0] = -vec0[0];
resultVec[1] = -vec0[1];
resultVec[2] = -vec0[2];
resultVec[3] = -vec0[3];
return resultVec;
};
/**
* Takes the absolute value of each component of vec0 storing the result in
* resultVec.
*
* @param {goog.vec.vec4f.Type} vec0 The source vector.
* @param {goog.vec.vec4f.Type} resultVec The vector to receive the result.
* May be vec0.
* @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4f.abs = function(vec0, resultVec) {
resultVec[0] = Math.abs(vec0[0]);
resultVec[1] = Math.abs(vec0[1]);
resultVec[2] = Math.abs(vec0[2]);
resultVec[3] = Math.abs(vec0[3]);
return resultVec;
};
/**
* Multiplies each component of vec0 with scalar storing the product into
* resultVec.
*
* @param {goog.vec.vec4f.Type} vec0 The source vector.
* @param {number} scalar The value to multiply with each component of vec0.
* @param {goog.vec.vec4f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4f.scale = function(vec0, scalar, resultVec) {
resultVec[0] = vec0[0] * scalar;
resultVec[1] = vec0[1] * scalar;
resultVec[2] = vec0[2] * scalar;
resultVec[3] = vec0[3] * scalar;
return resultVec;
};
/**
* Returns the magnitudeSquared of the given vector.
*
* @param {goog.vec.vec4f.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec4f.magnitudeSquared = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2], w = vec0[3];
return x * x + y * y + z * z + w * w;
};
/**
* Returns the magnitude of the given vector.
*
* @param {goog.vec.vec4f.Type} vec0 The vector.
* @return {number} The magnitude of the vector.
*/
goog.vec.vec4f.magnitude = function(vec0) {
var x = vec0[0], y = vec0[1], z = vec0[2], w = vec0[3];
return Math.sqrt(x * x + y * y + z * z + w * w);
};
/**
* Normalizes the given vector storing the result into resultVec.
*
* @param {goog.vec.vec4f.Type} vec0 The vector to normalize.
* @param {goog.vec.vec4f.Type} resultVec The vector to
* receive the result. May be vec0.
* @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4f.normalize = function(vec0, resultVec) {
var x = vec0[0], y = vec0[1], z = vec0[2], w = vec0[3];
var ilen = 1 / Math.sqrt(x * x + y * y + z * z + w * w);
resultVec[0] = x * ilen;
resultVec[1] = y * ilen;
resultVec[2] = z * ilen;
resultVec[3] = w * ilen;
return resultVec;
};
/**
* Returns the scalar product of vectors v0 and v1.
*
* @param {goog.vec.vec4f.Type} v0 The first vector.
* @param {goog.vec.vec4f.Type} v1 The second vector.
* @return {number} The scalar product.
*/
goog.vec.vec4f.dot = function(v0, v1) {
return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2] + v0[3] * v1[3];
};
/**
* Linearly interpolate from v0 to v1 according to f. The value of f should be
* in the range [0..1] otherwise the results are undefined.
*
* @param {goog.vec.vec4f.Type} v0 The first vector.
* @param {goog.vec.vec4f.Type} v1 The second vector.
* @param {number} f The interpolation factor.
* @param {goog.vec.vec4f.Type} resultVec The vector to receive the
* results (may be v0 or v1).
* @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4f.lerp = function(v0, v1, f, resultVec) {
var x = v0[0], y = v0[1], z = v0[2], w = v0[3];
resultVec[0] = (v1[0] - x) * f + x;
resultVec[1] = (v1[1] - y) * f + y;
resultVec[2] = (v1[2] - z) * f + z;
resultVec[3] = (v1[3] - w) * f + w;
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the larger values in resultVec.
*
* @param {goog.vec.vec4f.Type} vec0 The source vector.
* @param {goog.vec.vec4f.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec4f.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4f.max = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.max(vec0[0], limit);
resultVec[1] = Math.max(vec0[1], limit);
resultVec[2] = Math.max(vec0[2], limit);
resultVec[3] = Math.max(vec0[3], limit);
} else {
resultVec[0] = Math.max(vec0[0], limit[0]);
resultVec[1] = Math.max(vec0[1], limit[1]);
resultVec[2] = Math.max(vec0[2], limit[2]);
resultVec[3] = Math.max(vec0[3], limit[3]);
}
return resultVec;
};
/**
* Compares the components of vec0 with the components of another vector or
* scalar, storing the smaller values in resultVec.
*
* @param {goog.vec.vec4f.Type} vec0 The source vector.
* @param {goog.vec.vec4f.Type|number} limit The limit vector or scalar.
* @param {goog.vec.vec4f.Type} resultVec The vector to receive the
* results (may be vec0 or limit).
* @return {!goog.vec.vec4f.Type} Return resultVec so that operations can be
* chained together.
*/
goog.vec.vec4f.min = function(vec0, limit, resultVec) {
if (goog.isNumber(limit)) {
resultVec[0] = Math.min(vec0[0], limit);
resultVec[1] = Math.min(vec0[1], limit);
resultVec[2] = Math.min(vec0[2], limit);
resultVec[3] = Math.min(vec0[3], limit);
} else {
resultVec[0] = Math.min(vec0[0], limit[0]);
resultVec[1] = Math.min(vec0[1], limit[1]);
resultVec[2] = Math.min(vec0[2], limit[2]);
resultVec[3] = Math.min(vec0[3], limit[3]);
}
return resultVec;
};
/**
* Returns true if the components of v0 are equal to the components of v1.
*
* @param {goog.vec.vec4f.Type} v0 The first vector.
* @param {goog.vec.vec4f.Type} v1 The second vector.
* @return {boolean} True if the vectors are equal, false otherwise.
*/
goog.vec.vec4f.equals = function(v0, v1) {
return v0.length == v1.length &&
v0[0] == v1[0] && v0[1] == v1[1] && v0[2] == v1[2] && v0[3] == v1[3];
};
@@ -0,0 +1,206 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2013 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
// //
// Any edits to this file must be applied to vec4d_test.html by running: //
// swap_type.sh vec4f_test.html > vec4d_test.html //
// //
////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.vec.vec4f</title>
<script src="../base.js"></script>
<script>
goog.require('goog.vec.Float32Array');
goog.require('goog.vec.vec4f');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
function testCreate() {
var v = goog.vec.vec4f.create();
assertElementsEquals([0, 0, 0, 0], v);
}
function testSet() {
var v = goog.vec.vec4f.create();
goog.vec.vec4f.setFromValues(v, 1, 2, 3, 4);
assertElementsEquals([1, 2, 3, 4], v);
goog.vec.vec4f.setFromArray(v, [4, 5, 6, 7]);
assertElementsEquals([4, 5, 6, 7], v);
}
function testAdd() {
var v0 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [1, 2, 3, 4]);
var v1 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [5, 6, 7, 8]);
var v2 = goog.vec.vec4f.setFromVec4f(goog.vec.vec4f.create(), v0);
goog.vec.vec4f.add(v2, v1, v2);
assertElementsEquals([1, 2, 3, 4], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([6, 8, 10, 12], v2);
goog.vec.vec4f.add(goog.vec.vec4f.add(v0, v1, v2), v0, v2);
assertElementsEquals([7, 10, 13, 16], v2);
}
function testSubtract() {
var v0 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [4, 3, 2, 1]);
var v1 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [5, 6, 7, 8]);
var v2 = goog.vec.vec4f.setFromVec4f(goog.vec.vec4f.create(), v0);
goog.vec.vec4f.subtract(v2, v1, v2);
assertElementsEquals([4, 3, 2, 1], v0);
assertElementsEquals([5, 6, 7, 8], v1);
assertElementsEquals([-1, -3, -5, -7], v2);
goog.vec.vec4f.setFromValues(v2, 0, 0, 0, 0);
goog.vec.vec4f.subtract(v1, v0, v2);
assertElementsEquals([1, 3, 5, 7], v2);
goog.vec.vec4f.subtract(goog.vec.vec4f.subtract(v1, v0, v2), v0, v2);
assertElementsEquals([-3, 0, 3, 6], v2);
}
function testNegate() {
var v0 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [1, 2, 3, 4]);
var v1 = goog.vec.vec4f.create();
goog.vec.vec4f.negate(v0, v1);
assertElementsEquals([-1, -2, -3, -4], v1);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.vec4f.negate(v0, v0);
assertElementsEquals([-1, -2, -3, -4], v0);
}
function testAbs() {
var v0 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [-1, -2, -3, -4]);
var v1 = goog.vec.vec4f.create();
goog.vec.vec4f.abs(v0, v1);
assertElementsEquals([1, 2, 3, 4], v1);
assertElementsEquals([-1, -2, -3, -4], v0);
goog.vec.vec4f.abs(v0, v0);
assertElementsEquals([1, 2, 3, 4], v0);
}
function testScale() {
var v0 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [1, 2, 3, 4]);
var v1 = goog.vec.vec4f.create();
goog.vec.vec4f.scale(v0, 4, v1);
assertElementsEquals([4, 8, 12, 16], v1);
assertElementsEquals([1, 2, 3, 4], v0);
goog.vec.vec4f.setFromArray(v1, v0);
goog.vec.vec4f.scale(v1, 5, v1);
assertElementsEquals([5, 10, 15, 20], v1);
}
function testMagnitudeSquared() {
var v0 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [1, 2, 3, 4]);
assertEquals(30, goog.vec.vec4f.magnitudeSquared(v0));
}
function testMagnitude() {
var v0 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [1, 2, 3, 4]);
assertEquals(Math.sqrt(30), goog.vec.vec4f.magnitude(v0));
}
function testNormalize() {
var v0 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [2, 3, 4, 5]);
var v1 = goog.vec.vec4f.create();
var v2 = goog.vec.vec4f.create();
goog.vec.vec4f.scale(v0, 1 / goog.vec.vec4f.magnitude(v0), v2);
goog.vec.vec4f.normalize(v0, v1);
assertElementsEquals(v2, v1);
assertElementsEquals([2, 3, 4, 5], v0);
goog.vec.vec4f.setFromArray(v1, v0);
goog.vec.vec4f.normalize(v1, v1);
assertElementsEquals(v2, v1);
}
function testDot() {
var v0 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [1, 2, 3, 4]);
var v1 = goog.vec.vec4f.setFromArray(goog.vec.vec4f.create(), [5, 6, 7, 8]);
assertEquals(70, goog.vec.vec4f.dot(v0, v1));
assertEquals(70, goog.vec.vec4f.dot(v1, v0));
}
function testLerp() {
var v0 = goog.vec.vec4f.setFromValues(goog.vec.vec4f.create(), 1, 2, 3, 4);
var v1 = goog.vec.vec4f.setFromValues(goog.vec.vec4f.create(), 10, 20, 30, 40);
var v2 = goog.vec.vec4f.setFromVec4f(goog.vec.vec4f.create(), v0);
goog.vec.vec4f.lerp(v2, v1, 0, v2);
assertElementsEquals([1, 2, 3, 4], v2);
goog.vec.vec4f.lerp(v2, v1, 1, v2);
assertElementsEquals([10, 20, 30, 40], v2);
goog.vec.vec4f.lerp(v0, v1, .5, v2);
assertElementsEquals([5.5, 11, 16.5, 22], v2);
}
function testMax() {
var v0 = goog.vec.vec4f.setFromValues(goog.vec.vec4f.create(), 10, 20, 30, 40);
var v1 = goog.vec.vec4f.setFromValues(goog.vec.vec4f.create(), 5, 25, 35, 30);
var v2 = goog.vec.vec4f.create();
goog.vec.vec4f.max(v0, v1, v2);
assertElementsEquals([10, 25, 35, 40], v2);
goog.vec.vec4f.max(v1, v0, v1);
assertElementsEquals([10, 25, 35, 40], v1);
goog.vec.vec4f.max(v2, 20, v2);
assertElementsEquals([20, 25, 35, 40], v2);
}
function testMin() {
var v0 = goog.vec.vec4f.setFromValues(goog.vec.vec4f.create(), 10, 20, 30, 40);
var v1 = goog.vec.vec4f.setFromValues(goog.vec.vec4f.create(), 5, 25, 35, 30);
var v2 = goog.vec.vec4f.create();
goog.vec.vec4f.min(v0, v1, v2);
assertElementsEquals([5, 20, 30, 30], v2);
goog.vec.vec4f.min(v1, v0, v1);
assertElementsEquals([5, 20, 30, 30], v1);
goog.vec.vec4f.min(v2, 20, v2);
assertElementsEquals([5, 20, 20, 20], v2);
}
function testEquals() {
var v0 = goog.vec.vec4f.setFromValues(goog.vec.vec4f.create(), 1, 2, 3, 4);
var v1 = goog.vec.vec4f.setFromVec4f(goog.vec.vec4f.create(), v0);
assertElementsEquals(v0, v1);
v1[0] = 5;
assertFalse(goog.vec.vec4f.equals(v0, v1));
v1 = goog.vec.vec4f.setFromVec4f(goog.vec.vec4f.create(), v0);
v1[1] = 5;
assertFalse(goog.vec.vec4f.equals(v0, v1));
v1 = goog.vec.vec4f.setFromVec4f(goog.vec.vec4f.create(), v0);
v1[2] = 5;
assertFalse(goog.vec.vec4f.equals(v0, v1));
v1 = goog.vec.vec4f.setFromVec4f(goog.vec.vec4f.create(), v0);
v1[3] = 5;
assertFalse(goog.vec.vec4f.equals(v0, v1));
}
</script>
</body>
@@ -0,0 +1,443 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Performance Tests - Vector Array math</title>
<link rel="stylesheet" type="text/css"
href="../testing/performancetable.css"/>
<script type="text/javascript" src="../base.js"></script>
<script type="text/javascript">
goog.require('goog.testing.jsunit');
goog.require('goog.testing.PerformanceTable');
goog.require('goog.vec.Vec4');
goog.require('goog.vec.Mat4');
</script>
</head>
<body>
<h1>Closure Performance Tests - Vector Array Math</h1>
<p>
<strong>User-agent:</strong>
<script type="text/javascript">document.write(navigator.userAgent);</script>
</p>
<p>
These tests compare various methods of performing vector operations on
arrays of vectors.
</p>
<div id="perfTable"></div>
<hr>
<script type="text/javascript">
var table = new goog.testing.PerformanceTable(
goog.dom.getElement('perfTable'));
function createRandomFloat32Array(length) {
var array = new Float32Array(length);
for (var i = 0; i < length; i++) {
array[i] = Math.random();
}
return array;
}
function createRandomIndexArray(length) {
var array = [];
for (var i = 0; i < length; i++) {
array[i] = Math.floor(Math.random() * length);
array[i] = Math.min(length - 1, array[i]);
}
return array;
}
function createRandomVec4Array(length) {
var a = [];
for (var i = 0; i < length; i++) {
a[i] = goog.vec.Vec4.createFromValues(
Math.random(), Math.random(), Math.random(), Math.random());
}
return a;
}
function createRandomMat4() {
var m = goog.vec.Mat4.createFromValues(
Math.random(), Math.random(), Math.random(), Math.random(),
Math.random(), Math.random(), Math.random(), Math.random(),
Math.random(), Math.random(), Math.random(), Math.random(),
Math.random(), Math.random(), Math.random(), Math.random());
return m;
}
function createRandomMat4Array(length) {
var m = [];
for (var i = 0; i < length; i++) {
m[i] = createRandomMat4();
}
return m;
}
/**
* Vec4Object is a 4-vector object with x,y,z,w components.
* @param {number} x The x component.
* @param {number} y The y component.
* @param {number} z The z component.
* @param {number} w The w component.
* @constructor
*/
Vec4Object = function(x, y, z, w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
};
/**
* Add two vectors.
* @param {Vec4Object} v0 A vector.
* @param {Vec4Object} v1 Another vector.
* @param {Vec4Object} r The result.
*/
Vec4Object.add = function(v0, v1, r) {
r.x = v0.x + v1.x;
r.y = v0.y + v1.y;
r.z = v0.z + v1.z;
r.w = v0.w + v1.w;
};
function createRandomVec4ObjectArray(length) {
var a = [];
for (var i = 0; i < length; i++) {
a[i] = new Vec4Object(
Math.random(), Math.random(), Math.random(), Math.random());
}
return a;
}
function setVec4FromArray(v, a, o) {
v[0] = a[o + 0];
v[1] = a[o + 1];
v[2] = a[o + 2];
v[3] = a[o + 3];
}
function setArrayFromVec4(a, o, v) {
a[o + 0] = v[0];
a[o + 1] = v[1];
a[o + 2] = v[2];
a[o + 3] = v[3];
}
/**
* This is the same as goog.vec.Vec4.add(). Use this to avoid namespace lookup
* overheads.
* @param {goog.vec.Vec4.Vec4Like} v0 A vector.
* @param {goog.vec.Vec4.Vec4Like} v1 Another vector.
* @param {goog.vec.Vec4.Vec4Like} r The result.
*/
function addVec4(v0, v1, r) {
r[0] = v0[0] + v1[0];
r[1] = v0[1] + v1[1];
r[2] = v0[2] + v1[2];
r[3] = v0[3] + v1[3];
}
function addVec4ByOffset(v0Buf, v0Off, v1Buf, v1Off, rBuf, rOff) {
rBuf[rOff + 0] = v0Buf[v0Off + 0] + v1Buf[v1Off + 0];
rBuf[rOff + 1] = v0Buf[v0Off + 1] + v1Buf[v1Off + 1];
rBuf[rOff + 2] = v0Buf[v0Off + 2] + v1Buf[v1Off + 2];
rBuf[rOff + 3] = v0Buf[v0Off + 3] + v1Buf[v1Off + 3];
}
function addVec4ByOptionalOffset(v0, v1, r, opt_v0Off, opt_v1Off, opt_rOff) {
if (opt_v0Off && opt_v1Off && opt_rOff) {
r[opt_rOff + 0] = v0[opt_v0Off + 0] + v1[opt_v1Off + 0];
r[opt_rOff + 1] = v0[opt_v0Off + 1] + v1[opt_v1Off + 1];
r[opt_rOff + 2] = v0[opt_v0Off + 2] + v1[opt_v1Off + 2];
r[opt_rOff + 3] = v0[opt_v0Off + 3] + v1[opt_v1Off + 3];
} else {
r[0] = v0[0] + v1[0];
r[1] = v0[1] + v1[1];
r[2] = v0[2] + v1[2];
r[3] = v0[3] + v1[3];
}
}
function mat4MultVec4ByOffset(mBuf, mOff, vBuf, vOff, rBuf, rOff) {
var x = vBuf[vOff + 0], y = vBuf[vOff + 1],
z = vBuf[vOff + 2], w = vBuf[vOff + 3];
rBuf[rOff + 0] = x * mBuf[mOff + 0] + y * mBuf[mOff + 4] +
z * mBuf[mOff + 8] + w * mBuf[mOff + 12];
rBuf[rOff + 1] = x * mBuf[mOff + 1] + y * mBuf[mOff + 5] +
z * mBuf[mOff + 9] + w * mBuf[mOff + 13];
rBuf[rOff + 2] = x * mBuf[mOff + 2] + y * mBuf[mOff + 6] +
z * mBuf[mOff + 10] + w * mBuf[mOff + 14];
rBuf[rOff + 3] = x * mBuf[mOff + 3] + y * mBuf[mOff + 7] +
z * mBuf[mOff + 11] + w * mBuf[mOff + 15];
}
var NUM_ITERATIONS = 200000;
function testAddVec4ByOffset() {
var nVecs = NUM_ITERATIONS;
var nVals = nVecs * 4;
var a0 = createRandomFloat32Array(nVals);
var a1 = createRandomFloat32Array(nVals);
var a2 = new Float32Array(nVals);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
addVec4ByOffset(a0, i * 4, a1, i * 4, a2, i * 4);
}
},
'Add vectors using offsets');
}
function testAddVec4ByOptionalOffset() {
var nVecs = NUM_ITERATIONS;
var nVals = nVecs * 4;
var a0 = createRandomFloat32Array(nVals);
var a1 = createRandomFloat32Array(nVals);
var a2 = new Float32Array(nVals);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
addVec4ByOptionalOffset(a0, a1, a2, i * 4, i * 4, i * 4);
}
},
'Add vectors with optional offsets (requires branch)');
}
/**
* Check the overhead of using an array of individual
* Vec4s (Float32Arrays of length 4).
*/
function testAddVec4ByVec4s() {
var nVecs = NUM_ITERATIONS;
var a0 = createRandomVec4Array(nVecs);
var a1 = createRandomVec4Array(nVecs);
var a2 = createRandomVec4Array(nVecs);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
addVec4(a0[i], a1[i], a2[i]);
}
},
'Add vectors using an array of Vec4s (Float32Arrays of length 4)');
}
function testAddVec4ByTmp() {
var nVecs = NUM_ITERATIONS;
var nVals = nVecs * 4;
var a0 = createRandomFloat32Array(nVals);
var a1 = createRandomFloat32Array(nVals);
var a2 = new Float32Array(nVals);
table.run(
function() {
var t0 = new Float32Array(4);
var t1 = new Float32Array(4);
for (var i = 0; i < nVecs; i++) {
setVec4FromArray(t0, a0, i * 4);
setVec4FromArray(t1, a1, i * 4);
addVec4(t0, t1, t0);
setArrayFromVec4(a2, i * 4, t0);
}
},
'Add vectors using tmps');
}
/**
* Check the overhead of using an array of Objects with the implicit hash
* lookups for the x,y,z,w components.
*/
function testAddVec4ByObjects() {
var nVecs = NUM_ITERATIONS;
var a0 = createRandomVec4ObjectArray(nVecs);
var a1 = createRandomVec4ObjectArray(nVecs);
var a2 = createRandomVec4ObjectArray(nVecs);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
Vec4Object.add(a0[i], a1[i], a2[i]);
}
},
'Add vectors using an array of Objects ' +
'(with implicit hash lookups for the x,y,z,w components)');
}
function testAddVec4BySubarray() {
var nVecs = NUM_ITERATIONS;
var nVals = nVecs * 4;
var a0 = createRandomFloat32Array(nVals);
var a1 = createRandomFloat32Array(nVals);
var a2 = new Float32Array(nVals);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
var t0 = a0.subarray(i * 4 * 4);
var t1 = a1.subarray(i * 4 * 4);
var t2 = a2.subarray(i * 4 * 4);
addVec4(t0, t1, t2);
}
},
'Add vectors using Float32Array.subarray()');
}
function testAddVec4ByView() {
var nVecs = NUM_ITERATIONS;
var nVals = nVecs * 4;
var a0 = createRandomFloat32Array(nVals);
var a1 = createRandomFloat32Array(nVals);
var a2 = new Float32Array(nVals);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
var t0 = new Float32Array(a0.buffer, i * 4 * 4);
var t1 = new Float32Array(a1.buffer, i * 4 * 4);
var t2 = new Float32Array(a2.buffer, i * 4 * 4);
addVec4(t0, t1, t2);
}
},
'Add vectors using Float32 view');
}
function testMat4MultVec4ByOffset() {
var nVecs = NUM_ITERATIONS;
var nVecVals = nVecs * 4;
var nMatVals = nVecs * 16;
var m = createRandomFloat32Array(nMatVals);
var a0 = createRandomFloat32Array(nVecVals);
var a1 = new Float32Array(nVecVals);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
mat4MultVec4ByOffset(m, i * 16, a0, i * 4, a1, i * 4);
}
},
'vec4 = mat4 * vec4 using offsets.');
}
/**
* Check the overhead of using an array of individual
* Vec4s (Float32Arrays of length 4).
*/
function testMat4MultVec4ByVec4s() {
var nVecs = NUM_ITERATIONS;
var a0 = createRandomVec4Array(nVecs);
var a1 = createRandomVec4Array(nVecs);
var m = createRandomMat4Array(nVecs);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
goog.vec.Mat4.multVec4(m[i], a0[i], a1[i]);
}
},
'vec4 = mat4 * vec4 using arrays of Vec4s and Mat4s');
}
/**
* Do 10x as many for the one vector tests.
* @type {number}
*/
var NUM_ONE_ITERATIONS = NUM_ITERATIONS * 10;
function testAddOneVec4ByOffset() {
var a0 = createRandomFloat32Array(4);
var a1 = createRandomFloat32Array(4);
var a2 = new Float32Array(4);
table.run(
function() {
for (var i = 0; i < NUM_ONE_ITERATIONS; i++) {
addVec4ByOffset(a0, 0, a1, 0, a2, 0);
}
},
'Add one vector using offset of 0');
}
function testAddOneVec4() {
var a0 = createRandomFloat32Array(4);
var a1 = createRandomFloat32Array(4);
var a2 = new Float32Array(4);
table.run(
function() {
for (var i = 0; i < NUM_ONE_ITERATIONS; i++) {
addVec4(a0, a1, a2);
}
},
'Add one vector');
}
function testAddOneVec4ByOptionalOffset() {
var a0 = createRandomFloat32Array(4);
var a1 = createRandomFloat32Array(4);
var a2 = new Float32Array(4);
table.run(
function() {
for (var i = 0; i < NUM_ONE_ITERATIONS; i++) {
addVec4ByOptionalOffset(a0, a1, a2);
}
},
'Add one vector with optional offsets (requires branch)');
}
function testAddRandomVec4ByOffset() {
var nVecs = NUM_ITERATIONS;
var nVals = nVecs * 4;
var a0 = createRandomFloat32Array(nVals);
var a1 = createRandomFloat32Array(nVals);
var a2 = new Float32Array(nVals);
var i0 = createRandomIndexArray(nVecs);
var i1 = createRandomIndexArray(nVecs);
var i2 = createRandomIndexArray(nVecs);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
addVec4ByOffset(a0, i0[i] * 4, a1, i1[i] * 4, a2, i2[i] * 4);
}
},
'Add random vectors using offsets');
}
function testAddRandomVec4ByVec4s() {
var nVecs = NUM_ITERATIONS;
var a0 = createRandomVec4Array(nVecs);
var a1 = createRandomVec4Array(nVecs);
var a2 = createRandomVec4Array(nVecs);
var i0 = createRandomIndexArray(nVecs);
var i1 = createRandomIndexArray(nVecs);
var i2 = createRandomIndexArray(nVecs);
table.run(
function() {
for (var i = 0; i < nVecs; i++) {
addVec4(a0[i0[i]], a1[i1[i]], a2[i2[i]]);
}
},
'Add random vectors using an array of Vec4s');
}
// Make sure the tests are run in the order they are defined.
var testCase = new goog.testing.TestCase(document.title);
testCase.order = goog.testing.TestCase.Order.NATURAL;
testCase.autoDiscoverTests();
G_testRunner.initialize(testCase);
</script>
</body>
</html>
@@ -0,0 +1,101 @@
<!DOCTYPE html>
<html>
<!--
Copyright 2011 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
Author: nicksantos@google.com (Nick Santos)
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Performance Tests - Vector math</title>
<link rel="stylesheet" type="text/css"
href="../testing/performancetable.css"/>
<script src="../base.js"></script>
<script>
goog.require('goog.crypt');
goog.require('goog.string');
goog.require('goog.testing.PerformanceTable');
goog.require('goog.testing.jsunit');
goog.require('goog.vec.Vec4');
</script>
</head>
<body>
<h1>Closure Performance Tests - Vector Math</h1>
<p>
<strong>User-agent:</strong>
<script>document.write(navigator.userAgent);</script>
</p>
<div id="perfTable"></div>
<hr>
<script>
var table = new goog.testing.PerformanceTable(
goog.dom.getElement('perfTable'));
var createVec4FromValues = goog.vec.Vec4.createFromValues;
var scaleVec4 = goog.vec.Vec4.scale;
var negateVec4ByScaling = function(v, result) {
return scaleVec4(v, -1, result);
};
var negateVec4ByNegation = function(v, result) {
result[0] = -v[0];
result[1] = -v[1];
result[2] = -v[2];
result[3] = -v[3];
return result;
};
var negateVec4ByMultiplication = function(v, result) {
result[0] = -1 * v[0];
result[1] = -1 * v[1];
result[2] = -1 * v[2];
result[3] = -1 * v[3];
return result;
};
function createRandomVec4() {
return createVec4FromValues(
Math.random(),
Math.random(),
Math.random(),
Math.random());
}
function testNegateVec4ByScaling() {
var v = createRandomVec4();
for (var i = 0; i < 2000000; i++) {
// Warm the trace tree to see if that makes a difference.
scaleVec4(v, 1, v);
}
table.run(
function() {
for (var i = 0; i < 2000000; i++) {
negateVec4ByScaling(v, v);
}
},
'Negate vector by calling scale()');
}
function testNegateVec4ByNegation() {
var v = createRandomVec4();
for (var i = 0; i < 2000000; i++) {
// Warm the trace tree to see if that makes a difference.
scaleVec4(v, 1, v);
}
table.run(
function() {
for (var i = 0; i < 2000000; i++) {
negateVec4ByNegation(v, v);
}
},
'Negate vector by negating directly');
}
</script>
</body>
</html>