From 01909a07f0baba7286f5f9b9adf8b03c8a7146f2 Mon Sep 17 00:00:00 2001 From: hernowoaris <hernowoarisutanto@gmail.com> Date: Thu, 9 Mar 2023 03:08:38 +0700 Subject: [PATCH] Add Common folder --- Common/MV.js | 1178 ++++++++++++++++++++++++++++++++++++++ Common/MVES6.js | 1178 ++++++++++++++++++++++++++++++++++++++ Common/MVnew.js | 1178 ++++++++++++++++++++++++++++++++++++++ Common/flatten.js | 24 + Common/initShaders.js | 61 ++ Common/initShaders2.js | 43 ++ Common/initShaders3.js | 59 ++ Common/initShadersES6.js | 61 ++ Common/utility.js | 78 +++ style.css | 1 + worksheet1.html | 4 +- 11 files changed, 3863 insertions(+), 2 deletions(-) create mode 100644 Common/MV.js create mode 100644 Common/MVES6.js create mode 100644 Common/MVnew.js create mode 100644 Common/flatten.js create mode 100644 Common/initShaders.js create mode 100644 Common/initShaders2.js create mode 100644 Common/initShaders3.js create mode 100644 Common/initShadersES6.js create mode 100644 Common/utility.js diff --git a/Common/MV.js b/Common/MV.js new file mode 100644 index 0000000..10ddecc --- /dev/null +++ b/Common/MV.js @@ -0,0 +1,1178 @@ +////////////////////////////////////////////////////////////////////////////// +// +// MV.js +// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- + +// +// Helper Functions +// +function MVbuffer(size) { + var b = {}; + b.buf = new Float32Array(size); + b.index = 0; + b.push = function(x) { + for(var i=0; i<x.length; i++) { + b.buf[b.index+i] = x[i]; + } + b.index += x.length; + b.type = ''; + } + return b; +} + +function isVector(v) { + if(v.type == "vec2" || v.type == "vec3" || v.type == "vec4") return true; + return false; +} + +function isMatrix(v) { + if(v.type == "mat2" || v.type == "mat3" || v.type == "mat4") return true; + return false; +} + +function radians( degrees ) { + return degrees * Math.PI / 180.0; +} + +//---------------------------------------------------------------------------- + + +function patch() { + var out = new Array(4); + for(var i = 0; i< 4; i++) out[i] = new Array(4); + out.type = "patch"; + return out; +} + +function curve() { + var out = new Array(4); + out.type = "curve"; + return out; +} +// +// Vector Constructors +// + +function vec2() +{ + var out = new Array(2); + out.type = 'vec2'; + + switch ( arguments.length ) { + case 0: + out[0] = 0.0; + out[1] = 0.0; + break; + case 1: + if(isVector(arguments[0] && (arguments[0].type != 'vec2'))) { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + } + break; + + case 2: + out[0] = arguments[0]; + out[1] = arguments[1]; + break; + } + return out; +} + +function vec3() +{ +//var result = _argumentsToArray( arguments ); + + var out = new Array(3); + out.type = 'vec3'; + + switch ( arguments.length ) { + case 0: + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + return out; + case 1: + if(isVector(arguments[0]) && (arguments[0].type == "vec3")) { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + return out; + } + case 3: + out[0] = arguments[0]; + out[1] = arguments[1]; + out[2] = arguments[2]; + return out; + default: + throw "vec3: wrong arguments"; + } + + return out; +} + +function vec4() +{ + var out = new Array(4); + out.type = 'vec4'; + switch ( arguments.length ) { + + case 0: + + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + return out; + + case 1: + if(isVector(arguments[0])) { + if(arguments[0].type == "vec4") { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = arguments[0][3]; + return out; + } + } + else if(arguments[0].type == "vec3") { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = 1.0; + return out; + } + else { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = arguments[0][3]; + return out; + } + + + + case 2: + if(typeof(arguments[0])=='number'&&arguments[1].type == 'vec3') { + out[0] = arguments[0]; + out[1] = arguments[1][0]; + out[2] = arguments[1][1]; + out[3] = arguments[1][2]; + return out; + } + return out; + + case 4: + + if(isVector(arguments[0])) { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = arguments[0][3]; + return out; + } + out[0] = arguments[0]; + out[1] = arguments[1]; + out[2] = arguments[2]; + out[3] = arguments[3]; + return out; + case 3: + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = 1.0; + return out; + default: + throw "vec4: wrong arguments"; + } +} + +//---------------------------------------------------------------------------- +// +// Matrix Constructors +// + +function mat2() +{ + var out = new Array(2); + out[0] = new Array(2); + out[1] = new Array(2); + + switch ( arguments.length ) { + case 0: + out[0][0]=out[3]=1.0; + out[1]=out[2]=0.0; + break; + case 1: + if(arguments[0].type == 'mat2') { + out[0][0] = arguments[0][0][0]; + out[0][1] = arguments[0][0][1]; + out[1][0] = arguments[0][1][0]; + out[1][1] = arguments[0][1][1]; + break; + } + + case 4: + out[0][0] = arguments[0]; + out[0][1] = arguments[1]; + out[1][0] = arguments[2]; + out[1][1] = arguments[3]; + break; + default: + throw "mat2: wrong arguments"; + } + out.type = 'mat2'; + + return out; +} + +//---------------------------------------------------------------------------- + +function mat3() +{ + // v = _argumentsToArray( arguments ); + + var out = new Array(3); + out[0] = new Array(3); + out[1] = new Array(3); + out[2] = new Array(3); + + switch ( arguments.length ) { + case 0: + out[0][0]=out[1][1]=out[2][2]=1.0; + out[0][1]=out[0][2]=out[1][0]=out[1][2]=out[2][0]=out[2][1]=0.0; + break; + case 1: + for(var i=0; i<3; i++) for(var i=0; i<3; i++) { + out[i][j]=arguments[0][3*i+j]; + } + break; + + case 9: + for(var i=0; i<3; i++) for(var j=0; j<3; j++) { + out[i][j] = arguments[3*i+j]; + } + break; + default: + throw "mat3: wrong arguments"; + } + out.type = 'mat3'; + + return out; +} + +//---------------------------------------------------------------------------- + +function mat4() +{ + //var v = _argumentsToArray( arguments ); + + var out = new Array(4); + out[0] = new Array(4); + out[1] = new Array(4); + out[2] = new Array(4); + out[3] = new Array(4); + + switch ( arguments.length ) { + case 0: + out[0][0]=out[1][1]=out[2][2]=out[3][3] = 1.0; + out[0][1]=out[0][2]=out[0][3]=out[1][0]=out[1][2]=out[1][3]=out[2][0]=out[2][1] + =out[2][3]=out[3][0]=out[3][1]=out[3][2]=0.0; + + break; + + case 1: + for(var i=0; i<4; i++) for(var i=0; i<4; i++) { + out[i][j]=arguments[0][4*i+j]; + } + break; + + case 4: + if(arguments[0].type == "vec4") { + for( var i=0; i<4; i++) + for(var j=0; j<4; j++) + out[i][j] = arguments[i][j]; + break; + } + + case 16: + for(var i=0; i<4; i++) for(var j=0; j<4; j++) { + out[i][j] = arguments[4*i+j]; + } + break; + } + out.type = 'mat4'; + + return out; +} + +//---------------------------------------------------------------------------- +// +// Generic Mathematical Operations for Vectors and Matrices +// + +function equal( u, v ) +{ + if(!(isMatrix(u)&&isMatrix(v) || (isVector(u)&&isVector(v)))) + throw "equal: at least one input not a vec or mat"; + if ( u.type != v.type ) throw "equal: types different"; + if(isMatrix(u)) { + for ( var i = 0; i < u.length; ++i ) for ( var j = 0; j < u.length; ++j ) + if ( u[i][j] !== v[i][j] ) return false; + return true; + } + if(isVector(u)) { + for ( var i = 0; i < u.length; ++i ) + if ( u[i] !== v[i] ) return false; + return true; + } +} + + + +//---------------------------------------------------------------------------- + +function add( u, v ) +{ + + if ( u.type != v.type ) { + throw "add(): trying to add different types"; + } + if(isVector(u)){ + var result = new Array(u.length); + result.type = u.type; + for(var i=0; i<u.length; i++) { + result[i] = u[i] + v[i]; + } + return result; + } + if(isMatrix(u)){ + if(u.type == 'mat2') var result = mat2(); + if(u.type == 'mat3') var result = mat3(); + if(u.type == 'mat4') var result = mat4(); + for(var i=0; i<u.length; i++) for(var j=0; j<u.length; j++){ + result[i][j] = u[i][j] + v[i][j]; + } + return result; + } +} + +//---------------------------------------------------------------------------- + +function subtract( u, v ) +{ + + if ( u.type != v.type ) { + throw "add(): trying to add different types"; + } + if(isVector(u)){ + if(u.type == 'vec2') var result =vec2(); + if(u.type == 'vec3') var result = vec3(); + if(u.type == 'vec4') var result = vec4(); + result.type = u.type; + for(var i=0; i<u.length; i++) { + result[i] = u[i] - v[i]; + } + return result; + } + if(isMatrix(u)){ + if(u.type == 'mat2') var result = mat2(); + if(u.type == 'mat3') var result = mat3(); + if(u.type == 'mat4') var result = mat4(); + for(var i=0; i<u.length; i++) for(var j=0; j<u.length; j++){ + result[i][j] = u[i][j] - v[i][j]; + } + return result; + } +} + +//---------------------------------------------------------------------------- + +function mult( u, v ) +{ + + if(typeof(u)=="number" && (isMatrix(v)||isVector(v))) { + + if(isVector(v)){ + result = new Array(v.length); + result.type = v.type; + for(var i =0; i<v.length; i++) { + result[i] = u*v[i]; + } + return result; + } + if(v.type = 'mat2') result = mat2(); + if(v.type = 'mat3') result = mat3(); + if(v.type = 'mat4') result = mat4(); + } + if(u.type=='mat2' && v.type == 'vec2') { + var result = vec2(); + for(i=0;i<2;i++) { + result[i] = 0.0; + for(var k=0;k<2;k++) result[i]+=u[i][k]*v[k]; + } + return result; + } + if(u.type=='mat3'&& v.type=='vec3') { + var result = vec3(); + for(i=0;i<3;i++) { + result[i] = 0.0; + for(var k=0;k<3;k++) result[i]+=u[i][k]*v[k]; + } + return result; + } + if(u.type=='mat4'&& v.type=='vec4') { + var result = vec4(); + for(i=0;i<4;i++) { + result[i] = 0.0; + for(var k=0;k<4;k++) result[i]+=u[i][k]*v[k]; + } + return result; + } + if (u.type=='mat2'&&v.type=='mat2'){ + result = mat2(); + for(i=0;i<2;i++) for(j=0;j<2;j++) { + result[i][j] = 0.0; + for(var k=0;k<2;k++) result[i][j]+=u[i][k]*v[k][j]; + } + return result; + } + if (u.type=='mat3'&&v.type=='mat3'){ + result = mat3(); + for(i=0;i<3;i++) for(j=0;j<3;j++) { + result[i][j] = 0.0; + for(var k=0;k<3;k++) result[i][j]+=u[i][k]*v[k][j]; + } + return result; + } + else if (u.type=='mat4'&&v.type=='mat4'){ + result = mat4(); + for(i=0;i<4;i++) for(j=0;j<4;j++) { + result[i][j] = 0.0; + for(var k=0;k<4;k++) result[i][j]+=u[i][k]*v[k][j]; + } + + return result; + } + if (u.type=='vec3'&&v.type=='vec3'){ + var result = vec3(u[0]*v[0], u[1]*v[1], u[2]*v[2]); + return result; + } + if (u.type=='vec4'&&v.type=='vec4'){ + var result = vec4(u[0]*v[0], u[1]*v[1], u[2]*v[2], u[3]*v[3]); + return result; + } + throw "mult(): trying to mult incompatible types"; +} + + +//---------------------------------------------------------------------------- +// +// Basic Transformation Matrix Generators +// + +function translate( x, y, z ) +{ + if(arguments.length!=2 && arguments.length != 3) { + throw "translate(): not a mat3 or mat4"; + } + if(arguments.length == 2) { + result = mat3(); + result[0][2] = x; + result[1][2] = y; + + return result; + } + result = mat4(); + + result[0][3] = x; + result[1][3] = y; + result[2][3] = z; + + return result; + +} + +//---------------------------------------------------------------------------- + +function rotate( angle, axis ) +{ + if ( axis.length == 3 ) { + axis = vec3(axis[0], axis[1], axis[2] ); + } + if(arguments.length == 4) { + axis = vec3(arguments[1], arguments[2], arguments[3]); + } + if(axis.type != 'vec3') throw "rotate: axis not a vec3"; + var v = normalize( axis ); + + var x = v[0]; + var y = v[1]; + var z = v[2]; + + var c = Math.cos( radians(angle) ); + var omc = 1.0 - c; + var s = Math.sin( radians(angle) ); + + var result = mat4( + x*x*omc + c, x*y*omc + z*s, x*z*omc - y*s, 0.0 , + x*y*omc - z*s, y*y*omc + c, y*z*omc + x*s, 0.0 , + x*z*omc + y*s, y*z*omc - x*s, z*z*omc + c, 0.0 , + 0.0, 0.0, 0.0, 1.0 + ); + return result; +} + +function rotateX(theta) { + var c = Math.cos( radians(theta) ); + var s = Math.sin( radians(theta) ); + var rx = mat4( 1.0, 0.0, 0.0, 0.0, + 0.0, c, -s, 0.0, + 0.0, s, c, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + return rx; +} +function rotateY(theta) { + var c = Math.cos( radians(theta) ); + var s = Math.sin( radians(theta) ); + var ry = mat4( c, 0.0, s, 0.0, + 0.0, 1.0, 0.0, 0.0, + -s, 0.0, c, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + return ry; +} +function rotateZ(theta) { + var c = Math.cos( radians(theta) ); + var s = Math.sin( radians(theta) ); + var rz = mat4( c, -s, 0.0, 0.0, + s, c, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + return rz; +} +//---------------------------------------------------------------------------- + + +function scale( ) +{ +// legacy code +// should use mult + + if(arguments.length == 2 && isVector(arguments[1])) { + result = new Array(arguments[1].length); + result.type = arguments[1].type; + for(var i=0; i<arguments[1].length; i++) + result[i] = arguments[0]*arguments[1][i]; + return result; + } +// end legacy code + + if(arguments.length == 3) { + + var result = mat4(); + result[0][0] = arguments[0]; + result[1][1] = arguments[1]; + result[2][2] = arguments[2]; + result[3][3] = 1.0; + return result; + } + + throw "scale: wrong arguments"; + +} + + +//---------------------------------------------------------------------------- +// +// ModelView Matrix Generators +// + +function lookAt( eye, at, up ) +{ + if ( eye.type != 'vec3') { + throw "lookAt(): first parameter [eye] must be an a vec3"; + } + + if ( at.type != 'vec3') { + throw "lookAt(): first parameter [at] must be an a vec3"; + } + + if (up.type != 'vec3') { + throw "lookAt(): first parameter [up] must be an a vec3"; + } + + if ( equal(eye, at) ) { + return mat4(); + } + + var v = normalize( subtract(at, eye) ); // view direction vector + var n = normalize( cross(v, up) ); // perpendicular vector + var u = normalize( cross(n, v) ); // "new" up vector + v = negate( v ); + + var result = mat4( + n[0], n[1], n[2], -dot(n, eye), + u[0], u[1], u[2], -dot(u, eye), + v[0], v[1], v[2], -dot(v, eye), + 0.0, 0.0, 0.0, 1.0 + ); + + return result; +} + +//---------------------------------------------------------------------------- +// +// Projection Matrix Generators +// + +function ortho( left, right, bottom, top, near, far ) +{ + if ( left == right ) { throw "ortho(): left and right are equal"; } + if ( bottom == top ) { throw "ortho(): bottom and top are equal"; } + if ( near == far ) { throw "ortho(): near and far are equal"; } + + var w = right - left; + var h = top - bottom; + var d = far - near; + + var result = mat4(); + + result[0][0] = 2.0 / w; + result[1][1] = 2.0 / h; + result[2][2] = -2.0 / d; + + result[0][3] = -(left + right) / w; + result[1][3] = -(top + bottom) / h; + result[2][3] = -(near + far) / d; + result[3][3] = 1.0; + + return result; +} + +//---------------------------------------------------------------------------- + +function perspective( fovy, aspect, near, far ) +{ + var f = 1.0 / Math.tan( radians(fovy) / 2 ); + var d = far - near; + + var result = mat4(); + result[0][0] = f / aspect; + result[1][1] = f; + result[2][2] = -(near + far) / d; + result[2][3] = -2 * near * far / d; + result[3][2] = -1; + result[3][3] = 0.0; + + return result; +} + +//---------------------------------------------------------------------------- +// +// Matrix Functions +// + +function transpose( m ) +{ + if(m.type == 'patch') { + var out = patch() + for(var i=0; i<4; i++) out[i] = new Array(4); + for(var i=0; i<4; i++) + for(var j=0; j<4; j++) out[i][j] = m[j][i]; + return out; + } + + switch(m.type) { + case 'mat2': + var result = mat2(m[0][0], m[1][0], + m[0][1], m[1][1] + ); + return result; + break; + + case 'mat3': + var result = mat3(m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2] + ); + return result; + break; + + case 'mat4': + + var result = mat4(m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3] + ); + + return result; + break; + + default: throw "transpose(): trying to transpose a non-matrix"; + } +} + + +//---------------------------------------------------------------------------- +// +// Vector Functions +// + +function dot( u, v ) +{ + + if ( u.type != v.type ) { + throw "dot(): types are not the same "; + } + if (u.type != 'vec2' && u.type != 'vec3' && u.type != 'vec4') { + throw "dot(): not a vector "; + } + + var sum = 0.0; + for ( var i = 0; i < u.length; i++ ) { + sum += u[i] * v[i]; + } + return sum; +} + +//---------------------------------------------------------------------------- + +function negate( u ) +{ + if (u.type != 'vec2' && u.type != 'vec3' && u.type != 'vec4') { + throw "negate(): not a vector "; + } + var result = new Array(u.length); + result.type = u.type; + for ( var i = 0; i < u.length; ++i ) { + result[i] = -u[i]; + } + return result; +} + +//---------------------------------------------------------------------------- + +function cross( u, v ) +{ + if ( u.type == 'vec3' && v.type == 'vec3') { + var result = vec3( + u[1]*v[2] - u[2]*v[1], + u[2]*v[0] - u[0]*v[2], + u[0]*v[1] - u[1]*v[0] + ); + return result; + } + + if ( v.type == 'vec4' && v.type == 'vec4') { + var result = vec3( + u[1]*v[2] - u[2]*v[1], + u[2]*v[0] - u[0]*v[2], + u[0]*v[1] - u[1]*v[0] + ); + return result; + } + + throw "cross: types aren't matched vec3 or vec4"; +} + +//---------------------------------------------------------------------------- + +function length( u ) +{ + return Math.sqrt( dot(u, u) ); +} + +//---------------------------------------------------------------------------- + +function normalize( u, excludeLastComponent ) +{ + if(u.type != 'vec3' && u.type != 'vec4') { + + throw "normalize: not a vector type"; + } + switch(u.type) { + case 'vec2': + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]); + var result = vec2(u[0]/len, u[1]/len); + return result; + break; + case 'vec3': + if(excludeLastComponent) { + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]); + var result = vec3(u[0]/len, u[1]/len, u[2]); + return result; + break; + } + else { + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]+u[2]*u[2]); + var result = vec3(u[0]/len, u[1]/len, u[2]/len); + return result; + break; + } + case 'vec4': + if(excludeLastComponent) { + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]+u[2]*u[2]); + var result = vec4(u[0]/len, u[1]/len, u[2]/len, u[3]); + return result; + break; + } + else { + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]+u[2]*u[2]+u[3]*u[3]); + var result = vec4(u[0]/len, u[1]/len, u[2]/len, u[3]/len); + return result; + break; + } + } +} + +//---------------------------------------------------------------------------- + +function mix( u, v, s ) +{ + if ( typeof(s) !== "number" ) { + throw "mix: the last paramter " + s + " must be a number"; + } + if(typeof(u)=='number'&&typeof(v)=='number') { + return (1.0-s)*u + s*v; + } + + if ( u.length != v.length ) { + + throw "vector dimension mismatch"; + } + + var result = new Array(u.length); + for ( var i = 0; i < u.length; ++i ) { + result[i] = (1.0 - s) * u[i] + s * v[i] ; + } + result.type = u.type; + return result; +} + +//---------------------------------------------------------------------------- +// +// Vector and Matrix utility functions +// + + +function flatten( v ) +{ + + if(isVector(v)) { + var floats = new Float32Array(v.length) + for(var i =0; i<v.length; i++) floats[i] = v[i]; + return floats; + } + if(isMatrix(v)) { + + var floats = new Float32Array(v.length*v.length); + for(var i =0; i<v.length; i++) for(j=0;j<v.length; j++) { + floats[i*v.length+j] = v[j][i]; + } + return floats; + } + + var floats = new Float32Array( v.length*v[0].length ); + + for(var i = 0; i<v.length; i++) for(var j=0; j<v[0].length; j++) { + floats[i*v[0].length+j] = v[i][j]; + } + return floats; +} + +// +//---------------------------------------------------------------------------- + + +function cut(a) +{ + return Math.round(a*1000)/1000; +} +function printm(m) +{ + switch(m.type) { + case 'mat2': + console.log(cut(m[0][0]), cut(m[0][1])); + console.log(cut(m[1][0]), cut(m[1][1])); + break; + case 'mat3': + console.log(cut(m[0][0]), cut(m[0][1]), cut(m[0][2])); + console.log(cut(m[1][0]), cut(m[1][1]), cut(m[1][2])); + console.log(cut(m[2][0]), cut(m[2][1]), cut(m[2][2])); + break; + case 'mat4': + console.log(cut(m[0][0]), cut(m[0][1]), cut(m[0][2]), cut(m[0][3])); + console.log(cut(m[1][0]), cut(m[1][1]), cut(m[1][2]), cut(m[1][3])); + console.log(cut(m[2][0]), cut(m[2][1]), cut(m[2][2]), cut(m[2][3])); + console.log(cut(m[3][0]), cut(m[3][1]), cut(m[3][2]), cut(m[3][3])); + break; + case 'patch': + for(var i=0;i<4;i++) + console.log(m[i][0], m[i][1], m[i][2], m[i][3]); + break; + default: throw "printm: not a matrix"; + } +} +// determinants + +function det2(m) +{ + + return m[0][0]*m[1][1]-m[0][1]*m[1][0]; + +} + +function det3(m) +{ + var d = m[0][0]*m[1][1]*m[2][2] + + m[0][1]*m[1][2]*m[2][0] + + m[0][2]*m[2][1]*m[1][0] + - m[2][0]*m[1][1]*m[0][2] + - m[1][0]*m[0][1]*m[2][2] + - m[0][0]*m[1][2]*m[2][1] + ; + return d; +} + +function det4(m) +{ + var m0 = [ + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[2][1], m[2][2], m[2][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + var m1 = [ + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[2][0], m[2][2], m[2][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + var m2 = [ + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[2][0], m[2][1], m[2][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + var m3 = [ + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[2][0], m[2][1], m[2][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + return m[0][0]*det3(m0) - m[0][1]*det3(m1) + + m[0][2]*det3(m2) - m[0][3]*det3(m3); + +} + +function det(m) +{ + if(!isMatrix(m)) throw("det: m not a matrix"); + if(m.length == 2) return det2(m); + if(m.length == 3) return det3(m); + if(m.length == 4) return det4(m); +} + + +//--------------------------------------------------------- + +// inverses + +function inverse2(m) +{ + var a = mat2(); + var d = det2(m); + a[0][0] = m[1][1]/d; + a[0][1] = -m[0][1]/d; + a[1][0] = -m[1][0]/d; + a[1][1] = m[0][0]/d; + return a; +} + +function inverse3(m) +{ + var a = mat3(); + var d = det3(m); + + var a00 = [ + vec2(m[1][1], m[1][2]), + vec2(m[2][1], m[2][2]) + ]; + var a01 = [ + vec2(m[1][0], m[1][2]), + vec2(m[2][0], m[2][2]) + ]; + var a02 = [ + vec2(m[1][0], m[1][1]), + vec2(m[2][0], m[2][1]) + ]; + var a10 = [ + vec2(m[0][1], m[0][2]), + vec2(m[2][1], m[2][2]) + ]; + var a11 = [ + vec2(m[0][0], m[0][2]), + vec2(m[2][0], m[2][2]) + ]; + var a12 = [ + vec2(m[0][0], m[0][1]), + vec2(m[2][0], m[2][1]) + ]; + var a20 = [ + vec2(m[0][1], m[0][2]), + vec2(m[1][1], m[1][2]) + ]; + var a21 = [ + vec2(m[0][0], m[0][2]), + vec2(m[1][0], m[1][2]) + ]; + var a22 = [ + vec2(m[0][0], m[0][1]), + vec2(m[1][0], m[1][1]) + ]; + + a[0][0] = det2(a00)/d; + a[0][1] = -det2(a10)/d; + a[0][2] = det2(a20)/d; + a[1][0] = -det2(a01)/d; + a[1][1] = det2(a11)/d; + a[1][2] = -det2(a21)/d; + a[2][0] = det2(a02)/d; + a[2][1] = -det2(a12)/d; + a[2][2] = det2(a22)/d; + + return a; + +} + +function inverse4(m) +{ + var a = mat4(); + var d = det4(m); + + var a00 = [ + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[2][1], m[2][2], m[2][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + var a01 = [ + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[2][0], m[2][2], m[2][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + var a02 = [ + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[2][0], m[2][1], m[2][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + var a03 = [ + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[2][0], m[2][1], m[2][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + var a10 = [ + vec3(m[0][1], m[0][2], m[0][3]), + vec3(m[2][1], m[2][2], m[2][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + var a11 = [ + vec3(m[0][0], m[0][2], m[0][3]), + vec3(m[2][0], m[2][2], m[2][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + var a12 = [ + vec3(m[0][0], m[0][1], m[0][3]), + vec3(m[2][0], m[2][1], m[2][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + var a13 = [ + vec3(m[0][0], m[0][1], m[0][2]), + vec3(m[2][0], m[2][1], m[2][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + var a20 = [ + vec3(m[0][1], m[0][2], m[0][3]), + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + var a21 = [ + vec3(m[0][0], m[0][2], m[0][3]), + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + var a22 = [ + vec3(m[0][0], m[0][1], m[0][3]), + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + var a23 = [ + vec3(m[0][0], m[0][1], m[0][2]), + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + + var a30 = [ + vec3(m[0][1], m[0][2], m[0][3]), + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[2][1], m[2][2], m[2][3]) + ]; + var a31 = [ + vec3(m[0][0], m[0][2], m[0][3]), + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[2][0], m[2][2], m[2][3]) + ]; + var a32 = [ + vec3(m[0][0], m[0][1], m[0][3]), + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[2][0], m[2][1], m[2][3]) + ]; + var a33 = [ + vec3(m[0][0], m[0][1], m[0][2]), + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[2][0], m[2][1], m[2][2]) + ]; + + + + a[0][0] = det3(a00)/d; + a[0][1] = -det3(a10)/d; + a[0][2] = det3(a20)/d; + a[0][3] = -det3(a30)/d; + a[1][0] = -det3(a01)/d; + a[1][1] = det3(a11)/d; + a[1][2] = -det3(a21)/d; + a[1][3] = det3(a31)/d; + a[2][0] = det3(a02)/d; + a[2][1] = -det3(a12)/d; + a[2][2] = det3(a22)/d; + a[2][3] = -det3(a32)/d; + a[3][0] = -det3(a03)/d; + a[3][1] = det3(a13)/d; + a[3][2] = -det3(a23)/d; + a[3][3] = det3(a33)/d; + + return a; +} +function inverse(m) +{ + if(!isMatrix(m)) throw("inverse: m not a matrix"); + if(m.length == 2) return inverse2(m); + if(m.length == 3) return inverse3(m); + if(m.length == 4) return inverse4(m); +} + +//--------------------------------------------------------- + +// normal matrix + + +function normalMatrix(m, flag) +{ + if(m.type!='mat4') throw "normalMatrix: input not a mat4"; + var a = inverse(transpose(m)); + if(arguments.length == 1 &&flag == false) return a; + + var b = mat3(); + for(var i=0;i<3;i++) for(var j=0; j<3; j++) b[i][j] = a[i][j]; + + return b; +} diff --git a/Common/MVES6.js b/Common/MVES6.js new file mode 100644 index 0000000..7d0e0c2 --- /dev/null +++ b/Common/MVES6.js @@ -0,0 +1,1178 @@ +////////////////////////////////////////////////////////////////////////////// +// +// MV.js +// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- + +// +// Helper Functions +// +function MVbuffer(size) { + let b = {}; + b.buf = new Float32Array(size); + b.index = 0; + b.push = function(x) { + for(let i=0; i<x.length; i++) { + b.buf[b.index+i] = x[i]; + } + b.index += x.length; + b.type = ''; + } + return b; +} + +function isVector(v) { + if(v.type == "vec2" || v.type == "vec3" || v.type == "vec4") return true; + return false; +} + +function isMatrix(v) { + if(v.type == "mat2" || v.type == "mat3" || v.type == "mat4") return true; + return false; +} + +function radians( degrees ) { + return degrees * Math.PI / 180.0; +} + +//---------------------------------------------------------------------------- + + +function patch() { + let out = new Array(4); + for(let i = 0; i< 4; i++) out[i] = new Array(4); + out.type = "patch"; + return out; +} + +function curve() { + let out = new Array(4); + out.type = "curve"; + return out; +} +// +// Vector Constructors +// + +function vec2() +{ + let out = new Array(2); + out.type = 'vec2'; + + switch ( arguments.length ) { + case 0: + out[0] = 0.0; + out[1] = 0.0; + break; + case 1: + if(isVector(arguments[0] && (arguments[0].type != 'vec2'))) { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + } + break; + + case 2: + out[0] = arguments[0]; + out[1] = arguments[1]; + break; + } + return out; +} + +function vec3() +{ +//let result = _argumentsToArray( arguments ); + + let out = new Array(3); + out.type = 'vec3'; + + switch ( arguments.length ) { + case 0: + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + return out; + case 1: + if(isVector(arguments[0]) && (arguments[0].type == "vec3")) { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + return out; + } + case 3: + out[0] = arguments[0]; + out[1] = arguments[1]; + out[2] = arguments[2]; + return out; + default: + throw "vec3: wrong arguments"; + } + + return out; +} + +function vec4() +{ + let out = new Array(4); + out.type = 'vec4'; + switch ( arguments.length ) { + + case 0: + + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + return out; + + case 1: + if(isVector(arguments[0])) { + if(arguments[0].type == "vec4") { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = arguments[0][3]; + return out; + } + } + else if(arguments[0].type == "vec3") { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = 1.0; + return out; + } + else { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = arguments[0][3]; + return out; + } + + + + case 2: + if(typeof(arguments[0])=='number'&&arguments[1].type == 'vec3') { + out[0] = arguments[0]; + out[1] = arguments[1][0]; + out[2] = arguments[1][1]; + out[3] = arguments[1][2]; + return out; + } + return out; + + case 4: + + if(isVector(arguments[0])) { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = arguments[0][3]; + return out; + } + out[0] = arguments[0]; + out[1] = arguments[1]; + out[2] = arguments[2]; + out[3] = arguments[3]; + return out; + case 3: + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = 1.0; + return out; + default: + throw "vec4: wrong arguments"; + } +} + +//---------------------------------------------------------------------------- +// +// Matrix Constructors +// + +function mat2() +{ + let out = new Array(2); + out[0] = new Array(2); + out[1] = new Array(2); + + switch ( arguments.length ) { + case 0: + out[0][0]=out[3]=1.0; + out[1]=out[2]=0.0; + break; + case 1: + if(arguments[0].type == 'mat2') { + out[0][0] = arguments[0][0][0]; + out[0][1] = arguments[0][0][1]; + out[1][0] = arguments[0][1][0]; + out[1][1] = arguments[0][1][1]; + break; + } + + case 4: + out[0][0] = arguments[0]; + out[0][1] = arguments[1]; + out[1][0] = arguments[2]; + out[1][1] = arguments[3]; + break; + default: + throw "mat2: wrong arguments"; + } + out.type = 'mat2'; + + return out; +} + +//---------------------------------------------------------------------------- + +function mat3() +{ + // v = _argumentsToArray( arguments ); + + let out = new Array(3); + out[0] = new Array(3); + out[1] = new Array(3); + out[2] = new Array(3); + + switch ( arguments.length ) { + case 0: + out[0][0]=out[1][1]=out[2][2]=1.0; + out[0][1]=out[0][2]=out[1][0]=out[1][2]=out[2][0]=out[2][1]=0.0; + break; + case 1: + for(let i=0; i<3; i++) for(let i=0; i<3; i++) { + out[i][j]=arguments[0][3*i+j]; + } + break; + + case 9: + for(let i=0; i<3; i++) for(let j=0; j<3; j++) { + out[i][j] = arguments[3*i+j]; + } + break; + default: + throw "mat3: wrong arguments"; + } + out.type = 'mat3'; + + return out; +} + +//---------------------------------------------------------------------------- + +function mat4() +{ + //let v = _argumentsToArray( arguments ); + + let out = new Array(4); + out[0] = new Array(4); + out[1] = new Array(4); + out[2] = new Array(4); + out[3] = new Array(4); + + switch ( arguments.length ) { + case 0: + out[0][0]=out[1][1]=out[2][2]=out[3][3] = 1.0; + out[0][1]=out[0][2]=out[0][3]=out[1][0]=out[1][2]=out[1][3]=out[2][0]=out[2][1] + =out[2][3]=out[3][0]=out[3][1]=out[3][2]=0.0; + + break; + + case 1: + for(let i=0; i<4; i++) for(let i=0; i<4; i++) { + out[i][j]=arguments[0][4*i+j]; + } + break; + + case 4: + if(arguments[0].type == "vec4") { + for( let i=0; i<4; i++) + for(let j=0; j<4; j++) + out[i][j] = arguments[i][j]; + break; + } + + case 16: + for(let i=0; i<4; i++) for(let j=0; j<4; j++) { + out[i][j] = arguments[4*i+j]; + } + break; + } + out.type = 'mat4'; + + return out; +} + +//---------------------------------------------------------------------------- +// +// Generic Mathematical Operations for Vectors and Matrices +// + +function equal( u, v ) +{ + if(!(isMatrix(u)&&isMatrix(v) || (isVector(u)&&isVector(v)))) + throw "equal: at least one input not a vec or mat"; + if ( u.type != v.type ) throw "equal: types different"; + if(isMatrix(u)) { + for ( let i = 0; i < u.length; ++i ) for ( let j = 0; j < u.length; ++j ) + if ( u[i][j] !== v[i][j] ) return false; + return true; + } + if(isVector(u)) { + for ( let i = 0; i < u.length; ++i ) + if ( u[i] !== v[i] ) return false; + return true; + } +} + + + +//---------------------------------------------------------------------------- + +function add( u, v ) +{ + + if ( u.type != v.type ) { + throw "add(): trying to add different types"; + } + if(isVector(u)){ + let result = new Array(u.length); + result.type = u.type; + for(let i=0; i<u.length; i++) { + result[i] = u[i] + v[i]; + } + return result; + } + if(isMatrix(u)){ + if(u.type == 'mat2') result = mat2(); + if(u.type == 'mat3') result = mat3(); + if(u.type == 'mat4') result = mat4(); + for(let i=0; i<u.length; i++) for(let j=0; j<u.length; j++){ + result[i][j] = u[i][j] + v[i][j]; + } + return result; + } +} + +//---------------------------------------------------------------------------- + +function subtract( u, v ) +{ + + if ( u.type != v.type ) { + throw "add(): trying to add different types"; + } + if(isVector(u)){ + if(u.type == 'vec2') result =vec2(); + if(u.type == 'vec3') result = vec3(); + if(u.type == 'vec4') result = vec4(); + result.type = u.type; + for(let i=0; i<u.length; i++) { + result[i] = u[i] - v[i]; + } + return result; + } + if(isMatrix(u)){ + if(u.type == 'mat2') result = mat2(); + if(u.type == 'mat3') result = mat3(); + if(u.type == 'mat4') result = mat4(); + for(let i=0; i<u.length; i++) for(let j=0; j<u.length; j++){ + result[i][j] = u[i][j] - v[i][j]; + } + return result; + } +} + +//---------------------------------------------------------------------------- + +function mult( u, v ) +{ + + if(typeof(u)=="number" && (isMatrix(v)||isVector(v))) { + + if(isVector(v)){ + result = new Array(v.length); + result.type = v.type; + for(let i =0; i<v.length; i++) { + result[i] = u*v[i]; + } + return result; + } + if(v.type = 'mat2') result = mat2(); + if(v.type = 'mat3') result = mat3(); + if(v.type = 'mat4') result = mat4(); + } + if(u.type=='mat2' && v.type == 'vec2') { + let result = vec2(); + for(i=0;i<2;i++) { + result[i] = 0.0; + for(let k=0;k<2;k++) result[i]+=u[i][k]*v[k]; + } + return result; + } + if(u.type=='mat3'&& v.type=='vec3') { + let result = vec3(); + for(i=0;i<3;i++) { + result[i] = 0.0; + for(let k=0;k<3;k++) result[i]+=u[i][k]*v[k]; + } + return result; + } + if(u.type=='mat4'&& v.type=='vec4') { + let result = vec4(); + for(i=0;i<4;i++) { + result[i] = 0.0; + for(let k=0;k<4;k++) result[i]+=u[i][k]*v[k]; + } + return result; + } + if (u.type=='mat2'&&v.type=='mat2'){ + result = mat2(); + for(i=0;i<2;i++) for(j=0;j<2;j++) { + result[i][j] = 0.0; + for(let k=0;k<2;k++) result[i][j]+=u[i][k]*v[k][j]; + } + return result; + } + if (u.type=='mat3'&&v.type=='mat3'){ + result = mat3(); + for(i=0;i<3;i++) for(j=0;j<3;j++) { + result[i][j] = 0.0; + for(let k=0;k<3;k++) result[i][j]+=u[i][k]*v[k][j]; + } + return result; + } + else if (u.type=='mat4'&&v.type=='mat4'){ + result = mat4(); + for(i=0;i<4;i++) for(j=0;j<4;j++) { + result[i][j] = 0.0; + for(let k=0;k<4;k++) result[i][j]+=u[i][k]*v[k][j]; + } + + return result; + } + if (u.type=='vec3'&&v.type=='vec3'){ + let result = vec3(u[0]*v[0], u[1]*v[1], u[2]*v[2]); + return result; + } + if (u.type=='vec4'&&v.type=='vec4'){ + let result = vec4(u[0]*v[0], u[1]*v[1], u[2]*v[2], u[3]*v[3]); + return result; + } + throw "mult(): trying to mult incompatible types"; +} + + +//---------------------------------------------------------------------------- +// +// Basic Transformation Matrix Generators +// + +function translate( x, y, z ) +{ + if(arguments.length!=2 && arguments.length != 3) { + throw "translate(): not a mat3 or mat4"; + } + if(arguments.length == 2) { + result = mat3(); + result[0][2] = x; + result[1][2] = y; + + return result; + } + result = mat4(); + + result[0][3] = x; + result[1][3] = y; + result[2][3] = z; + + return result; + +} + +//---------------------------------------------------------------------------- + +function rotate( angle, axis ) +{ + if ( axis.length == 3 ) { + axis = vec3(axis[0], axis[1], axis[2] ); + } + if(arguments.length == 4) { + axis = vec3(arguments[1], arguments[2], arguments[3]); + } + if(axis.type != 'vec3') throw "rotate: axis not a vec3"; + let v = normalize( axis ); + + let x = v[0]; + let y = v[1]; + let z = v[2]; + + let c = Math.cos( radians(angle) ); + let omc = 1.0 - c; + let s = Math.sin( radians(angle) ); + + let result = mat4( + x*x*omc + c, x*y*omc + z*s, x*z*omc - y*s, 0.0 , + x*y*omc - z*s, y*y*omc + c, y*z*omc + x*s, 0.0 , + x*z*omc + y*s, y*z*omc - x*s, z*z*omc + c, 0.0 , + 0.0, 0.0, 0.0, 1.0 + ); + return result; +} + +function rotateX(theta) { + let c = Math.cos( radians(theta) ); + let s = Math.sin( radians(theta) ); + let rx = mat4( 1.0, 0.0, 0.0, 0.0, + 0.0, c, -s, 0.0, + 0.0, s, c, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + return rx; +} +function rotateY(theta) { + let c = Math.cos( radians(theta) ); + let s = Math.sin( radians(theta) ); + let ry = mat4( c, 0.0, s, 0.0, + 0.0, 1.0, 0.0, 0.0, + -s, 0.0, c, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + return ry; +} +function rotateZ(theta) { + let c = Math.cos( radians(theta) ); + let s = Math.sin( radians(theta) ); + let rz = mat4( c, -s, 0.0, 0.0, + s, c, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + return rz; +} +//---------------------------------------------------------------------------- + + +function scale( ) +{ +// legacy code +// should use mult + + if(arguments.length == 2 && isVector(arguments[1])) { + result = new Array(arguments[1].length); + result.type = arguments[1].type; + for(let i=0; i<arguments[1].length; i++) + result[i] = arguments[0]*arguments[1][i]; + return result; + } +// end legacy code + + if(arguments.length == 3) { + + let result = mat4(); + result[0][0] = arguments[0]; + result[1][1] = arguments[1]; + result[2][2] = arguments[2]; + result[3][3] = 1.0; + return result; + } + + throw "scale: wrong arguments"; + +} + + +//---------------------------------------------------------------------------- +// +// ModelView Matrix Generators +// + +function lookAt( eye, at, up ) +{ + if ( eye.type != 'vec3') { + throw "lookAt(): first parameter [eye] must be an a vec3"; + } + + if ( at.type != 'vec3') { + throw "lookAt(): first parameter [at] must be an a vec3"; + } + + if (up.type != 'vec3') { + throw "lookAt(): first parameter [up] must be an a vec3"; + } + + if ( equal(eye, at) ) { + return mat4(); + } + + let v = normalize( subtract(at, eye) ); // view direction vector + let n = normalize( cross(v, up) ); // perpendicular vector + let u = normalize( cross(n, v) ); // "new" up vector + v = negate( v ); + + let result = mat4( + n[0], n[1], n[2], -dot(n, eye), + u[0], u[1], u[2], -dot(u, eye), + v[0], v[1], v[2], -dot(v, eye), + 0.0, 0.0, 0.0, 1.0 + ); + + return result; +} + +//---------------------------------------------------------------------------- +// +// Projection Matrix Generators +// + +function ortho( left, right, bottom, top, near, far ) +{ + if ( left == right ) { throw "ortho(): left and right are equal"; } + if ( bottom == top ) { throw "ortho(): bottom and top are equal"; } + if ( near == far ) { throw "ortho(): near and far are equal"; } + + let w = right - left; + let h = top - bottom; + let d = far - near; + + let result = mat4(); + + result[0][0] = 2.0 / w; + result[1][1] = 2.0 / h; + result[2][2] = -2.0 / d; + + result[0][3] = -(left + right) / w; + result[1][3] = -(top + bottom) / h; + result[2][3] = -(near + far) / d; + result[3][3] = 1.0; + + return result; +} + +//---------------------------------------------------------------------------- + +function perspective( fovy, aspect, near, far ) +{ + let f = 1.0 / Math.tan( radians(fovy) / 2 ); + let d = far - near; + + let result = mat4(); + result[0][0] = f / aspect; + result[1][1] = f; + result[2][2] = -(near + far) / d; + result[2][3] = -2 * near * far / d; + result[3][2] = -1; + result[3][3] = 0.0; + + return result; +} + +//---------------------------------------------------------------------------- +// +// Matrix Functions +// + +function transpose( m ) +{ + if(m.type == 'patch') { + let out = patch() + for(let i=0; i<4; i++) out[i] = new Array(4); + for(let i=0; i<4; i++) + for(let j=0; j<4; j++) out[i][j] = m[j][i]; + return out; + } + + switch(m.type) { + case 'mat2': + let result = mat2(m[0][0], m[1][0], + m[0][1], m[1][1] + ); + return result; + break; + + case 'mat3': + result = mat3(m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2] + ); + return result; + break; + + case 'mat4': + + result = mat4(m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3] + ); + + return result; + break; + + default: throw "transpose(): trying to transpose a non-matrix"; + } +} + + +//---------------------------------------------------------------------------- +// +// Vector Functions +// + +function dot( u, v ) +{ + + if ( u.type != v.type ) { + throw "dot(): types are not the same "; + } + if (u.type != 'vec2' && u.type != 'vec3' && u.type != 'vec4') { + throw "dot(): not a vector "; + } + + let sum = 0.0; + for ( let i = 0; i < u.length; i++ ) { + sum += u[i] * v[i]; + } + return sum; +} + +//---------------------------------------------------------------------------- + +function negate( u ) +{ + if (u.type != 'vec2' && u.type != 'vec3' && u.type != 'vec4') { + throw "negate(): not a vector "; + } + let result = new Array(u.length); + result.type = u.type; + for ( let i = 0; i < u.length; ++i ) { + result[i] = -u[i]; + } + return result; +} + +//---------------------------------------------------------------------------- + +function cross( u, v ) +{ + if ( u.type == 'vec3' && v.type == 'vec3') { + let result = vec3( + u[1]*v[2] - u[2]*v[1], + u[2]*v[0] - u[0]*v[2], + u[0]*v[1] - u[1]*v[0] + ); + return result; + } + + if ( v.type == 'vec4' && v.type == 'vec4') { + let result = vec3( + u[1]*v[2] - u[2]*v[1], + u[2]*v[0] - u[0]*v[2], + u[0]*v[1] - u[1]*v[0] + ); + return result; + } + + throw "cross: types aren't matched vec3 or vec4"; +} + +//---------------------------------------------------------------------------- + +function length( u ) +{ + return Math.sqrt( dot(u, u) ); +} + +//---------------------------------------------------------------------------- + +function normalize( u, excludeLastComponent ) +{ + if(u.type != 'vec3' && u.type != 'vec4') { + + throw "normalize: not a vector type"; + } + switch(u.type) { + case 'vec2': + let len = Math.sqrt(u[0]*u[0]+u[1]*u[1]); + let result = vec2(u[0]/len, u[1]/len); + return result; + break; + case 'vec3': + if(excludeLastComponent) { + let len = Math.sqrt(u[0]*u[0]+u[1]*u[1]); + let result = vec3(u[0]/len, u[1]/len, u[2]); + return result; + break; + } + else { + let len = Math.sqrt(u[0]*u[0]+u[1]*u[1]+u[2]*u[2]); + let result = vec3(u[0]/len, u[1]/len, u[2]/len); + return result; + break; + } + case 'vec4': + if(excludeLastComponent) { + let len = Math.sqrt(u[0]*u[0]+u[1]*u[1]+u[2]*u[2]); + let result = vec4(u[0]/len, u[1]/len, u[2]/len, u[3]); + return result; + break; + } + else { + let len = Math.sqrt(u[0]*u[0]+u[1]*u[1]+u[2]*u[2]+u[3]*u[3]); + let result = vec4(u[0]/len, u[1]/len, u[2]/len, u[3]/len); + return result; + break; + } + } +} + +//---------------------------------------------------------------------------- + +function mix( u, v, s ) +{ + if ( typeof(s) !== "number" ) { + throw "mix: the last paramter " + s + " must be a number"; + } + if(typeof(u)=='number'&&typeof(v)=='number') { + return (1.0-s)*u + s*v; + } + + if ( u.length != v.length ) { + + throw "vector dimension mismatch"; + } + + let result = new Array(u.length); + for ( let i = 0; i < u.length; ++i ) { + result[i] = (1.0 - s) * u[i] + s * v[i] ; + } + result.type = u.type; + return result; +} + +//---------------------------------------------------------------------------- +// +// Vector and Matrix utility functions +// + + +function flatten( v ) +{ + + if(isVector(v)) { + let floats = new Float32Array(v.length) + for(let i =0; i<v.length; i++) floats[i] = v[i]; + return floats; + } + if(isMatrix(v)) { + + let floats = new Float32Array(v.length*v.length); + for(let i =0; i<v.length; i++) for(j=0;j<v.length; j++) { + floats[i*v.length+j] = v[j][i]; + } + return floats; + } + + let floats = new Float32Array( v.length*v[0].length ); + + for(let i = 0; i<v.length; i++) for(let j=0; j<v[0].length; j++) { + floats[i*v[0].length+j] = v[i][j]; + } + return floats; +} + +// +//---------------------------------------------------------------------------- + + +function cut(a) +{ + return Math.round(a*1000)/1000; +} +function printm(m) +{ + switch(m.type) { + case 'mat2': + console.log(cut(m[0][0]), cut(m[0][1])); + console.log(cut(m[1][0]), cut(m[1][1])); + break; + case 'mat3': + console.log(cut(m[0][0]), cut(m[0][1]), cut(m[0][2])); + console.log(cut(m[1][0]), cut(m[1][1]), cut(m[1][2])); + console.log(cut(m[2][0]), cut(m[2][1]), cut(m[2][2])); + break; + case 'mat4': + console.log(cut(m[0][0]), cut(m[0][1]), cut(m[0][2]), cut(m[0][3])); + console.log(cut(m[1][0]), cut(m[1][1]), cut(m[1][2]), cut(m[1][3])); + console.log(cut(m[2][0]), cut(m[2][1]), cut(m[2][2]), cut(m[2][3])); + console.log(cut(m[3][0]), cut(m[3][1]), cut(m[3][2]), cut(m[3][3])); + break; + case 'patch': + for(let i=0;i<4;i++) + console.log(m[i][0], m[i][1], m[i][2], m[i][3]); + break; + default: throw "printm: not a matrix"; + } +} +// determinants + +function det2(m) +{ + + return m[0][0]*m[1][1]-m[0][1]*m[1][0]; + +} + +function det3(m) +{ + let d = m[0][0]*m[1][1]*m[2][2] + + m[0][1]*m[1][2]*m[2][0] + + m[0][2]*m[2][1]*m[1][0] + - m[2][0]*m[1][1]*m[0][2] + - m[1][0]*m[0][1]*m[2][2] + - m[0][0]*m[1][2]*m[2][1] + ; + return d; +} + +function det4(m) +{ + let m0 = [ + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[2][1], m[2][2], m[2][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + let m1 = [ + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[2][0], m[2][2], m[2][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + let m2 = [ + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[2][0], m[2][1], m[2][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + let m3 = [ + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[2][0], m[2][1], m[2][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + return m[0][0]*det3(m0) - m[0][1]*det3(m1) + + m[0][2]*det3(m2) - m[0][3]*det3(m3); + +} + +function det(m) +{ + if(!isMatrix(m)) throw("det: m not a matrix"); + if(m.length == 2) return det2(m); + if(m.length == 3) return det3(m); + if(m.length == 4) return det4(m); +} + + +//--------------------------------------------------------- + +// inverses + +function inverse2(m) +{ + let a = mat2(); + let d = det2(m); + a[0][0] = m[1][1]/d; + a[0][1] = -m[0][1]/d; + a[1][0] = -m[1][0]/d; + a[1][1] = m[0][0]/d; + return a; +} + +function inverse3(m) +{ + let a = mat3(); + let d = det3(m); + + let a00 = [ + vec2(m[1][1], m[1][2]), + vec2(m[2][1], m[2][2]) + ]; + let a01 = [ + vec2(m[1][0], m[1][2]), + vec2(m[2][0], m[2][2]) + ]; + let a02 = [ + vec2(m[1][0], m[1][1]), + vec2(m[2][0], m[2][1]) + ]; + let a10 = [ + vec2(m[0][1], m[0][2]), + vec2(m[2][1], m[2][2]) + ]; + let a11 = [ + vec2(m[0][0], m[0][2]), + vec2(m[2][0], m[2][2]) + ]; + let a12 = [ + vec2(m[0][0], m[0][1]), + vec2(m[2][0], m[2][1]) + ]; + let a20 = [ + vec2(m[0][1], m[0][2]), + vec2(m[1][1], m[1][2]) + ]; + let a21 = [ + vec2(m[0][0], m[0][2]), + vec2(m[1][0], m[1][2]) + ]; + let a22 = [ + vec2(m[0][0], m[0][1]), + vec2(m[1][0], m[1][1]) + ]; + + a[0][0] = det2(a00)/d; + a[0][1] = -det2(a10)/d; + a[0][2] = det2(a20)/d; + a[1][0] = -det2(a01)/d; + a[1][1] = det2(a11)/d; + a[1][2] = -det2(a21)/d; + a[2][0] = det2(a02)/d; + a[2][1] = -det2(a12)/d; + a[2][2] = det2(a22)/d; + + return a; + +} + +function inverse4(m) +{ + let a = mat4(); + let d = det4(m); + + let a00 = [ + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[2][1], m[2][2], m[2][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + let a01 = [ + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[2][0], m[2][2], m[2][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + let a02 = [ + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[2][0], m[2][1], m[2][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + let a03 = [ + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[2][0], m[2][1], m[2][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + let a10 = [ + vec3(m[0][1], m[0][2], m[0][3]), + vec3(m[2][1], m[2][2], m[2][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + let a11 = [ + vec3(m[0][0], m[0][2], m[0][3]), + vec3(m[2][0], m[2][2], m[2][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + let a12 = [ + vec3(m[0][0], m[0][1], m[0][3]), + vec3(m[2][0], m[2][1], m[2][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + let a13 = [ + vec3(m[0][0], m[0][1], m[0][2]), + vec3(m[2][0], m[2][1], m[2][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + let a20 = [ + vec3(m[0][1], m[0][2], m[0][3]), + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + let a21 = [ + vec3(m[0][0], m[0][2], m[0][3]), + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + let a22 = [ + vec3(m[0][0], m[0][1], m[0][3]), + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + let a23 = [ + vec3(m[0][0], m[0][1], m[0][2]), + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + + let a30 = [ + vec3(m[0][1], m[0][2], m[0][3]), + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[2][1], m[2][2], m[2][3]) + ]; + let a31 = [ + vec3(m[0][0], m[0][2], m[0][3]), + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[2][0], m[2][2], m[2][3]) + ]; + let a32 = [ + vec3(m[0][0], m[0][1], m[0][3]), + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[2][0], m[2][1], m[2][3]) + ]; + let a33 = [ + vec3(m[0][0], m[0][1], m[0][2]), + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[2][0], m[2][1], m[2][2]) + ]; + + + + a[0][0] = det3(a00)/d; + a[0][1] = -det3(a10)/d; + a[0][2] = det3(a20)/d; + a[0][3] = -det3(a30)/d; + a[1][0] = -det3(a01)/d; + a[1][1] = det3(a11)/d; + a[1][2] = -det3(a21)/d; + a[1][3] = det3(a31)/d; + a[2][0] = det3(a02)/d; + a[2][1] = -det3(a12)/d; + a[2][2] = det3(a22)/d; + a[2][3] = -det3(a32)/d; + a[3][0] = -det3(a03)/d; + a[3][1] = det3(a13)/d; + a[3][2] = -det3(a23)/d; + a[3][3] = det3(a33)/d; + + return a; +} +function inverse(m) +{ + if(!isMatrix(m)) throw("inverse: m not a matrix"); + if(m.length == 2) return inverse2(m); + if(m.length == 3) return inverse3(m); + if(m.length == 4) return inverse4(m); +} + +//--------------------------------------------------------- + +// normal matrix + + +function normalMatrix(m, flag) +{ + if(m.type!='mat4') throw "normalMatrix: input not a mat4"; + let a = inverse(transpose(m)); + if(arguments.length == 1 &&flag == false) return a; + + let b = mat3(); + for(let i=0;i<3;i++) for(let j=0; j<3; j++) b[i][j] = a[i][j]; + + return b; +} diff --git a/Common/MVnew.js b/Common/MVnew.js new file mode 100644 index 0000000..10ddecc --- /dev/null +++ b/Common/MVnew.js @@ -0,0 +1,1178 @@ +////////////////////////////////////////////////////////////////////////////// +// +// MV.js +// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- + +// +// Helper Functions +// +function MVbuffer(size) { + var b = {}; + b.buf = new Float32Array(size); + b.index = 0; + b.push = function(x) { + for(var i=0; i<x.length; i++) { + b.buf[b.index+i] = x[i]; + } + b.index += x.length; + b.type = ''; + } + return b; +} + +function isVector(v) { + if(v.type == "vec2" || v.type == "vec3" || v.type == "vec4") return true; + return false; +} + +function isMatrix(v) { + if(v.type == "mat2" || v.type == "mat3" || v.type == "mat4") return true; + return false; +} + +function radians( degrees ) { + return degrees * Math.PI / 180.0; +} + +//---------------------------------------------------------------------------- + + +function patch() { + var out = new Array(4); + for(var i = 0; i< 4; i++) out[i] = new Array(4); + out.type = "patch"; + return out; +} + +function curve() { + var out = new Array(4); + out.type = "curve"; + return out; +} +// +// Vector Constructors +// + +function vec2() +{ + var out = new Array(2); + out.type = 'vec2'; + + switch ( arguments.length ) { + case 0: + out[0] = 0.0; + out[1] = 0.0; + break; + case 1: + if(isVector(arguments[0] && (arguments[0].type != 'vec2'))) { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + } + break; + + case 2: + out[0] = arguments[0]; + out[1] = arguments[1]; + break; + } + return out; +} + +function vec3() +{ +//var result = _argumentsToArray( arguments ); + + var out = new Array(3); + out.type = 'vec3'; + + switch ( arguments.length ) { + case 0: + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + return out; + case 1: + if(isVector(arguments[0]) && (arguments[0].type == "vec3")) { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + return out; + } + case 3: + out[0] = arguments[0]; + out[1] = arguments[1]; + out[2] = arguments[2]; + return out; + default: + throw "vec3: wrong arguments"; + } + + return out; +} + +function vec4() +{ + var out = new Array(4); + out.type = 'vec4'; + switch ( arguments.length ) { + + case 0: + + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + return out; + + case 1: + if(isVector(arguments[0])) { + if(arguments[0].type == "vec4") { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = arguments[0][3]; + return out; + } + } + else if(arguments[0].type == "vec3") { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = 1.0; + return out; + } + else { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = arguments[0][3]; + return out; + } + + + + case 2: + if(typeof(arguments[0])=='number'&&arguments[1].type == 'vec3') { + out[0] = arguments[0]; + out[1] = arguments[1][0]; + out[2] = arguments[1][1]; + out[3] = arguments[1][2]; + return out; + } + return out; + + case 4: + + if(isVector(arguments[0])) { + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = arguments[0][3]; + return out; + } + out[0] = arguments[0]; + out[1] = arguments[1]; + out[2] = arguments[2]; + out[3] = arguments[3]; + return out; + case 3: + out[0] = arguments[0][0]; + out[1] = arguments[0][1]; + out[2] = arguments[0][2]; + out[3] = 1.0; + return out; + default: + throw "vec4: wrong arguments"; + } +} + +//---------------------------------------------------------------------------- +// +// Matrix Constructors +// + +function mat2() +{ + var out = new Array(2); + out[0] = new Array(2); + out[1] = new Array(2); + + switch ( arguments.length ) { + case 0: + out[0][0]=out[3]=1.0; + out[1]=out[2]=0.0; + break; + case 1: + if(arguments[0].type == 'mat2') { + out[0][0] = arguments[0][0][0]; + out[0][1] = arguments[0][0][1]; + out[1][0] = arguments[0][1][0]; + out[1][1] = arguments[0][1][1]; + break; + } + + case 4: + out[0][0] = arguments[0]; + out[0][1] = arguments[1]; + out[1][0] = arguments[2]; + out[1][1] = arguments[3]; + break; + default: + throw "mat2: wrong arguments"; + } + out.type = 'mat2'; + + return out; +} + +//---------------------------------------------------------------------------- + +function mat3() +{ + // v = _argumentsToArray( arguments ); + + var out = new Array(3); + out[0] = new Array(3); + out[1] = new Array(3); + out[2] = new Array(3); + + switch ( arguments.length ) { + case 0: + out[0][0]=out[1][1]=out[2][2]=1.0; + out[0][1]=out[0][2]=out[1][0]=out[1][2]=out[2][0]=out[2][1]=0.0; + break; + case 1: + for(var i=0; i<3; i++) for(var i=0; i<3; i++) { + out[i][j]=arguments[0][3*i+j]; + } + break; + + case 9: + for(var i=0; i<3; i++) for(var j=0; j<3; j++) { + out[i][j] = arguments[3*i+j]; + } + break; + default: + throw "mat3: wrong arguments"; + } + out.type = 'mat3'; + + return out; +} + +//---------------------------------------------------------------------------- + +function mat4() +{ + //var v = _argumentsToArray( arguments ); + + var out = new Array(4); + out[0] = new Array(4); + out[1] = new Array(4); + out[2] = new Array(4); + out[3] = new Array(4); + + switch ( arguments.length ) { + case 0: + out[0][0]=out[1][1]=out[2][2]=out[3][3] = 1.0; + out[0][1]=out[0][2]=out[0][3]=out[1][0]=out[1][2]=out[1][3]=out[2][0]=out[2][1] + =out[2][3]=out[3][0]=out[3][1]=out[3][2]=0.0; + + break; + + case 1: + for(var i=0; i<4; i++) for(var i=0; i<4; i++) { + out[i][j]=arguments[0][4*i+j]; + } + break; + + case 4: + if(arguments[0].type == "vec4") { + for( var i=0; i<4; i++) + for(var j=0; j<4; j++) + out[i][j] = arguments[i][j]; + break; + } + + case 16: + for(var i=0; i<4; i++) for(var j=0; j<4; j++) { + out[i][j] = arguments[4*i+j]; + } + break; + } + out.type = 'mat4'; + + return out; +} + +//---------------------------------------------------------------------------- +// +// Generic Mathematical Operations for Vectors and Matrices +// + +function equal( u, v ) +{ + if(!(isMatrix(u)&&isMatrix(v) || (isVector(u)&&isVector(v)))) + throw "equal: at least one input not a vec or mat"; + if ( u.type != v.type ) throw "equal: types different"; + if(isMatrix(u)) { + for ( var i = 0; i < u.length; ++i ) for ( var j = 0; j < u.length; ++j ) + if ( u[i][j] !== v[i][j] ) return false; + return true; + } + if(isVector(u)) { + for ( var i = 0; i < u.length; ++i ) + if ( u[i] !== v[i] ) return false; + return true; + } +} + + + +//---------------------------------------------------------------------------- + +function add( u, v ) +{ + + if ( u.type != v.type ) { + throw "add(): trying to add different types"; + } + if(isVector(u)){ + var result = new Array(u.length); + result.type = u.type; + for(var i=0; i<u.length; i++) { + result[i] = u[i] + v[i]; + } + return result; + } + if(isMatrix(u)){ + if(u.type == 'mat2') var result = mat2(); + if(u.type == 'mat3') var result = mat3(); + if(u.type == 'mat4') var result = mat4(); + for(var i=0; i<u.length; i++) for(var j=0; j<u.length; j++){ + result[i][j] = u[i][j] + v[i][j]; + } + return result; + } +} + +//---------------------------------------------------------------------------- + +function subtract( u, v ) +{ + + if ( u.type != v.type ) { + throw "add(): trying to add different types"; + } + if(isVector(u)){ + if(u.type == 'vec2') var result =vec2(); + if(u.type == 'vec3') var result = vec3(); + if(u.type == 'vec4') var result = vec4(); + result.type = u.type; + for(var i=0; i<u.length; i++) { + result[i] = u[i] - v[i]; + } + return result; + } + if(isMatrix(u)){ + if(u.type == 'mat2') var result = mat2(); + if(u.type == 'mat3') var result = mat3(); + if(u.type == 'mat4') var result = mat4(); + for(var i=0; i<u.length; i++) for(var j=0; j<u.length; j++){ + result[i][j] = u[i][j] - v[i][j]; + } + return result; + } +} + +//---------------------------------------------------------------------------- + +function mult( u, v ) +{ + + if(typeof(u)=="number" && (isMatrix(v)||isVector(v))) { + + if(isVector(v)){ + result = new Array(v.length); + result.type = v.type; + for(var i =0; i<v.length; i++) { + result[i] = u*v[i]; + } + return result; + } + if(v.type = 'mat2') result = mat2(); + if(v.type = 'mat3') result = mat3(); + if(v.type = 'mat4') result = mat4(); + } + if(u.type=='mat2' && v.type == 'vec2') { + var result = vec2(); + for(i=0;i<2;i++) { + result[i] = 0.0; + for(var k=0;k<2;k++) result[i]+=u[i][k]*v[k]; + } + return result; + } + if(u.type=='mat3'&& v.type=='vec3') { + var result = vec3(); + for(i=0;i<3;i++) { + result[i] = 0.0; + for(var k=0;k<3;k++) result[i]+=u[i][k]*v[k]; + } + return result; + } + if(u.type=='mat4'&& v.type=='vec4') { + var result = vec4(); + for(i=0;i<4;i++) { + result[i] = 0.0; + for(var k=0;k<4;k++) result[i]+=u[i][k]*v[k]; + } + return result; + } + if (u.type=='mat2'&&v.type=='mat2'){ + result = mat2(); + for(i=0;i<2;i++) for(j=0;j<2;j++) { + result[i][j] = 0.0; + for(var k=0;k<2;k++) result[i][j]+=u[i][k]*v[k][j]; + } + return result; + } + if (u.type=='mat3'&&v.type=='mat3'){ + result = mat3(); + for(i=0;i<3;i++) for(j=0;j<3;j++) { + result[i][j] = 0.0; + for(var k=0;k<3;k++) result[i][j]+=u[i][k]*v[k][j]; + } + return result; + } + else if (u.type=='mat4'&&v.type=='mat4'){ + result = mat4(); + for(i=0;i<4;i++) for(j=0;j<4;j++) { + result[i][j] = 0.0; + for(var k=0;k<4;k++) result[i][j]+=u[i][k]*v[k][j]; + } + + return result; + } + if (u.type=='vec3'&&v.type=='vec3'){ + var result = vec3(u[0]*v[0], u[1]*v[1], u[2]*v[2]); + return result; + } + if (u.type=='vec4'&&v.type=='vec4'){ + var result = vec4(u[0]*v[0], u[1]*v[1], u[2]*v[2], u[3]*v[3]); + return result; + } + throw "mult(): trying to mult incompatible types"; +} + + +//---------------------------------------------------------------------------- +// +// Basic Transformation Matrix Generators +// + +function translate( x, y, z ) +{ + if(arguments.length!=2 && arguments.length != 3) { + throw "translate(): not a mat3 or mat4"; + } + if(arguments.length == 2) { + result = mat3(); + result[0][2] = x; + result[1][2] = y; + + return result; + } + result = mat4(); + + result[0][3] = x; + result[1][3] = y; + result[2][3] = z; + + return result; + +} + +//---------------------------------------------------------------------------- + +function rotate( angle, axis ) +{ + if ( axis.length == 3 ) { + axis = vec3(axis[0], axis[1], axis[2] ); + } + if(arguments.length == 4) { + axis = vec3(arguments[1], arguments[2], arguments[3]); + } + if(axis.type != 'vec3') throw "rotate: axis not a vec3"; + var v = normalize( axis ); + + var x = v[0]; + var y = v[1]; + var z = v[2]; + + var c = Math.cos( radians(angle) ); + var omc = 1.0 - c; + var s = Math.sin( radians(angle) ); + + var result = mat4( + x*x*omc + c, x*y*omc + z*s, x*z*omc - y*s, 0.0 , + x*y*omc - z*s, y*y*omc + c, y*z*omc + x*s, 0.0 , + x*z*omc + y*s, y*z*omc - x*s, z*z*omc + c, 0.0 , + 0.0, 0.0, 0.0, 1.0 + ); + return result; +} + +function rotateX(theta) { + var c = Math.cos( radians(theta) ); + var s = Math.sin( radians(theta) ); + var rx = mat4( 1.0, 0.0, 0.0, 0.0, + 0.0, c, -s, 0.0, + 0.0, s, c, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + return rx; +} +function rotateY(theta) { + var c = Math.cos( radians(theta) ); + var s = Math.sin( radians(theta) ); + var ry = mat4( c, 0.0, s, 0.0, + 0.0, 1.0, 0.0, 0.0, + -s, 0.0, c, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + return ry; +} +function rotateZ(theta) { + var c = Math.cos( radians(theta) ); + var s = Math.sin( radians(theta) ); + var rz = mat4( c, -s, 0.0, 0.0, + s, c, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + return rz; +} +//---------------------------------------------------------------------------- + + +function scale( ) +{ +// legacy code +// should use mult + + if(arguments.length == 2 && isVector(arguments[1])) { + result = new Array(arguments[1].length); + result.type = arguments[1].type; + for(var i=0; i<arguments[1].length; i++) + result[i] = arguments[0]*arguments[1][i]; + return result; + } +// end legacy code + + if(arguments.length == 3) { + + var result = mat4(); + result[0][0] = arguments[0]; + result[1][1] = arguments[1]; + result[2][2] = arguments[2]; + result[3][3] = 1.0; + return result; + } + + throw "scale: wrong arguments"; + +} + + +//---------------------------------------------------------------------------- +// +// ModelView Matrix Generators +// + +function lookAt( eye, at, up ) +{ + if ( eye.type != 'vec3') { + throw "lookAt(): first parameter [eye] must be an a vec3"; + } + + if ( at.type != 'vec3') { + throw "lookAt(): first parameter [at] must be an a vec3"; + } + + if (up.type != 'vec3') { + throw "lookAt(): first parameter [up] must be an a vec3"; + } + + if ( equal(eye, at) ) { + return mat4(); + } + + var v = normalize( subtract(at, eye) ); // view direction vector + var n = normalize( cross(v, up) ); // perpendicular vector + var u = normalize( cross(n, v) ); // "new" up vector + v = negate( v ); + + var result = mat4( + n[0], n[1], n[2], -dot(n, eye), + u[0], u[1], u[2], -dot(u, eye), + v[0], v[1], v[2], -dot(v, eye), + 0.0, 0.0, 0.0, 1.0 + ); + + return result; +} + +//---------------------------------------------------------------------------- +// +// Projection Matrix Generators +// + +function ortho( left, right, bottom, top, near, far ) +{ + if ( left == right ) { throw "ortho(): left and right are equal"; } + if ( bottom == top ) { throw "ortho(): bottom and top are equal"; } + if ( near == far ) { throw "ortho(): near and far are equal"; } + + var w = right - left; + var h = top - bottom; + var d = far - near; + + var result = mat4(); + + result[0][0] = 2.0 / w; + result[1][1] = 2.0 / h; + result[2][2] = -2.0 / d; + + result[0][3] = -(left + right) / w; + result[1][3] = -(top + bottom) / h; + result[2][3] = -(near + far) / d; + result[3][3] = 1.0; + + return result; +} + +//---------------------------------------------------------------------------- + +function perspective( fovy, aspect, near, far ) +{ + var f = 1.0 / Math.tan( radians(fovy) / 2 ); + var d = far - near; + + var result = mat4(); + result[0][0] = f / aspect; + result[1][1] = f; + result[2][2] = -(near + far) / d; + result[2][3] = -2 * near * far / d; + result[3][2] = -1; + result[3][3] = 0.0; + + return result; +} + +//---------------------------------------------------------------------------- +// +// Matrix Functions +// + +function transpose( m ) +{ + if(m.type == 'patch') { + var out = patch() + for(var i=0; i<4; i++) out[i] = new Array(4); + for(var i=0; i<4; i++) + for(var j=0; j<4; j++) out[i][j] = m[j][i]; + return out; + } + + switch(m.type) { + case 'mat2': + var result = mat2(m[0][0], m[1][0], + m[0][1], m[1][1] + ); + return result; + break; + + case 'mat3': + var result = mat3(m[0][0], m[1][0], m[2][0], + m[0][1], m[1][1], m[2][1], + m[0][2], m[1][2], m[2][2] + ); + return result; + break; + + case 'mat4': + + var result = mat4(m[0][0], m[1][0], m[2][0], m[3][0], + m[0][1], m[1][1], m[2][1], m[3][1], + m[0][2], m[1][2], m[2][2], m[3][2], + m[0][3], m[1][3], m[2][3], m[3][3] + ); + + return result; + break; + + default: throw "transpose(): trying to transpose a non-matrix"; + } +} + + +//---------------------------------------------------------------------------- +// +// Vector Functions +// + +function dot( u, v ) +{ + + if ( u.type != v.type ) { + throw "dot(): types are not the same "; + } + if (u.type != 'vec2' && u.type != 'vec3' && u.type != 'vec4') { + throw "dot(): not a vector "; + } + + var sum = 0.0; + for ( var i = 0; i < u.length; i++ ) { + sum += u[i] * v[i]; + } + return sum; +} + +//---------------------------------------------------------------------------- + +function negate( u ) +{ + if (u.type != 'vec2' && u.type != 'vec3' && u.type != 'vec4') { + throw "negate(): not a vector "; + } + var result = new Array(u.length); + result.type = u.type; + for ( var i = 0; i < u.length; ++i ) { + result[i] = -u[i]; + } + return result; +} + +//---------------------------------------------------------------------------- + +function cross( u, v ) +{ + if ( u.type == 'vec3' && v.type == 'vec3') { + var result = vec3( + u[1]*v[2] - u[2]*v[1], + u[2]*v[0] - u[0]*v[2], + u[0]*v[1] - u[1]*v[0] + ); + return result; + } + + if ( v.type == 'vec4' && v.type == 'vec4') { + var result = vec3( + u[1]*v[2] - u[2]*v[1], + u[2]*v[0] - u[0]*v[2], + u[0]*v[1] - u[1]*v[0] + ); + return result; + } + + throw "cross: types aren't matched vec3 or vec4"; +} + +//---------------------------------------------------------------------------- + +function length( u ) +{ + return Math.sqrt( dot(u, u) ); +} + +//---------------------------------------------------------------------------- + +function normalize( u, excludeLastComponent ) +{ + if(u.type != 'vec3' && u.type != 'vec4') { + + throw "normalize: not a vector type"; + } + switch(u.type) { + case 'vec2': + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]); + var result = vec2(u[0]/len, u[1]/len); + return result; + break; + case 'vec3': + if(excludeLastComponent) { + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]); + var result = vec3(u[0]/len, u[1]/len, u[2]); + return result; + break; + } + else { + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]+u[2]*u[2]); + var result = vec3(u[0]/len, u[1]/len, u[2]/len); + return result; + break; + } + case 'vec4': + if(excludeLastComponent) { + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]+u[2]*u[2]); + var result = vec4(u[0]/len, u[1]/len, u[2]/len, u[3]); + return result; + break; + } + else { + var len = Math.sqrt(u[0]*u[0]+u[1]*u[1]+u[2]*u[2]+u[3]*u[3]); + var result = vec4(u[0]/len, u[1]/len, u[2]/len, u[3]/len); + return result; + break; + } + } +} + +//---------------------------------------------------------------------------- + +function mix( u, v, s ) +{ + if ( typeof(s) !== "number" ) { + throw "mix: the last paramter " + s + " must be a number"; + } + if(typeof(u)=='number'&&typeof(v)=='number') { + return (1.0-s)*u + s*v; + } + + if ( u.length != v.length ) { + + throw "vector dimension mismatch"; + } + + var result = new Array(u.length); + for ( var i = 0; i < u.length; ++i ) { + result[i] = (1.0 - s) * u[i] + s * v[i] ; + } + result.type = u.type; + return result; +} + +//---------------------------------------------------------------------------- +// +// Vector and Matrix utility functions +// + + +function flatten( v ) +{ + + if(isVector(v)) { + var floats = new Float32Array(v.length) + for(var i =0; i<v.length; i++) floats[i] = v[i]; + return floats; + } + if(isMatrix(v)) { + + var floats = new Float32Array(v.length*v.length); + for(var i =0; i<v.length; i++) for(j=0;j<v.length; j++) { + floats[i*v.length+j] = v[j][i]; + } + return floats; + } + + var floats = new Float32Array( v.length*v[0].length ); + + for(var i = 0; i<v.length; i++) for(var j=0; j<v[0].length; j++) { + floats[i*v[0].length+j] = v[i][j]; + } + return floats; +} + +// +//---------------------------------------------------------------------------- + + +function cut(a) +{ + return Math.round(a*1000)/1000; +} +function printm(m) +{ + switch(m.type) { + case 'mat2': + console.log(cut(m[0][0]), cut(m[0][1])); + console.log(cut(m[1][0]), cut(m[1][1])); + break; + case 'mat3': + console.log(cut(m[0][0]), cut(m[0][1]), cut(m[0][2])); + console.log(cut(m[1][0]), cut(m[1][1]), cut(m[1][2])); + console.log(cut(m[2][0]), cut(m[2][1]), cut(m[2][2])); + break; + case 'mat4': + console.log(cut(m[0][0]), cut(m[0][1]), cut(m[0][2]), cut(m[0][3])); + console.log(cut(m[1][0]), cut(m[1][1]), cut(m[1][2]), cut(m[1][3])); + console.log(cut(m[2][0]), cut(m[2][1]), cut(m[2][2]), cut(m[2][3])); + console.log(cut(m[3][0]), cut(m[3][1]), cut(m[3][2]), cut(m[3][3])); + break; + case 'patch': + for(var i=0;i<4;i++) + console.log(m[i][0], m[i][1], m[i][2], m[i][3]); + break; + default: throw "printm: not a matrix"; + } +} +// determinants + +function det2(m) +{ + + return m[0][0]*m[1][1]-m[0][1]*m[1][0]; + +} + +function det3(m) +{ + var d = m[0][0]*m[1][1]*m[2][2] + + m[0][1]*m[1][2]*m[2][0] + + m[0][2]*m[2][1]*m[1][0] + - m[2][0]*m[1][1]*m[0][2] + - m[1][0]*m[0][1]*m[2][2] + - m[0][0]*m[1][2]*m[2][1] + ; + return d; +} + +function det4(m) +{ + var m0 = [ + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[2][1], m[2][2], m[2][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + var m1 = [ + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[2][0], m[2][2], m[2][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + var m2 = [ + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[2][0], m[2][1], m[2][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + var m3 = [ + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[2][0], m[2][1], m[2][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + return m[0][0]*det3(m0) - m[0][1]*det3(m1) + + m[0][2]*det3(m2) - m[0][3]*det3(m3); + +} + +function det(m) +{ + if(!isMatrix(m)) throw("det: m not a matrix"); + if(m.length == 2) return det2(m); + if(m.length == 3) return det3(m); + if(m.length == 4) return det4(m); +} + + +//--------------------------------------------------------- + +// inverses + +function inverse2(m) +{ + var a = mat2(); + var d = det2(m); + a[0][0] = m[1][1]/d; + a[0][1] = -m[0][1]/d; + a[1][0] = -m[1][0]/d; + a[1][1] = m[0][0]/d; + return a; +} + +function inverse3(m) +{ + var a = mat3(); + var d = det3(m); + + var a00 = [ + vec2(m[1][1], m[1][2]), + vec2(m[2][1], m[2][2]) + ]; + var a01 = [ + vec2(m[1][0], m[1][2]), + vec2(m[2][0], m[2][2]) + ]; + var a02 = [ + vec2(m[1][0], m[1][1]), + vec2(m[2][0], m[2][1]) + ]; + var a10 = [ + vec2(m[0][1], m[0][2]), + vec2(m[2][1], m[2][2]) + ]; + var a11 = [ + vec2(m[0][0], m[0][2]), + vec2(m[2][0], m[2][2]) + ]; + var a12 = [ + vec2(m[0][0], m[0][1]), + vec2(m[2][0], m[2][1]) + ]; + var a20 = [ + vec2(m[0][1], m[0][2]), + vec2(m[1][1], m[1][2]) + ]; + var a21 = [ + vec2(m[0][0], m[0][2]), + vec2(m[1][0], m[1][2]) + ]; + var a22 = [ + vec2(m[0][0], m[0][1]), + vec2(m[1][0], m[1][1]) + ]; + + a[0][0] = det2(a00)/d; + a[0][1] = -det2(a10)/d; + a[0][2] = det2(a20)/d; + a[1][0] = -det2(a01)/d; + a[1][1] = det2(a11)/d; + a[1][2] = -det2(a21)/d; + a[2][0] = det2(a02)/d; + a[2][1] = -det2(a12)/d; + a[2][2] = det2(a22)/d; + + return a; + +} + +function inverse4(m) +{ + var a = mat4(); + var d = det4(m); + + var a00 = [ + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[2][1], m[2][2], m[2][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + var a01 = [ + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[2][0], m[2][2], m[2][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + var a02 = [ + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[2][0], m[2][1], m[2][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + var a03 = [ + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[2][0], m[2][1], m[2][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + var a10 = [ + vec3(m[0][1], m[0][2], m[0][3]), + vec3(m[2][1], m[2][2], m[2][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + var a11 = [ + vec3(m[0][0], m[0][2], m[0][3]), + vec3(m[2][0], m[2][2], m[2][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + var a12 = [ + vec3(m[0][0], m[0][1], m[0][3]), + vec3(m[2][0], m[2][1], m[2][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + var a13 = [ + vec3(m[0][0], m[0][1], m[0][2]), + vec3(m[2][0], m[2][1], m[2][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + var a20 = [ + vec3(m[0][1], m[0][2], m[0][3]), + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[3][1], m[3][2], m[3][3]) + ]; + var a21 = [ + vec3(m[0][0], m[0][2], m[0][3]), + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[3][0], m[3][2], m[3][3]) + ]; + var a22 = [ + vec3(m[0][0], m[0][1], m[0][3]), + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[3][0], m[3][1], m[3][3]) + ]; + var a23 = [ + vec3(m[0][0], m[0][1], m[0][2]), + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[3][0], m[3][1], m[3][2]) + ]; + + var a30 = [ + vec3(m[0][1], m[0][2], m[0][3]), + vec3(m[1][1], m[1][2], m[1][3]), + vec3(m[2][1], m[2][2], m[2][3]) + ]; + var a31 = [ + vec3(m[0][0], m[0][2], m[0][3]), + vec3(m[1][0], m[1][2], m[1][3]), + vec3(m[2][0], m[2][2], m[2][3]) + ]; + var a32 = [ + vec3(m[0][0], m[0][1], m[0][3]), + vec3(m[1][0], m[1][1], m[1][3]), + vec3(m[2][0], m[2][1], m[2][3]) + ]; + var a33 = [ + vec3(m[0][0], m[0][1], m[0][2]), + vec3(m[1][0], m[1][1], m[1][2]), + vec3(m[2][0], m[2][1], m[2][2]) + ]; + + + + a[0][0] = det3(a00)/d; + a[0][1] = -det3(a10)/d; + a[0][2] = det3(a20)/d; + a[0][3] = -det3(a30)/d; + a[1][0] = -det3(a01)/d; + a[1][1] = det3(a11)/d; + a[1][2] = -det3(a21)/d; + a[1][3] = det3(a31)/d; + a[2][0] = det3(a02)/d; + a[2][1] = -det3(a12)/d; + a[2][2] = det3(a22)/d; + a[2][3] = -det3(a32)/d; + a[3][0] = -det3(a03)/d; + a[3][1] = det3(a13)/d; + a[3][2] = -det3(a23)/d; + a[3][3] = det3(a33)/d; + + return a; +} +function inverse(m) +{ + if(!isMatrix(m)) throw("inverse: m not a matrix"); + if(m.length == 2) return inverse2(m); + if(m.length == 3) return inverse3(m); + if(m.length == 4) return inverse4(m); +} + +//--------------------------------------------------------- + +// normal matrix + + +function normalMatrix(m, flag) +{ + if(m.type!='mat4') throw "normalMatrix: input not a mat4"; + var a = inverse(transpose(m)); + if(arguments.length == 1 &&flag == false) return a; + + var b = mat3(); + for(var i=0;i<3;i++) for(var j=0; j<3; j++) b[i][j] = a[i][j]; + + return b; +} diff --git a/Common/flatten.js b/Common/flatten.js new file mode 100644 index 0000000..a5d9c15 --- /dev/null +++ b/Common/flatten.js @@ -0,0 +1,24 @@ +function flatten( v ) +{ + + if(!Array.isArray(v)) return v; + + + if(typeof(v[0])=='number'){ + var floats = new Float32Array( v.length ); + + for(var i = 0; i<v.length; i++) + floats[i] = v[i]; + + return floats; + } + + var floats = new Float32Array( v.length*v[0].length ); + + for(var i = 0; i<v.length; i++) for(var j=0; j<v[0].length; j++) { + floats[i*v[0].length+j] = v[i][j]; + + } + + return floats; +} diff --git a/Common/initShaders.js b/Common/initShaders.js new file mode 100644 index 0000000..b621a45 --- /dev/null +++ b/Common/initShaders.js @@ -0,0 +1,61 @@ + // +// initShaders.js +// + +function initShaders( gl, vertexShaderId, fragmentShaderId ) +{ + var vertShdr; + var fragShdr; + + var vertElem = document.getElementById( vertexShaderId ); + if ( !vertElem ) { + alert( "Unable to load vertex shader " + vertexShaderId ); + return -1; + } + else { + vertShdr = gl.createShader( gl.VERTEX_SHADER ); + gl.shaderSource( vertShdr, vertElem.textContent.replace(/^\s+|\s+$/g, '' )); + gl.compileShader( vertShdr ); + if ( !gl.getShaderParameter(vertShdr, gl.COMPILE_STATUS) ) { + var msg = "Vertex shader '" + + vertexShaderId + + "' failed to compile. The error log is:\n\n" + + gl.getShaderInfoLog( vertShdr ); + alert( msg ); + return -1; + } + } + + var fragElem = document.getElementById( fragmentShaderId ); + if ( !fragElem ) { + alert( "Unable to load vertex shader " + fragmentShaderId ); + return -1; + } + else { + fragShdr = gl.createShader( gl.FRAGMENT_SHADER ); + gl.shaderSource( fragShdr, fragElem.textContent.replace(/^\s+|\s+$/g, '' ) ); + gl.compileShader( fragShdr ); + if ( !gl.getShaderParameter(fragShdr, gl.COMPILE_STATUS) ) { + var msg = "Fragment shader '" + + fragmentShaderId + + "' failed to compile. The error log is:\n\n" + + gl.getShaderInfoLog( fragShdr ); + alert( msg ); + return -1; + } + } + + var program = gl.createProgram(); + gl.attachShader( program, vertShdr ); + gl.attachShader( program, fragShdr ); + gl.linkProgram( program ); + + if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) { + var msg = "Shader program failed to link. The error log is:\n\n" + + gl.getProgramInfoLog( program ); + alert( msg ); + return -1; + } + + return program; +} diff --git a/Common/initShaders2.js b/Common/initShaders2.js new file mode 100644 index 0000000..344fb8a --- /dev/null +++ b/Common/initShaders2.js @@ -0,0 +1,43 @@ + + // Get a file as a string using AJAX + function loadFileAJAX(name) { + var xhr = new XMLHttpRequest(), + okStatus = document.location.protocol === "file:" ? 0 : 200; + xhr.open('GET', name, false); + xhr.send(null); + return xhr.status == okStatus ? xhr.responseText : null; + }; + + + function initShaders(gl, vShaderName, fShaderName) { + function getShader(gl, shaderName, type) { + var shader = gl.createShader(type), + shaderScript = loadFileAJAX(shaderName); + if (!shaderScript) { + alert("Could not find shader source: "+shaderName); + } + gl.shaderSource(shader, shaderScript); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + alert(gl.getShaderInfoLog(shader)); + return null; + } + return shader; + } + var vertexShader = getShader(gl, vShaderName, gl.VERTEX_SHADER), + fragmentShader = getShader(gl, fShaderName, gl.FRAGMENT_SHADER), + program = gl.createProgram(); + + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + alert("Could not initialise shaders"); + return null; + } + + + return program; + }; diff --git a/Common/initShaders3.js b/Common/initShaders3.js new file mode 100644 index 0000000..24c5d6f --- /dev/null +++ b/Common/initShaders3.js @@ -0,0 +1,59 @@ + // +// initShaders.js +// + +function initShaders( gl, vertexShaderId, fragmentShaderId ) +{ + var vertShdr; + var fragShdr; + + var vertElem = document.getElementById( vertexShaderId ); + if ( !vertElem ) { + alert( "Unable to load vertex shader " + vertexShaderId ); + return -1; + } + else { + vertShdr = gl.createShader( gl.VERTEX_SHADER ); + vertElem.textContent = "#version 300 es" + vertElem.textContent; + gl.shaderSource( vertShdr, vertElem.textContent.replace(/^\s+|\s+$/g, '' )); + gl.compileShader( vertShdr ); + if ( !gl.getShaderParameter(vertShdr, gl.COMPILE_STATUS) ) { + var msg = "Vertex shader failed to compile. The error log is:" + + "<pre>" + gl.getShaderInfoLog( vertShdr ) + "</pre>"; + alert( msg ); + return -1; + } + } + + var fragElem = document.getElementById( fragmentShaderId ); + if ( !fragElem ) { + alert( "Unable to load vertex shader " + fragmentShaderId ); + return -1; + } + else { + fragShdr = gl.createShader( gl.FRAGMENT_SHADER ); + fragElem.textContent = "#version 300 es" + fragElem.textContent; + gl.shaderSource( fragShdr, fragElem.textContent.replace(/^\s+|\s+$/g, '' ) ); + gl.compileShader( fragShdr ); + if ( !gl.getShaderParameter(fragShdr, gl.COMPILE_STATUS) ) { + var msg = "Fragment shader failed to compile. The error log is:" + + "<pre>" + gl.getShaderInfoLog( fragShdr ) + "</pre>"; + alert( msg ); + return -1; + } + } + + var program = gl.createProgram(); + gl.attachShader( program, vertShdr ); + gl.attachShader( program, fragShdr ); + gl.linkProgram( program ); + + if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) { + var msg = "Shader program failed to link. The error log is:" + + "<pre>" + gl.getProgramInfoLog( program ) + "</pre>"; + alert( msg ); + return -1; + } + + return program; +} diff --git a/Common/initShadersES6.js b/Common/initShadersES6.js new file mode 100644 index 0000000..a0d853a --- /dev/null +++ b/Common/initShadersES6.js @@ -0,0 +1,61 @@ + // +// initShaders.js +// + +function initShaders( gl, vertexShaderId, fragmentShaderId ) +{ + let vertShdr; + let fragShdr; + + let vertElem = document.getElementById( vertexShaderId ); + if ( !vertElem ) { + alert( "Unable to load vertex shader " + vertexShaderId ); + return -1; + } + else { + vertShdr = gl.createShader( gl.VERTEX_SHADER ); + gl.shaderSource( vertShdr, vertElem.textContent.replace(/^\s+|\s+$/g, '' )); + gl.compileShader( vertShdr ); + if ( !gl.getShaderParameter(vertShdr, gl.COMPILE_STATUS) ) { + let msg = "Vertex shader '" + + vertexShaderId + + "' failed to compile. The error log is:\n\n" + + gl.getShaderInfoLog( vertShdr ); + alert( msg ); + return -1; + } + } + + let fragElem = document.getElementById( fragmentShaderId ); + if ( !fragElem ) { + alert( "Unable to load vertex shader " + fragmentShaderId ); + return -1; + } + else { + fragShdr = gl.createShader( gl.FRAGMENT_SHADER ); + gl.shaderSource( fragShdr, fragElem.textContent.replace(/^\s+|\s+$/g, '' ) ); + gl.compileShader( fragShdr ); + if ( !gl.getShaderParameter(fragShdr, gl.COMPILE_STATUS) ) { + let msg = "Fragment shader '" + + fragmentShaderId + + "' failed to compile. The error log is:\n\n" + + gl.getShaderInfoLog( fragShdr ); + alert( msg ); + return -1; + } + } + + let program = gl.createProgram(); + gl.attachShader( program, vertShdr ); + gl.attachShader( program, fragShdr ); + gl.linkProgram( program ); + + if ( !gl.getProgramParameter(program, gl.LINK_STATUS) ) { + let msg = "Shader program failed to link. The error log is:\n\n" + + gl.getProgramInfoLog( program ); + alert( msg ); + return -1; + } + + return program; +} diff --git a/Common/utility.js b/Common/utility.js new file mode 100644 index 0000000..706dbec --- /dev/null +++ b/Common/utility.js @@ -0,0 +1,78 @@ +(function () { + 'use strict'; + + window.getShaderSource = function(id) { + return document.getElementById(id).textContent.replace(/^\s+|\s+$/g, ''); + }; + + function createShader(gl, source, type) { + var shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + return shader; + } + + window.createProgram = function(gl, vertexShaderSource, fragmentShaderSource) { + var program = gl.createProgram(); + var vshader = createShader(gl, vertexShaderSource, gl.VERTEX_SHADER); + var fshader = createShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER); + gl.attachShader(program, vshader); + gl.deleteShader(vshader); + gl.attachShader(program, fshader); + gl.deleteShader(fshader); + gl.linkProgram(program); + + var log = gl.getProgramInfoLog(program); + if (log) { + console.log(log); + } + + log = gl.getShaderInfoLog(vshader); + if (log) { + console.log(log); + } + + log = gl.getShaderInfoLog(fshader); + if (log) { + console.log(log); + } + + return program; + }; +/* + window.loadImage = function(url, onload) { + var img = new Image(); + img.src = url; + img.onload = function() { + onload(img); + }; + return img; + }; + + window.loadImages = function(urls, onload) { + var imgs = []; + var imgsToLoad = urls.length; + + function onImgLoad() { + if (--imgsToLoad <= 0) { + onload(imgs); + } + } + + for (var i = 0; i < imgsToLoad; ++i) { + imgs.push(loadImage(urls[i], onImgLoad)); + } + }; + + window.loadObj = function(url, onload) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.responseType = 'text'; + xhr.onload = function(e) { + var mesh = new OBJ.Mesh(this.response); + onload(mesh); + }; + xhr.send(); + }; +*/ +})(); diff --git a/style.css b/style.css index c701424..f95aac5 100644 --- a/style.css +++ b/style.css @@ -14,6 +14,7 @@ border-style: solid; border-color: black; border-width: 5px; + border-radius: 10px; } .container-color-shape { diff --git a/worksheet1.html b/worksheet1.html index b855366..6066839 100644 --- a/worksheet1.html +++ b/worksheet1.html @@ -83,7 +83,7 @@ } </script> -<script src="../Common/initShaders.js"></script> -<script src="../Common/MVnew.js"></script> +<script src="Common/initShaders.js"></script> +<script src="Common/MVnew.js"></script> <script src="worksheet1.js"></script> </html> \ No newline at end of file -- GitLab