comparison webGL/dandy/resources/CanvasMatrix.js @ 3:10344afb38a6

upload dandy
author NOBUYASU Oshiro
date Mon, 07 Jun 2010 17:58:31 +0900
parents
children
comparison
equal deleted inserted replaced
2:be36da713ffd 3:10344afb38a6
1 /*
2 * Copyright (C) 2009 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25 /*
26 CanvasMatrix4 class
27
28 This class implements a 4x4 matrix. It has functions which
29 duplicate the functionality of the OpenGL matrix stack and
30 glut functions.
31
32 IDL:
33
34 [
35 Constructor(in CanvasMatrix4 matrix), // copy passed matrix into new CanvasMatrix4
36 Constructor(in sequence<float> array) // create new CanvasMatrix4 with 16 floats (row major)
37 Constructor() // create new CanvasMatrix4 with identity matrix
38 ]
39 interface CanvasMatrix4 {
40 attribute float m11;
41 attribute float m12;
42 attribute float m13;
43 attribute float m14;
44 attribute float m21;
45 attribute float m22;
46 attribute float m23;
47 attribute float m24;
48 attribute float m31;
49 attribute float m32;
50 attribute float m33;
51 attribute float m34;
52 attribute float m41;
53 attribute float m42;
54 attribute float m43;
55 attribute float m44;
56
57 void load(in CanvasMatrix4 matrix); // copy the values from the passed matrix
58 void load(in sequence<float> array); // copy 16 floats into the matrix
59 sequence<float> getAsArray(); // return the matrix as an array of 16 floats
60 WebGLFloatArray getAsCanvasFloatArray(); // return the matrix as a WebGLFloatArray with 16 values
61 void makeIdentity(); // replace the matrix with identity
62 void transpose(); // replace the matrix with its transpose
63 void invert(); // replace the matrix with its inverse
64
65 void translate(in float x, in float y, in float z); // multiply the matrix by passed translation values on the right
66 void scale(in float x, in float y, in float z); // multiply the matrix by passed scale values on the right
67 void rotate(in float angle, // multiply the matrix by passed rotation values on the right
68 in float x, in float y, in float z); // (angle is in degrees)
69 void multRight(in CanvasMatrix matrix); // multiply the matrix by the passed matrix on the right
70 void multLeft(in CanvasMatrix matrix); // multiply the matrix by the passed matrix on the left
71 void ortho(in float left, in float right, // multiply the matrix by the passed ortho values on the right
72 in float bottom, in float top,
73 in float near, in float far);
74 void frustum(in float left, in float right, // multiply the matrix by the passed frustum values on the right
75 in float bottom, in float top,
76 in float near, in float far);
77 void perspective(in float fovy, in float aspect, // multiply the matrix by the passed perspective values on the right
78 in float zNear, in float zFar);
79 void lookat(in float eyex, in float eyey, in float eyez, // multiply the matrix by the passed lookat
80 in float ctrx, in float ctry, in float ctrz, // values on the right
81 in float upx, in float upy, in float upz);
82 }
83 */
84
85 CanvasMatrix4 = function(m)
86 {
87 if (typeof m == 'object') {
88 if ("length" in m && m.length >= 16) {
89 this.load(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]);
90 return;
91 }
92 else if (m instanceof CanvasMatrix4) {
93 this.load(m);
94 return;
95 }
96 }
97 this.makeIdentity();
98 }
99
100 CanvasMatrix4.prototype.load = function()
101 {
102 if (arguments.length == 1 && typeof arguments[0] == 'object') {
103 var matrix = arguments[0];
104
105 if ("length" in matrix && matrix.length == 16) {
106 this.m11 = matrix[0];
107 this.m12 = matrix[1];
108 this.m13 = matrix[2];
109 this.m14 = matrix[3];
110
111 this.m21 = matrix[4];
112 this.m22 = matrix[5];
113 this.m23 = matrix[6];
114 this.m24 = matrix[7];
115
116 this.m31 = matrix[8];
117 this.m32 = matrix[9];
118 this.m33 = matrix[10];
119 this.m34 = matrix[11];
120
121 this.m41 = matrix[12];
122 this.m42 = matrix[13];
123 this.m43 = matrix[14];
124 this.m44 = matrix[15];
125 return;
126 }
127
128 if (arguments[0] instanceof CanvasMatrix4) {
129
130 this.m11 = matrix.m11;
131 this.m12 = matrix.m12;
132 this.m13 = matrix.m13;
133 this.m14 = matrix.m14;
134
135 this.m21 = matrix.m21;
136 this.m22 = matrix.m22;
137 this.m23 = matrix.m23;
138 this.m24 = matrix.m24;
139
140 this.m31 = matrix.m31;
141 this.m32 = matrix.m32;
142 this.m33 = matrix.m33;
143 this.m34 = matrix.m34;
144
145 this.m41 = matrix.m41;
146 this.m42 = matrix.m42;
147 this.m43 = matrix.m43;
148 this.m44 = matrix.m44;
149 return;
150 }
151 }
152
153 this.makeIdentity();
154 }
155
156 CanvasMatrix4.prototype.getAsArray = function()
157 {
158 return [
159 this.m11, this.m12, this.m13, this.m14,
160 this.m21, this.m22, this.m23, this.m24,
161 this.m31, this.m32, this.m33, this.m34,
162 this.m41, this.m42, this.m43, this.m44
163 ];
164 }
165
166 CanvasMatrix4.prototype.getAsWebGLFloatArray = function()
167 {
168 return new WebGLFloatArray(this.getAsArray());
169 }
170
171 CanvasMatrix4.prototype.makeIdentity = function()
172 {
173 this.m11 = 1;
174 this.m12 = 0;
175 this.m13 = 0;
176 this.m14 = 0;
177
178 this.m21 = 0;
179 this.m22 = 1;
180 this.m23 = 0;
181 this.m24 = 0;
182
183 this.m31 = 0;
184 this.m32 = 0;
185 this.m33 = 1;
186 this.m34 = 0;
187
188 this.m41 = 0;
189 this.m42 = 0;
190 this.m43 = 0;
191 this.m44 = 1;
192 }
193
194 CanvasMatrix4.prototype.transpose = function()
195 {
196 var tmp = this.m12;
197 this.m12 = this.m21;
198 this.m21 = tmp;
199
200 tmp = this.m13;
201 this.m13 = this.m31;
202 this.m31 = tmp;
203
204 tmp = this.m14;
205 this.m14 = this.m41;
206 this.m41 = tmp;
207
208 tmp = this.m23;
209 this.m23 = this.m32;
210 this.m32 = tmp;
211
212 tmp = this.m24;
213 this.m24 = this.m42;
214 this.m42 = tmp;
215
216 tmp = this.m34;
217 this.m34 = this.m43;
218 this.m43 = tmp;
219 }
220
221 CanvasMatrix4.prototype.invert = function()
222 {
223 // Calculate the 4x4 determinant
224 // If the determinant is zero,
225 // then the inverse matrix is not unique.
226 var det = this._determinant4x4();
227
228 if (Math.abs(det) < 1e-8)
229 return null;
230
231 this._makeAdjoint();
232
233 // Scale the adjoint matrix to get the inverse
234 this.m11 /= det;
235 this.m12 /= det;
236 this.m13 /= det;
237 this.m14 /= det;
238
239 this.m21 /= det;
240 this.m22 /= det;
241 this.m23 /= det;
242 this.m24 /= det;
243
244 this.m31 /= det;
245 this.m32 /= det;
246 this.m33 /= det;
247 this.m34 /= det;
248
249 this.m41 /= det;
250 this.m42 /= det;
251 this.m43 /= det;
252 this.m44 /= det;
253 }
254
255 CanvasMatrix4.prototype.translate = function(x,y,z)
256 {
257 if (x == undefined)
258 x = 0;
259 if (y == undefined)
260 y = 0;
261 if (z == undefined)
262 z = 0;
263
264 var matrix = new CanvasMatrix4();
265 matrix.m41 = x;
266 matrix.m42 = y;
267 matrix.m43 = z;
268
269 this.multRight(matrix);
270 }
271
272 CanvasMatrix4.prototype.scale = function(x,y,z)
273 {
274 if (x == undefined)
275 x = 1;
276 if (z == undefined) {
277 if (y == undefined) {
278 y = x;
279 z = x;
280 }
281 else
282 z = 1;
283 }
284 else if (y == undefined)
285 y = x;
286
287 var matrix = new CanvasMatrix4();
288 matrix.m11 = x;
289 matrix.m22 = y;
290 matrix.m33 = z;
291
292 this.multRight(matrix);
293 }
294
295 CanvasMatrix4.prototype.rotate = function(angle,x,y,z)
296 {
297 // angles are in degrees. Switch to radians
298 angle = angle / 180 * Math.PI;
299
300 angle /= 2;
301 var sinA = Math.sin(angle);
302 var cosA = Math.cos(angle);
303 var sinA2 = sinA * sinA;
304
305 // normalize
306 var length = Math.sqrt(x * x + y * y + z * z);
307 if (length == 0) {
308 // bad vector, just use something reasonable
309 x = 0;
310 y = 0;
311 z = 1;
312 } else if (length != 1) {
313 x /= length;
314 y /= length;
315 z /= length;
316 }
317
318 var mat = new CanvasMatrix4();
319
320 // optimize case where axis is along major axis
321 if (x == 1 && y == 0 && z == 0) {
322 mat.m11 = 1;
323 mat.m12 = 0;
324 mat.m13 = 0;
325 mat.m21 = 0;
326 mat.m22 = 1 - 2 * sinA2;
327 mat.m23 = 2 * sinA * cosA;
328 mat.m31 = 0;
329 mat.m32 = -2 * sinA * cosA;
330 mat.m33 = 1 - 2 * sinA2;
331 mat.m14 = mat.m24 = mat.m34 = 0;
332 mat.m41 = mat.m42 = mat.m43 = 0;
333 mat.m44 = 1;
334 } else if (x == 0 && y == 1 && z == 0) {
335 mat.m11 = 1 - 2 * sinA2;
336 mat.m12 = 0;
337 mat.m13 = -2 * sinA * cosA;
338 mat.m21 = 0;
339 mat.m22 = 1;
340 mat.m23 = 0;
341 mat.m31 = 2 * sinA * cosA;
342 mat.m32 = 0;
343 mat.m33 = 1 - 2 * sinA2;
344 mat.m14 = mat.m24 = mat.m34 = 0;
345 mat.m41 = mat.m42 = mat.m43 = 0;
346 mat.m44 = 1;
347 } else if (x == 0 && y == 0 && z == 1) {
348 mat.m11 = 1 - 2 * sinA2;
349 mat.m12 = 2 * sinA * cosA;
350 mat.m13 = 0;
351 mat.m21 = -2 * sinA * cosA;
352 mat.m22 = 1 - 2 * sinA2;
353 mat.m23 = 0;
354 mat.m31 = 0;
355 mat.m32 = 0;
356 mat.m33 = 1;
357 mat.m14 = mat.m24 = mat.m34 = 0;
358 mat.m41 = mat.m42 = mat.m43 = 0;
359 mat.m44 = 1;
360 } else {
361 var x2 = x*x;
362 var y2 = y*y;
363 var z2 = z*z;
364
365 mat.m11 = 1 - 2 * (y2 + z2) * sinA2;
366 mat.m12 = 2 * (x * y * sinA2 + z * sinA * cosA);
367 mat.m13 = 2 * (x * z * sinA2 - y * sinA * cosA);
368 mat.m21 = 2 * (y * x * sinA2 - z * sinA * cosA);
369 mat.m22 = 1 - 2 * (z2 + x2) * sinA2;
370 mat.m23 = 2 * (y * z * sinA2 + x * sinA * cosA);
371 mat.m31 = 2 * (z * x * sinA2 + y * sinA * cosA);
372 mat.m32 = 2 * (z * y * sinA2 - x * sinA * cosA);
373 mat.m33 = 1 - 2 * (x2 + y2) * sinA2;
374 mat.m14 = mat.m24 = mat.m34 = 0;
375 mat.m41 = mat.m42 = mat.m43 = 0;
376 mat.m44 = 1;
377 }
378 this.multRight(mat);
379 }
380
381 CanvasMatrix4.prototype.multRight = function(mat)
382 {
383 var m11 = (this.m11 * mat.m11 + this.m12 * mat.m21
384 + this.m13 * mat.m31 + this.m14 * mat.m41);
385 var m12 = (this.m11 * mat.m12 + this.m12 * mat.m22
386 + this.m13 * mat.m32 + this.m14 * mat.m42);
387 var m13 = (this.m11 * mat.m13 + this.m12 * mat.m23
388 + this.m13 * mat.m33 + this.m14 * mat.m43);
389 var m14 = (this.m11 * mat.m14 + this.m12 * mat.m24
390 + this.m13 * mat.m34 + this.m14 * mat.m44);
391
392 var m21 = (this.m21 * mat.m11 + this.m22 * mat.m21
393 + this.m23 * mat.m31 + this.m24 * mat.m41);
394 var m22 = (this.m21 * mat.m12 + this.m22 * mat.m22
395 + this.m23 * mat.m32 + this.m24 * mat.m42);
396 var m23 = (this.m21 * mat.m13 + this.m22 * mat.m23
397 + this.m23 * mat.m33 + this.m24 * mat.m43);
398 var m24 = (this.m21 * mat.m14 + this.m22 * mat.m24
399 + this.m23 * mat.m34 + this.m24 * mat.m44);
400
401 var m31 = (this.m31 * mat.m11 + this.m32 * mat.m21
402 + this.m33 * mat.m31 + this.m34 * mat.m41);
403 var m32 = (this.m31 * mat.m12 + this.m32 * mat.m22
404 + this.m33 * mat.m32 + this.m34 * mat.m42);
405 var m33 = (this.m31 * mat.m13 + this.m32 * mat.m23
406 + this.m33 * mat.m33 + this.m34 * mat.m43);
407 var m34 = (this.m31 * mat.m14 + this.m32 * mat.m24
408 + this.m33 * mat.m34 + this.m34 * mat.m44);
409
410 var m41 = (this.m41 * mat.m11 + this.m42 * mat.m21
411 + this.m43 * mat.m31 + this.m44 * mat.m41);
412 var m42 = (this.m41 * mat.m12 + this.m42 * mat.m22
413 + this.m43 * mat.m32 + this.m44 * mat.m42);
414 var m43 = (this.m41 * mat.m13 + this.m42 * mat.m23
415 + this.m43 * mat.m33 + this.m44 * mat.m43);
416 var m44 = (this.m41 * mat.m14 + this.m42 * mat.m24
417 + this.m43 * mat.m34 + this.m44 * mat.m44);
418
419 this.m11 = m11;
420 this.m12 = m12;
421 this.m13 = m13;
422 this.m14 = m14;
423
424 this.m21 = m21;
425 this.m22 = m22;
426 this.m23 = m23;
427 this.m24 = m24;
428
429 this.m31 = m31;
430 this.m32 = m32;
431 this.m33 = m33;
432 this.m34 = m34;
433
434 this.m41 = m41;
435 this.m42 = m42;
436 this.m43 = m43;
437 this.m44 = m44;
438 }
439
440 CanvasMatrix4.prototype.multLeft = function(mat)
441 {
442 var m11 = (mat.m11 * this.m11 + mat.m12 * this.m21
443 + mat.m13 * this.m31 + mat.m14 * this.m41);
444 var m12 = (mat.m11 * this.m12 + mat.m12 * this.m22
445 + mat.m13 * this.m32 + mat.m14 * this.m42);
446 var m13 = (mat.m11 * this.m13 + mat.m12 * this.m23
447 + mat.m13 * this.m33 + mat.m14 * this.m43);
448 var m14 = (mat.m11 * this.m14 + mat.m12 * this.m24
449 + mat.m13 * this.m34 + mat.m14 * this.m44);
450
451 var m21 = (mat.m21 * this.m11 + mat.m22 * this.m21
452 + mat.m23 * this.m31 + mat.m24 * this.m41);
453 var m22 = (mat.m21 * this.m12 + mat.m22 * this.m22
454 + mat.m23 * this.m32 + mat.m24 * this.m42);
455 var m23 = (mat.m21 * this.m13 + mat.m22 * this.m23
456 + mat.m23 * this.m33 + mat.m24 * this.m43);
457 var m24 = (mat.m21 * this.m14 + mat.m22 * this.m24
458 + mat.m23 * this.m34 + mat.m24 * this.m44);
459
460 var m31 = (mat.m31 * this.m11 + mat.m32 * this.m21
461 + mat.m33 * this.m31 + mat.m34 * this.m41);
462 var m32 = (mat.m31 * this.m12 + mat.m32 * this.m22
463 + mat.m33 * this.m32 + mat.m34 * this.m42);
464 var m33 = (mat.m31 * this.m13 + mat.m32 * this.m23
465 + mat.m33 * this.m33 + mat.m34 * this.m43);
466 var m34 = (mat.m31 * this.m14 + mat.m32 * this.m24
467 + mat.m33 * this.m34 + mat.m34 * this.m44);
468
469 var m41 = (mat.m41 * this.m11 + mat.m42 * this.m21
470 + mat.m43 * this.m31 + mat.m44 * this.m41);
471 var m42 = (mat.m41 * this.m12 + mat.m42 * this.m22
472 + mat.m43 * this.m32 + mat.m44 * this.m42);
473 var m43 = (mat.m41 * this.m13 + mat.m42 * this.m23
474 + mat.m43 * this.m33 + mat.m44 * this.m43);
475 var m44 = (mat.m41 * this.m14 + mat.m42 * this.m24
476 + mat.m43 * this.m34 + mat.m44 * this.m44);
477
478 this.m11 = m11;
479 this.m12 = m12;
480 this.m13 = m13;
481 this.m14 = m14;
482
483 this.m21 = m21;
484 this.m22 = m22;
485 this.m23 = m23;
486 this.m24 = m24;
487
488 this.m31 = m31;
489 this.m32 = m32;
490 this.m33 = m33;
491 this.m34 = m34;
492
493 this.m41 = m41;
494 this.m42 = m42;
495 this.m43 = m43;
496 this.m44 = m44;
497 }
498
499 CanvasMatrix4.prototype.ortho = function(left, right, bottom, top, near, far)
500 {
501 var tx = (left + right) / (left - right);
502 var ty = (top + bottom) / (top - bottom);
503 var tz = (far + near) / (far - near);
504
505 var matrix = new CanvasMatrix4();
506 matrix.m11 = 2 / (left - right);
507 matrix.m12 = 0;
508 matrix.m13 = 0;
509 matrix.m14 = 0;
510 matrix.m21 = 0;
511 matrix.m22 = 2 / (top - bottom);
512 matrix.m23 = 0;
513 matrix.m24 = 0;
514 matrix.m31 = 0;
515 matrix.m32 = 0;
516 matrix.m33 = -2 / (far - near);
517 matrix.m34 = 0;
518 matrix.m41 = tx;
519 matrix.m42 = ty;
520 matrix.m43 = tz;
521 matrix.m44 = 1;
522
523 this.multRight(matrix);
524 }
525
526 CanvasMatrix4.prototype.frustum = function(left, right, bottom, top, near, far)
527 {
528 var matrix = new CanvasMatrix4();
529 var A = (right + left) / (right - left);
530 var B = (top + bottom) / (top - bottom);
531 var C = -(far + near) / (far - near);
532 var D = -(2 * far * near) / (far - near);
533
534 matrix.m11 = (2 * near) / (right - left);
535 matrix.m12 = 0;
536 matrix.m13 = 0;
537 matrix.m14 = 0;
538
539 matrix.m21 = 0;
540 matrix.m22 = 2 * near / (top - bottom);
541 matrix.m23 = 0;
542 matrix.m24 = 0;
543
544 matrix.m31 = A;
545 matrix.m32 = B;
546 matrix.m33 = C;
547 matrix.m34 = -1;
548
549 matrix.m41 = 0;
550 matrix.m42 = 0;
551 matrix.m43 = D;
552 matrix.m44 = 0;
553
554 this.multRight(matrix);
555 }
556
557 CanvasMatrix4.prototype.perspective = function(fovy, aspect, zNear, zFar)
558 {
559 var top = Math.tan(fovy * Math.PI / 360) * zNear;
560 var bottom = -top;
561 var left = aspect * bottom;
562 var right = aspect * top;
563 this.frustum(left, right, bottom, top, zNear, zFar);
564 }
565
566 CanvasMatrix4.prototype.lookat = function(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz)
567 {
568 var matrix = new CanvasMatrix4();
569
570 // Make rotation matrix
571
572 // Z vector
573 var zx = eyex - centerx;
574 var zy = eyey - centery;
575 var zz = eyez - centerz;
576 var mag = Math.sqrt(zx * zx + zy * zy + zz * zz);
577 if (mag) {
578 zx /= mag;
579 zy /= mag;
580 zz /= mag;
581 }
582
583 // Y vector
584 var yx = upx;
585 var yy = upy;
586 var yz = upz;
587
588 // X vector = Y cross Z
589 xx = yy * zz - yz * zy;
590 xy = -yx * zz + yz * zx;
591 xz = yx * zy - yy * zx;
592
593 // Recompute Y = Z cross X
594 yx = zy * xz - zz * xy;
595 yy = -zx * xz + zz * xx;
596 yx = zx * xy - zy * xx;
597
598 // cross product gives area of parallelogram, which is < 1.0 for
599 // non-perpendicular unit-length vectors; so normalize x, y here
600
601 mag = Math.sqrt(xx * xx + xy * xy + xz * xz);
602 if (mag) {
603 xx /= mag;
604 xy /= mag;
605 xz /= mag;
606 }
607
608 mag = Math.sqrt(yx * yx + yy * yy + yz * yz);
609 if (mag) {
610 yx /= mag;
611 yy /= mag;
612 yz /= mag;
613 }
614
615 matrix.m11 = xx;
616 matrix.m12 = xy;
617 matrix.m13 = xz;
618 matrix.m14 = 0;
619
620 matrix.m21 = yx;
621 matrix.m22 = yy;
622 matrix.m23 = yz;
623 matrix.m24 = 0;
624
625 matrix.m31 = zx;
626 matrix.m32 = zy;
627 matrix.m33 = zz;
628 matrix.m34 = 0;
629
630 matrix.m41 = 0;
631 matrix.m42 = 0;
632 matrix.m43 = 0;
633 matrix.m44 = 1;
634 matrix.translate(-eyex, -eyey, -eyez);
635
636 this.multRight(matrix);
637 }
638
639 // Support functions
640 CanvasMatrix4.prototype._determinant2x2 = function(a, b, c, d)
641 {
642 return a * d - b * c;
643 }
644
645 CanvasMatrix4.prototype._determinant3x3 = function(a1, a2, a3, b1, b2, b3, c1, c2, c3)
646 {
647 return a1 * this._determinant2x2(b2, b3, c2, c3)
648 - b1 * this._determinant2x2(a2, a3, c2, c3)
649 + c1 * this._determinant2x2(a2, a3, b2, b3);
650 }
651
652 CanvasMatrix4.prototype._determinant4x4 = function()
653 {
654 var a1 = this.m11;
655 var b1 = this.m12;
656 var c1 = this.m13;
657 var d1 = this.m14;
658
659 var a2 = this.m21;
660 var b2 = this.m22;
661 var c2 = this.m23;
662 var d2 = this.m24;
663
664 var a3 = this.m31;
665 var b3 = this.m32;
666 var c3 = this.m33;
667 var d3 = this.m34;
668
669 var a4 = this.m41;
670 var b4 = this.m42;
671 var c4 = this.m43;
672 var d4 = this.m44;
673
674 return a1 * this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)
675 - b1 * this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)
676 + c1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)
677 - d1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
678 }
679
680 CanvasMatrix4.prototype._makeAdjoint = function()
681 {
682 var a1 = this.m11;
683 var b1 = this.m12;
684 var c1 = this.m13;
685 var d1 = this.m14;
686
687 var a2 = this.m21;
688 var b2 = this.m22;
689 var c2 = this.m23;
690 var d2 = this.m24;
691
692 var a3 = this.m31;
693 var b3 = this.m32;
694 var c3 = this.m33;
695 var d3 = this.m34;
696
697 var a4 = this.m41;
698 var b4 = this.m42;
699 var c4 = this.m43;
700 var d4 = this.m44;
701
702 // Row column labeling reversed since we transpose rows & columns
703 this.m11 = this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
704 this.m21 = - this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
705 this.m31 = this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
706 this.m41 = - this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
707
708 this.m12 = - this._determinant3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
709 this.m22 = this._determinant3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
710 this.m32 = - this._determinant3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
711 this.m42 = this._determinant3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
712
713 this.m13 = this._determinant3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
714 this.m23 = - this._determinant3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
715 this.m33 = this._determinant3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
716 this.m43 = - this._determinant3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
717
718 this.m14 = - this._determinant3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
719 this.m24 = this._determinant3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
720 this.m34 = - this._determinant3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
721 this.m44 = this._determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
722 }