1 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
3 Redistribution and use in source and binary forms, with or without modification,
4 are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright notice, this
7 list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice,
9 this list of conditions and the following disclaimer in the documentation
10 and/or other materials provided with the distribution.
12 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
16 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
23 describe("quat", function() {
24 var out, quatA, quatB, result;
26 beforeEach(function() { quatA = [1, 2, 3, 4]; quatB = [5, 6, 7, 8]; out = [0, 0, 0, 0]; });
28 describe("create", function() {
29 beforeEach(function() { result = quat.create(); });
30 it("should return a 4 element array initialized to an identity quaternion", function() { expect(result).toBeEqualish([0, 0, 0, 1]); });
33 describe("clone", function() {
34 beforeEach(function() { result = quat.clone(quatA); });
35 it("should return a 4 element array initialized to the values in quatA", function() { expect(result).toBeEqualish(quatA); });
38 describe("fromValues", function() {
39 beforeEach(function() { result = quat.fromValues(1, 2, 3, 4); });
40 it("should return a 4 element array initialized to the values passed", function() { expect(result).toBeEqualish([1, 2, 3, 4]); });
43 describe("copy", function() {
44 beforeEach(function() { result = quat.copy(out, quatA); });
45 it("should place values into out", function() { expect(out).toBeEqualish([1, 2, 3, 4]); });
46 it("should return out", function() { expect(result).toBe(out); });
49 describe("set", function() {
50 beforeEach(function() { result = quat.set(out, 1, 2, 3, 4); });
51 it("should place values into out", function() { expect(out).toBeEqualish([1, 2, 3, 4]); });
52 it("should return out", function() { expect(result).toBe(out); });
55 describe("identity", function() {
56 beforeEach(function() { result = quat.identity(out); });
57 it("should place values into out", function() { expect(result).toBeEqualish([0, 0, 0, 1]); });
58 it("should return out", function() { expect(result).toBe(out); });
61 describe("setAxisAngle", function() {
62 beforeEach(function() { result = quat.setAxisAngle(out, [1, 0, 0], Math.PI * 0.5); });
63 it("should place values into out", function() { expect(result).toBeEqualish([0.707106, 0, 0, 0.707106]); });
64 it("should return out", function() { expect(result).toBe(out); });
67 describe("add", function() {
68 describe("with a separate output quaternion", function() {
69 beforeEach(function() { result = quat.add(out, quatA, quatB); });
71 it("should place values into out", function() { expect(out).toBeEqualish([6, 8, 10, 12]); });
72 it("should return out", function() { expect(result).toBe(out); });
73 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
74 it("should not modify quatB", function() { expect(quatB).toBeEqualish([5, 6, 7, 8]); });
77 describe("when quatA is the output quaternion", function() {
78 beforeEach(function() { result = quat.add(quatA, quatA, quatB); });
80 it("should place values into quatA", function() { expect(quatA).toBeEqualish([6, 8, 10, 12]); });
81 it("should return quatA", function() { expect(result).toBe(quatA); });
82 it("should not modify quatB", function() { expect(quatB).toBeEqualish([5, 6, 7, 8]); });
85 describe("when quatB is the output quaternion", function() {
86 beforeEach(function() { result = quat.add(quatB, quatA, quatB); });
88 it("should place values into quatB", function() { expect(quatB).toBeEqualish([6, 8, 10, 12]); });
89 it("should return quatB", function() { expect(result).toBe(quatB); });
90 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
94 describe("multiply", function() {
95 it("should have an alias called 'mul'", function() { expect(quat.mul).toEqual(quat.multiply); });
97 describe("with a separate output quaternion", function() {
98 beforeEach(function() { result = quat.multiply(out, quatA, quatB); });
100 it("should place values into out", function() { expect(out).toBeEqualish([24, 48, 48, -6]); });
101 it("should return out", function() { expect(result).toBe(out); });
102 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
103 it("should not modify quatB", function() { expect(quatB).toBeEqualish([5, 6, 7, 8]); });
106 describe("when quatA is the output quaternion", function() {
107 beforeEach(function() { result = quat.multiply(quatA, quatA, quatB); });
109 it("should place values into quatA", function() { expect(quatA).toBeEqualish([24, 48, 48, -6]); });
110 it("should return quatA", function() { expect(result).toBe(quatA); });
111 it("should not modify quatB", function() { expect(quatB).toBeEqualish([5, 6, 7, 8]); });
114 describe("when quatB is the output quaternion", function() {
115 beforeEach(function() { result = quat.multiply(quatB, quatA, quatB); });
117 it("should place values into quatB", function() { expect(quatB).toBeEqualish([24, 48, 48, -6]); });
118 it("should return quatB", function() { expect(result).toBe(quatB); });
119 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
123 describe("scale", function() {
124 describe("with a separate output quaternion", function() {
125 beforeEach(function() { result = quat.scale(out, quatA, 2); });
127 it("should place values into out", function() { expect(out).toBeEqualish([2, 4, 6, 8]); });
128 it("should return out", function() { expect(result).toBe(out); });
129 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
132 describe("when quatA is the output quaternion", function() {
133 beforeEach(function() { result = quat.scale(quatA, quatA, 2); });
135 it("should place values into quatA", function() { expect(quatA).toBeEqualish([2, 4, 6, 8]); });
136 it("should return quatA", function() { expect(result).toBe(quatA); });
140 describe("length", function() {
141 it("should have an alias called 'len'", function() { expect(quat.len).toEqual(quat.length); });
143 beforeEach(function() { result = quat.length(quatA); });
145 it("should return the length", function() { expect(result).toBeCloseTo(5.477225); });
148 describe("squaredLength", function() {
149 it("should have an alias called 'sqrLen'", function() { expect(quat.sqrLen).toEqual(quat.squaredLength); });
151 beforeEach(function() { result = quat.squaredLength(quatA); });
153 it("should return the squared length", function() { expect(result).toEqual(30); });
156 describe("normalize", function() {
157 beforeEach(function() { quatA = [5, 0, 0, 0]; });
159 describe("with a separate output quaternion", function() {
160 beforeEach(function() { result = quat.normalize(out, quatA); });
162 it("should place values into out", function() { expect(out).toBeEqualish([1, 0, 0, 0]); });
163 it("should return out", function() { expect(result).toBe(out); });
164 it("should not modify quatA", function() { expect(quatA).toBeEqualish([5, 0, 0, 0]); });
167 describe("when quatA is the output quaternion", function() {
168 beforeEach(function() { result = quat.normalize(quatA, quatA); });
170 it("should place values into quatA", function() { expect(quatA).toBeEqualish([1, 0, 0, 0]); });
171 it("should return quatA", function() { expect(result).toBe(quatA); });
175 describe("lerp", function() {
176 describe("with a separate output quaternion", function() {
177 beforeEach(function() { result = quat.lerp(out, quatA, quatB, 0.5); });
179 it("should place values into out", function() { expect(out).toBeEqualish([3, 4, 5, 6]); });
180 it("should return out", function() { expect(result).toBe(out); });
181 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
182 it("should not modify quatB", function() { expect(quatB).toBeEqualish([5, 6, 7, 8]); });
185 describe("when quatA is the output quaternion", function() {
186 beforeEach(function() { result = quat.lerp(quatA, quatA, quatB, 0.5); });
188 it("should place values into quatA", function() { expect(quatA).toBeEqualish([3, 4, 5, 6]); });
189 it("should return quatA", function() { expect(result).toBe(quatA); });
190 it("should not modify quatB", function() { expect(quatB).toBeEqualish([5, 6, 7, 8]); });
193 describe("when quatB is the output quaternion", function() {
194 beforeEach(function() { result = quat.lerp(quatB, quatA, quatB, 0.5); });
196 it("should place values into quatB", function() { expect(quatB).toBeEqualish([3, 4, 5, 6]); });
197 it("should return quatB", function() { expect(result).toBe(quatB); });
198 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
202 /*describe("slerp", function() {
203 describe("with a separate output quaternion", function() {
204 beforeEach(function() { result = quat.slerp(out, quatA, quatB, 0.5); });
206 it("should place values into out", function() { expect(out).toBeEqualish([3, 4, 5, 6]); });
207 it("should return out", function() { expect(result).toBe(out); });
208 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
209 it("should not modify quatB", function() { expect(quatB).toBeEqualish([5, 6, 7, 8]); });
212 describe("when quatA is the output quaternion", function() {
213 beforeEach(function() { result = quat.slerp(quatA, quatA, quatB, 0.5); });
215 it("should place values into quatA", function() { expect(quatA).toBeEqualish([3, 4, 5, 6]); });
216 it("should return quatA", function() { expect(result).toBe(quatA); });
217 it("should not modify quatB", function() { expect(quatB).toBeEqualish([5, 6, 7, 8]); });
220 describe("when quatB is the output quaternion", function() {
221 beforeEach(function() { result = quat.slerp(quatB, quatA, quatB, 0.5); });
223 it("should place values into quatB", function() { expect(quatB).toBeEqualish([3, 4, 5, 6]); });
224 it("should return quatB", function() { expect(result).toBe(quatB); });
225 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
229 // TODO: slerp, calcuateW, rotateX, rotateY, rotateZ
231 describe("invert", function() {
232 describe("with a separate output quaternion", function() {
233 beforeEach(function() { result = quat.invert(out, quatA); });
235 it("should place values into out", function() { expect(out).toBeEqualish([-0.033333, -0.066666, -0.1, 0.133333]); });
236 it("should return out", function() { expect(result).toBe(out); });
237 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
240 describe("when quatA is the output quaternion", function() {
241 beforeEach(function() { result = quat.invert(quatA, quatA); });
243 it("should place values into quatA", function() { expect(quatA).toBeEqualish([-0.033333, -0.066666, -0.1, 0.133333]); });
244 it("should return quatA", function() { expect(result).toBe(quatA); });
248 describe("conjugate", function() {
249 describe("with a separate output quaternion", function() {
250 beforeEach(function() { result = quat.conjugate(out, quatA); });
252 it("should place values into out", function() { expect(out).toBeEqualish([-1, -2, -3, 4]); });
253 it("should return out", function() { expect(result).toBe(out); });
254 it("should not modify quatA", function() { expect(quatA).toBeEqualish([1, 2, 3, 4]); });
257 describe("when quatA is the output quaternion", function() {
258 beforeEach(function() { result = quat.conjugate(quatA, quatA); });
260 it("should place values into quatA", function() { expect(quatA).toBeEqualish([-1, -2, -3, 4]); });
261 it("should return quatA", function() { expect(result).toBe(quatA); });
265 describe("str", function() {
266 beforeEach(function() { result = quat.str(quatA); });
268 it("should return a string representation of the quaternion", function() { expect(result).toEqual("quat(1, 2, 3, 4)"); });