2
GLGE WebGL Graphics Engine
3
Copyright (c) 2010, Paul Brunt
6
Redistribution and use in source and binary forms, with or without
7
modification, are permitted provided that the following conditions are met:
8
* Redistributions of source code must retain the above copyright
9
notice, this list of conditions and the following disclaimer.
10
* Redistributions in binary form must reproduce the above copyright
11
notice, this list of conditions and the following disclaimer in the
12
documentation and/or other materials provided with the distribution.
13
* Neither the name of GLGE nor the
14
names of its contributors may be used to endorse or promote products
15
derived from this software without specific prior written permission.
17
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
21
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
* @namespace Holds the functionality of the library
43
GLGE.Vec=function(array) {
44
return array.slice(0);
48
* The Vec3 Class creates a vector
49
* @param {Array} array An array of 3 floats
51
GLGE.Vec3=function(x,y,z){
56
* The Vec4 Class creates a vector
57
* @param {Array} array An array of 4 floats
59
GLGE.Vec4=function(x,y,z,w){
64
* Gets the nth element (1 indexed) from the array
65
* @param {Array} v A vector with 4 elements
66
* @param {number} i The index from one
68
GLGE.get1basedVec4=function(v,i){
72
* Gets the nth element (1 indexed) from the array
73
* @param {Array} v A vector with 3 elements
74
* @param {number} i The index from one
76
GLGE.get1basedVec3=function(v,i){
81
* Gets the nth element (1 indexed) from the array
82
* @param {Array} v A vector with 4 elements
83
* @param {number} i The index from one
85
GLGE.getVec4=function(v,i){
89
* Gets the nth element (1 indexed) from the array
90
* @param {Array} v A vector with 3 elements
91
* @param {number} i The index from one
93
GLGE.getVec3=function(v,i){
100
* Adds a GLGE.Vec4 to this Vec4
101
* @param {Array} a The first value to add
102
* * @param {Array} b The second value to add
104
GLGE.addVec4=function(a,b) {
105
return [a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3]];
108
* Adds a GLGE.Vec3 to this GLGE.Vec3
109
* @param {Array} a The first value to add
110
* @param {Array} b The second value to add
112
GLGE.addVec3=function(a,b) {
113
return [a[0]+b[0],a[1]+b[1],a[2]+b[2]];
118
* Adds a GLGE.Vec4 to this Vec4
119
* @param {Array} a The first value
120
* * @param {Array} b The second value to subtract from the first
122
GLGE.subVec4=function(a,b) {
123
return [a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]];
126
* Adds a GLGE.Vec3 to this GLGE.Vec3
127
* @param {Array} a The first value
128
* @param {Array} b The second value to subtract from the first
130
GLGE.subVec3=function(a,b) {
131
return [a[0]-b[0],a[1]-b[1],a[2]-b[2]];
136
* Gets the dot product between this and the input vector
137
* @param {Array} a the first value to dot
138
* @param {Array} b the second value to dot
140
GLGE.dotVec3=function(a,b) {
141
return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
146
* Gets the dot product between this and the input vector
147
* @param {Array} a the first value to dot
148
* @param {Array} b the second value to dot
150
GLGE.dotVec4=function(a,b) {
151
return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3];
155
* Gets the dot product between this and the input vector
156
* @param {Array} a the vector to scale
157
* @param {Number} b the scalar
159
GLGE.scaleVec4=function(a,b) {
160
return [a[0]*b,a[1]*b,a[2]*b,a[3]*b];
164
* Gets the dot product between this and the input vector
165
* @param {Array} a the vector to scale
166
* @param {Number} b the scalar
168
GLGE.scaleVec3=function(a,b) {
169
return [a[0]*b,a[1]*b,a[2]*b];
174
* Gets the cross product between this and the input vector
175
* @param {Array} a the first value to dot
176
* @param {Array} b the second value to dot
178
GLGE.crossVec3=function(a,b) {
179
return [a[1]*b[2]-a[2]*b[1],
181
a[0]*b[1]-a[1]*b[0]];
185
* Returns a unitized version of the input vector3
186
* @param {Array} a the vector3 to be unitized
188
GLGE.toUnitVec3=function(a) {
189
var sq=a[0]*a[0]+a[1]*a[1]+a[2]*a[2];
194
return [a[0]/f,a[1]/f,a[2]/f];
198
* Returns a unitized version of the input vector4
199
* @param {Array} a the vector4 to be unitized
201
GLGE.toUnitVec4=function(a) {
202
var sq=a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3];
207
return [a[0]/f,a[1]/f,a[2]/f,a[3]/f];
212
* Returns the length of a vector3
213
* @param {Array} a the vector to be measured
215
GLGE.lengthVec3=function(a) {
216
return Math.pow(a[0]*a[0]+a[1]*a[1]+a[2]*a[2],0.5);
220
* Returns the distance between 2 vector3s
221
* @param {Array} a the first vector
222
* @param {Array} b the second vector
224
GLGE.distanceVec3=function(a,b){
225
return GLGE.lengthVec3(GLGE.subVec3(a,b));
229
* Returns the length of a vector3
230
* @param {Array} a the vector to be measured
232
GLGE.lengthVec4=function(a,b) {
233
return Math.pow(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3],0.5);
237
* Returns the distance between 2 vector4s
238
* @param {Array} a the first vector
239
* @param {Array} b the second vector
241
GLGE.distanceVec4=function(a,b){
242
return GLGE.lengthVec4(GLGE.subVec4(a,b));
247
* Returns the angle between 2 vector3s in radians
248
* @param {Array} a the first vector
249
* @param {Array} b the second vector
251
GLGE.angleVec3=function(a,b){
252
a=GLGE.toUnitVec3(a);
253
b=GLGE.toUnitVec3(b);
263
* Returns the angle between 2 vector4s in radians
264
* @param {Array} a the first vector
265
* @param {Array} b the second vector
267
GLGE.angleVec4=function(a,b){
268
a=GLGE.toUnitVec4(a);
269
b=GLGE.toUnitVec4(b);
278
GLGE_math_use_webgl_float=false;
281
* The Mat class creates a matrix from an array
282
* @param {Array} array An array of 9 or 16 floats
284
GLGE.Mat3=GLGE_math_use_webgl_float?function(array) {
285
if (array.length==9) {
286
return new Float32Array(array);
287
}else if (array.length==16) {
288
return new Float32Array([array[0],array[1],array[2],array[4],array[5],array[6],array[8],array[9],array[10]]);
290
throw "invalid matrix length";
294
if (array.length==9) {
295
retval=array.slice(0);
296
}else if (array.length==16) {
297
retval=[array[0],array[1],array[2],array[4],array[5],array[6],array[8],array[9],array[10]];
299
throw "invalid matrix length";
301
retval.get=function(i){return this[i];};
304
GLGE.Mat=GLGE_math_use_webgl_float?function(array) {
305
return new Float32Array(array);
307
var retval=array.slice(0);
308
retval.get=function(i){return this[i];};
311
GLGE.Mat4=function(array) {
313
if (array.length==9) {
314
retval=[array[0],array[1],array[2],0,array[3],array[4],array[5],0,array[6],array[7],array[8],0,0,0,0,1];
315
}else if (array.length==16) {
316
retval=array.slice(0);
318
throw "invalid matrix length";
320
retval.get=function(i){return this[i];};
324
* Finds the determinate of the matrix
325
* @returns {number} the determinate
327
GLGE.determinantMat4=function(m) {
328
return m[12] * m[9] * m[6] * m[3] - m[8] * m[13] * m[6] * m[3] - m[12] * m[5] * m[10] * m[3] + m[4] * m[13] * m[10] * m[3] + m[8] * m[5] * m[14] * m[3] - m[4] * m[9] * m[14] * m[3] - m[12] * m[9] * m[2] * m[7] + m[8] * m[13] * m[2] * m[7] + m[12] * m[1] * m[10] * m[7] - m[0] * m[13] * m[10] * m[7] - m[8] * m[1] * m[14] * m[7] + m[0] * m[9] * m[14] * m[7] + m[12] * m[5] * m[2] * m[11] - m[4] * m[13] * m[2] * m[11] - m[12] * m[1] * m[6] * m[11] + m[0] * m[13] * m[6] * m[11] + m[4] * m[1] * m[14] * m[11] - m[0] * m[5] * m[14] * m[11] - m[8] * m[5] * m[2] * m[15] + m[4] * m[9] * m[2] * m[15] + m[8] * m[1] * m[6] * m[15] - m[0] * m[9] * m[6] * m[15] - m[4] * m[1] * m[10] * m[15] + m[0] * m[5] * m[10] * m[15];
332
* Finds the inverse of the matrix
333
* @returns {GLGE.Mat} the inverse
335
GLGE.inverseMat4=function(mat){
336
// Cache the matrix values (makes for huge speed increases!)
337
var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
338
var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
339
var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
340
var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
342
var d = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
343
a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
344
a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
345
a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
346
a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
347
a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
349
return [ (a21*a32*a13 - a31*a22*a13 + a31*a12*a23 - a11*a32*a23 - a21*a12*a33 + a11*a22*a33)/d,
350
(a31*a22*a03 - a21*a32*a03 - a31*a02*a23 + a01*a32*a23 + a21*a02*a33 - a01*a22*a33)/d,
351
(a11*a32*a03 - a31*a12*a03 + a31*a02*a13 - a01*a32*a13 - a11*a02*a33 + a01*a12*a33)/d,
352
(a21*a12*a03 - a11*a22*a03 - a21*a02*a13 + a01*a22*a13 + a11*a02*a23 - a01*a12*a23)/d,
353
(a30*a22*a13 - a20*a32*a13 - a30*a12*a23 + a10*a32*a23 + a20*a12*a33 - a10*a22*a33)/d,
354
(a20*a32*a03 - a30*a22*a03 + a30*a02*a23 - a00*a32*a23 - a20*a02*a33 + a00*a22*a33)/d,
355
(a30*a12*a03 - a10*a32*a03 - a30*a02*a13 + a00*a32*a13 + a10*a02*a33 - a00*a12*a33)/d,
356
(a10*a22*a03 - a20*a12*a03 + a20*a02*a13 - a00*a22*a13 - a10*a02*a23 + a00*a12*a23)/d,
357
(a20*a31*a13 - a30*a21*a13 + a30*a11*a23 - a10*a31*a23 - a20*a11*a33 + a10*a21*a33)/d,
358
(a30*a21*a03 - a20*a31*a03 - a30*a01*a23 + a00*a31*a23 + a20*a01*a33 - a00*a21*a33)/d,
359
(a10*a31*a03 - a30*a11*a03 + a30*a01*a13 - a00*a31*a13 - a10*a01*a33 + a00*a11*a33)/d,
360
(a20*a11*a03 - a10*a21*a03 - a20*a01*a13 + a00*a21*a13 + a10*a01*a23 - a00*a11*a23)/d,
361
(a30*a21*a12 - a20*a31*a12 - a30*a11*a22 + a10*a31*a22 + a20*a11*a32 - a10*a21*a32)/d,
362
(a20*a31*a02 - a30*a21*a02 + a30*a01*a22 - a00*a31*a22 - a20*a01*a32 + a00*a21*a32)/d,
363
(a30*a11*a02 - a10*a31*a02 - a30*a01*a12 + a00*a31*a12 + a10*a01*a32 - a00*a11*a32)/d,
364
(a10*a21*a02 - a20*a11*a02 + a20*a01*a12 - a00*a21*a12 - a10*a01*a22 + a00*a11*a22)/d]
368
* multiplies two mat4's
369
* @returns {GLGE.Mat} the matrix multiplication of the matrices
371
GLGE.mulMat4Vec4=function(mat1,vec2){
372
return GLGE.Vec4(mat1[0]*vec2[0]+mat1[1]*vec2[1]+mat1[2]*vec2[2]+mat1[3]*vec2[3],
373
mat1[4]*vec2[0]+mat1[5]*vec2[1]+mat1[6]*vec2[2]+mat1[7]*vec2[3],
374
mat1[8]*vec2[0]+mat1[9]*vec2[1]+mat1[10]*vec2[2]+mat1[11]*vec2[3],
375
mat1[12]*vec2[0]+mat1[13]*vec2[1]+mat1[14]*vec2[2]+mat1[15]*vec2[3]);
379
* multiplies a Mat4 by a scalar value
380
* @returns {GLGE.Mat} the matrix multiplication of the matrices
382
GLGE.scaleMat4=function(m,value) {
383
return GLGE.Mat([m[0]*value,m[1]*value,m[2]*value,m[3]*value,
384
m[4]*value,m[5]*value,m[6]*value,m[7]*value,
385
m[8]*value,m[9]*value,m[10]*value,m[11]*value,
386
m[12]*value,m[13]*value,m[14]*value,m[15]*value]);
389
* multiplies a Mat4 by a scalar value in place without allocation
390
* @returns {GLGE.Mat} the input matrix, modified
392
GLGE.scaleInPlaceMat4=function(m,value) {
403
m.set(10,m[10]*value);
404
m.set(11,m[11]*value);
405
m.set(12,m[12]*value);
406
m.set(13,m[13]*value);
407
m.set(14,m[14]*value);
408
m.set(15,m[15]*value);
413
* adds a Mat4 to another Mat4 in place without allocation
414
* @returns {GLGE.Mat} the first input matrix, modified to be added
416
GLGE.addInPlaceMat4=function(m,value) {
417
m.set(0,m[0]+value[0]);
418
m.set(1,m[1]+value[1]);
419
m.set(2,m[2]+value[2]);
420
m.set(3,m[3]+value[3]);
421
m.set(4,m[4]+value[4]);
422
m.set(5,m[5]+value[5]);
423
m.set(6,m[6]+value[6]);
424
m.set(7,m[7]+value[7]);
425
m.set(8,m[8]+value[8]);
426
m.set(9,m[9]+value[9]);
427
m.set(10,m[10]+value[10]);
428
m.set(11,m[11]+value[11]);
429
m.set(12,m[12]+value[12]);
430
m.set(13,m[13]+value[13]);
431
m.set(14,m[14]+value[14]);
432
m.set(15,m[15]+value[15]);
439
* adds two Mat4 together
440
* @returns {GLGE.Mat} a new, added Mat4
442
GLGE.addMat4=function(m,value) {
443
return GLGE.Mat([m[0]+value[0],
465
* subs a Mat4 from another Mat4 in place without allocation
466
* @returns {GLGE.Mat} the first input matrix, modified to have the second subtacted
468
GLGE.subInPlaceMat4=function(m,value) {
469
m.set(0,m[0]-value[0]);
470
m.set(1,m[1]-value[1]);
471
m.set(2,m[2]-value[2]);
472
m.set(3,m[3]-value[3]);
473
m.set(4,m[4]-value[4]);
474
m.set(5,m[5]-value[5]);
475
m.set(6,m[6]-value[6]);
476
m.set(7,m[7]-value[7]);
477
m.set(8,m[8]-value[8]);
478
m.set(9,m[9]-value[9]);
479
m.set(10,m[10]-value[10]);
480
m.set(11,m[11]-value[11]);
481
m.set(12,m[12]-value[12]);
482
m.set(13,m[13]-value[13]);
483
m.set(14,m[14]-value[14]);
484
m.set(15,m[15]-value[15]);
491
* subtracts the second matrix from the first
492
* @returns {GLGE.Mat} a new, subed Mat4
494
GLGE.subMat4=function(m,value) {
495
return GLGE.Mat([m[0]-value[0],
516
* Finds the matrix multiplication with another GLGE.Mat or GLGE.vec or an Array of length 3-4
517
* @param {object} value An GLGE.Mat, GLGE.vec or Array
518
* @returns {GLGE.Mat|GLGE.Vec}
520
GLGE.mulMat4=function(mat2,mat1){
522
var a00 = mat1[0], a01 = mat1[1], a02 = mat1[2], a03 = mat1[3];
523
var a10 = mat1[4], a11 = mat1[5], a12 = mat1[6], a13 = mat1[7];
524
var a20 = mat1[8], a21 = mat1[9], a22 = mat1[10], a23 = mat1[11];
525
var a30 = mat1[12], a31 = mat1[13], a32 = mat1[14], a33 = mat1[15];
527
var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3];
528
var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7];
529
var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11];
530
var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15];
531
return [b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
532
b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
533
b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
534
b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33,
536
b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
537
b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
538
b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
539
b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,
541
b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
542
b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
543
b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
544
b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,
546
b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
547
b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
548
b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
549
b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33];
552
GLGE.transposeInPlaceMat4=function(m) {
582
* Builds the transpose of the matrix
583
* @returns {GLGE.Mat} the transposed matrix
585
GLGE.transposeMat4=function(m) {
586
return GLGE.Mat4([m[0],m[4],m[8],m[12],
587
m[1],m[5],m[9],m[13],
588
m[2],m[6],m[10],m[14],
589
m[3],m[7],m[11],m[15]]);
593
* copys a js array into a webglarray
594
* @param {array} mat the source array
595
* @param {webglarray} glarray the destination array
597
GLGE.mat4gl=function(mat,glarray){
617
* Sets the value at the specified index
618
* @param {number} i the first index 1 offset
619
* @param {number} j the second index 1 offset
620
* @param {number} value the value to set
622
GLGE.set1basedMat4=function(m,i,j,value){
623
m[(i-1)*4+(j-1)]=value;
624
if(m.glData!==undefined){
630
* Sets the value at the specified index
631
* @param {number} i the first index from zero
632
* @param {number} j the second index from zero
633
* @param {number} value the value to set
635
GLGE.setMat4=function(m,i,j,value){
637
if(m.glData!==undefined){
643
* Gets the value at the specified index
644
* @param {number} i the first index from one
645
* @param {number} j the second index from one
646
* @returns {number} the value at the given index
648
GLGE.get1basedMat4=function(m,i,j){
649
return m.get((i-1)*4+(j-1));
653
* Gets the value at the specified index
654
* @param {number} i the first index from zero
655
* @param {number} j the second index from zero
656
* @returns {number} the value at the given index
658
GLGE.getMat4=function(m,i,j){
662
* gets the a webgl float array for this Matrix, once generated it will cache it so it doesn't need to recreate everytime
663
* @returns {Float32Array} the webgl array for this Matrix
666
GLGE.glDataMat4=function(m) {
667
m.glArray=new Float32Array(m);
671
* Creates an identity matrix
672
* @returns {GLGE.Mat} the identity matrix
674
GLGE.identMatrix=function(){
675
return GLGE.Mat([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);
678
* Creates a translation matrix
679
* @returns {Array} value an array GLGE.Vec or 3 paramters
680
* @returns {GLGE.Mat} the translation matrix
682
GLGE.translateMatrix=function(value){
686
if(arguments.length==3){
696
else if(value instanceof Array){
709
* Creates a scale matrix
710
* @returns {Array} value an array GLGE.Vec or 3 paramters
711
* @returns {GLGE.Mat} the scale matrix
713
GLGE.scaleMatrix=function(value){
717
if(arguments.length==3){
727
else if(value instanceof Array){
741
* @description Enum for XYZ rotation order
746
* @description Enum for XZY rotation order
751
* @description Enum for YXZ rotation order
756
* @description Enum for YZX rotation order
761
* @description Enum for ZXY rotation order
766
* @description Enum for ZYX rotation order
770
* Creates a rotation matrix
771
* @returns {Array} value an array GLGE.Vec or 3 paramters
772
* @returns {GLGE.Mat} the rotation matrix
774
GLGE.rotateMatrix=function(value,type) {
778
if(arguments.length>2){
789
else if(value instanceof Array){
794
if(!type) type=GLGE.ROT_XYZ;
795
var cosx=Math.cos(x);
796
var sinx=Math.sin(x);
797
var cosy=Math.cos(y);
798
var siny=Math.sin(y);
799
var cosz=Math.cos(z);
800
var sinz=Math.sin(z);
801
var rotx=GLGE.Mat([1,0,0,0,0,cosx,-sinx,0,0,sinx,cosx,0,0,0,0,1]);
802
var roty=GLGE.Mat([cosy,0,siny,0,0,1,0,0,-siny,0,cosy,0,0,0,0,1]);
803
var rotz=GLGE.Mat([cosz,-sinz,0,0,sinz,cosz,0,0,0,0,1,0,0,0,0,1]);
806
return GLGE.mulMat4(rotx,GLGE.mulMat4(roty,rotz));
809
return GLGE.mulMat4(rotx,GLGE.mulMat4(rotz,roty));
812
return GLGE.mulMat4(roty,GLGE.mulMat4(rotx,rotz));
815
return GLGE.mulMat4(roty,GLGE.mulMat4(rotz,rotx));
818
return GLGE.mulMat4(rotz,GLGE.mulMat4(rotx,roty));
821
return GLGE.mulMat4(rotz,GLGE.mulMat4(roty,rotx));
827
GLGE.angleAxis=function(angle, axis) {
828
var xmx,ymy,zmz,xmy,ymz,zmx,xms,yms,zms;
829
axis=[axis[0],axis[1],axis[2],0];
836
var cos = Math.cos(angle);
837
var cosi = 1.0 - cos;
838
var sin = Math.sin(angle);
840
xms = x * sin;yms = y * sin;zms = z * sin;
841
xmx = x * x;ymy = y * y;zmz = z * z;
842
xmy = x * y;ymz = y * z;zmx = z * x;
844
var matrix = [(cosi * xmx) + cos,(cosi * xmy) - zms,(cosi * zmx) + yms,0,
845
(cosi * xmy) + zms,(cosi * ymy) + cos,(cosi * ymz) - xms,0,
846
(cosi * zmx) - yms,(cosi * ymz) + xms,(cosi * zmz) + cos,0,
849
return GLGE.Mat(matrix);
852
GLGE.quatRotation=function(qx,qy,qz,qw){
854
1 - 2*qy*qy - 2*qz*qz,2*qx*qy - 2*qz*qw,2*qx*qz + 2*qy*qw,0,
855
2*qx*qy + 2*qz*qw,1 - 2*qx*qx - 2*qz*qz,2*qy*qz - 2*qx*qw,0,
856
2*qx*qz - 2*qy*qw,2*qy*qz + 2*qx*qw,1 - 2*qx*qx - 2*qy*qy,0,
861
GLGE.makeOrtho=function(left,right,bottom,top,near,far){
862
var x = -(right+left)/(right-left);
863
var y = -(top+bottom)/(top-bottom);
864
var z = -(far+near)/(far-near);
866
return GLGE.Mat([2/(right-left), 0, 0, x,
867
0, 2/(top-bottom), 0, y,
868
0, 0, -2/(far-near), z,
872
GLGE.makeFrustum=function(left,right,bottom,top,near,far){
873
var x = 2*near/(right-left);
874
var y = 2*near/(top-bottom);
875
var a = (right+left)/(right-left);
876
var b = (top+bottom)/(top-bottom);
877
var c = -(far+near)/(far-near);
878
var d = -2*far*near/(far-near);
879
return GLGE.Mat([x, 0, a, 0,
885
GLGE.makePerspective=function(fovy, aspect, near, far){
886
var ymax = near * Math.tan(fovy * 0.00872664625972);
888
var xmin = ymin * aspect;
889
var xmax = ymax * aspect;
890
return GLGE.makeFrustum(xmin, xmax, ymin, ymax, near, far);
893
GLGE.matrix2Scale=function(m){
903
var scaleX=Math.sqrt(m1*m1+m2*m2+m3*m3);
904
var scaleY=Math.sqrt(m4*m4+m5*m5+m6*m6);
905
var scaleZ=Math.sqrt(m7*m7+m8*m8+m9*m9);
906
return [scaleX,scaleY,scaleZ]
910
GLGE.rotationMatrix2Quat=function(m){
911
var tr = m[0] + m[5] + m[10]+1.0;
915
S = 0.5/Math.sqrt(tr);
917
x = (m[9] - m[6]) * S;
918
y = (m[2] - m[8]) * S;
919
z = (m[4] - m[1]) * S;
920
} else if ((m[0] > m[5])&&(m[0] > m[10])) {
921
S = Math.sqrt(1.0 + m[0] - m[5] - m[10]) * 2;
922
w = (m[9] - m[6]) / S;
924
y = (m[1] + m[4]) / S;
925
z = (m[2] + m[8]) / S;
926
} else if (m[5] > m[10]) {
927
S = Math.sqrt(1.0 + m[5] - m[0] - m[10]) * 2;
928
w = (m[2] - m[8]) / S;
929
x = (m[1] + m[4]) / S;
931
z = (m[6] + m[9]) / S;
933
S = Math.sqrt(1.0 + m[10] - m[0] - m[5]) * 2;
934
w = (m[4] - m[1]) / S;
935
x = (m[2] + m[8]) / S;
936
y = (m[6] + m[9]) / S;
939
var N=Math.sqrt(x*x+y*y+z*z+w*w)
941
return [x/N,y/N,z/N,w/N];
946
//returns plane as array [X,Y,Z,D]
947
GLGE.rayToPlane=function(origin,dir){
948
var dirnorm=GLGE.toUnitVec3(dir);
949
return [dirnorm[0],dirnorm[1],dirnorm[2],GLGE.dotVec3(origin,dirnorm)];
952
GLGE.rayIntersectPlane=function(origin,dir,plane){
953
var planeN=[plane[0],plane[1],plane[2]];
955
var vdir=GLGE.dotVec3(planeN,dir);
957
//ray in wrong direction
960
var vo=-(GLGE.dotVec3(planeN,origin)+planeD);
965
return GLGE.addVec3(origin,GLGE.scaleVec3(dir,t));
967
//assumes perspective projection
968
GLGE.screenToDirection=function(x,y,width,height,proj){
969
xcoord = -( ( ( 2 * x ) / width ) - 1 ) / proj[0];
970
ycoord =( ( ( 2 * y ) / height ) - 1 ) / proj[5];
972
return GLGE.toUnitVec3([xcoord,ycoord,zcoord]);
975
GLGE.BoundingVolume=function(minX,maxX,minY,maxY,minZ,maxZ){
976
var dims=[maxX-minX,maxY-minY,maxZ-minZ];
978
this.center=[dims[0]/2+minX,dims[1]/2+minY,dims[2]/2+minZ];
981
//returns the center of the bounding area
982
GLGE.BoundingVolume.prototype.getCenter=function(matrix){
983
return GLGE.mulMat4Vec4(matrix,this.center);
987
GLGE.BoundingVolume.prototype.getBoxPoint=function(matrix,point){
988
var coord=[this.dims[0]/2*point[0]+this.center[0],this.dims[1]/2*point[1]+this.center[1],this.dims[2]/2*point[2]+this.center[2]];
989
return GLGE.mulMat4Vec4(matrix,coord);
992
//returns the radius of a bounding sphere
993
GLGE.BoundingVolume.prototype.getSphereRadius=function(){
994
return Math.pow((this.dims[0]*this.dims[0]+this.dims[1]*this.dims[1]+this.dims[2]*this.dims[2])/4,0.5);
997
//adds an additional bounding volume to resize the current and returns the result
998
GLGE.BoundingVolume.prototype.addBoundingVolume=function(vol){
999
var minX=Math.min(this.center[0]-this.dims[0]/2,vol.center[0]-vol.dims[0]/2);
1000
var maxX=Math.max(this.center[0]+this.dims[0]/2,vol.center[0]+vol.dims[0]/2);
1001
var minY=Math.min(this.center[1]-this.dims[1]/2,vol.center[1]-vol.dims[1]/2);
1002
var maxY=Math.max(this.center[1]+this.dims[1]/2,vol.center[1]+vol.dims[1]/2);
1003
var minZ=Math.min(this.center[2]-this.dims[2]/2,vol.center[2]-vol.dims[2]/2);
1004
var maxZ=Math.max(this.center[2]+this.dims[2]/2,vol.center[2]+vol.dims[2]/2);
1005
var dims=[maxX-minX,maxY-minY,maxZ-minZ];
1007
this.center=[dims[0]/2+minX,dims[1]/2+minY,dims[2]/2+minZ];
1010
//scales a volume based on a transform matrix
1011
GLGE.BoundingVolume.prototype.applyMatrixScale=function(matrix){
1012
var scaleX=GLGE.lengthVec3([matrix[0],matrix[4],matrix[8]]);
1013
var scaleY=GLGE.lengthVec3([matrix[1],matrix[5],matrix[9]]);
1014
var scaleZ=GLGE.lengthVec3([matrix[2],matrix[6],matrix[10]]);
1015
var minX=(this.center[0]-this.dims[0]/2)*scaleX;
1016
var maxX=(this.center[0]+this.dims[0]/2)*scaleX;
1017
var minY=(this.center[1]-this.dims[1]/2)*scaleY;
1018
var maxY=(this.center[1]+this.dims[1]/2)*scaleY;
1019
var minZ=(this.center[2]-this.dims[2]/2)*scaleZ;
1020
var maxZ=(this.center[2]+this.dims[2]/2)*scaleZ;
1021
var dims=[maxX-minX,maxY-minY,maxZ-minZ];
1023
this.center=[dims[0]/2+minX,dims[1]/2+minY,dims[2]/2+minZ];
1026
GLGE.BoundingVolume.prototype.clone=function(){
1027
var minX=this.center[0]-this.dims[0]/2;
1028
var maxX=this.center[0]+this.dims[0]/2;
1029
var minY=this.center[1]-this.dims[1]/2;
1030
var maxY=this.center[1]+this.dims[1]/2;
1031
var minZ=this.center[2]-this.dims[2]/2;
1032
var maxZ=this.center[2]+this.dims[2]/2;
1033
return new GLGE.BoundingVolume(minX,maxX,minY,maxY,minZ,maxZ);
1036
GLGE.BoundingVolume.prototype.toString=function(){
1037
var minX=this.center[0]-this.dims[0]/2;
1038
var maxX=this.center[0]+this.dims[0]/2;
1039
var minY=this.center[1]-this.dims[1]/2;
1040
var maxY=this.center[1]+this.dims[1]/2;
1041
var minZ=this.center[2]-this.dims[2]/2;
1042
var maxZ=this.center[2]+this.dims[2]/2;
1043
return [minX,maxX,minY,maxY,minZ,maxZ].toString();
1047
function GLGE_mathUnitTest() {
1048
var a=GLGE.Vec([1,2,3,4]);
1049
var b=GLGE.Vec4(GLGE.getVec4(a,3),
1050
GLGE.get1basedVec4(a,3),
1053
var c=GLGE.identMatrix();
1054
var d=GLGE.mulMat4Vec4(c,b);
1055
if (GLGE.getVec4(d,0)!=4||
1056
GLGE.getVec4(d,1)!=3||
1057
GLGE.getVec4(d,2)!=2||
1058
GLGE.getVec4(d,3)!=1) {
1059
throw "Unit Test 1 failed MatVecMul "+d;
1061
var m=GLGE.Mat4([3,4,5,0,.5,.75,0,0,.75,.5,0,0,.25,.25,1,1]);
1062
var m1=GLGE.Mat4([2,1,8,2,1,4,3,2,1,.5,6.5,2,8,3,1,.25]);
1063
var mm1=GLGE.mulMat4(m,m1);
1064
var am1=GLGE.Mat4([15,21.5,68.5,24,
1067
9.75,4.75,10.25,3.25]);
1068
for (var i=0;i<4;++i) {
1069
for (var j=0;j<4;++j) {
1070
var diff=GLGE.getMat4(mm1,i,j)-GLGE.getMat4(am1,i,j);
1071
if (diff<.000001&&diff>-.000001) {
1074
throw "Unit Test 1 failed Multiplication "+GLGE.getMat4(mm1,i,j)+" != "+GLGE.getMat4(am1,i,j);
1078
var inv = GLGE.inverseMat4(m);
1079
var k = GLGE.mulMat4(m,inv);
1080
var l = GLGE.mulMat4(inv,m);
1081
for (var i=0;i<4;++i) {
1082
for (var j=0;j<4;++j) {
1083
var diff=GLGE.getMat4(k,i,j)-GLGE.getMat4(c,i,j);
1084
if (diff<.0001&&diff>-.0001) {
1086
throw "Unit Test 1 failed Inverse "+GLGE.getMat4(k,i,j)+" != "+GLGE.getMat4(c,i,j);
1091
GLGE_mathUnitTest() ;
1095
GLGE["Vec3"]=GLGE.Vec3;
1096
GLGE["Vec4"]=GLGE.Vec4;
1097
GLGE["get1basedVec4"]=GLGE.get1basedVec4;
1098
GLGE["get1basedVec3"]=GLGE.get1basedVec3;
1099
GLGE["getVec4"]=GLGE.getVec4;
1100
GLGE["getVec3"]=GLGE.getVec3;
1101
GLGE["addVec4"]=GLGE.addVec4;
1102
GLGE["addVec3"]=GLGE.addVec3;
1103
GLGE["subVec4"]=GLGE.subVec4;
1104
GLGE["subVec3"]=GLGE.subVec3;
1105
GLGE["dotVec3"]=GLGE.dotVec3;
1106
GLGE["dotVec4"]=GLGE.dotVec4;
1107
GLGE["scaleVec4"]=GLGE.scaleVec4;
1108
GLGE["scaleVec3"]=GLGE.scaleVec3;
1109
GLGE["crossVec3"]=GLGE.crossVec3;
1110
GLGE["toUnitVec3"]=GLGE.toUnitVec3;
1111
GLGE["toUnitVec4"]=GLGE.toUnitVec4;
1112
GLGE["lengthVec3"]=GLGE.lengthVec3;
1113
GLGE["distanceVec3"]=GLGE.distanceVec3;
1114
GLGE["lengthVec4"]=GLGE.lengthVec4;
1115
GLGE["distanceVec4"]=GLGE.distanceVec4;
1116
GLGE["angleVec3"]=GLGE.angleVec3;
1117
GLGE["angleVec4"]=GLGE.angleVec4;
1118
GLGE["Mat3"]=GLGE.Mat3;
1119
GLGE["Mat"]=GLGE.Mat;
1120
GLGE["Mat4"]=GLGE.Mat4;
1121
GLGE["determinantMat4"]=GLGE.determinantMat4;
1122
GLGE["inverseMat4"]=GLGE.inverseMat4;
1123
GLGE["mulMat4Vec4"]=GLGE.mulMat4Vec4;
1124
GLGE["scaleMat4"]=GLGE.scaleMat4;
1125
GLGE["scaleInPlaceMat4"]=GLGE.scaleInPlaceMat4;
1126
GLGE["addInPlaceMat4"]=GLGE.addInPlaceMat4;
1127
GLGE["addMat4"]=GLGE.addMat4;
1128
GLGE["subInPlaceMat4"]=GLGE.subInPlaceMat4;
1129
GLGE["subMat4"]=GLGE.subMat4;
1130
GLGE["mulMat4"]=GLGE.mulMat4;
1131
GLGE["transposeInPlaceMat4"]=GLGE.transposeInPlaceMat4;
1132
GLGE["transposeMat4"]=GLGE.transposeMat4;
1133
GLGE["set1basedMat4"]=GLGE.set1basedMat4;
1134
GLGE["setMat4"]=GLGE.setMat4;
1135
GLGE["get1basedMat4"]=GLGE.get1basedMat4;
1136
GLGE["getMat4"]=GLGE.getMat4;
1137
GLGE["glDataMat4"]=GLGE.glDataMat4;
1138
GLGE["identMatrix"]=GLGE.identMatrix;
1139
GLGE["translateMatrix"]=GLGE.translateMatrix;
1140
GLGE["scaleMatrix"]=GLGE.scaleMatrix;
1141
GLGE["ROT_XYZ"]=GLGE.ROT_XYZ;
1142
GLGE["ROT_XZY"]=GLGE.ROT_XZY;
1143
GLGE["ROT_YXZ"]=GLGE.ROT_YXZ;
1144
GLGE["ROT_YZX"]=GLGE.ROT_YZX;
1145
GLGE["ROT_ZXY"]=GLGE.ROT_ZXY;
1146
GLGE["ROT_ZYX"]=GLGE.ROT_ZYX;
1147
GLGE["rotateMatrix"]=GLGE.rotateMatrix;
1148
GLGE["angleAxis"]=GLGE.angleAxis;
1149
GLGE["quatRotation"]=GLGE.quatRotation;
1150
GLGE["makeOrtho"]=GLGE.makeOrtho;
1151
GLGE["makeFrustum"]=GLGE.makeFrustum;
1152
GLGE["makePerspective"]=GLGE.makePerspective;
1153
GLGE["matrix2Scale"]=GLGE.matrix2Scale;
1154
GLGE["rotationMatrix2Quat"]=GLGE.rotationMatrix2Quat;
1155
GLGE["mat4gl"]=GLGE.mat4gl;