|
| 1 | +// augment Sylvester some |
| 2 | +Matrix.Translation = function (v) |
| 3 | +{ |
| 4 | + if (v.elements.length == 2) { |
| 5 | + var r = Matrix.I(3); |
| 6 | + r.elements[2][0] = v.elements[0]; |
| 7 | + r.elements[2][1] = v.elements[1]; |
| 8 | + return r; |
| 9 | + } |
| 10 | + |
| 11 | + if (v.elements.length == 3) { |
| 12 | + var r = Matrix.I(4); |
| 13 | + r.elements[0][3] = v.elements[0]; |
| 14 | + r.elements[1][3] = v.elements[1]; |
| 15 | + r.elements[2][3] = v.elements[2]; |
| 16 | + return r; |
| 17 | + } |
| 18 | + |
| 19 | + throw "Invalid length for Translation"; |
| 20 | +} |
| 21 | + |
| 22 | +Matrix.prototype.flatten = function () |
| 23 | +{ |
| 24 | + var result = []; |
| 25 | + if (this.elements.length == 0) |
| 26 | + return []; |
| 27 | + |
| 28 | + |
| 29 | + for (var j = 0; j < this.elements[0].length; j++) |
| 30 | + for (var i = 0; i < this.elements.length; i++) |
| 31 | + result.push(this.elements[i][j]); |
| 32 | + return result; |
| 33 | +} |
| 34 | + |
| 35 | +Matrix.prototype.ensure4x4 = function() |
| 36 | +{ |
| 37 | + if (this.elements.length == 4 && |
| 38 | + this.elements[0].length == 4) |
| 39 | + return this; |
| 40 | + |
| 41 | + if (this.elements.length > 4 || |
| 42 | + this.elements[0].length > 4) |
| 43 | + return null; |
| 44 | + |
| 45 | + for (var i = 0; i < this.elements.length; i++) { |
| 46 | + for (var j = this.elements[i].length; j < 4; j++) { |
| 47 | + if (i == j) |
| 48 | + this.elements[i].push(1); |
| 49 | + else |
| 50 | + this.elements[i].push(0); |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + for (var i = this.elements.length; i < 4; i++) { |
| 55 | + if (i == 0) |
| 56 | + this.elements.push([1, 0, 0, 0]); |
| 57 | + else if (i == 1) |
| 58 | + this.elements.push([0, 1, 0, 0]); |
| 59 | + else if (i == 2) |
| 60 | + this.elements.push([0, 0, 1, 0]); |
| 61 | + else if (i == 3) |
| 62 | + this.elements.push([0, 0, 0, 1]); |
| 63 | + } |
| 64 | + |
| 65 | + return this; |
| 66 | +}; |
| 67 | + |
| 68 | +Matrix.prototype.make3x3 = function() |
| 69 | +{ |
| 70 | + if (this.elements.length != 4 || |
| 71 | + this.elements[0].length != 4) |
| 72 | + return null; |
| 73 | + |
| 74 | + return Matrix.create([[this.elements[0][0], this.elements[0][1], this.elements[0][2]], |
| 75 | + [this.elements[1][0], this.elements[1][1], this.elements[1][2]], |
| 76 | + [this.elements[2][0], this.elements[2][1], this.elements[2][2]]]); |
| 77 | +}; |
| 78 | + |
| 79 | +Vector.prototype.flatten = function () |
| 80 | +{ |
| 81 | + return this.elements; |
| 82 | +}; |
| 83 | + |
| 84 | +function mht(m) { |
| 85 | + var s = ""; |
| 86 | + if (m.length == 16) { |
| 87 | + for (var i = 0; i < 4; i++) { |
| 88 | + s += "<span style='font-family: monospace'>[" + m[i*4+0].toFixed(4) + "," + m[i*4+1].toFixed(4) + "," + m[i*4+2].toFixed(4) + "," + m[i*4+3].toFixed(4) + "]</span><br>"; |
| 89 | + } |
| 90 | + } else if (m.length == 9) { |
| 91 | + for (var i = 0; i < 3; i++) { |
| 92 | + s += "<span style='font-family: monospace'>[" + m[i*3+0].toFixed(4) + "," + m[i*3+1].toFixed(4) + "," + m[i*3+2].toFixed(4) + "]</font><br>"; |
| 93 | + } |
| 94 | + } else { |
| 95 | + return m.toString(); |
| 96 | + } |
| 97 | + return s; |
| 98 | +} |
| 99 | + |
| 100 | +// |
| 101 | +// gluLookAt |
| 102 | +// |
| 103 | +function makeLookAt(ex, ey, ez, |
| 104 | + cx, cy, cz, |
| 105 | + ux, uy, uz) |
| 106 | +{ |
| 107 | + var eye = $V([ex, ey, ez]); |
| 108 | + var center = $V([cx, cy, cz]); |
| 109 | + var up = $V([ux, uy, uz]); |
| 110 | + |
| 111 | + var mag; |
| 112 | + |
| 113 | + var z = eye.subtract(center).toUnitVector(); |
| 114 | + var x = up.cross(z).toUnitVector(); |
| 115 | + var y = z.cross(x).toUnitVector(); |
| 116 | + |
| 117 | + var m = $M([[x.e(1), x.e(2), x.e(3), 0], |
| 118 | + [y.e(1), y.e(2), y.e(3), 0], |
| 119 | + [z.e(1), z.e(2), z.e(3), 0], |
| 120 | + [0, 0, 0, 1]]); |
| 121 | + |
| 122 | + var t = $M([[1, 0, 0, -ex], |
| 123 | + [0, 1, 0, -ey], |
| 124 | + [0, 0, 1, -ez], |
| 125 | + [0, 0, 0, 1]]); |
| 126 | + return m.x(t); |
| 127 | +} |
| 128 | + |
| 129 | +// |
| 130 | +// glOrtho |
| 131 | +// |
| 132 | +function makeOrtho(left, right, |
| 133 | + bottom, top, |
| 134 | + znear, zfar) |
| 135 | +{ |
| 136 | + var tx = -(right+left)/(right-left); |
| 137 | + var ty = -(top+bottom)/(top-bottom); |
| 138 | + var tz = -(zfar+znear)/(zfar-znear); |
| 139 | + |
| 140 | + return $M([[2/(right-left), 0, 0, tx], |
| 141 | + [0, 2/(top-bottom), 0, ty], |
| 142 | + [0, 0, -2/(zfar-znear), tz], |
| 143 | + [0, 0, 0, 1]]); |
| 144 | +} |
| 145 | + |
| 146 | +// |
| 147 | +// gluPerspective |
| 148 | +// |
| 149 | +function makePerspective(fovy, aspect, znear, zfar) |
| 150 | +{ |
| 151 | + var ymax = znear * Math.tan(fovy * Math.PI / 360.0); |
| 152 | + var ymin = -ymax; |
| 153 | + var xmin = ymin * aspect; |
| 154 | + var xmax = ymax * aspect; |
| 155 | + |
| 156 | + return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar); |
| 157 | +} |
| 158 | + |
| 159 | +// |
| 160 | +// glFrustum |
| 161 | +// |
| 162 | +function makeFrustum(left, right, |
| 163 | + bottom, top, |
| 164 | + znear, zfar) |
| 165 | +{ |
| 166 | + var X = 2*znear/(right-left); |
| 167 | + var Y = 2*znear/(top-bottom); |
| 168 | + var A = (right+left)/(right-left); |
| 169 | + var B = (top+bottom)/(top-bottom); |
| 170 | + var C = -(zfar+znear)/(zfar-znear); |
| 171 | + var D = -2*zfar*znear/(zfar-znear); |
| 172 | + |
| 173 | + return $M([[X, 0, A, 0], |
| 174 | + [0, Y, B, 0], |
| 175 | + [0, 0, C, D], |
| 176 | + [0, 0, -1, 0]]); |
| 177 | +} |
| 178 | + |
| 179 | +// |
| 180 | +// glOrtho |
| 181 | +// |
| 182 | +function makeOrtho(left, right, bottom, top, znear, zfar) |
| 183 | +{ |
| 184 | + var tx = - (right + left) / (right - left); |
| 185 | + var ty = - (top + bottom) / (top - bottom); |
| 186 | + var tz = - (zfar + znear) / (zfar - znear); |
| 187 | + |
| 188 | + return $M([[2 / (right - left), 0, 0, tx], |
| 189 | + [0, 2 / (top - bottom), 0, ty], |
| 190 | + [0, 0, -2 / (zfar - znear), tz], |
| 191 | + [0, 0, 0, 1]]); |
| 192 | +} |
| 193 | + |
0 commit comments