Refact.
authorEugen Sawin <sawine@me73.com>
Fri, 01 Apr 2011 01:45:39 +0200
changeset 192e65293655d
parent 0 6dc831fb5a60
child 2 746643fc3738
Refact.
machine.html
scripts/CanvasMatrix.js
scripts/glMatrix.js
scripts/machine.js
scripts/utils3d.js
     1.1 --- a/machine.html	Thu Mar 31 23:53:48 2011 +0200
     1.2 +++ b/machine.html	Fri Apr 01 01:45:39 2011 +0200
     1.3 @@ -1,39 +0,0 @@
     1.4 -<html>
     1.5 -<head>
     1.6 -<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     1.7 -<title>Machine</title>
     1.8 -<script src="scripts/CanvasMatrix.js" type="text/javascript"> </script>
     1.9 -<script src="scripts/utils3d.js" type="text/javascript"> </script>
    1.10 -<script src="scripts/glMatrix.js" type="text/javascript"></script>
    1.11 -
    1.12 -<script id="shader-fs" type="x-shader/x-fragment"> 
    1.13 -    #ifdef GL_ES
    1.14 -    precision highp float;
    1.15 -    #endif
    1.16 - 
    1.17 -    void main(void) {
    1.18 -        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    1.19 -    }
    1.20 -</script> 
    1.21 - 
    1.22 -<script id="shader-vs" type="x-shader/x-vertex"> 
    1.23 -    attribute vec3 aVertexPosition;
    1.24 - 
    1.25 -    uniform mat4 uMVMatrix;
    1.26 -    uniform mat4 uPMatrix;
    1.27 - 
    1.28 -    void main(void) {
    1.29 -        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    1.30 -    }
    1.31 -</script>
    1.32 -
    1.33 -<script src="scripts/machine.js" type="text/javascript"></script>
    1.34 -</head>
    1.35 - 
    1.36 -<body onload="main();">
    1.37 -<canvas id="machine" width="500" height="500">
    1.38 -    If you're seeing this your web browser doesn't support the canvas element!
    1.39 -</canvas>
    1.40 -</body>
    1.41 - 
    1.42 -</html>
     2.1 --- a/scripts/CanvasMatrix.js	Thu Mar 31 23:53:48 2011 +0200
     2.2 +++ b/scripts/CanvasMatrix.js	Fri Apr 01 01:45:39 2011 +0200
     2.3 @@ -1,698 +0,0 @@
     2.4 -/*
     2.5 -    CanvasMatrix4 class
     2.6 -    
     2.7 -    This class implements a 4x4 matrix. It has functions which
     2.8 -    duplicate the functionality of the OpenGL matrix stack and
     2.9 -    glut functions.
    2.10 -    
    2.11 -    IDL:
    2.12 -    
    2.13 -    [
    2.14 -        Constructor(in CanvasMatrix4 matrix),           // copy passed matrix into new CanvasMatrix4
    2.15 -        Constructor(in sequence<float> array)           // create new CanvasMatrix4 with 16 floats (row major)
    2.16 -        Constructor()                                   // create new CanvasMatrix4 with identity matrix
    2.17 -    ]
    2.18 -    interface CanvasMatrix4 {
    2.19 -        attribute float m11;
    2.20 -        attribute float m12;
    2.21 -        attribute float m13;
    2.22 -        attribute float m14;
    2.23 -        attribute float m21;
    2.24 -        attribute float m22;
    2.25 -        attribute float m23;
    2.26 -        attribute float m24;
    2.27 -        attribute float m31;
    2.28 -        attribute float m32;
    2.29 -        attribute float m33;
    2.30 -        attribute float m34;
    2.31 -        attribute float m41;
    2.32 -        attribute float m42;
    2.33 -        attribute float m43;
    2.34 -        attribute float m44;
    2.35 -
    2.36 -        void load(in CanvasMatrix4 matrix);                 // copy the values from the passed matrix
    2.37 -        void load(in sequence<float> array);                // copy 16 floats into the matrix
    2.38 -        sequence<float> getAsArray();                       // return the matrix as an array of 16 floats
    2.39 -        WebGLFloatArray getAsCanvasFloatArray();           // return the matrix as a WebGLFloatArray with 16 values
    2.40 -        void makeIdentity();                                // replace the matrix with identity
    2.41 -        void transpose();                                   // replace the matrix with its transpose
    2.42 -        void invert();                                      // replace the matrix with its inverse
    2.43 -        
    2.44 -        void translate(in float x, in float y, in float z); // multiply the matrix by passed translation values on the right
    2.45 -        void scale(in float x, in float y, in float z);     // multiply the matrix by passed scale values on the right
    2.46 -        void rotate(in float angle,                         // multiply the matrix by passed rotation values on the right
    2.47 -                    in float x, in float y, in float z);    // (angle is in degrees)
    2.48 -        void multRight(in CanvasMatrix matrix);             // multiply the matrix by the passed matrix on the right
    2.49 -        void multLeft(in CanvasMatrix matrix);              // multiply the matrix by the passed matrix on the left
    2.50 -        void ortho(in float left, in float right,           // multiply the matrix by the passed ortho values on the right
    2.51 -                   in float bottom, in float top, 
    2.52 -                   in float near, in float far);
    2.53 -        void frustum(in float left, in float right,         // multiply the matrix by the passed frustum values on the right
    2.54 -                     in float bottom, in float top, 
    2.55 -                     in float near, in float far);
    2.56 -        void perspective(in float fovy, in float aspect,    // multiply the matrix by the passed perspective values on the right
    2.57 -                         in float zNear, in float zFar);
    2.58 -        void lookat(in float eyex, in float eyey, in float eyez,    // multiply the matrix by the passed lookat 
    2.59 -                    in float ctrx, in float ctry, in float ctrz,    // values on the right
    2.60 -                    in float upx, in float upy, in float upz);
    2.61 -    }
    2.62 -*/
    2.63 -
    2.64 -CanvasMatrix4 = function(m)
    2.65 -{
    2.66 -    if (typeof m == 'object') {
    2.67 -        if ("length" in m && m.length >= 16) {
    2.68 -            this.load(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]);
    2.69 -            return;
    2.70 -        }
    2.71 -        else if (m instanceof CanvasMatrix4) {
    2.72 -            this.load(m);
    2.73 -            return;
    2.74 -        }
    2.75 -    }
    2.76 -    this.makeIdentity();
    2.77 -}
    2.78 -
    2.79 -CanvasMatrix4.prototype.load = function()
    2.80 -{
    2.81 -    if (arguments.length == 1 && typeof arguments[0] == 'object') {
    2.82 -        var matrix = arguments[0];
    2.83 -        
    2.84 -        if ("length" in matrix && matrix.length == 16) {
    2.85 -            this.m11 = matrix[0];
    2.86 -            this.m12 = matrix[1];
    2.87 -            this.m13 = matrix[2];
    2.88 -            this.m14 = matrix[3];
    2.89 -
    2.90 -            this.m21 = matrix[4];
    2.91 -            this.m22 = matrix[5];
    2.92 -            this.m23 = matrix[6];
    2.93 -            this.m24 = matrix[7];
    2.94 -
    2.95 -            this.m31 = matrix[8];
    2.96 -            this.m32 = matrix[9];
    2.97 -            this.m33 = matrix[10];
    2.98 -            this.m34 = matrix[11];
    2.99 -
   2.100 -            this.m41 = matrix[12];
   2.101 -            this.m42 = matrix[13];
   2.102 -            this.m43 = matrix[14];
   2.103 -            this.m44 = matrix[15];
   2.104 -            return;
   2.105 -        }
   2.106 -            
   2.107 -        if (arguments[0] instanceof CanvasMatrix4) {
   2.108 -        
   2.109 -            this.m11 = matrix.m11;
   2.110 -            this.m12 = matrix.m12;
   2.111 -            this.m13 = matrix.m13;
   2.112 -            this.m14 = matrix.m14;
   2.113 -
   2.114 -            this.m21 = matrix.m21;
   2.115 -            this.m22 = matrix.m22;
   2.116 -            this.m23 = matrix.m23;
   2.117 -            this.m24 = matrix.m24;
   2.118 -
   2.119 -            this.m31 = matrix.m31;
   2.120 -            this.m32 = matrix.m32;
   2.121 -            this.m33 = matrix.m33;
   2.122 -            this.m34 = matrix.m34;
   2.123 -
   2.124 -            this.m41 = matrix.m41;
   2.125 -            this.m42 = matrix.m42;
   2.126 -            this.m43 = matrix.m43;
   2.127 -            this.m44 = matrix.m44;
   2.128 -            return;
   2.129 -        }
   2.130 -    }
   2.131 -    
   2.132 -    this.makeIdentity();
   2.133 -}
   2.134 -
   2.135 -CanvasMatrix4.prototype.getAsArray = function()
   2.136 -{
   2.137 -    return [
   2.138 -        this.m11, this.m12, this.m13, this.m14, 
   2.139 -        this.m21, this.m22, this.m23, this.m24, 
   2.140 -        this.m31, this.m32, this.m33, this.m34, 
   2.141 -        this.m41, this.m42, this.m43, this.m44
   2.142 -    ];
   2.143 -}
   2.144 -
   2.145 -CanvasMatrix4.prototype.getAsCanvasFloatArray = function()
   2.146 -{
   2.147 -    return new WebGLFloatArray(this.getAsArray());
   2.148 -}
   2.149 -
   2.150 -CanvasMatrix4.prototype.makeIdentity = function()
   2.151 -{
   2.152 -    this.m11 = 1;
   2.153 -    this.m12 = 0;
   2.154 -    this.m13 = 0;
   2.155 -    this.m14 = 0;
   2.156 -    
   2.157 -    this.m21 = 0;
   2.158 -    this.m22 = 1;
   2.159 -    this.m23 = 0;
   2.160 -    this.m24 = 0;
   2.161 -    
   2.162 -    this.m31 = 0;
   2.163 -    this.m32 = 0;
   2.164 -    this.m33 = 1;
   2.165 -    this.m34 = 0;
   2.166 -    
   2.167 -    this.m41 = 0;
   2.168 -    this.m42 = 0;
   2.169 -    this.m43 = 0;
   2.170 -    this.m44 = 1;
   2.171 -}
   2.172 -
   2.173 -CanvasMatrix4.prototype.transpose = function()
   2.174 -{
   2.175 -    var tmp = this.m12;
   2.176 -    this.m12 = this.m21;
   2.177 -    this.m21 = tmp;
   2.178 -    
   2.179 -    tmp = this.m13;
   2.180 -    this.m13 = this.m31;
   2.181 -    this.m31 = tmp;
   2.182 -    
   2.183 -    tmp = this.m14;
   2.184 -    this.m14 = this.m41;
   2.185 -    this.m41 = tmp;
   2.186 -    
   2.187 -    tmp = this.m23;
   2.188 -    this.m23 = this.m32;
   2.189 -    this.m32 = tmp;
   2.190 -    
   2.191 -    tmp = this.m24;
   2.192 -    this.m24 = this.m42;
   2.193 -    this.m42 = tmp;
   2.194 -    
   2.195 -    tmp = this.m34;
   2.196 -    this.m34 = this.m43;
   2.197 -    this.m43 = tmp;
   2.198 -}
   2.199 -
   2.200 -CanvasMatrix4.prototype.invert = function()
   2.201 -{
   2.202 -    // Calculate the 4x4 determinant
   2.203 -    // If the determinant is zero, 
   2.204 -    // then the inverse matrix is not unique.
   2.205 -    var det = this._determinant4x4();
   2.206 -
   2.207 -    if (Math.abs(det) < 1e-8)
   2.208 -        return null;
   2.209 -
   2.210 -    this._makeAdjoint();
   2.211 -
   2.212 -    // Scale the adjoint matrix to get the inverse
   2.213 -    this.m11 /= det;
   2.214 -    this.m12 /= det;
   2.215 -    this.m13 /= det;
   2.216 -    this.m14 /= det;
   2.217 -    
   2.218 -    this.m21 /= det;
   2.219 -    this.m22 /= det;
   2.220 -    this.m23 /= det;
   2.221 -    this.m24 /= det;
   2.222 -    
   2.223 -    this.m31 /= det;
   2.224 -    this.m32 /= det;
   2.225 -    this.m33 /= det;
   2.226 -    this.m34 /= det;
   2.227 -    
   2.228 -    this.m41 /= det;
   2.229 -    this.m42 /= det;
   2.230 -    this.m43 /= det;
   2.231 -    this.m44 /= det;
   2.232 -}
   2.233 -
   2.234 -CanvasMatrix4.prototype.translate = function(x,y,z)
   2.235 -{
   2.236 -    if (x == undefined)
   2.237 -        x = 0;
   2.238 -        if (y == undefined)
   2.239 -            y = 0;
   2.240 -    if (z == undefined)
   2.241 -        z = 0;
   2.242 -    
   2.243 -    var matrix = new CanvasMatrix4();
   2.244 -    matrix.m41 = x;
   2.245 -    matrix.m42 = y;
   2.246 -    matrix.m43 = z;
   2.247 -
   2.248 -    this.multRight(matrix);
   2.249 -}
   2.250 -
   2.251 -CanvasMatrix4.prototype.scale = function(x,y,z)
   2.252 -{
   2.253 -    if (x == undefined)
   2.254 -        x = 1;
   2.255 -    if (z == undefined) {
   2.256 -        if (y == undefined) {
   2.257 -            y = x;
   2.258 -            z = x;
   2.259 -        }
   2.260 -        else
   2.261 -            z = 1;
   2.262 -    }
   2.263 -    else if (y == undefined)
   2.264 -        y = x;
   2.265 -    
   2.266 -    var matrix = new CanvasMatrix4();
   2.267 -    matrix.m11 = x;
   2.268 -    matrix.m22 = y;
   2.269 -    matrix.m33 = z;
   2.270 -    
   2.271 -    this.multRight(matrix);
   2.272 -}
   2.273 -
   2.274 -CanvasMatrix4.prototype.rotate = function(angle,x,y,z)
   2.275 -{
   2.276 -    // angles are in degrees. Switch to radians
   2.277 -    angle = angle / 180 * Math.PI;
   2.278 -    
   2.279 -    angle /= 2;
   2.280 -    var sinA = Math.sin(angle);
   2.281 -    var cosA = Math.cos(angle);
   2.282 -    var sinA2 = sinA * sinA;
   2.283 -    
   2.284 -    // normalize
   2.285 -    var length = Math.sqrt(x * x + y * y + z * z);
   2.286 -    if (length == 0) {
   2.287 -        // bad vector, just use something reasonable
   2.288 -        x = 0;
   2.289 -        y = 0;
   2.290 -        z = 1;
   2.291 -    } else if (length != 1) {
   2.292 -        x /= length;
   2.293 -        y /= length;
   2.294 -        z /= length;
   2.295 -    }
   2.296 -    
   2.297 -    var mat = new CanvasMatrix4();
   2.298 -
   2.299 -    // optimize case where axis is along major axis
   2.300 -    if (x == 1 && y == 0 && z == 0) {
   2.301 -        mat.m11 = 1;
   2.302 -        mat.m12 = 0;
   2.303 -        mat.m13 = 0;
   2.304 -        mat.m21 = 0;
   2.305 -        mat.m22 = 1 - 2 * sinA2;
   2.306 -        mat.m23 = 2 * sinA * cosA;
   2.307 -        mat.m31 = 0;
   2.308 -        mat.m32 = -2 * sinA * cosA;
   2.309 -        mat.m33 = 1 - 2 * sinA2;
   2.310 -        mat.m14 = mat.m24 = mat.m34 = 0;
   2.311 -        mat.m41 = mat.m42 = mat.m43 = 0;
   2.312 -        mat.m44 = 1;
   2.313 -    } else if (x == 0 && y == 1 && z == 0) {
   2.314 -        mat.m11 = 1 - 2 * sinA2;
   2.315 -        mat.m12 = 0;
   2.316 -        mat.m13 = -2 * sinA * cosA;
   2.317 -        mat.m21 = 0;
   2.318 -        mat.m22 = 1;
   2.319 -        mat.m23 = 0;
   2.320 -        mat.m31 = 2 * sinA * cosA;
   2.321 -        mat.m32 = 0;
   2.322 -        mat.m33 = 1 - 2 * sinA2;
   2.323 -        mat.m14 = mat.m24 = mat.m34 = 0;
   2.324 -        mat.m41 = mat.m42 = mat.m43 = 0;
   2.325 -        mat.m44 = 1;
   2.326 -    } else if (x == 0 && y == 0 && z == 1) {
   2.327 -        mat.m11 = 1 - 2 * sinA2;
   2.328 -        mat.m12 = 2 * sinA * cosA;
   2.329 -        mat.m13 = 0;
   2.330 -        mat.m21 = -2 * sinA * cosA;
   2.331 -        mat.m22 = 1 - 2 * sinA2;
   2.332 -        mat.m23 = 0;
   2.333 -        mat.m31 = 0;
   2.334 -        mat.m32 = 0;
   2.335 -        mat.m33 = 1;
   2.336 -        mat.m14 = mat.m24 = mat.m34 = 0;
   2.337 -        mat.m41 = mat.m42 = mat.m43 = 0;
   2.338 -        mat.m44 = 1;
   2.339 -    } else {
   2.340 -        var x2 = x*x;
   2.341 -        var y2 = y*y;
   2.342 -        var z2 = z*z;
   2.343 -    
   2.344 -        mat.m11 = 1 - 2 * (y2 + z2) * sinA2;
   2.345 -        mat.m12 = 2 * (x * y * sinA2 + z * sinA * cosA);
   2.346 -        mat.m13 = 2 * (x * z * sinA2 - y * sinA * cosA);
   2.347 -        mat.m21 = 2 * (y * x * sinA2 - z * sinA * cosA);
   2.348 -        mat.m22 = 1 - 2 * (z2 + x2) * sinA2;
   2.349 -        mat.m23 = 2 * (y * z * sinA2 + x * sinA * cosA);
   2.350 -        mat.m31 = 2 * (z * x * sinA2 + y * sinA * cosA);
   2.351 -        mat.m32 = 2 * (z * y * sinA2 - x * sinA * cosA);
   2.352 -        mat.m33 = 1 - 2 * (x2 + y2) * sinA2;
   2.353 -        mat.m14 = mat.m24 = mat.m34 = 0;
   2.354 -        mat.m41 = mat.m42 = mat.m43 = 0;
   2.355 -        mat.m44 = 1;
   2.356 -    }
   2.357 -    this.multRight(mat);
   2.358 -}
   2.359 -
   2.360 -CanvasMatrix4.prototype.multRight = function(mat)
   2.361 -{
   2.362 -    var m11 = (this.m11 * mat.m11 + this.m12 * mat.m21
   2.363 -               + this.m13 * mat.m31 + this.m14 * mat.m41);
   2.364 -    var m12 = (this.m11 * mat.m12 + this.m12 * mat.m22
   2.365 -               + this.m13 * mat.m32 + this.m14 * mat.m42);
   2.366 -    var m13 = (this.m11 * mat.m13 + this.m12 * mat.m23
   2.367 -               + this.m13 * mat.m33 + this.m14 * mat.m43);
   2.368 -    var m14 = (this.m11 * mat.m14 + this.m12 * mat.m24
   2.369 -               + this.m13 * mat.m34 + this.m14 * mat.m44);
   2.370 -
   2.371 -    var m21 = (this.m21 * mat.m11 + this.m22 * mat.m21
   2.372 -               + this.m23 * mat.m31 + this.m24 * mat.m41);
   2.373 -    var m22 = (this.m21 * mat.m12 + this.m22 * mat.m22
   2.374 -               + this.m23 * mat.m32 + this.m24 * mat.m42);
   2.375 -    var m23 = (this.m21 * mat.m13 + this.m22 * mat.m23
   2.376 -               + this.m23 * mat.m33 + this.m24 * mat.m43);
   2.377 -    var m24 = (this.m21 * mat.m14 + this.m22 * mat.m24
   2.378 -               + this.m23 * mat.m34 + this.m24 * mat.m44);
   2.379 -
   2.380 -    var m31 = (this.m31 * mat.m11 + this.m32 * mat.m21
   2.381 -               + this.m33 * mat.m31 + this.m34 * mat.m41);
   2.382 -    var m32 = (this.m31 * mat.m12 + this.m32 * mat.m22
   2.383 -               + this.m33 * mat.m32 + this.m34 * mat.m42);
   2.384 -    var m33 = (this.m31 * mat.m13 + this.m32 * mat.m23
   2.385 -               + this.m33 * mat.m33 + this.m34 * mat.m43);
   2.386 -    var m34 = (this.m31 * mat.m14 + this.m32 * mat.m24
   2.387 -               + this.m33 * mat.m34 + this.m34 * mat.m44);
   2.388 -
   2.389 -    var m41 = (this.m41 * mat.m11 + this.m42 * mat.m21
   2.390 -               + this.m43 * mat.m31 + this.m44 * mat.m41);
   2.391 -    var m42 = (this.m41 * mat.m12 + this.m42 * mat.m22
   2.392 -               + this.m43 * mat.m32 + this.m44 * mat.m42);
   2.393 -    var m43 = (this.m41 * mat.m13 + this.m42 * mat.m23
   2.394 -               + this.m43 * mat.m33 + this.m44 * mat.m43);
   2.395 -    var m44 = (this.m41 * mat.m14 + this.m42 * mat.m24
   2.396 -               + this.m43 * mat.m34 + this.m44 * mat.m44);
   2.397 -    
   2.398 -    this.m11 = m11;
   2.399 -    this.m12 = m12;
   2.400 -    this.m13 = m13;
   2.401 -    this.m14 = m14;
   2.402 -    
   2.403 -    this.m21 = m21;
   2.404 -    this.m22 = m22;
   2.405 -    this.m23 = m23;
   2.406 -    this.m24 = m24;
   2.407 -    
   2.408 -    this.m31 = m31;
   2.409 -    this.m32 = m32;
   2.410 -    this.m33 = m33;
   2.411 -    this.m34 = m34;
   2.412 -    
   2.413 -    this.m41 = m41;
   2.414 -    this.m42 = m42;
   2.415 -    this.m43 = m43;
   2.416 -    this.m44 = m44;
   2.417 -}
   2.418 -
   2.419 -CanvasMatrix4.prototype.multLeft = function(mat)
   2.420 -{
   2.421 -    var m11 = (mat.m11 * this.m11 + mat.m12 * this.m21
   2.422 -               + mat.m13 * this.m31 + mat.m14 * this.m41);
   2.423 -    var m12 = (mat.m11 * this.m12 + mat.m12 * this.m22
   2.424 -               + mat.m13 * this.m32 + mat.m14 * this.m42);
   2.425 -    var m13 = (mat.m11 * this.m13 + mat.m12 * this.m23
   2.426 -               + mat.m13 * this.m33 + mat.m14 * this.m43);
   2.427 -    var m14 = (mat.m11 * this.m14 + mat.m12 * this.m24
   2.428 -               + mat.m13 * this.m34 + mat.m14 * this.m44);
   2.429 -
   2.430 -    var m21 = (mat.m21 * this.m11 + mat.m22 * this.m21
   2.431 -               + mat.m23 * this.m31 + mat.m24 * this.m41);
   2.432 -    var m22 = (mat.m21 * this.m12 + mat.m22 * this.m22
   2.433 -               + mat.m23 * this.m32 + mat.m24 * this.m42);
   2.434 -    var m23 = (mat.m21 * this.m13 + mat.m22 * this.m23
   2.435 -               + mat.m23 * this.m33 + mat.m24 * this.m43);
   2.436 -    var m24 = (mat.m21 * this.m14 + mat.m22 * this.m24
   2.437 -               + mat.m23 * this.m34 + mat.m24 * this.m44);
   2.438 -
   2.439 -    var m31 = (mat.m31 * this.m11 + mat.m32 * this.m21
   2.440 -               + mat.m33 * this.m31 + mat.m34 * this.m41);
   2.441 -    var m32 = (mat.m31 * this.m12 + mat.m32 * this.m22
   2.442 -               + mat.m33 * this.m32 + mat.m34 * this.m42);
   2.443 -    var m33 = (mat.m31 * this.m13 + mat.m32 * this.m23
   2.444 -               + mat.m33 * this.m33 + mat.m34 * this.m43);
   2.445 -    var m34 = (mat.m31 * this.m14 + mat.m32 * this.m24
   2.446 -               + mat.m33 * this.m34 + mat.m34 * this.m44);
   2.447 -
   2.448 -    var m41 = (mat.m41 * this.m11 + mat.m42 * this.m21
   2.449 -               + mat.m43 * this.m31 + mat.m44 * this.m41);
   2.450 -    var m42 = (mat.m41 * this.m12 + mat.m42 * this.m22
   2.451 -               + mat.m43 * this.m32 + mat.m44 * this.m42);
   2.452 -    var m43 = (mat.m41 * this.m13 + mat.m42 * this.m23
   2.453 -               + mat.m43 * this.m33 + mat.m44 * this.m43);
   2.454 -    var m44 = (mat.m41 * this.m14 + mat.m42 * this.m24
   2.455 -               + mat.m43 * this.m34 + mat.m44 * this.m44);
   2.456 -    
   2.457 -    this.m11 = m11;
   2.458 -    this.m12 = m12;
   2.459 -    this.m13 = m13;
   2.460 -    this.m14 = m14;
   2.461 -
   2.462 -    this.m21 = m21;
   2.463 -    this.m22 = m22;
   2.464 -    this.m23 = m23;
   2.465 -    this.m24 = m24;
   2.466 -
   2.467 -    this.m31 = m31;
   2.468 -    this.m32 = m32;
   2.469 -    this.m33 = m33;
   2.470 -    this.m34 = m34;
   2.471 -
   2.472 -    this.m41 = m41;
   2.473 -    this.m42 = m42;
   2.474 -    this.m43 = m43;
   2.475 -    this.m44 = m44;
   2.476 -}
   2.477 -
   2.478 -CanvasMatrix4.prototype.ortho = function(left, right, bottom, top, near, far)
   2.479 -{
   2.480 -    var tx = (left + right) / (left - right);
   2.481 -    var ty = (top + bottom) / (top - bottom);
   2.482 -    var tz = (far + near) / (far - near);
   2.483 -    
   2.484 -    var matrix = new CanvasMatrix4();
   2.485 -    matrix.m11 = 2 / (left - right);
   2.486 -    matrix.m12 = 0;
   2.487 -    matrix.m13 = 0;
   2.488 -    matrix.m14 = 0;
   2.489 -    matrix.m21 = 0;
   2.490 -    matrix.m22 = 2 / (top - bottom);
   2.491 -    matrix.m23 = 0;
   2.492 -    matrix.m24 = 0;
   2.493 -    matrix.m31 = 0;
   2.494 -    matrix.m32 = 0;
   2.495 -    matrix.m33 = -2 / (far - near);
   2.496 -    matrix.m34 = 0;
   2.497 -    matrix.m41 = tx;
   2.498 -    matrix.m42 = ty;
   2.499 -    matrix.m43 = tz;
   2.500 -    matrix.m44 = 1;
   2.501 -    
   2.502 -    this.multRight(matrix);
   2.503 -}
   2.504 -
   2.505 -CanvasMatrix4.prototype.frustum = function(left, right, bottom, top, near, far)
   2.506 -{
   2.507 -    var matrix = new CanvasMatrix4();
   2.508 -    var A = (right + left) / (right - left);
   2.509 -    var B = (top + bottom) / (top - bottom);
   2.510 -    var C = -(far + near) / (far - near);
   2.511 -    var D = -(2 * far * near) / (far - near);
   2.512 -    
   2.513 -    matrix.m11 = (2 * near) / (right - left);
   2.514 -    matrix.m12 = 0;
   2.515 -    matrix.m13 = 0;
   2.516 -    matrix.m14 = 0;
   2.517 -    
   2.518 -    matrix.m21 = 0;
   2.519 -    matrix.m22 = 2 * near / (top - bottom);
   2.520 -    matrix.m23 = 0;
   2.521 -    matrix.m24 = 0;
   2.522 -    
   2.523 -    matrix.m31 = A;
   2.524 -    matrix.m32 = B;
   2.525 -    matrix.m33 = C;
   2.526 -    matrix.m34 = -1;
   2.527 -    
   2.528 -    matrix.m41 = 0;
   2.529 -    matrix.m42 = 0;
   2.530 -    matrix.m43 = D;
   2.531 -    matrix.m44 = 0;
   2.532 -    
   2.533 -    this.multRight(matrix);
   2.534 -}
   2.535 -
   2.536 -CanvasMatrix4.prototype.perspective = function(fovy, aspect, zNear, zFar)
   2.537 -{
   2.538 -    var top = Math.tan(fovy * Math.PI / 360) * zNear;
   2.539 -    var bottom = -top;
   2.540 -    var left = aspect * bottom;
   2.541 -    var right = aspect * top;
   2.542 -    this.frustum(left, right, bottom, top, zNear, zFar);
   2.543 -}
   2.544 -
   2.545 -CanvasMatrix4.prototype.lookat = function(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz)
   2.546 -{
   2.547 -    var matrix = new CanvasMatrix4();
   2.548 -    
   2.549 -    // Make rotation matrix
   2.550 -
   2.551 -    // Z vector
   2.552 -    var zx = eyex - centerx;
   2.553 -    var zy = eyey - centery;
   2.554 -    var zz = eyez - centerz;
   2.555 -    var mag = Math.sqrt(zx * zx + zy * zy + zz * zz);
   2.556 -    if (mag) {
   2.557 -        zx /= mag;
   2.558 -        zy /= mag;
   2.559 -        zz /= mag;
   2.560 -    }
   2.561 -
   2.562 -    // Y vector
   2.563 -    var yx = upx;
   2.564 -    var yy = upy;
   2.565 -    var yz = upz;
   2.566 -
   2.567 -    // X vector = Y cross Z
   2.568 -    xx =  yy * zz - yz * zy;
   2.569 -    xy = -yx * zz + yz * zx;
   2.570 -    xz =  yx * zy - yy * zx;
   2.571 -
   2.572 -    // Recompute Y = Z cross X
   2.573 -    yx = zy * xz - zz * xy;
   2.574 -    yy = -zx * xz + zz * xx;
   2.575 -    yx = zx * xy - zy * xx;
   2.576 -
   2.577 -    // cross product gives area of parallelogram, which is < 1.0 for
   2.578 -    // non-perpendicular unit-length vectors; so normalize x, y here
   2.579 -
   2.580 -    mag = Math.sqrt(xx * xx + xy * xy + xz * xz);
   2.581 -    if (mag) {
   2.582 -        xx /= mag;
   2.583 -        xy /= mag;
   2.584 -        xz /= mag;
   2.585 -    }
   2.586 -
   2.587 -    mag = Math.sqrt(yx * yx + yy * yy + yz * yz);
   2.588 -    if (mag) {
   2.589 -        yx /= mag;
   2.590 -        yy /= mag;
   2.591 -        yz /= mag;
   2.592 -    }
   2.593 -
   2.594 -    matrix.m11 = xx;
   2.595 -    matrix.m12 = xy;
   2.596 -    matrix.m13 = xz;
   2.597 -    matrix.m14 = 0;
   2.598 -    
   2.599 -    matrix.m21 = yx;
   2.600 -    matrix.m22 = yy;
   2.601 -    matrix.m23 = yz;
   2.602 -    matrix.m24 = 0;
   2.603 -    
   2.604 -    matrix.m31 = zx;
   2.605 -    matrix.m32 = zy;
   2.606 -    matrix.m33 = zz;
   2.607 -    matrix.m34 = 0;
   2.608 -    
   2.609 -    matrix.m41 = 0;
   2.610 -    matrix.m42 = 0;
   2.611 -    matrix.m43 = 0;
   2.612 -    matrix.m44 = 1;
   2.613 -    matrix.translate(-eyex, -eyey, -eyez);
   2.614 -    
   2.615 -    this.multRight(matrix);
   2.616 -}
   2.617 -
   2.618 -// Support functions
   2.619 -CanvasMatrix4.prototype._determinant2x2 = function(a, b, c, d)
   2.620 -{
   2.621 -    return a * d - b * c;
   2.622 -}
   2.623 -
   2.624 -CanvasMatrix4.prototype._determinant3x3 = function(a1, a2, a3, b1, b2, b3, c1, c2, c3)
   2.625 -{
   2.626 -    return a1 * this._determinant2x2(b2, b3, c2, c3)
   2.627 -         - b1 * this._determinant2x2(a2, a3, c2, c3)
   2.628 -         + c1 * this._determinant2x2(a2, a3, b2, b3);
   2.629 -}
   2.630 -
   2.631 -CanvasMatrix4.prototype._determinant4x4 = function()
   2.632 -{
   2.633 -    var a1 = this.m11;
   2.634 -    var b1 = this.m12; 
   2.635 -    var c1 = this.m13;
   2.636 -    var d1 = this.m14;
   2.637 -
   2.638 -    var a2 = this.m21;
   2.639 -    var b2 = this.m22; 
   2.640 -    var c2 = this.m23;
   2.641 -    var d2 = this.m24;
   2.642 -
   2.643 -    var a3 = this.m31;
   2.644 -    var b3 = this.m32; 
   2.645 -    var c3 = this.m33;
   2.646 -    var d3 = this.m34;
   2.647 -
   2.648 -    var a4 = this.m41;
   2.649 -    var b4 = this.m42; 
   2.650 -    var c4 = this.m43;
   2.651 -    var d4 = this.m44;
   2.652 -
   2.653 -    return a1 * this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)
   2.654 -         - b1 * this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)
   2.655 -         + c1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)
   2.656 -         - d1 * this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
   2.657 -}
   2.658 -
   2.659 -CanvasMatrix4.prototype._makeAdjoint = function()
   2.660 -{
   2.661 -    var a1 = this.m11;
   2.662 -    var b1 = this.m12; 
   2.663 -    var c1 = this.m13;
   2.664 -    var d1 = this.m14;
   2.665 -
   2.666 -    var a2 = this.m21;
   2.667 -    var b2 = this.m22; 
   2.668 -    var c2 = this.m23;
   2.669 -    var d2 = this.m24;
   2.670 -
   2.671 -    var a3 = this.m31;
   2.672 -    var b3 = this.m32; 
   2.673 -    var c3 = this.m33;
   2.674 -    var d3 = this.m34;
   2.675 -
   2.676 -    var a4 = this.m41;
   2.677 -    var b4 = this.m42; 
   2.678 -    var c4 = this.m43;
   2.679 -    var d4 = this.m44;
   2.680 -
   2.681 -    // Row column labeling reversed since we transpose rows & columns
   2.682 -    this.m11  =   this._determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
   2.683 -    this.m21  = - this._determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
   2.684 -    this.m31  =   this._determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
   2.685 -    this.m41  = - this._determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
   2.686 -        
   2.687 -    this.m12  = - this._determinant3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
   2.688 -    this.m22  =   this._determinant3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
   2.689 -    this.m32  = - this._determinant3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
   2.690 -    this.m42  =   this._determinant3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
   2.691 -        
   2.692 -    this.m13  =   this._determinant3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
   2.693 -    this.m23  = - this._determinant3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
   2.694 -    this.m33  =   this._determinant3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
   2.695 -    this.m43  = - this._determinant3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
   2.696 -        
   2.697 -    this.m14  = - this._determinant3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
   2.698 -    this.m24  =   this._determinant3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
   2.699 -    this.m34  = - this._determinant3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
   2.700 -    this.m44  =   this._determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
   2.701 -}
   2.702 \ No newline at end of file
     3.1 --- a/scripts/glMatrix.js	Thu Mar 31 23:53:48 2011 +0200
     3.2 +++ b/scripts/glMatrix.js	Fri Apr 01 01:45:39 2011 +0200
     3.3 @@ -1,32 +0,0 @@
     3.4 -// glMatrix v0.9.5
     3.5 -glMatrixArrayType=typeof Float32Array!="undefined"?Float32Array:typeof WebGLFloatArray!="undefined"?WebGLFloatArray:Array;var vec3={};vec3.create=function(a){var b=new glMatrixArrayType(3);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2]}return b};vec3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];return b};vec3.add=function(a,b,c){if(!c||a==c){a[0]+=b[0];a[1]+=b[1];a[2]+=b[2];return a}c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];return c};
     3.6 -vec3.subtract=function(a,b,c){if(!c||a==c){a[0]-=b[0];a[1]-=b[1];a[2]-=b[2];return a}c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];return c};vec3.negate=function(a,b){b||(b=a);b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];return b};vec3.scale=function(a,b,c){if(!c||a==c){a[0]*=b;a[1]*=b;a[2]*=b;return a}c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;return c};
     3.7 -vec3.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=Math.sqrt(c*c+d*d+e*e);if(g){if(g==1){b[0]=c;b[1]=d;b[2]=e;return b}}else{b[0]=0;b[1]=0;b[2]=0;return b}g=1/g;b[0]=c*g;b[1]=d*g;b[2]=e*g;return b};vec3.cross=function(a,b,c){c||(c=a);var d=a[0],e=a[1];a=a[2];var g=b[0],f=b[1];b=b[2];c[0]=e*b-a*f;c[1]=a*g-d*b;c[2]=d*f-e*g;return c};vec3.length=function(a){var b=a[0],c=a[1];a=a[2];return Math.sqrt(b*b+c*c+a*a)};vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]};
     3.8 -vec3.direction=function(a,b,c){c||(c=a);var d=a[0]-b[0],e=a[1]-b[1];a=a[2]-b[2];b=Math.sqrt(d*d+e*e+a*a);if(!b){c[0]=0;c[1]=0;c[2]=0;return c}b=1/b;c[0]=d*b;c[1]=e*b;c[2]=a*b;return c};vec3.lerp=function(a,b,c,d){d||(d=a);d[0]=a[0]+c*(b[0]-a[0]);d[1]=a[1]+c*(b[1]-a[1]);d[2]=a[2]+c*(b[2]-a[2]);return d};vec3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+"]"};var mat3={};
     3.9 -mat3.create=function(a){var b=new glMatrixArrayType(9);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9]}return b};mat3.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return b};mat3.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a};
    3.10 -mat3.transpose=function(a,b){if(!b||a==b){var c=a[1],d=a[2],e=a[5];a[1]=a[3];a[2]=a[6];a[3]=c;a[5]=a[7];a[6]=d;a[7]=e;return a}b[0]=a[0];b[1]=a[3];b[2]=a[6];b[3]=a[1];b[4]=a[4];b[5]=a[7];b[6]=a[2];b[7]=a[5];b[8]=a[8];return b};mat3.toMat4=function(a,b){b||(b=mat4.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=0;b[4]=a[3];b[5]=a[4];b[6]=a[5];b[7]=0;b[8]=a[6];b[9]=a[7];b[10]=a[8];b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};
    3.11 -mat3.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+"]"};var mat4={};mat4.create=function(a){var b=new glMatrixArrayType(16);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15]}return b};
    3.12 -mat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return b};mat4.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=1;a[6]=0;a[7]=0;a[8]=0;a[9]=0;a[10]=1;a[11]=0;a[12]=0;a[13]=0;a[14]=0;a[15]=1;return a};
    3.13 -mat4.transpose=function(a,b){if(!b||a==b){var c=a[1],d=a[2],e=a[3],g=a[6],f=a[7],h=a[11];a[1]=a[4];a[2]=a[8];a[3]=a[12];a[4]=c;a[6]=a[9];a[7]=a[13];a[8]=d;a[9]=g;a[11]=a[14];a[12]=e;a[13]=f;a[14]=h;return a}b[0]=a[0];b[1]=a[4];b[2]=a[8];b[3]=a[12];b[4]=a[1];b[5]=a[5];b[6]=a[9];b[7]=a[13];b[8]=a[2];b[9]=a[6];b[10]=a[10];b[11]=a[14];b[12]=a[3];b[13]=a[7];b[14]=a[11];b[15]=a[15];return b};
    3.14 -mat4.determinant=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],g=a[4],f=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],o=a[11],m=a[12],n=a[13],p=a[14];a=a[15];return m*k*h*e-j*n*h*e-m*f*l*e+g*n*l*e+j*f*p*e-g*k*p*e-m*k*d*i+j*n*d*i+m*c*l*i-b*n*l*i-j*c*p*i+b*k*p*i+m*f*d*o-g*n*d*o-m*c*h*o+b*n*h*o+g*c*p*o-b*f*p*o-j*f*d*a+g*k*d*a+j*c*h*a-b*k*h*a-g*c*l*a+b*f*l*a};
    3.15 -mat4.inverse=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],o=a[10],m=a[11],n=a[12],p=a[13],r=a[14],s=a[15],A=c*h-d*f,B=c*i-e*f,t=c*j-g*f,u=d*i-e*h,v=d*j-g*h,w=e*j-g*i,x=k*p-l*n,y=k*r-o*n,z=k*s-m*n,C=l*r-o*p,D=l*s-m*p,E=o*s-m*r,q=1/(A*E-B*D+t*C+u*z-v*y+w*x);b[0]=(h*E-i*D+j*C)*q;b[1]=(-d*E+e*D-g*C)*q;b[2]=(p*w-r*v+s*u)*q;b[3]=(-l*w+o*v-m*u)*q;b[4]=(-f*E+i*z-j*y)*q;b[5]=(c*E-e*z+g*y)*q;b[6]=(-n*w+r*t-s*B)*q;b[7]=(k*w-o*t+m*B)*q;b[8]=(f*D-h*z+j*x)*q;
    3.16 -b[9]=(-c*D+d*z-g*x)*q;b[10]=(n*v-p*t+s*A)*q;b[11]=(-k*v+l*t-m*A)*q;b[12]=(-f*C+h*y-i*x)*q;b[13]=(c*C-d*y+e*x)*q;b[14]=(-n*u+p*B-r*A)*q;b[15]=(k*u-l*B+o*A)*q;return b};mat4.toRotationMat=function(a,b){b||(b=mat4.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};
    3.17 -mat4.toMat3=function(a,b){b||(b=mat3.create());b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[4];b[4]=a[5];b[5]=a[6];b[6]=a[8];b[7]=a[9];b[8]=a[10];return b};mat4.toInverseMat3=function(a,b){var c=a[0],d=a[1],e=a[2],g=a[4],f=a[5],h=a[6],i=a[8],j=a[9],k=a[10],l=k*f-h*j,o=-k*g+h*i,m=j*g-f*i,n=c*l+d*o+e*m;if(!n)return null;n=1/n;b||(b=mat3.create());b[0]=l*n;b[1]=(-k*d+e*j)*n;b[2]=(h*d-e*f)*n;b[3]=o*n;b[4]=(k*c-e*i)*n;b[5]=(-h*c+e*g)*n;b[6]=m*n;b[7]=(-j*c+d*i)*n;b[8]=(f*c-d*g)*n;return b};
    3.18 -mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2],f=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],o=a[9],m=a[10],n=a[11],p=a[12],r=a[13],s=a[14];a=a[15];var A=b[0],B=b[1],t=b[2],u=b[3],v=b[4],w=b[5],x=b[6],y=b[7],z=b[8],C=b[9],D=b[10],E=b[11],q=b[12],F=b[13],G=b[14];b=b[15];c[0]=A*d+B*h+t*l+u*p;c[1]=A*e+B*i+t*o+u*r;c[2]=A*g+B*j+t*m+u*s;c[3]=A*f+B*k+t*n+u*a;c[4]=v*d+w*h+x*l+y*p;c[5]=v*e+w*i+x*o+y*r;c[6]=v*g+w*j+x*m+y*s;c[7]=v*f+w*k+x*n+y*a;c[8]=z*d+C*h+D*l+E*p;c[9]=z*e+C*i+D*o+E*r;c[10]=z*
    3.19 -g+C*j+D*m+E*s;c[11]=z*f+C*k+D*n+E*a;c[12]=q*d+F*h+G*l+b*p;c[13]=q*e+F*i+G*o+b*r;c[14]=q*g+F*j+G*m+b*s;c[15]=q*f+F*k+G*n+b*a;return c};mat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1];b=b[2];c[0]=a[0]*d+a[4]*e+a[8]*b+a[12];c[1]=a[1]*d+a[5]*e+a[9]*b+a[13];c[2]=a[2]*d+a[6]*e+a[10]*b+a[14];return c};
    3.20 -mat4.multiplyVec4=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2];b=b[3];c[0]=a[0]*d+a[4]*e+a[8]*g+a[12]*b;c[1]=a[1]*d+a[5]*e+a[9]*g+a[13]*b;c[2]=a[2]*d+a[6]*e+a[10]*g+a[14]*b;c[3]=a[3]*d+a[7]*e+a[11]*g+a[15]*b;return c};
    3.21 -mat4.translate=function(a,b,c){var d=b[0],e=b[1];b=b[2];if(!c||a==c){a[12]=a[0]*d+a[4]*e+a[8]*b+a[12];a[13]=a[1]*d+a[5]*e+a[9]*b+a[13];a[14]=a[2]*d+a[6]*e+a[10]*b+a[14];a[15]=a[3]*d+a[7]*e+a[11]*b+a[15];return a}var g=a[0],f=a[1],h=a[2],i=a[3],j=a[4],k=a[5],l=a[6],o=a[7],m=a[8],n=a[9],p=a[10],r=a[11];c[0]=g;c[1]=f;c[2]=h;c[3]=i;c[4]=j;c[5]=k;c[6]=l;c[7]=o;c[8]=m;c[9]=n;c[10]=p;c[11]=r;c[12]=g*d+j*e+m*b+a[12];c[13]=f*d+k*e+n*b+a[13];c[14]=h*d+l*e+p*b+a[14];c[15]=i*d+o*e+r*b+a[15];return c};
    3.22 -mat4.scale=function(a,b,c){var d=b[0],e=b[1];b=b[2];if(!c||a==c){a[0]*=d;a[1]*=d;a[2]*=d;a[3]*=d;a[4]*=e;a[5]*=e;a[6]*=e;a[7]*=e;a[8]*=b;a[9]*=b;a[10]*=b;a[11]*=b;return a}c[0]=a[0]*d;c[1]=a[1]*d;c[2]=a[2]*d;c[3]=a[3]*d;c[4]=a[4]*e;c[5]=a[5]*e;c[6]=a[6]*e;c[7]=a[7]*e;c[8]=a[8]*b;c[9]=a[9]*b;c[10]=a[10]*b;c[11]=a[11]*b;c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15];return c};
    3.23 -mat4.rotate=function(a,b,c,d){var e=c[0],g=c[1];c=c[2];var f=Math.sqrt(e*e+g*g+c*c);if(!f)return null;if(f!=1){f=1/f;e*=f;g*=f;c*=f}var h=Math.sin(b),i=Math.cos(b),j=1-i;b=a[0];f=a[1];var k=a[2],l=a[3],o=a[4],m=a[5],n=a[6],p=a[7],r=a[8],s=a[9],A=a[10],B=a[11],t=e*e*j+i,u=g*e*j+c*h,v=c*e*j-g*h,w=e*g*j-c*h,x=g*g*j+i,y=c*g*j+e*h,z=e*c*j+g*h;e=g*c*j-e*h;g=c*c*j+i;if(d){if(a!=d){d[12]=a[12];d[13]=a[13];d[14]=a[14];d[15]=a[15]}}else d=a;d[0]=b*t+o*u+r*v;d[1]=f*t+m*u+s*v;d[2]=k*t+n*u+A*v;d[3]=l*t+p*u+B*
    3.24 -v;d[4]=b*w+o*x+r*y;d[5]=f*w+m*x+s*y;d[6]=k*w+n*x+A*y;d[7]=l*w+p*x+B*y;d[8]=b*z+o*e+r*g;d[9]=f*z+m*e+s*g;d[10]=k*z+n*e+A*g;d[11]=l*z+p*e+B*g;return d};mat4.rotateX=function(a,b,c){var d=Math.sin(b);b=Math.cos(b);var e=a[4],g=a[5],f=a[6],h=a[7],i=a[8],j=a[9],k=a[10],l=a[11];if(c){if(a!=c){c[0]=a[0];c[1]=a[1];c[2]=a[2];c[3]=a[3];c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15]}}else c=a;c[4]=e*b+i*d;c[5]=g*b+j*d;c[6]=f*b+k*d;c[7]=h*b+l*d;c[8]=e*-d+i*b;c[9]=g*-d+j*b;c[10]=f*-d+k*b;c[11]=h*-d+l*b;return c};
    3.25 -mat4.rotateY=function(a,b,c){var d=Math.sin(b);b=Math.cos(b);var e=a[0],g=a[1],f=a[2],h=a[3],i=a[8],j=a[9],k=a[10],l=a[11];if(c){if(a!=c){c[4]=a[4];c[5]=a[5];c[6]=a[6];c[7]=a[7];c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15]}}else c=a;c[0]=e*b+i*-d;c[1]=g*b+j*-d;c[2]=f*b+k*-d;c[3]=h*b+l*-d;c[8]=e*d+i*b;c[9]=g*d+j*b;c[10]=f*d+k*b;c[11]=h*d+l*b;return c};
    3.26 -mat4.rotateZ=function(a,b,c){var d=Math.sin(b);b=Math.cos(b);var e=a[0],g=a[1],f=a[2],h=a[3],i=a[4],j=a[5],k=a[6],l=a[7];if(c){if(a!=c){c[8]=a[8];c[9]=a[9];c[10]=a[10];c[11]=a[11];c[12]=a[12];c[13]=a[13];c[14]=a[14];c[15]=a[15]}}else c=a;c[0]=e*b+i*d;c[1]=g*b+j*d;c[2]=f*b+k*d;c[3]=h*b+l*d;c[4]=e*-d+i*b;c[5]=g*-d+j*b;c[6]=f*-d+k*b;c[7]=h*-d+l*b;return c};
    3.27 -mat4.frustum=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f};mat4.perspective=function(a,b,c,d,e){a=c*Math.tan(a*Math.PI/360);b=a*b;return mat4.frustum(-b,b,-a,a,c,d,e)};
    3.28 -mat4.ortho=function(a,b,c,d,e,g,f){f||(f=mat4.create());var h=b-a,i=d-c,j=g-e;f[0]=2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=2/i;f[6]=0;f[7]=0;f[8]=0;f[9]=0;f[10]=-2/j;f[11]=0;f[12]=-(a+b)/h;f[13]=-(d+c)/i;f[14]=-(g+e)/j;f[15]=1;return f};
    3.29 -mat4.lookAt=function(a,b,c,d){d||(d=mat4.create());var e=a[0],g=a[1];a=a[2];var f=c[0],h=c[1],i=c[2];c=b[1];var j=b[2];if(e==b[0]&&g==c&&a==j)return mat4.identity(d);var k,l,o,m;c=e-b[0];j=g-b[1];b=a-b[2];m=1/Math.sqrt(c*c+j*j+b*b);c*=m;j*=m;b*=m;k=h*b-i*j;i=i*c-f*b;f=f*j-h*c;if(m=Math.sqrt(k*k+i*i+f*f)){m=1/m;k*=m;i*=m;f*=m}else f=i=k=0;h=j*f-b*i;l=b*k-c*f;o=c*i-j*k;if(m=Math.sqrt(h*h+l*l+o*o)){m=1/m;h*=m;l*=m;o*=m}else o=l=h=0;d[0]=k;d[1]=h;d[2]=c;d[3]=0;d[4]=i;d[5]=l;d[6]=j;d[7]=0;d[8]=f;d[9]=
    3.30 -o;d[10]=b;d[11]=0;d[12]=-(k*e+i*g+f*a);d[13]=-(h*e+l*g+o*a);d[14]=-(c*e+j*g+b*a);d[15]=1;return d};mat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+", "+a[4]+", "+a[5]+", "+a[6]+", "+a[7]+", "+a[8]+", "+a[9]+", "+a[10]+", "+a[11]+", "+a[12]+", "+a[13]+", "+a[14]+", "+a[15]+"]"};quat4={};quat4.create=function(a){var b=new glMatrixArrayType(4);if(a){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3]}return b};quat4.set=function(a,b){b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];return b};
    3.31 -quat4.calculateW=function(a,b){var c=a[0],d=a[1],e=a[2];if(!b||a==b){a[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return a}b[0]=c;b[1]=d;b[2]=e;b[3]=-Math.sqrt(Math.abs(1-c*c-d*d-e*e));return b};quat4.inverse=function(a,b){if(!b||a==b){a[0]*=1;a[1]*=1;a[2]*=1;return a}b[0]=-a[0];b[1]=-a[1];b[2]=-a[2];b[3]=a[3];return b};quat4.length=function(a){var b=a[0],c=a[1],d=a[2];a=a[3];return Math.sqrt(b*b+c*c+d*d+a*a)};
    3.32 -quat4.normalize=function(a,b){b||(b=a);var c=a[0],d=a[1],e=a[2],g=a[3],f=Math.sqrt(c*c+d*d+e*e+g*g);if(f==0){b[0]=0;b[1]=0;b[2]=0;b[3]=0;return b}f=1/f;b[0]=c*f;b[1]=d*f;b[2]=e*f;b[3]=g*f;return b};quat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],g=a[2];a=a[3];var f=b[0],h=b[1],i=b[2];b=b[3];c[0]=d*b+a*f+e*i-g*h;c[1]=e*b+a*h+g*f-d*i;c[2]=g*b+a*i+d*h-e*f;c[3]=a*b-d*f-e*h-g*i;return c};
    3.33 -quat4.multiplyVec3=function(a,b,c){c||(c=b);var d=b[0],e=b[1],g=b[2];b=a[0];var f=a[1],h=a[2];a=a[3];var i=a*d+f*g-h*e,j=a*e+h*d-b*g,k=a*g+b*e-f*d;d=-b*d-f*e-h*g;c[0]=i*a+d*-b+j*-h-k*-f;c[1]=j*a+d*-f+k*-b-i*-h;c[2]=k*a+d*-h+i*-f-j*-b;return c};quat4.toMat3=function(a,b){b||(b=mat3.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c=c*i;var l=d*h;d=d*i;e=e*i;f=g*f;h=g*h;g=g*i;b[0]=1-(l+e);b[1]=k-g;b[2]=c+h;b[3]=k+g;b[4]=1-(j+e);b[5]=d-f;b[6]=c-h;b[7]=d+f;b[8]=1-(j+l);return b};
    3.34 -quat4.toMat4=function(a,b){b||(b=mat4.create());var c=a[0],d=a[1],e=a[2],g=a[3],f=c+c,h=d+d,i=e+e,j=c*f,k=c*h;c=c*i;var l=d*h;d=d*i;e=e*i;f=g*f;h=g*h;g=g*i;b[0]=1-(l+e);b[1]=k-g;b[2]=c+h;b[3]=0;b[4]=k+g;b[5]=1-(j+e);b[6]=d-f;b[7]=0;b[8]=c-h;b[9]=d+f;b[10]=1-(j+l);b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return b};quat4.slerp=function(a,b,c,d){d||(d=a);var e=c;if(a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]<0)e=-1*c;d[0]=1-c*a[0]+e*b[0];d[1]=1-c*a[1]+e*b[1];d[2]=1-c*a[2]+e*b[2];d[3]=1-c*a[3]+e*b[3];return d};
    3.35 -quat4.str=function(a){return"["+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+"]"};
     4.1 --- a/scripts/machine.js	Thu Mar 31 23:53:48 2011 +0200
     4.2 +++ b/scripts/machine.js	Fri Apr 01 01:45:39 2011 +0200
     4.3 @@ -1,129 +0,0 @@
     4.4 -function main()
     4.5 -{
     4.6 -    var canvas = document.getElementById("machine");
     4.7 -    var context = new Context(canvas);
     4.8 -    var gl = context.gl;
     4.9 -    var object = new Box(1, context);
    4.10 -    context.object = object
    4.11 -    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    4.12 -    gl.enable(gl.DEPTH_TEST);
    4.13 -    draw(context);
    4.14 -}
    4.15 -
    4.16 -function Context(canvas)
    4.17 -{
    4.18 -    try 
    4.19 -    {
    4.20 -	this.gl = canvas.getContext("experimental-webgl");
    4.21 -	this.viewport = {'width': canvas.width,
    4.22 -			 'height': canvas.height};
    4.23 -    } 
    4.24 -    catch(e) 
    4.25 -    {
    4.26 -	alert(e);
    4.27 -    }
    4.28 -    if (!this.gl) alert("Failed: WebGL init.");
    4.29 -    this.mvMatrix = mat4.create();
    4.30 -    this.pMatrix = mat4.create();
    4.31 -    this.shader = new Shader(this);    
    4.32 -}
    4.33 -Context.prototype.updateMatrixUniforms = function()
    4.34 -{
    4.35 -    var gl = this.gl;
    4.36 -    var program = this.shader;
    4.37 -    var pMatrix = this.pMatrix;
    4.38 -    var mvMatrix = this.mvMatrix;
    4.39 -    gl.uniformMatrix4fv(program.pMatrixUniform, false, pMatrix);
    4.40 -    gl.uniformMatrix4fv(program.mvMatrixUniform, false, mvMatrix);
    4.41 -}
    4.42 -
    4.43 -function Shader(context)
    4.44 -{
    4.45 -    var gl = context.gl;
    4.46 -    var fragment = loadShader(gl, "shader-fs");
    4.47 -    var vertex = loadShader(gl, "shader-vs");
    4.48 -    this.program = gl.createProgram();
    4.49 -    gl.attachShader(this.program, vertex);
    4.50 -    gl.attachShader(this.program, fragment);
    4.51 -    gl.linkProgram(this.program);
    4.52 -
    4.53 -    if (!gl.getProgramParameter(this.program, gl.LINK_STATUS))
    4.54 -    {
    4.55 -	alert("Failed: Shader init.");
    4.56 -    }
    4.57 -
    4.58 -    gl.useProgram(this.program);
    4.59 -    this.vertexPosition = gl.getAttribLocation(this.program, "aVertexPosition");
    4.60 -    gl.enableVertexAttribArray(this.vertexPosition);
    4.61 -    this.pMatrixUniform = gl.getUniformLocation(this.program, "uPMatrix");
    4.62 -    this.mvMatrixUniform = gl.getUniformLocation(this.program, "uMVMatrix");
    4.63 -
    4.64 -    function loadShader(gl, id)
    4.65 -    {
    4.66 -	var script = document.getElementById(id);
    4.67 -	if (!script) return null;
    4.68 -	
    4.69 -	var str = "";
    4.70 -	var child = script.firstChild;
    4.71 -	while (child)
    4.72 -	{
    4.73 -	    if (child.nodeType == 3) str += child.textContent;
    4.74 -	    child = child.nextSibling;
    4.75 -	}
    4.76 -	
    4.77 -	var shader;
    4.78 -	var common = "x-shader/x-";
    4.79 -	if (script.type == common + "fragment") shader = gl.createShader(gl.FRAGMENT_SHADER);
    4.80 -	else if (script.type == common + "vertex") shader = gl.createShader(gl.VERTEX_SHADER);
    4.81 -	else return null;
    4.82 -
    4.83 -	gl.shaderSource(shader, str);
    4.84 -	gl.compileShader(shader);
    4.85 -
    4.86 -	if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
    4.87 -        {
    4.88 -	    alert(gl.getShaderInfoLog(shader));
    4.89 -	    return null;
    4.90 -	}
    4.91 -
    4.92 -	return shader;
    4.93 -    }
    4.94 -}
    4.95 -
    4.96 -
    4.97 -function Box(size, context)
    4.98 -{
    4.99 -    var gl = context.gl;
   4.100 -    this.size = size || 1;
   4.101 -    this.buffer = gl.createBuffer();
   4.102 -    gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
   4.103 -    var vertices = [1.0, 1.0, 0.0,
   4.104 -		    -1.0, 1.0, 0.0,
   4.105 -		    1.0, -1.0, 0.0,
   4.106 -		    -1.0, -1.0, 0.0];
   4.107 -    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
   4.108 -    this.itemSize = 3;
   4.109 -    this.numItems = 4;
   4.110 -}
   4.111 -
   4.112 -function draw(context)
   4.113 -{
   4.114 -    var gl = context.gl;
   4.115 -    var viewport = context.viewport;
   4.116 -    var shader = context.shader;
   4.117 -    var mvMatrix = context.mvMatrix;
   4.118 -    var pMatrix = context.pMatrix;
   4.119 -    var object = context.object;
   4.120 -    gl.viewport(0, 0, viewport.width, viewport.height);
   4.121 -    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
   4.122 -    mat4.perspective(45, viewport.width / viewport.height, 0.1, 100.0, pMatrix);
   4.123 -    mat4.identity(mvMatrix);
   4.124 -    mat4.translate(mvMatrix, [0.0, 0.0, -7.0]);
   4.125 -    gl.bindBuffer(gl.ARRAY_BUFFER, object.buffer);
   4.126 -    gl.vertexAttribPointer(shader.vertexPosition, object.itemSize, gl.FLOAT, false, 0, 0);
   4.127 -    context.updateMatrixUniforms();
   4.128 -    //gl.uniformMatrix4fv(shader.pMatrixUniform, false, pMatrix);
   4.129 -    //gl.uniformMatrix4fv(shader.mvMatrixUniform, false, mvMatrix);
   4.130 -    gl.drawArrays(gl.TRIANGLE_STRIP, 0, object.numItems);
   4.131 -    return context;
   4.132 -}
   4.133 \ No newline at end of file
     5.1 --- a/scripts/utils3d.js	Thu Mar 31 23:53:48 2011 +0200
     5.2 +++ b/scripts/utils3d.js	Fri Apr 01 01:45:39 2011 +0200
     5.3 @@ -1,530 +0,0 @@
     5.4 -//
     5.5 -// initWebGL
     5.6 -//
     5.7 -// Initialize the Canvas element with the passed name as a WebGL object and return the
     5.8 -// WebGLRenderingContext. 
     5.9 -//
    5.10 -// Load shaders with the passed names and create a program with them. Return this program 
    5.11 -// in the 'program' property of the returned context.
    5.12 -//
    5.13 -// For each string in the passed attribs array, bind an attrib with that name at that index.
    5.14 -// Once the attribs are bound, link the program and then use it.
    5.15 -//
    5.16 -// Set the clear color to the passed array (4 values) and set the clear depth to the passed value.
    5.17 -// Enable depth testing and blending with a blend func of (SRC_ALPHA, ONE_MINUS_SRC_ALPHA)
    5.18 -//
    5.19 -function initWebGL(canvasName, vshader, fshader, attribs, clearColor, clearDepth)
    5.20 -{
    5.21 -    var canvas = document.getElementById(canvasName);
    5.22 -    var gl = canvas.getContext("webkit-3d");
    5.23 -
    5.24 -    // create our shaders
    5.25 -    var vertexShader = loadShader(gl, vshader);
    5.26 -    var fragmentShader = loadShader(gl, fshader);
    5.27 -
    5.28 -    if (!vertexShader || !fragmentShader)
    5.29 -        return null;
    5.30 -
    5.31 -    // Create the program object
    5.32 -    gl.program = gl.createProgram();
    5.33 -
    5.34 -    if (!gl.program)
    5.35 -        return null;
    5.36 -
    5.37 -    // Attach our two shaders to the program
    5.38 -    gl.attachShader (gl.program, vertexShader);
    5.39 -    gl.attachShader (gl.program, fragmentShader);
    5.40 -
    5.41 -    // Bind attributes
    5.42 -    for (var i in attribs)
    5.43 -        gl.bindAttribLocation (gl.program, i, attribs[i]);
    5.44 -
    5.45 -    // Link the program
    5.46 -    gl.linkProgram(gl.program);
    5.47 -
    5.48 -    // Check the link status
    5.49 -    var linked = gl.getProgrami(gl.program, gl.LINK_STATUS);
    5.50 -    if (!linked) {
    5.51 -        // something went wrong with the link
    5.52 -        var error = gl.getProgramInfoLog (gl.program);
    5.53 -        console.log("Error in program linking:"+error);
    5.54 -
    5.55 -        gl.deleteProgram(gl.program);
    5.56 -        gl.deleteProgram(fragmentShader);
    5.57 -        gl.deleteProgram(vertexShader);
    5.58 -
    5.59 -        return null;
    5.60 -    }
    5.61 -
    5.62 -    gl.useProgram(gl.program);
    5.63 -
    5.64 -    gl.clearColor (clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
    5.65 -    gl.clearDepth (clearDepth);
    5.66 -
    5.67 -    gl.enable(gl.DEPTH_TEST);
    5.68 -    gl.enable(gl.BLEND);
    5.69 -    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    5.70 -
    5.71 -    return gl;
    5.72 -}
    5.73 -
    5.74 -//
    5.75 -// loadShader
    5.76 -//
    5.77 -// 'shaderId' is the id of a <script> element containing the shader source string.
    5.78 -// Load this shader and return the WebGLShader object corresponding to it.
    5.79 -//
    5.80 -function loadShader(ctx, shaderId)
    5.81 -{
    5.82 -    var shaderScript = document.getElementById(shaderId);
    5.83 -    if (!shaderScript) {
    5.84 -        console.log("*** Error: shader script '"+shaderId+"' not found");
    5.85 -        return null;
    5.86 -    }
    5.87 -        
    5.88 -    if (shaderScript.type == "x-shader/x-vertex")
    5.89 -        var shaderType = ctx.VERTEX_SHADER;
    5.90 -    else if (shaderScript.type == "x-shader/x-fragment")
    5.91 -        var shaderType = ctx.FRAGMENT_SHADER;
    5.92 -    else {
    5.93 -        console.log("*** Error: shader script '"+shaderId+"' of undefined type '"+shaderScript.type+"'");       
    5.94 -        return null;
    5.95 -    }
    5.96 -
    5.97 -    // Create the shader object
    5.98 -    var shader = ctx.createShader(shaderType);
    5.99 -    if (shader == null) {
   5.100 -        console.log("*** Error: unable to create shader '"+shaderId+"'");       
   5.101 -        return null;
   5.102 -    }
   5.103 -
   5.104 -    // Load the shader source
   5.105 -    ctx.shaderSource(shader, shaderScript.text);
   5.106 -
   5.107 -    // Compile the shader
   5.108 -    ctx.compileShader(shader);
   5.109 -
   5.110 -    // Check the compile status
   5.111 -    var compiled = ctx.getShaderi(shader, ctx.COMPILE_STATUS);
   5.112 -    if (!compiled) {
   5.113 -        // Something went wrong during compilation; get the error
   5.114 -        var error = ctx.getShaderInfoLog(shader);
   5.115 -        console.log("*** Error compiling shader '"+shaderId+"':"+error);
   5.116 -        ctx.deleteShader(shader);
   5.117 -        return null;
   5.118 -    }
   5.119 -
   5.120 -    return shader;
   5.121 -}
   5.122 -
   5.123 -// 
   5.124 -// makeBox
   5.125 -//
   5.126 -// Create a box with vertices, normals and texCoords. Create VBOs for each as well as the index array.
   5.127 -// Return an object with the following properties:
   5.128 -//
   5.129 -//  normalObject        WebGLBuffer object for normals
   5.130 -//  texCoordObject      WebGLBuffer object for texCoords
   5.131 -//  vertexObject        WebGLBuffer object for vertices
   5.132 -//  indexObject         WebGLBuffer object for indices
   5.133 -//  numIndices          The number of indices in the indexObject
   5.134 -// 
   5.135 -function makeBox(ctx)
   5.136 -{
   5.137 -    // box
   5.138 -    //    v6----- v5
   5.139 -    //   /|      /|
   5.140 -    //  v1------v0|
   5.141 -    //  | |     | |
   5.142 -    //  | |v7---|-|v4
   5.143 -    //  |/      |/
   5.144 -    //  v2------v3
   5.145 -    //
   5.146 -    // vertex coords array
   5.147 -    var vertices = new WebGLFloatArray(
   5.148 -        [  1, 1, 1,  -1, 1, 1,  -1,-1, 1,   1,-1, 1,    // v0-v1-v2-v3 front
   5.149 -           1, 1, 1,   1,-1, 1,   1,-1,-1,   1, 1,-1,    // v0-v3-v4-v5 right
   5.150 -           1, 1, 1,   1, 1,-1,  -1, 1,-1,  -1, 1, 1,    // v0-v5-v6-v1 top
   5.151 -          -1, 1, 1,  -1, 1,-1,  -1,-1,-1,  -1,-1, 1,    // v1-v6-v7-v2 left
   5.152 -          -1,-1,-1,   1,-1,-1,   1,-1, 1,  -1,-1, 1,    // v7-v4-v3-v2 bottom
   5.153 -           1,-1,-1,  -1,-1,-1,  -1, 1,-1,   1, 1,-1 ]   // v4-v7-v6-v5 back
   5.154 -    );
   5.155 -
   5.156 -    // normal array
   5.157 -    var normals = new WebGLFloatArray(
   5.158 -        [  0, 0, 1,   0, 0, 1,   0, 0, 1,   0, 0, 1,     // v0-v1-v2-v3 front
   5.159 -           1, 0, 0,   1, 0, 0,   1, 0, 0,   1, 0, 0,     // v0-v3-v4-v5 right
   5.160 -           0, 1, 0,   0, 1, 0,   0, 1, 0,   0, 1, 0,     // v0-v5-v6-v1 top
   5.161 -          -1, 0, 0,  -1, 0, 0,  -1, 0, 0,  -1, 0, 0,     // v1-v6-v7-v2 left
   5.162 -           0,-1, 0,   0,-1, 0,   0,-1, 0,   0,-1, 0,     // v7-v4-v3-v2 bottom
   5.163 -           0, 0,-1,   0, 0,-1,   0, 0,-1,   0, 0,-1 ]    // v4-v7-v6-v5 back
   5.164 -       );
   5.165 -
   5.166 -
   5.167 -    // texCoord array
   5.168 -    var texCoords = new WebGLFloatArray(
   5.169 -        [  1, 1,   0, 1,   0, 0,   1, 0,    // v0-v1-v2-v3 front
   5.170 -           0, 1,   0, 0,   1, 0,   1, 1,    // v0-v3-v4-v5 right
   5.171 -           1, 0,   1, 1,   0, 1,   0, 0,    // v0-v5-v6-v1 top
   5.172 -           1, 1,   0, 1,   0, 0,   1, 0,    // v1-v6-v7-v2 left
   5.173 -           0, 0,   1, 0,   1, 1,   0, 1,    // v7-v4-v3-v2 bottom
   5.174 -           0, 0,   1, 0,   1, 1,   0, 1 ]   // v4-v7-v6-v5 back
   5.175 -       );
   5.176 -
   5.177 -    // index array
   5.178 -    var indices = new WebGLUnsignedByteArray(
   5.179 -        [  0, 1, 2,   0, 2, 3,    // front
   5.180 -           4, 5, 6,   4, 6, 7,    // right
   5.181 -           8, 9,10,   8,10,11,    // top
   5.182 -          12,13,14,  12,14,15,    // left
   5.183 -          16,17,18,  16,18,19,    // bottom
   5.184 -          20,21,22,  20,22,23 ]   // back
   5.185 -      );
   5.186 -
   5.187 -    var retval = { };
   5.188 -    
   5.189 -    retval.normalObject = ctx.createBuffer();
   5.190 -    ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.normalObject);
   5.191 -    ctx.bufferData(ctx.ARRAY_BUFFER, normals, ctx.STATIC_DRAW);
   5.192 -    
   5.193 -    retval.texCoordObject = ctx.createBuffer();
   5.194 -    ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.texCoordObject);
   5.195 -    ctx.bufferData(ctx.ARRAY_BUFFER, texCoords, ctx.STATIC_DRAW);
   5.196 -
   5.197 -    retval.vertexObject = ctx.createBuffer();
   5.198 -    ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.vertexObject);
   5.199 -    ctx.bufferData(ctx.ARRAY_BUFFER, vertices, ctx.STATIC_DRAW);
   5.200 -    
   5.201 -    ctx.bindBuffer(ctx.ARRAY_BUFFER, 0);
   5.202 -
   5.203 -    retval.indexObject = ctx.createBuffer();
   5.204 -    ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, retval.indexObject);
   5.205 -    ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, indices, ctx.STATIC_DRAW);
   5.206 -    ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, 0);
   5.207 -    
   5.208 -    retval.numIndices = indices.length;
   5.209 -
   5.210 -    return retval;
   5.211 -}
   5.212 -
   5.213 -// 
   5.214 -// makeSphere
   5.215 -//
   5.216 -// Create a sphere with the passed number of latitude and longitude bands and the passed radius. 
   5.217 -// Sphere has vertices, normals and texCoords. Create VBOs for each as well as the index array.
   5.218 -// Return an object with the following properties:
   5.219 -//
   5.220 -//  normalObject        WebGLBuffer object for normals
   5.221 -//  texCoordObject      WebGLBuffer object for texCoords
   5.222 -//  vertexObject        WebGLBuffer object for vertices
   5.223 -//  indexObject         WebGLBuffer object for indices
   5.224 -//  numIndices          The number of indices in the indexObject
   5.225 -// 
   5.226 -function makeSphere(ctx, radius, lats, longs)
   5.227 -{
   5.228 -    var geometryData = [ ];
   5.229 -    var normalData = [ ];
   5.230 -    var texCoordData = [ ];
   5.231 -    var indexData = [ ];
   5.232 -    
   5.233 -    for (var latNumber = 0; latNumber <= lats; ++latNumber) {
   5.234 -        for (var longNumber = 0; longNumber <= longs; ++longNumber) {
   5.235 -            var theta = latNumber * Math.PI / lats;
   5.236 -            var phi = longNumber * 2 * Math.PI / longs;
   5.237 -            var sinTheta = Math.sin(theta);
   5.238 -            var sinPhi = Math.sin(phi);
   5.239 -            var cosTheta = Math.cos(theta);
   5.240 -            var cosPhi = Math.cos(phi);
   5.241 -            
   5.242 -            var x = cosPhi * sinTheta;
   5.243 -            var y = cosTheta;
   5.244 -            var z = sinPhi * sinTheta;
   5.245 -            var u = 1-(longNumber/longs);
   5.246 -            var v = latNumber/lats;
   5.247 -            
   5.248 -            normalData.push(x);
   5.249 -            normalData.push(y);
   5.250 -            normalData.push(z);
   5.251 -            texCoordData.push(u);
   5.252 -            texCoordData.push(v);
   5.253 -            geometryData.push(radius * x);
   5.254 -            geometryData.push(radius * y);
   5.255 -            geometryData.push(radius * z);
   5.256 -        }
   5.257 -    }
   5.258 -    
   5.259 -    longs += 1;
   5.260 -    for (var latNumber = 0; latNumber < lats; ++latNumber) {
   5.261 -        for (var longNumber = 0; longNumber < longs; ++longNumber) {
   5.262 -            var first = (latNumber * longs) + (longNumber % longs);
   5.263 -            var second = first + longs;
   5.264 -            indexData.push(first);
   5.265 -            indexData.push(second);
   5.266 -            indexData.push(first+1);
   5.267 -
   5.268 -            indexData.push(second);
   5.269 -            indexData.push(second+1);
   5.270 -            indexData.push(first+1);
   5.271 -        }
   5.272 -    }
   5.273 -    
   5.274 -    var retval = { };
   5.275 -    
   5.276 -    retval.normalObject = ctx.createBuffer();
   5.277 -    ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.normalObject);
   5.278 -    ctx.bufferData(ctx.ARRAY_BUFFER, new WebGLFloatArray(normalData), ctx.STATIC_DRAW);
   5.279 -
   5.280 -    retval.texCoordObject = ctx.createBuffer();
   5.281 -    ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.texCoordObject);
   5.282 -    ctx.bufferData(ctx.ARRAY_BUFFER, new WebGLFloatArray(texCoordData), ctx.STATIC_DRAW);
   5.283 -
   5.284 -    retval.vertexObject = ctx.createBuffer();
   5.285 -    ctx.bindBuffer(ctx.ARRAY_BUFFER, retval.vertexObject);
   5.286 -    ctx.bufferData(ctx.ARRAY_BUFFER, new WebGLFloatArray(geometryData), ctx.STATIC_DRAW);
   5.287 -    
   5.288 -    retval.numIndices = indexData.length;
   5.289 -    retval.indexObject = ctx.createBuffer();
   5.290 -    ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, retval.indexObject);
   5.291 -    ctx.bufferData(ctx.ELEMENT_ARRAY_BUFFER, new WebGLUnsignedShortArray(indexData), ctx.STREAM_DRAW);
   5.292 -    
   5.293 -    return retval;
   5.294 -}
   5.295 -
   5.296 -//
   5.297 -// loadObj
   5.298 -//
   5.299 -// Load a .obj file from the passed URL. Return an object with a 'loaded' property set to false.
   5.300 -// When the object load is complete, the 'loaded' property becomes true and the following 
   5.301 -// properties are set:
   5.302 -//
   5.303 -//  normalObject        WebGLBuffer object for normals
   5.304 -//  texCoordObject      WebGLBuffer object for texCoords
   5.305 -//  vertexObject        WebGLBuffer object for vertices
   5.306 -//  indexObject         WebGLBuffer object for indices
   5.307 -//  numIndices          The number of indices in the indexObject
   5.308 -//  
   5.309 -function loadObj(ctx, url)
   5.310 -{
   5.311 -    var obj = { loaded : false };
   5.312 -    obj.ctx = ctx;
   5.313 -    var req = new XMLHttpRequest();
   5.314 -    req.obj = obj;
   5.315 -    req.onreadystatechange = function () { processLoadObj(req) };
   5.316 -    req.open("GET", url, true);
   5.317 -    req.send(null);
   5.318 -    return obj;
   5.319 -}
   5.320 -
   5.321 -function processLoadObj(req) 
   5.322 -{
   5.323 -    console.log("req="+req)
   5.324 -    // only if req shows "complete"
   5.325 -    if (req.readyState == 4) {
   5.326 -        doLoadObj(req.obj, req.responseText);
   5.327 -    }
   5.328 -}
   5.329 -
   5.330 -function doLoadObj(obj, text)
   5.331 -{
   5.332 -    vertexArray = [ ];
   5.333 -    normalArray = [ ];
   5.334 -    textureArray = [ ];
   5.335 -    indexArray = [ ];
   5.336 -    
   5.337 -    var vertex = [ ];
   5.338 -    var normal = [ ];
   5.339 -    var texture = [ ];
   5.340 -    var facemap = { };
   5.341 -    var index = 0;
   5.342 -        
   5.343 -    var lines = text.split("\n");
   5.344 -    for (var lineIndex in lines) {
   5.345 -        var line = lines[lineIndex].replace(/[ \t]+/g, " ").replace(/\s\s*$/, "");
   5.346 -        
   5.347 -        // ignore comments
   5.348 -        if (line[0] == "#")
   5.349 -            continue;
   5.350 -            
   5.351 -        var array = line.split(" ");
   5.352 -        if (array[0] == "v") {
   5.353 -            // vertex
   5.354 -            vertex.push(parseFloat(array[1]));
   5.355 -            vertex.push(parseFloat(array[2]));
   5.356 -            vertex.push(parseFloat(array[3]));
   5.357 -        }
   5.358 -        else if (array[0] == "vt") {
   5.359 -            // normal
   5.360 -            texture.push(parseFloat(array[1]));
   5.361 -            texture.push(parseFloat(array[2]));
   5.362 -        }
   5.363 -        else if (array[0] == "vn") {
   5.364 -            // normal
   5.365 -            normal.push(parseFloat(array[1]));
   5.366 -            normal.push(parseFloat(array[2]));
   5.367 -            normal.push(parseFloat(array[3]));
   5.368 -        }
   5.369 -        else if (array[0] == "f") {
   5.370 -            // face
   5.371 -            if (array.length != 4) {
   5.372 -                console.log("*** Error: face '"+line+"' not handled");
   5.373 -                continue;
   5.374 -            }
   5.375 -            
   5.376 -            for (var i = 1; i < 4; ++i) {
   5.377 -                if (!(array[i] in facemap)) {
   5.378 -                    // add a new entry to the map and arrays
   5.379 -                    var f = array[i].split("/");
   5.380 -                    var vtx, nor, tex;
   5.381 -                    
   5.382 -                    if (f.length == 1) {
   5.383 -                        vtx = parseInt(f[0]) - 1;
   5.384 -                        nor = vtx;
   5.385 -                        tex = vtx;
   5.386 -                    }
   5.387 -                    else if (f.length = 3) {
   5.388 -                        vtx = parseInt(f[0]) - 1;
   5.389 -                        tex = parseInt(f[1]) - 1;
   5.390 -                        nor = parseInt(f[2]) - 1;
   5.391 -                    }
   5.392 -                    else {
   5.393 -                        console.log("*** Error: did not understand face '"+array[i]+"'");
   5.394 -                        return null;
   5.395 -                    }
   5.396 -                    
   5.397 -                    // do the vertices
   5.398 -                    var x = 0;
   5.399 -                    var y = 0;
   5.400 -                    var z = 0;
   5.401 -                    if (vtx * 3 + 2 < vertex.length) {
   5.402 -                        x = vertex[vtx*3];
   5.403 -                        y = vertex[vtx*3+1];
   5.404 -                        z = vertex[vtx*3+2];
   5.405 -                    }
   5.406 -                    vertexArray.push(x);
   5.407 -                    vertexArray.push(y);
   5.408 -                    vertexArray.push(z);
   5.409 -                    
   5.410 -                    // do the textures
   5.411 -                    x = 0;
   5.412 -                    y = 0;
   5.413 -                    if (tex * 2 + 1 < texture.length) {
   5.414 -                        x = texture[tex*2];
   5.415 -                        y = texture[tex*2+1];
   5.416 -                    }
   5.417 -                    textureArray.push(x);
   5.418 -                    textureArray.push(y);
   5.419 -                    
   5.420 -                    // do the normals
   5.421 -                    x = 0;
   5.422 -                    y = 0;
   5.423 -                    z = 1;
   5.424 -                    if (nor * 3 + 2 < normal.length) {
   5.425 -                        x = normal[nor*3];
   5.426 -                        y = normal[nor*3+1];
   5.427 -                        z = normal[nor*3+2];
   5.428 -                    }
   5.429 -                    normalArray.push(x);
   5.430 -                    normalArray.push(y);
   5.431 -                    normalArray.push(z);
   5.432 -                    
   5.433 -                    facemap[array[i]] = index++;
   5.434 -                }
   5.435 -                
   5.436 -                indexArray.push(facemap[array[i]]);
   5.437 -            }
   5.438 -        }
   5.439 -    }
   5.440 -
   5.441 -    // set the VBOs
   5.442 -    obj.normalObject = obj.ctx.createBuffer();
   5.443 -    obj.ctx.bindBuffer(obj.ctx.ARRAY_BUFFER, obj.normalObject);
   5.444 -    obj.ctx.bufferData(obj.ctx.ARRAY_BUFFER, new WebGLFloatArray(normalArray), obj.ctx.STATIC_DRAW);
   5.445 -
   5.446 -    obj.texCoordObject = obj.ctx.createBuffer();
   5.447 -    obj.ctx.bindBuffer(obj.ctx.ARRAY_BUFFER, obj.texCoordObject);
   5.448 -    obj.ctx.bufferData(obj.ctx.ARRAY_BUFFER, new WebGLFloatArray(textureArray), obj.ctx.STATIC_DRAW);
   5.449 -
   5.450 -    obj.vertexObject = obj.ctx.createBuffer();
   5.451 -    obj.ctx.bindBuffer(obj.ctx.ARRAY_BUFFER, obj.vertexObject);
   5.452 -    obj.ctx.bufferData(obj.ctx.ARRAY_BUFFER, new WebGLFloatArray(vertexArray), obj.ctx.STATIC_DRAW);
   5.453 -    
   5.454 -    obj.numIndices = indexArray.length;
   5.455 -    obj.indexObject = obj.ctx.createBuffer();
   5.456 -    obj.ctx.bindBuffer(obj.ctx.ELEMENT_ARRAY_BUFFER, obj.indexObject);
   5.457 -    obj.ctx.bufferData(obj.ctx.ELEMENT_ARRAY_BUFFER, new WebGLUnsignedShortArray(indexArray), obj.ctx.STREAM_DRAW);
   5.458 -    
   5.459 -    obj.loaded = true;
   5.460 -}
   5.461 -
   5.462 -//
   5.463 -// loadImageTexture
   5.464 -//
   5.465 -// Load the image at the passed url, place it in a new WebGLTexture object and return the WebGLTexture.
   5.466 -//
   5.467 -function loadImageTexture(ctx, url)
   5.468 -{
   5.469 -    var texture = ctx.createTexture();
   5.470 -    texture.image = new Image();
   5.471 -    texture.image.onload = function() { doLoadImageTexture(ctx, texture.image, texture) }
   5.472 -    texture.image.src = url;
   5.473 -    return texture;
   5.474 -}
   5.475 -
   5.476 -function doLoadImageTexture(ctx, image, texture)
   5.477 -{
   5.478 -    ctx.enable(ctx.TEXTURE_2D);
   5.479 -    ctx.bindTexture(ctx.TEXTURE_2D, texture);
   5.480 -    ctx.texImage2D(ctx.TEXTURE_2D, 0, image);
   5.481 -    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR);
   5.482 -    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR_MIPMAP_LINEAR);
   5.483 -    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
   5.484 -    ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
   5.485 -    ctx.generateMipmap(ctx.TEXTURE_2D)
   5.486 -    ctx.bindTexture(ctx.TEXTURE_2D, 0);
   5.487 -}
   5.488 -
   5.489 -//
   5.490 -// Framerate object
   5.491 -//
   5.492 -// This object keeps track of framerate and displays it as the innerHTML text of the 
   5.493 -// HTML element with the passed id. Once created you call snapshot at the end
   5.494 -// of every rendering cycle. Every 500ms the framerate is updated in the HTML element.
   5.495 -//
   5.496 -Framerate = function(id)
   5.497 -{
   5.498 -    this.numFramerates = 10;
   5.499 -    this.framerateUpdateInterval = 500;
   5.500 -    this.id = id;
   5.501 -
   5.502 -    this.renderTime = -1;
   5.503 -    this.framerates = [ ];
   5.504 -    self = this;
   5.505 -    var fr = function() { self.updateFramerate() }
   5.506 -    setInterval(fr, this.framerateUpdateInterval);
   5.507 -}
   5.508 -
   5.509 -Framerate.prototype.updateFramerate = function()
   5.510 -{
   5.511 -    var tot = 0;
   5.512 -    for (var i = 0; i < this.framerates.length; ++i)
   5.513 -        tot += this.framerates[i];
   5.514 -        
   5.515 -    var framerate = tot / this.framerates.length;
   5.516 -    framerate = Math.round(framerate);
   5.517 -    document.getElementById(this.id).innerHTML = "Framerate:"+framerate+"fps";
   5.518 -}
   5.519 -
   5.520 -Framerate.prototype.snapshot = function()
   5.521 -{
   5.522 -    if (this.renderTime < 0)
   5.523 -        this.renderTime = new Date().getTime();
   5.524 -    else {
   5.525 -        var newTime = new Date().getTime();
   5.526 -        var t = newTime - this.renderTime;
   5.527 -        var framerate = 1000/t;
   5.528 -        this.framerates.push(framerate);
   5.529 -        while (this.framerates.length > this.numFramerates)
   5.530 -            this.framerates.shift();
   5.531 -        this.renderTime = newTime;
   5.532 -    }
   5.533 -}
   5.534 \ No newline at end of file