Home | History | Annotate | Download | only in gl-matrix
      1 /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved.
      2 
      3 Redistribution and use in source and binary forms, with or without modification,
      4 are permitted provided that the following conditions are met:
      5 
      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.
     11 
     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. */
     22 
     23 describe("mat4", function() {
     24     var out, matA, matB, identity, result;
     25 
     26     beforeEach(function() {
     27         // Attempting to portray a semi-realistic transform matrix
     28         matA = [1, 0, 0, 0,
     29                 0, 1, 0, 0,
     30                 0, 0, 1, 0,
     31                 1, 2, 3, 1];
     32 
     33         matB = [1, 0, 0, 0,
     34                 0, 1, 0, 0,
     35                 0, 0, 1, 0,
     36                 4, 5, 6, 1];
     37 
     38         out =  [0, 0, 0, 0,
     39                 0, 0, 0, 0,
     40                 0, 0, 0, 0,
     41                 0, 0, 0, 0];
     42 
     43         identity = [1, 0, 0, 0,
     44                     0, 1, 0, 0,
     45                     0, 0, 1, 0,
     46                     0, 0, 0, 1];
     47     });
     48 
     49     describe("create", function() {
     50         beforeEach(function() { result = mat4.create(); });
     51         it("should return a 16 element array initialized to a 4x4 identity matrix", function() { expect(result).toBeEqualish(identity); });
     52     });
     53 
     54     describe("clone", function() {
     55         beforeEach(function() { result = mat4.clone(matA); });
     56         it("should return a 16 element array initialized to the values in matA", function() { expect(result).toBeEqualish(matA); });
     57     });
     58 
     59     describe("copy", function() {
     60         beforeEach(function() { result = mat4.copy(out, matA); });
     61         it("should place values into out", function() { expect(out).toBeEqualish(matA); });
     62         it("should return out", function() { expect(result).toBe(out); });
     63     });
     64 
     65     describe("identity", function() {
     66         beforeEach(function() { result = mat4.identity(out); });
     67         it("should place values into out", function() { expect(result).toBeEqualish(identity); });
     68         it("should return out", function() { expect(result).toBe(out); });
     69     });
     70 
     71     describe("transpose", function() {
     72         describe("with a separate output matrix", function() {
     73             beforeEach(function() { result = mat4.transpose(out, matA); });
     74 
     75             it("should place values into out", function() {
     76                 expect(out).toBeEqualish([
     77                     1, 0, 0, 1,
     78                     0, 1, 0, 2,
     79                     0, 0, 1, 3,
     80                     0, 0, 0, 1
     81                 ]);
     82             });
     83             it("should return out", function() { expect(result).toBe(out); });
     84             it("should not modify matA", function() {
     85                 expect(matA).toBeEqualish([
     86                     1, 0, 0, 0,
     87                     0, 1, 0, 0,
     88                     0, 0, 1, 0,
     89                     1, 2, 3, 1
     90                 ]);
     91             });
     92         });
     93 
     94         describe("when matA is the output matrix", function() {
     95             beforeEach(function() { result = mat4.transpose(matA, matA); });
     96 
     97             it("should place values into matA", function() {
     98                 expect(matA).toBeEqualish([
     99                     1, 0, 0, 1,
    100                     0, 1, 0, 2,
    101                     0, 0, 1, 3,
    102                     0, 0, 0, 1
    103                 ]);
    104             });
    105             it("should return matA", function() { expect(result).toBe(matA); });
    106         });
    107     });
    108 
    109     describe("invert", function() {
    110         describe("with a separate output matrix", function() {
    111             beforeEach(function() { result = mat4.invert(out, matA); });
    112 
    113             it("should place values into out", function() {
    114                 expect(out).toBeEqualish([
    115                     1, 0, 0, 0,
    116                     0, 1, 0, 0,
    117                     0, 0, 1, 0,
    118                     -1, -2, -3, 1
    119                 ]);
    120             });
    121             it("should return out", function() { expect(result).toBe(out); });
    122             it("should not modify matA", function() {
    123                 expect(matA).toBeEqualish([
    124                     1, 0, 0, 0,
    125                     0, 1, 0, 0,
    126                     0, 0, 1, 0,
    127                     1, 2, 3, 1
    128                 ]);
    129             });
    130         });
    131 
    132         describe("when matA is the output matrix", function() {
    133             beforeEach(function() { result = mat4.invert(matA, matA); });
    134 
    135             it("should place values into matA", function() {
    136                 expect(matA).toBeEqualish([
    137                     1, 0, 0, 0,
    138                     0, 1, 0, 0,
    139                     0, 0, 1, 0,
    140                     -1, -2, -3, 1
    141                 ]);
    142             });
    143             it("should return matA", function() { expect(result).toBe(matA); });
    144         });
    145     });
    146 
    147     describe("adjoint", function() {
    148         describe("with a separate output matrix", function() {
    149             beforeEach(function() { result = mat4.adjoint(out, matA); });
    150 
    151             it("should place values into out", function() {
    152                 expect(out).toBeEqualish([
    153                     1, 0, 0, 0,
    154                     0, 1, 0, 0,
    155                     0, 0, 1, 0,
    156                     -1, -2, -3, 1
    157                 ]);
    158             });
    159             it("should return out", function() { expect(result).toBe(out); });
    160             it("should not modify matA", function() {
    161                 expect(matA).toBeEqualish([
    162                     1, 0, 0, 0,
    163                     0, 1, 0, 0,
    164                     0, 0, 1, 0,
    165                     1, 2, 3, 1
    166                 ]);
    167             });
    168         });
    169 
    170         describe("when matA is the output matrix", function() {
    171             beforeEach(function() { result = mat4.adjoint(matA, matA); });
    172 
    173             it("should place values into matA", function() {
    174                 expect(matA).toBeEqualish([
    175                     1, 0, 0, 0,
    176                     0, 1, 0, 0,
    177                     0, 0, 1, 0,
    178                     -1, -2, -3, 1
    179                 ]);
    180             });
    181             it("should return matA", function() { expect(result).toBe(matA); });
    182         });
    183     });
    184 
    185     describe("determinant", function() {
    186         beforeEach(function() { result = mat4.determinant(matA); });
    187 
    188         it("should return the determinant", function() { expect(result).toEqual(1); });
    189     });
    190 
    191     describe("multiply", function() {
    192         it("should have an alias called 'mul'", function() { expect(mat4.mul).toEqual(mat4.multiply); });
    193 
    194         describe("with a separate output matrix", function() {
    195             beforeEach(function() { result = mat4.multiply(out, matA, matB); });
    196 
    197             it("should place values into out", function() {
    198                 expect(out).toBeEqualish([
    199                     1, 0, 0, 0,
    200                     0, 1, 0, 0,
    201                     0, 0, 1, 0,
    202                     5, 7, 9, 1
    203                 ]);
    204             });
    205             it("should return out", function() { expect(result).toBe(out); });
    206             it("should not modify matA", function() {
    207                 expect(matA).toBeEqualish([
    208                     1, 0, 0, 0,
    209                     0, 1, 0, 0,
    210                     0, 0, 1, 0,
    211                     1, 2, 3, 1
    212                 ]);
    213             });
    214             it("should not modify matB", function() {
    215                 expect(matB).toBeEqualish([
    216                     1, 0, 0, 0,
    217                     0, 1, 0, 0,
    218                     0, 0, 1, 0,
    219                     4, 5, 6, 1
    220                 ]);
    221             });
    222         });
    223 
    224         describe("when matA is the output matrix", function() {
    225             beforeEach(function() { result = mat4.multiply(matA, matA, matB); });
    226 
    227             it("should place values into matA", function() {
    228                 expect(matA).toBeEqualish([
    229                     1, 0, 0, 0,
    230                     0, 1, 0, 0,
    231                     0, 0, 1, 0,
    232                     5, 7, 9, 1
    233                 ]);
    234             });
    235             it("should return matA", function() { expect(result).toBe(matA); });
    236             it("should not modify matB", function() {
    237                 expect(matB).toBeEqualish([
    238                     1, 0, 0, 0,
    239                     0, 1, 0, 0,
    240                     0, 0, 1, 0,
    241                     4, 5, 6, 1
    242                 ]);
    243             });
    244         });
    245 
    246         describe("when matB is the output matrix", function() {
    247             beforeEach(function() { result = mat4.multiply(matB, matA, matB); });
    248 
    249             it("should place values into matB", function() {
    250                 expect(matB).toBeEqualish([
    251                     1, 0, 0, 0,
    252                     0, 1, 0, 0,
    253                     0, 0, 1, 0,
    254                     5, 7, 9, 1
    255                 ]);
    256             });
    257             it("should return matB", function() { expect(result).toBe(matB); });
    258             it("should not modify matA", function() {
    259                 expect(matA).toBeEqualish([
    260                     1, 0, 0, 0,
    261                     0, 1, 0, 0,
    262                     0, 0, 1, 0,
    263                     1, 2, 3, 1
    264                 ]);
    265             });
    266         });
    267     });
    268 
    269     describe("translate", function() {
    270         describe("with a separate output matrix", function() {
    271             beforeEach(function() { result = mat4.translate(out, matA, [4, 5, 6]); });
    272 
    273             it("should place values into out", function() {
    274                 expect(out).toBeEqualish([
    275                     1, 0, 0, 0,
    276                     0, 1, 0, 0,
    277                     0, 0, 1, 0,
    278                     5, 7, 9, 1
    279                 ]);
    280             });
    281             it("should return out", function() { expect(result).toBe(out); });
    282             it("should not modify matA", function() {
    283                 expect(matA).toBeEqualish([
    284                     1, 0, 0, 0,
    285                     0, 1, 0, 0,
    286                     0, 0, 1, 0,
    287                     1, 2, 3, 1
    288                 ]);
    289             });
    290         });
    291 
    292         describe("when matA is the output matrix", function() {
    293             beforeEach(function() { result = mat4.translate(matA, matA, [4, 5, 6]); });
    294 
    295             it("should place values into matA", function() {
    296                 expect(matA).toBeEqualish([
    297                     1, 0, 0, 0,
    298                     0, 1, 0, 0,
    299                     0, 0, 1, 0,
    300                     5, 7, 9, 1
    301                 ]);
    302             });
    303             it("should return matA", function() { expect(result).toBe(matA); });
    304         });
    305     });
    306 
    307     describe("scale", function() {
    308         describe("with a separate output matrix", function() {
    309             beforeEach(function() { result = mat4.scale(out, matA, [4, 5, 6]); });
    310 
    311             it("should place values into out", function() {
    312                 expect(out).toBeEqualish([
    313                     4, 0, 0, 0,
    314                     0, 5, 0, 0,
    315                     0, 0, 6, 0,
    316                     1, 2, 3, 1
    317                 ]);
    318             });
    319             it("should return out", function() { expect(result).toBe(out); });
    320             it("should not modify matA", function() {
    321                 expect(matA).toBeEqualish([
    322                     1, 0, 0, 0,
    323                     0, 1, 0, 0,
    324                     0, 0, 1, 0,
    325                     1, 2, 3, 1
    326                 ]);
    327             });
    328         });
    329 
    330         describe("when matA is the output matrix", function() {
    331             beforeEach(function() { result = mat4.scale(matA, matA, [4, 5, 6]); });
    332 
    333             it("should place values into matA", function() {
    334                 expect(matA).toBeEqualish([
    335                     4, 0, 0, 0,
    336                     0, 5, 0, 0,
    337                     0, 0, 6, 0,
    338                     1, 2, 3, 1
    339                 ]);
    340             });
    341             it("should return matA", function() { expect(result).toBe(matA); });
    342         });
    343     });
    344 
    345     describe("rotate", function() {
    346         var rad = Math.PI * 0.5;
    347         var axis = [1, 0, 0];
    348 
    349         describe("with a separate output matrix", function() {
    350             beforeEach(function() { result = mat4.rotate(out, matA, rad, axis); });
    351 
    352             it("should place values into out", function() {
    353                 expect(out).toBeEqualish([
    354                     1, 0, 0, 0,
    355                     0, Math.cos(rad), Math.sin(rad), 0,
    356                     0, -Math.sin(rad), Math.cos(rad), 0,
    357                     1, 2, 3, 1
    358                 ]);
    359             });
    360             it("should return out", function() { expect(result).toBe(out); });
    361             it("should not modify matA", function() {
    362                 expect(matA).toBeEqualish([
    363                     1, 0, 0, 0,
    364                     0, 1, 0, 0,
    365                     0, 0, 1, 0,
    366                     1, 2, 3, 1
    367                 ]);
    368             });
    369         });
    370 
    371         describe("when matA is the output matrix", function() {
    372             beforeEach(function() { result = mat4.rotate(matA, matA, rad, axis); });
    373 
    374             it("should place values into matA", function() {
    375                 expect(matA).toBeEqualish([
    376                     1, 0, 0, 0,
    377                     0, Math.cos(rad), Math.sin(rad), 0,
    378                     0, -Math.sin(rad), Math.cos(rad), 0,
    379                     1, 2, 3, 1
    380                 ]);
    381             });
    382             it("should return matA", function() { expect(result).toBe(matA); });
    383         });
    384     });
    385 
    386     describe("rotateX", function() {
    387         var rad = Math.PI * 0.5;
    388 
    389         describe("with a separate output matrix", function() {
    390             beforeEach(function() { result = mat4.rotateX(out, matA, rad); });
    391 
    392             it("should place values into out", function() {
    393                 expect(out).toBeEqualish([
    394                     1, 0, 0, 0,
    395                     0, Math.cos(rad), Math.sin(rad), 0,
    396                     0, -Math.sin(rad), Math.cos(rad), 0,
    397                     1, 2, 3, 1
    398                 ]);
    399             });
    400             it("should return out", function() { expect(result).toBe(out); });
    401             it("should not modify matA", function() {
    402                 expect(matA).toBeEqualish([
    403                     1, 0, 0, 0,
    404                     0, 1, 0, 0,
    405                     0, 0, 1, 0,
    406                     1, 2, 3, 1
    407                 ]);
    408             });
    409         });
    410 
    411         describe("when matA is the output matrix", function() {
    412             beforeEach(function() { result = mat4.rotateX(matA, matA, rad); });
    413 
    414             it("should place values into matA", function() {
    415                 expect(matA).toBeEqualish([
    416                     1, 0, 0, 0,
    417                     0, Math.cos(rad), Math.sin(rad), 0,
    418                     0, -Math.sin(rad), Math.cos(rad), 0,
    419                     1, 2, 3, 1
    420                 ]);
    421             });
    422             it("should return matA", function() { expect(result).toBe(matA); });
    423         });
    424     });
    425 
    426     describe("rotateY", function() {
    427         var rad = Math.PI * 0.5;
    428 
    429         describe("with a separate output matrix", function() {
    430             beforeEach(function() { result = mat4.rotateY(out, matA, rad); });
    431 
    432             it("should place values into out", function() {
    433                 expect(out).toBeEqualish([
    434                     Math.cos(rad), 0, -Math.sin(rad), 0,
    435                     0, 1, 0, 0,
    436                     Math.sin(rad), 0, Math.cos(rad), 0,
    437                     1, 2, 3, 1
    438                 ]);
    439             });
    440             it("should return out", function() { expect(result).toBe(out); });
    441             it("should not modify matA", function() {
    442                 expect(matA).toBeEqualish([
    443                     1, 0, 0, 0,
    444                     0, 1, 0, 0,
    445                     0, 0, 1, 0,
    446                     1, 2, 3, 1
    447                 ]);
    448             });
    449         });
    450 
    451         describe("when matA is the output matrix", function() {
    452             beforeEach(function() { result = mat4.rotateY(matA, matA, rad); });
    453 
    454             it("should place values into matA", function() {
    455                 expect(matA).toBeEqualish([
    456                     Math.cos(rad), 0, -Math.sin(rad), 0,
    457                     0, 1, 0, 0,
    458                     Math.sin(rad), 0, Math.cos(rad), 0,
    459                     1, 2, 3, 1
    460                 ]);
    461             });
    462             it("should return matA", function() { expect(result).toBe(matA); });
    463         });
    464     });
    465 
    466     describe("rotateZ", function() {
    467         var rad = Math.PI * 0.5;
    468 
    469         describe("with a separate output matrix", function() {
    470             beforeEach(function() { result = mat4.rotateZ(out, matA, rad); });
    471 
    472             it("should place values into out", function() {
    473                 expect(out).toBeEqualish([
    474                     Math.cos(rad), Math.sin(rad), 0, 0,
    475                     -Math.sin(rad), Math.cos(rad), 0, 0,
    476                     0, 0, 1, 0,
    477                     1, 2, 3, 1
    478                 ]);
    479             });
    480             it("should return out", function() { expect(result).toBe(out); });
    481             it("should not modify matA", function() {
    482                 expect(matA).toBeEqualish([
    483                     1, 0, 0, 0,
    484                     0, 1, 0, 0,
    485                     0, 0, 1, 0,
    486                     1, 2, 3, 1
    487                 ]);
    488             });
    489         });
    490 
    491         describe("when matA is the output matrix", function() {
    492             beforeEach(function() { result = mat4.rotateZ(matA, matA, rad); });
    493 
    494             it("should place values into matA", function() {
    495                 expect(matA).toBeEqualish([
    496                     Math.cos(rad), Math.sin(rad), 0, 0,
    497                     -Math.sin(rad), Math.cos(rad), 0, 0,
    498                     0, 0, 1, 0,
    499                     1, 2, 3, 1
    500                 ]);
    501             });
    502             it("should return matA", function() { expect(result).toBe(matA); });
    503         });
    504     });
    505 
    506     // TODO: fromRotationTranslation
    507 
    508     describe("frustum", function() {
    509         beforeEach(function() { result = mat4.frustum(out, -1, 1, -1, 1, -1, 1); });
    510         it("should place values into out", function() { expect(result).toBeEqualish([
    511                 -1, 0, 0, 0,
    512                 0, -1, 0, 0,
    513                 0, 0, 0, -1,
    514                 0, 0, 1, 0
    515             ]);
    516         });
    517         it("should return out", function() { expect(result).toBe(out); });
    518     });
    519 
    520     describe("perspective", function() {
    521         var fovy = Math.PI * 0.5;
    522         beforeEach(function() { result = mat4.perspective(out, fovy, 1, 0, 1); });
    523         it("should place values into out", function() { expect(result).toBeEqualish([
    524                 1, 0, 0, 0,
    525                 0, 1, 0, 0,
    526                 0, 0, -1, -1,
    527                 0, 0, 0, 0
    528             ]);
    529         });
    530         it("should return out", function() { expect(result).toBe(out); });
    531     });
    532 
    533     describe("ortho", function() {
    534         beforeEach(function() { result = mat4.ortho(out, -1, 1, -1, 1, -1, 1); });
    535         it("should place values into out", function() { expect(result).toBeEqualish([
    536                 1, 0, 0, 0,
    537                 0, 1, 0, 0,
    538                 0, 0, -1, 0,
    539                 0, 0, 0, 1
    540             ]);
    541         });
    542         it("should return out", function() { expect(result).toBe(out); });
    543     });
    544 
    545     describe("lookAt", function() {
    546         var eye = [0, 0, 1];
    547         var center = [0, 0, -1];
    548         var up = [0, 1, 0];
    549 
    550         beforeEach(function() { result = mat4.lookAt(out, eye, center, up); });
    551         it("should place values into out", function() { expect(result).toBeEqualish([
    552                 1, 0, 0, 0,
    553                 0, 1, 0, 0,
    554                 0, 0, 1, 0,
    555                 0, 0, -1, 1
    556             ]);
    557         });
    558         it("should return out", function() { expect(result).toBe(out); });
    559     });
    560 
    561     describe("str", function() {
    562         beforeEach(function() { result = mat4.str(matA); });
    563 
    564         it("should return a string representation of the matrix", function() { expect(result).toEqual("mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1)"); });
    565     });
    566 });