1/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. 2 3Permission is hereby granted, free of charge, to any person obtaining a copy 4of this software and associated documentation files (the "Software"), to deal 5in the Software without restriction, including without limitation the rights 6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7copies of the Software, and to permit persons to whom the Software is 8furnished to do so, subject to the following conditions: 9 10The above copyright notice and this permission notice shall be included in 11all copies or substantial portions of the Software. 12 13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19THE SOFTWARE. */ 20 21describe("vec3", function() { 22 var mat3 = require("../../src/gl-matrix/mat3.js"); 23 var mat4 = require("../../src/gl-matrix/mat4.js"); 24 var vec3 = require("../../src/gl-matrix/vec3.js"); 25 26 var out, vecA, vecB, result; 27 28 beforeEach(function() { vecA = [1, 2, 3]; vecB = [4, 5, 6]; out = [0, 0, 0]; }); 29 30 describe('rotateX', function(){ 31 describe('rotation around world origin [0, 0, 0]', function(){ 32 beforeEach(function(){ vecA = [0, 1, 0]; vecB = [0, 0, 0]; result = vec3.rotateX(out, vecA, vecB, Math.PI); }); 33 it("should return the rotated vector", function(){ expect(result).toBeEqualish([0, -1, 0]); }); 34 }); 35 describe('rotation around an arbitrary origin', function(){ 36 beforeEach(function(){ vecA = [2, 7, 0]; vecB = [2, 5, 0]; result = vec3.rotateX(out, vecA, vecB, Math.PI); }); 37 it("should return the rotated vector", function(){ expect(result).toBeEqualish([2, 3, 0]); }); 38 }); 39 }); 40 41 describe('rotateY', function(){ 42 describe('rotation around world origin [0, 0, 0]', function(){ 43 beforeEach(function(){ vecA = [1, 0, 0]; vecB = [0, 0, 0]; result = vec3.rotateY(out, vecA, vecB, Math.PI); }); 44 it("should return the rotated vector", function(){ expect(result).toBeEqualish([-1, 0, 0]); }); 45 }); 46 describe('rotation around an arbitrary origin', function(){ 47 beforeEach(function(){ vecA = [-2, 3, 10]; vecB = [-4, 3, 10]; result = vec3.rotateY(out, vecA, vecB, Math.PI); }); 48 it("should return the rotated vector", function(){ expect(result).toBeEqualish([-6, 3, 10]); }); 49 }); 50 }); 51 52 describe('rotateZ', function(){ 53 describe('rotation around world origin [0, 0, 0]', function(){ 54 beforeEach(function(){ vecA = [0, 1, 0]; vecB = [0, 0, 0]; result = vec3.rotateZ(out, vecA, vecB, Math.PI); }); 55 it("should return the rotated vector", function(){ expect(result).toBeEqualish([0, -1, 0]); }); 56 }); 57 describe('rotation around an arbitrary origin', function(){ 58 beforeEach(function(){ vecA = [0, 6, -5]; vecB = [0, 0, -5]; result = vec3.rotateZ(out, vecA, vecB, Math.PI); }); 59 it("should return the rotated vector", function(){ expect(result).toBeEqualish([0, -6, -5]); }); 60 }); 61 }); 62 63 describe('transformMat4', function() { 64 var matr; 65 describe("with an identity", function() { 66 beforeEach(function() { matr = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] }); 67 68 beforeEach(function() { result = vec3.transformMat4(out, vecA, matr); }); 69 70 it("should produce the input", function() { 71 expect(out).toBeEqualish([1, 2, 3]); 72 }); 73 74 it("should return out", function() { expect(result).toBe(out); }); 75 }); 76 77 describe("with a lookAt", function() { 78 beforeEach(function() { matr = mat4.lookAt(mat4.create(), [5, 6, 7], [2, 6, 7], [0, 1, 0]); }); 79 80 beforeEach(function() { result = vec3.transformMat4(out, vecA, matr); }); 81 82 it("should rotate and translate the input", function() { 83 expect(out).toBeEqualish([ 4, -4, -4 ]); 84 }); 85 86 it("should return out", function() { expect(result).toBe(out); }); 87 }); 88 89 describe("with a perspective matrix (#92)", function() { 90 it("should transform a point from perspective(pi/2, 4/3, 1, 100)", function() { 91 matr = [0.750, 0, 0, 0, 92 0, 1, 0, 0, 93 0, 0, -1.02, -1, 94 0, 0, -2.02, 0]; 95 result = vec3.transformMat4([], [10, 20, 30], matr); 96 expect(result).toBeEqualish([-0.25, -0.666666, 1.087333]); 97 }); 98 }); 99 100 }); 101 102 describe('transformMat3', function() { 103 var matr; 104 describe("with an identity", function() { 105 beforeEach(function() { matr = [1, 0, 0, 0, 1, 0, 0, 0, 1 ] }); 106 107 beforeEach(function() { result = vec3.transformMat3(out, vecA, matr); }); 108 109 it("should produce the input", function() { 110 expect(out).toBeEqualish([1, 2, 3]); 111 }); 112 113 it("should return out", function() { expect(result).toBe(out); }); 114 }); 115 116 describe("with 90deg about X", function() { 117 beforeEach(function() { 118 result = vec3.transformMat3(out, [0,1,0], [1,0,0,0,0,1,0,-1,0]); 119 }); 120 121 it("should produce correct output", function() { 122 expect(out).toBeEqualish([0,0,1]); 123 }); 124 }); 125 126 describe("with 90deg about Y", function() { 127 beforeEach(function() { 128 result = vec3.transformMat3(out, [1,0,0], [0,0,-1,0,1,0,1,0,0]); 129 }); 130 131 it("should produce correct output", function() { 132 expect(out).toBeEqualish([0,0,-1]); 133 }); 134 }); 135 136 describe("with 90deg about Z", function() { 137 beforeEach(function() { 138 result = vec3.transformMat3(out, [1,0,0], [0,1,0,-1,0,0,0,0,1]); 139 }); 140 141 it("should produce correct output", function() { 142 expect(out).toBeEqualish([0,1,0]); 143 }); 144 }); 145 146 describe("with a lookAt normal matrix", function() { 147 beforeEach(function() { 148 matr = mat4.lookAt(mat4.create(), [5, 6, 7], [2, 6, 7], [0, 1, 0]); 149 var n = mat3.create(); 150 matr = mat3.transpose(n, mat3.invert(n, mat3.fromMat4(n, matr))); 151 }); 152 153 beforeEach(function() { result = vec3.transformMat3(out, [1,0,0], matr); }); 154 155 it("should rotate the input", function() { 156 expect(out).toBeEqualish([ 0,0,1 ]); 157 }); 158 159 it("should return out", function() { expect(result).toBe(out); }); 160 }); 161 }); 162 163 describe("create", function() { 164 beforeEach(function() { result = vec3.create(); }); 165 it("should return a 3 element array initialized to 0s", function() { expect(result).toBeEqualish([0, 0, 0]); }); 166 }); 167 168 describe("clone", function() { 169 beforeEach(function() { result = vec3.clone(vecA); }); 170 it("should return a 3 element array initialized to the values in vecA", function() { expect(result).toBeEqualish(vecA); }); 171 }); 172 173 describe("fromValues", function() { 174 beforeEach(function() { result = vec3.fromValues(1, 2, 3); }); 175 it("should return a 3 element array initialized to the values passed", function() { expect(result).toBeEqualish([1, 2, 3]); }); 176 }); 177 178 describe("copy", function() { 179 beforeEach(function() { result = vec3.copy(out, vecA); }); 180 it("should place values into out", function() { expect(out).toBeEqualish([1, 2, 3]); }); 181 it("should return out", function() { expect(result).toBe(out); }); 182 }); 183 184 describe("set", function() { 185 beforeEach(function() { result = vec3.set(out, 1, 2, 3); }); 186 it("should place values into out", function() { expect(out).toBeEqualish([1, 2, 3]); }); 187 it("should return out", function() { expect(result).toBe(out); }); 188 }); 189 190 describe("add", function() { 191 describe("with a separate output vector", function() { 192 beforeEach(function() { result = vec3.add(out, vecA, vecB); }); 193 194 it("should place values into out", function() { expect(out).toBeEqualish([5, 7, 9]); }); 195 it("should return out", function() { expect(result).toBe(out); }); 196 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 197 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 198 }); 199 200 describe("when vecA is the output vector", function() { 201 beforeEach(function() { result = vec3.add(vecA, vecA, vecB); }); 202 203 it("should place values into vecA", function() { expect(vecA).toBeEqualish([5, 7, 9]); }); 204 it("should return vecA", function() { expect(result).toBe(vecA); }); 205 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 206 }); 207 208 describe("when vecB is the output vector", function() { 209 beforeEach(function() { result = vec3.add(vecB, vecA, vecB); }); 210 211 it("should place values into vecB", function() { expect(vecB).toBeEqualish([5, 7, 9]); }); 212 it("should return vecB", function() { expect(result).toBe(vecB); }); 213 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 214 }); 215 }); 216 217 describe("subtract", function() { 218 it("should have an alias called 'sub'", function() { expect(vec3.sub).toEqual(vec3.subtract); }); 219 220 describe("with a separate output vector", function() { 221 beforeEach(function() { result = vec3.subtract(out, vecA, vecB); }); 222 223 it("should place values into out", function() { expect(out).toBeEqualish([-3, -3, -3]); }); 224 it("should return out", function() { expect(result).toBe(out); }); 225 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 226 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 227 }); 228 229 describe("when vecA is the output vector", function() { 230 beforeEach(function() { result = vec3.subtract(vecA, vecA, vecB); }); 231 232 it("should place values into vecA", function() { expect(vecA).toBeEqualish([-3, -3, -3]); }); 233 it("should return vecA", function() { expect(result).toBe(vecA); }); 234 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 235 }); 236 237 describe("when vecB is the output vector", function() { 238 beforeEach(function() { result = vec3.subtract(vecB, vecA, vecB); }); 239 240 it("should place values into vecB", function() { expect(vecB).toBeEqualish([-3, -3, -3]); }); 241 it("should return vecB", function() { expect(result).toBe(vecB); }); 242 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 243 }); 244 }); 245 246 describe("multiply", function() { 247 it("should have an alias called 'mul'", function() { expect(vec3.mul).toEqual(vec3.multiply); }); 248 249 describe("with a separate output vector", function() { 250 beforeEach(function() { result = vec3.multiply(out, vecA, vecB); }); 251 252 it("should place values into out", function() { expect(out).toBeEqualish([4, 10, 18]); }); 253 it("should return out", function() { expect(result).toBe(out); }); 254 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 255 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 256 }); 257 258 describe("when vecA is the output vector", function() { 259 beforeEach(function() { result = vec3.multiply(vecA, vecA, vecB); }); 260 261 it("should place values into vecA", function() { expect(vecA).toBeEqualish([4, 10, 18]); }); 262 it("should return vecA", function() { expect(result).toBe(vecA); }); 263 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 264 }); 265 266 describe("when vecB is the output vector", function() { 267 beforeEach(function() { result = vec3.multiply(vecB, vecA, vecB); }); 268 269 it("should place values into vecB", function() { expect(vecB).toBeEqualish([4, 10, 18]); }); 270 it("should return vecB", function() { expect(result).toBe(vecB); }); 271 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 272 }); 273 }); 274 275 describe("divide", function() { 276 it("should have an alias called 'div'", function() { expect(vec3.div).toEqual(vec3.divide); }); 277 278 describe("with a separate output vector", function() { 279 beforeEach(function() { result = vec3.divide(out, vecA, vecB); }); 280 281 it("should place values into out", function() { expect(out).toBeEqualish([0.25, 0.4, 0.5]); }); 282 it("should return out", function() { expect(result).toBe(out); }); 283 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 284 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 285 }); 286 287 describe("when vecA is the output vector", function() { 288 beforeEach(function() { result = vec3.divide(vecA, vecA, vecB); }); 289 290 it("should place values into vecA", function() { expect(vecA).toBeEqualish([0.25, 0.4, 0.5]); }); 291 it("should return vecA", function() { expect(result).toBe(vecA); }); 292 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 293 }); 294 295 describe("when vecB is the output vector", function() { 296 beforeEach(function() { result = vec3.divide(vecB, vecA, vecB); }); 297 298 it("should place values into vecB", function() { expect(vecB).toBeEqualish([0.25, 0.4, 0.5]); }); 299 it("should return vecB", function() { expect(result).toBe(vecB); }); 300 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 301 }); 302 }); 303 304 describe("min", function() { 305 beforeEach(function() { vecA = [1, 3, 1]; vecB = [3, 1, 3]; }); 306 307 describe("with a separate output vector", function() { 308 beforeEach(function() { result = vec3.min(out, vecA, vecB); }); 309 310 it("should place values into out", function() { expect(out).toBeEqualish([1, 1, 1]); }); 311 it("should return out", function() { expect(result).toBe(out); }); 312 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 3, 1]); }); 313 it("should not modify vecB", function() { expect(vecB).toBeEqualish([3, 1, 3]); }); 314 }); 315 316 describe("when vecA is the output vector", function() { 317 beforeEach(function() { result = vec3.min(vecA, vecA, vecB); }); 318 319 it("should place values into vecA", function() { expect(vecA).toBeEqualish([1, 1, 1]); }); 320 it("should return vecA", function() { expect(result).toBe(vecA); }); 321 it("should not modify vecB", function() { expect(vecB).toBeEqualish([3, 1, 3]); }); 322 }); 323 324 describe("when vecB is the output vector", function() { 325 beforeEach(function() { result = vec3.min(vecB, vecA, vecB); }); 326 327 it("should place values into vecB", function() { expect(vecB).toBeEqualish([1, 1, 1]); }); 328 it("should return vecB", function() { expect(result).toBe(vecB); }); 329 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 3, 1]); }); 330 }); 331 }); 332 333 describe("max", function() { 334 beforeEach(function() { vecA = [1, 3, 1]; vecB = [3, 1, 3]; }); 335 336 describe("with a separate output vector", function() { 337 beforeEach(function() { result = vec3.max(out, vecA, vecB); }); 338 339 it("should place values into out", function() { expect(out).toBeEqualish([3, 3, 3]); }); 340 it("should return out", function() { expect(result).toBe(out); }); 341 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 3, 1]); }); 342 it("should not modify vecB", function() { expect(vecB).toBeEqualish([3, 1, 3]); }); 343 }); 344 345 describe("when vecA is the output vector", function() { 346 beforeEach(function() { result = vec3.max(vecA, vecA, vecB); }); 347 348 it("should place values into vecA", function() { expect(vecA).toBeEqualish([3, 3, 3]); }); 349 it("should return vecA", function() { expect(result).toBe(vecA); }); 350 it("should not modify vecB", function() { expect(vecB).toBeEqualish([3, 1, 3]); }); 351 }); 352 353 describe("when vecB is the output vector", function() { 354 beforeEach(function() { result = vec3.max(vecB, vecA, vecB); }); 355 356 it("should place values into vecB", function() { expect(vecB).toBeEqualish([3, 3, 3]); }); 357 it("should return vecB", function() { expect(result).toBe(vecB); }); 358 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 3, 1]); }); 359 }); 360 }); 361 362 describe("scale", function() { 363 describe("with a separate output vector", function() { 364 beforeEach(function() { result = vec3.scale(out, vecA, 2); }); 365 366 it("should place values into out", function() { expect(out).toBeEqualish([2, 4, 6]); }); 367 it("should return out", function() { expect(result).toBe(out); }); 368 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 369 }); 370 371 describe("when vecA is the output vector", function() { 372 beforeEach(function() { result = vec3.scale(vecA, vecA, 2); }); 373 374 it("should place values into vecA", function() { expect(vecA).toBeEqualish([2, 4, 6]); }); 375 it("should return vecA", function() { expect(result).toBe(vecA); }); 376 }); 377 }); 378 379 describe("scaleAndAdd", function() { 380 describe("with a separate output vector", function() { 381 beforeEach(function() { result = vec3.scaleAndAdd(out, vecA, vecB, 0.5); }); 382 383 it("should place values into out", function() { expect(out).toBeEqualish([3, 4.5, 6]); }); 384 it("should return out", function() { expect(result).toBe(out); }); 385 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 386 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 387 }); 388 389 describe("when vecA is the output vector", function() { 390 beforeEach(function() { result = vec3.scaleAndAdd(vecA, vecA, vecB, 0.5); }); 391 392 it("should place values into vecA", function() { expect(vecA).toBeEqualish([3, 4.5, 6]); }); 393 it("should return vecA", function() { expect(result).toBe(vecA); }); 394 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 395 }); 396 397 describe("when vecB is the output vector", function() { 398 beforeEach(function() { result = vec3.scaleAndAdd(vecB, vecA, vecB, 0.5); }); 399 400 it("should place values into vecB", function() { expect(vecB).toBeEqualish([3, 4.5, 6]); }); 401 it("should return vecB", function() { expect(result).toBe(vecB); }); 402 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 403 }); 404 }); 405 406 describe("distance", function() { 407 it("should have an alias called 'dist'", function() { expect(vec3.dist).toEqual(vec3.distance); }); 408 409 beforeEach(function() { result = vec3.distance(vecA, vecB); }); 410 411 it("should return the distance", function() { expect(result).toBeCloseTo(5.196152); }); 412 }); 413 414 describe("squaredDistance", function() { 415 it("should have an alias called 'sqrDist'", function() { expect(vec3.sqrDist).toEqual(vec3.squaredDistance); }); 416 417 beforeEach(function() { result = vec3.squaredDistance(vecA, vecB); }); 418 419 it("should return the squared distance", function() { expect(result).toEqual(27); }); 420 }); 421 422 describe("length", function() { 423 it("should have an alias called 'len'", function() { expect(vec3.len).toEqual(vec3.length); }); 424 425 beforeEach(function() { result = vec3.length(vecA); }); 426 427 it("should return the length", function() { expect(result).toBeCloseTo(3.741657); }); 428 }); 429 430 describe("squaredLength", function() { 431 it("should have an alias called 'sqrLen'", function() { expect(vec3.sqrLen).toEqual(vec3.squaredLength); }); 432 433 beforeEach(function() { result = vec3.squaredLength(vecA); }); 434 435 it("should return the squared length", function() { expect(result).toEqual(14); }); 436 }); 437 438 describe("negate", function() { 439 describe("with a separate output vector", function() { 440 beforeEach(function() { result = vec3.negate(out, vecA); }); 441 442 it("should place values into out", function() { expect(out).toBeEqualish([-1, -2, -3]); }); 443 it("should return out", function() { expect(result).toBe(out); }); 444 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 445 }); 446 447 describe("when vecA is the output vector", function() { 448 beforeEach(function() { result = vec3.negate(vecA, vecA); }); 449 450 it("should place values into vecA", function() { expect(vecA).toBeEqualish([-1, -2, -3]); }); 451 it("should return vecA", function() { expect(result).toBe(vecA); }); 452 }); 453 }); 454 455 describe("normalize", function() { 456 beforeEach(function() { vecA = [5, 0, 0]; }); 457 458 describe("with a separate output vector", function() { 459 beforeEach(function() { result = vec3.normalize(out, vecA); }); 460 461 it("should place values into out", function() { expect(out).toBeEqualish([1, 0, 0]); }); 462 it("should return out", function() { expect(result).toBe(out); }); 463 it("should not modify vecA", function() { expect(vecA).toBeEqualish([5, 0, 0]); }); 464 }); 465 466 describe("when vecA is the output vector", function() { 467 beforeEach(function() { result = vec3.normalize(vecA, vecA); }); 468 469 it("should place values into vecA", function() { expect(vecA).toBeEqualish([1, 0, 0]); }); 470 it("should return vecA", function() { expect(result).toBe(vecA); }); 471 }); 472 }); 473 474 describe("dot", function() { 475 beforeEach(function() { result = vec3.dot(vecA, vecB); }); 476 477 it("should return the dot product", function() { expect(result).toEqual(32); }); 478 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 479 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 480 }); 481 482 describe("cross", function() { 483 describe("with a separate output vector", function() { 484 beforeEach(function() { result = vec3.cross(out, vecA, vecB); }); 485 486 it("should place values into out", function() { expect(out).toBeEqualish([-3, 6, -3]); }); 487 it("should return out", function() { expect(result).toBe(out); }); 488 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 489 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 490 }); 491 492 describe("when vecA is the output vector", function() { 493 beforeEach(function() { result = vec3.cross(vecA, vecA, vecB); }); 494 495 it("should place values into vecA", function() { expect(vecA).toBeEqualish([-3, 6, -3]); }); 496 it("should return vecA", function() { expect(result).toBe(vecA); }); 497 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 498 }); 499 500 describe("when vecB is the output vector", function() { 501 beforeEach(function() { result = vec3.cross(vecB, vecA, vecB); }); 502 503 it("should place values into vecB", function() { expect(vecB).toBeEqualish([-3, 6, -3]); }); 504 it("should return vecB", function() { expect(result).toBe(vecB); }); 505 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 506 }); 507 }); 508 509 describe("lerp", function() { 510 describe("with a separate output vector", function() { 511 beforeEach(function() { result = vec3.lerp(out, vecA, vecB, 0.5); }); 512 513 it("should place values into out", function() { expect(out).toBeEqualish([2.5, 3.5, 4.5]); }); 514 it("should return out", function() { expect(result).toBe(out); }); 515 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 516 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 517 }); 518 519 describe("when vecA is the output vector", function() { 520 beforeEach(function() { result = vec3.lerp(vecA, vecA, vecB, 0.5); }); 521 522 it("should place values into vecA", function() { expect(vecA).toBeEqualish([2.5, 3.5, 4.5]); }); 523 it("should return vecA", function() { expect(result).toBe(vecA); }); 524 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 525 }); 526 527 describe("when vecB is the output vector", function() { 528 beforeEach(function() { result = vec3.lerp(vecB, vecA, vecB, 0.5); }); 529 530 it("should place values into vecB", function() { expect(vecB).toBeEqualish([2.5, 3.5, 4.5]); }); 531 it("should return vecB", function() { expect(result).toBe(vecB); }); 532 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 533 }); 534 }); 535 536 describe("random", function() { 537 describe("with no scale", function() { 538 beforeEach(function() { result = vec3.random(out); }); 539 540 it("should result in a unit length vector", function() { expect(vec3.length(out)).toBeCloseTo(1.0); }); 541 it("should return out", function() { expect(result).toBe(out); }); 542 }); 543 544 describe("with a scale", function() { 545 beforeEach(function() { result = vec3.random(out, 5.0); }); 546 547 it("should result in a unit length vector", function() { expect(vec3.length(out)).toBeCloseTo(5.0); }); 548 it("should return out", function() { expect(result).toBe(out); }); 549 }); 550 }); 551 552 describe("forEach", function() { 553 var vecArray; 554 555 beforeEach(function() { 556 vecArray = [ 557 1, 2, 3, 558 4, 5, 6, 559 0, 0, 0 560 ]; 561 }); 562 563 describe("when performing operations that take no extra arguments", function() { 564 beforeEach(function() { result = vec3.forEach(vecArray, 0, 0, 0, vec3.normalize); }); 565 566 it("should update all values", function() { 567 expect(vecArray).toBeEqualish([ 568 0.267261, 0.534522, 0.801783, 569 0.455842, 0.569802, 0.683763, 570 0, 0, 0 571 ]); 572 }); 573 it("should return vecArray", function() { expect(result).toBe(vecArray); }); 574 }); 575 576 describe("when performing operations that takes one extra arguments", function() { 577 beforeEach(function() { result = vec3.forEach(vecArray, 0, 0, 0, vec3.add, vecA); }); 578 579 it("should update all values", function() { 580 expect(vecArray).toBeEqualish([ 581 2, 4, 6, 582 5, 7, 9, 583 1, 2, 3 584 ]); 585 }); 586 it("should return vecArray", function() { expect(result).toBe(vecArray); }); 587 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 588 }); 589 590 describe("when specifying an offset", function() { 591 beforeEach(function() { result = vec3.forEach(vecArray, 0, 3, 0, vec3.add, vecA); }); 592 593 it("should update all values except the first vector", function() { 594 expect(vecArray).toBeEqualish([ 595 1, 2, 3, 596 5, 7, 9, 597 1, 2, 3 598 ]); 599 }); 600 it("should return vecArray", function() { expect(result).toBe(vecArray); }); 601 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 602 }); 603 604 describe("when specifying a count", function() { 605 beforeEach(function() { result = vec3.forEach(vecArray, 0, 0, 2, vec3.add, vecA); }); 606 607 it("should update all values except the last vector", function() { 608 expect(vecArray).toBeEqualish([ 609 2, 4, 6, 610 5, 7, 9, 611 0, 0, 0 612 ]); 613 }); 614 it("should return vecArray", function() { expect(result).toBe(vecArray); }); 615 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 616 }); 617 618 describe("when specifying a stride", function() { 619 beforeEach(function() { result = vec3.forEach(vecArray, 6, 0, 0, vec3.add, vecA); }); 620 621 it("should update all values except the second vector", function() { 622 expect(vecArray).toBeEqualish([ 623 2, 4, 6, 624 4, 5, 6, 625 1, 2, 3 626 ]); 627 }); 628 it("should return vecArray", function() { expect(result).toBe(vecArray); }); 629 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 630 }); 631 632 describe("when calling a function that does not modify the out variable", function() { 633 beforeEach(function() { 634 result = vec3.forEach(vecArray, 0, 0, 0, function(out, vec) {}); 635 }); 636 637 it("values should remain unchanged", function() { 638 expect(vecArray).toBeEqualish([ 639 1, 2, 3, 640 4, 5, 6, 641 0, 0, 0 642 ]); 643 }); 644 it("should return vecArray", function() { expect(result).toBe(vecArray); }); 645 }); 646 }); 647 648 describe("angle", function() { 649 beforeEach(function() { result = vec3.angle(vecA, vecB); }); 650 651 it("should return the angle", function() { expect(result).toBeEqualish(0.225726); }); 652 it("should not modify vecA", function() { expect(vecA).toBeEqualish([1, 2, 3]); }); 653 it("should not modify vecB", function() { expect(vecB).toBeEqualish([4, 5, 6]); }); 654 }); 655 656 describe("str", function() { 657 beforeEach(function() { result = vec3.str(vecA); }); 658 659 it("should return a string representation of the vector", function() { expect(result).toEqual("vec3(1, 2, 3)"); }); 660 }); 661}); 662