├── .gitignore ├── LICENSE ├── README.md ├── _config.yml ├── css └── style.css ├── dwgl ├── dw_app.js ├── dw_easycam.js ├── dw_geometry.js ├── dw_gl.js ├── dw_orbit.js └── dw_utils.js ├── lib ├── dat.gui-0.6.5 │ ├── CHANGELOG.md │ ├── LICENSE │ ├── dat.gui.css │ ├── dat.gui.js │ ├── dat.gui.js.map │ └── dat.gui.min.js └── gl-matrix-2.4.0 │ ├── CNAME │ ├── LICENSE.md │ ├── VERSION │ ├── gl-matrix-min.js │ ├── gl-matrix.js │ └── src │ ├── gl-matrix.js │ └── gl-matrix │ ├── common.js │ ├── mat2.js │ ├── mat2d.js │ ├── mat3.js │ ├── mat4.js │ ├── quat.js │ ├── vec2.js │ ├── vec3.js │ └── vec4.js └── sketches ├── ConstructionCubes.html ├── Cubes_FBO.html ├── Cubes_VBO_Test.html ├── EdgesDisplay.html ├── GeometryPrimitives.html ├── HilbertCurve.html ├── MengerSponge.html ├── NormalsDisplay.html ├── PerPixelPhong.html ├── PerPixelPhong_Primitives.html ├── Quads_VBO_Test.html ├── ReactionDiffusion.html ├── ShadowMapping_Basic.html ├── Smoothstep.html ├── SubdivisionPrimitives.html ├── depthmap.js ├── screenshots ├── DeconstructionCubes1.jpg ├── DeconstructionCubes1_small1.jpg ├── DeconstructionCubes2.jpg ├── DeconstructionCubes2_small1.jpg ├── EdgesDisplay.jpg ├── EdgesDisplay_small1.jpg ├── GeometryPrimitives.jpg ├── GeometryPrimitives_small1.jpg ├── HilbertCurve1.jpg ├── HilbertCurve1_small1.jpg ├── HilbertCurve2.jpg ├── HilbertCurve2_small1.jpg ├── MengerSponge1.jpg ├── MengerSponge1_small1.jpg ├── MengerSponge2.jpg ├── MengerSponge2_small1.jpg ├── MengerSponge3.jpg ├── NormalsDisplay.jpg ├── NormalsDisplay_small1.jpg ├── PerPixelPhong1.jpg ├── PerPixelPhong1_small1.jpg ├── PerPixelPhong_Primitives1.jpg ├── PerPixelPhong_Primitives1_small1.jpg ├── ReactionDiffusion1.jpg ├── ReactionDiffusion1_small1.jpg ├── Smoothstep1.jpg ├── Smoothstep1_small1.jpg ├── SubdivisionPrimitives1.jpg ├── SubdivisionPrimitives1_small1.jpg ├── SubdivisionPrimitives2.jpg ├── SubdivisionPrimitives2_small1.jpg ├── SubdivisionPrimitives3.jpg └── SubdivisionPrimitives3_small1.jpg ├── setup_global.html └── setup_local.html /.gitignore: -------------------------------------------------------------------------------- 1 | /sketches/screenshots/small 2 | /sketches/screenshots/screenshots.psd 3 | /sketches/screenshots/screenshots_small.psd 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Thomas Diewald 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dw-webgl-sketchbook 2 | 3 | Showroom for my Webgl Experiments. 4 | 5 | The demos require a browser that supports webgl2. 6 | 7 | 8 | # Sketches 9 | 10 | - [Construction Cubes](https://diwi.github.io/dw-webgl-sketchbook/sketches/ConstructionCubes.html) 11 | - [GeometryPrimitives](https://diwi.github.io/dw-webgl-sketchbook/sketches/GeometryPrimitives.html) 12 | - [HilbertCurve](https://diwi.github.io/dw-webgl-sketchbook/sketches/HilbertCurve.html) 13 | - [MengerSponge](https://diwi.github.io/dw-webgl-sketchbook/sketches/MengerSponge.html) 14 | - [NormalsDisplay](https://diwi.github.io/dw-webgl-sketchbook/sketches/NormalsDisplay.html) 15 | - [EdgesDisplay](https://diwi.github.io/dw-webgl-sketchbook/sketches/EdgesDisplay.html) 16 | - [PerPixelPhong](https://diwi.github.io/dw-webgl-sketchbook/sketches/PerPixelPhong.html) 17 | - [PerPixelPhong_Primitives](https://diwi.github.io/dw-webgl-sketchbook/sketches/PerPixelPhong_Primitives.html) 18 | - [ReactionDiffusion](https://diwi.github.io/dw-webgl-sketchbook/sketches/ReactionDiffusion.html) 19 | - [Smoothstep](https://diwi.github.io/dw-webgl-sketchbook/sketches/Smoothstep.html) 20 | - [SubdivisionPrimitives](https://diwi.github.io/dw-webgl-sketchbook/sketches/SubdivisionPrimitives.html) 21 | - [ShadowMapping](https://diwi.github.io/dw-webgl-sketchbook/sketches/ShadowMapping_Basic.html) 22 | # Screenshots 23 | 24 |  25 |  26 |  27 |  28 |  29 |  30 |  31 |  32 |  33 |  34 |  35 |  36 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | } 3 | 4 | .unselectable{ 5 | -moz-user-select: none; 6 | -webkit-user-select: none; 7 | -ms-user-select: none; 8 | -o-user-select: none; 9 | user-select: none; 10 | } 11 | 12 | .selectable-text{ 13 | -moz-user-select: text; 14 | -webkit-user-select: text; 15 | -ms-user-select: text; 16 | -o-user-select: text; 17 | user-select: text; 18 | } 19 | 20 | *{ 21 | margin: 0px; 22 | padding: 0px; 23 | } 24 | 25 | html{ 26 | width:100%; 27 | height:100%; 28 | } 29 | 30 | body{ 31 | width:100%; 32 | height:100%; 33 | background-color: rgba(0,0,0,1); 34 | font-family: FontAwesome, Optima, Segoe, Segoe UI, Candara, Calibri, Arial, sans-serif; 35 | font-style: normal; 36 | font-variant: normal; 37 | font-weight: 400; 38 | letter-spacing: 1px; 39 | font-size: small; 40 | color: rgb(96, 96, 96); 41 | } 42 | 43 | #Dw-Canvas, 44 | #DwCanvas{ 45 | z-index : 0; 46 | position: absolute; 47 | margin: auto; 48 | top: 0; 49 | bottom: 0; 50 | left: 0; 51 | right: 0; 52 | width: 100%; 53 | height: 100%; 54 | background: #000; 55 | } 56 | 57 | #hud{ 58 | z-index : 2; 59 | position: absolute; 60 | margin: auto; 61 | top : 0; 62 | left: 0; 63 | right: 0; 64 | padding: 10px; 65 | background: rgba(0,0,0,0.8); 66 | color: #FFF; 67 | text-align: center; 68 | } 69 | 70 | #sketch-title { 71 | /* color: #99ccff; */ 72 | margin-bottom: 7; 73 | } 74 | 75 | #sketch-stats { 76 | /* font-weight: lighter; */ 77 | /* letter-spacing: 0; */ 78 | font-size: smaller; 79 | color: #ffa64c; 80 | } 81 | 82 | #sketch-controls { 83 | font-weight: lighter; 84 | /* letter-spacing: 0; */ 85 | font-size: smaller; 86 | color: #ffa64c; 87 | } 88 | 89 | 90 | .dg.ac { 91 | z-index : 12; 92 | } 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /dwgl/dw_app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * dw-webgl-sketchbook: https://github.com/diwi/dw-webgl-sketchbook 4 | * 5 | * Copyright 2018 by Thomas Diewald, https://www.thomasdiewald.com 6 | * 7 | * MIT License: https://opensource.org/licenses/MIT 8 | * 9 | */ 10 | 11 | 12 | 13 | var Dw = (function(out) { 14 | 15 | 16 | 17 | class Mouse { 18 | 19 | constructor(){ 20 | this.x = 0; this.px = 0; 21 | this.y = 0; this.py = 0; 22 | this.LMB = 0; 23 | this.MMB = 0; 24 | this.RMB = 0; 25 | this.down = 0; 26 | } 27 | 28 | attach(canvas){ 29 | this.canvas = canvas; 30 | canvas .addEventListener('mousedown', this.mousedown.bind(this), false); 31 | document.addEventListener('mouseup' , this.mouseup .bind(this), false); 32 | document.addEventListener('mousemove', this.mousemove.bind(this), false); 33 | } 34 | 35 | setPos(ev){ 36 | var canvas = this.canvas; 37 | this.x = ev.clientX - canvas.clientLeft - canvas.offsetLeft; 38 | this.y = ev.clientY - canvas.clientLeft - canvas.offsetTop; 39 | } 40 | 41 | mousedown(ev){ 42 | this.down = true; 43 | if(ev.button === 0) this.LMB = true; 44 | if(ev.button === 1) this.MMB = true; 45 | if(ev.button === 2) this.RMB = true; 46 | this.setPos(ev); 47 | } 48 | 49 | mouseup(ev){ 50 | this.down = false; 51 | if(ev.button === 0) this.LMB = false; 52 | if(ev.button === 1) this.MMB = false; 53 | if(ev.button === 2) this.RMB = false; 54 | this.setPos(ev); 55 | } 56 | 57 | mousemove(ev){ 58 | this.setPos(ev); 59 | } 60 | 61 | }; 62 | 63 | 64 | 65 | 66 | var requestAnimationFrame = (function() { 67 | return window.requestAnimationFrame || 68 | window.webkitRequestAnimationFrame || 69 | window.mozRequestAnimationFrame || 70 | window.oRequestAnimationFrame || 71 | window.msRequestAnimationFrame || 72 | function(callback, element) { 73 | return window.setTimeout(callback, 1000/60); 74 | }; 75 | })(); 76 | 77 | var cancelAnimationFrame = (function() { 78 | return window.cancelAnimationFrame || 79 | window.webkitCancelAnimationFrame || 80 | window.mozCancelAnimationFrame || 81 | window.oCancelAnimationFrame || 82 | window.msCancelAnimationFrame || 83 | window.clearTimeout; 84 | })(); 85 | 86 | var performance = window.performance || {}; 87 | performance.now = (function() { 88 | const start_time = Date.now(); 89 | return ( 90 | window.performance.now || 91 | window.performance.webkitNow || 92 | window.performance.mozNow || 93 | window.performance.oNow || 94 | window.performance.msNow || 95 | function() { 96 | return Date.now() - start_time; 97 | } 98 | ); 99 | })(); 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | class App { 113 | 114 | constructor(opt, user_cb){ 115 | 116 | if(typeof arguments[0] === 'function' && arguments.length === 1){ 117 | user_cb = arguments[0]; 118 | } 119 | 120 | opt = (typeof opt === 'object') ? opt : {}; 121 | opt.title = opt.title || 'Dw-Webgl-Sketchbook'; 122 | 123 | if(typeof arguments[0] === 'string'){ 124 | opt.title = arguments[0]; 125 | } 126 | 127 | var app = this; 128 | 129 | this.setTitle(opt.title); 130 | 131 | this.webgl_attributes = { 132 | alpha: true, // canvas contains an alpha buffer. 133 | depth: true, // drawing buffer has a depth buffer of at least 16 bits. 134 | stencil: true, // drawing buffer has a stencil buffer of at least 8 bits. 135 | antialias: true, // whether or not to perform anti-aliasing. 136 | premultipliedAlpha: false, // drawing buffer contains colors with pre-multiplied alpha. 137 | preserveDrawingBuffer: true, // buffers will not be cleared 138 | preferLowPowerToHighPerformance : false, 139 | failIfMajorPerformanceCaveat: true 140 | }; 141 | // this.webgl_names = ['webgl2', 'webgl', 'experimental-webgl']; 142 | this.webgl_names = ['webgl2']; 143 | 144 | this.smooth = 0.9; 145 | this.framecount = 0; 146 | this.framerate = 60; 147 | this.frametime = performance.now() - 1000/this.framerate; 148 | 149 | this.mouse = new Mouse(); 150 | 151 | 152 | window.addEventListener('resize', function(ev) { 153 | var w = app.canvas.clientWidth; 154 | var h = app.canvas.clientHeight; 155 | app.canvas.resize(w, h); 156 | if(app.resize) app.resize(w, h); 157 | }, false); 158 | 159 | // TODO 160 | window.addEventListener('unload', function(){ 161 | if(app.release) app.release(); 162 | }, false); 163 | 164 | this.init = ('undefined' !== typeof init ) ? init : null; 165 | this.setup = ('undefined' !== typeof setup ) ? setup : null; 166 | this.resize = ('undefined' !== typeof resize ) ? resize : null; 167 | this.draw = ('undefined' !== typeof draw ) ? draw : null; 168 | this.release = ('undefined' !== typeof release) ? release : null; 169 | 170 | // input events 171 | this.mousemove = ('undefined' !== typeof mousemove ) ? mousemove : null; 172 | this.mouseup = ('undefined' !== typeof mouseup ) ? mouseup : null; 173 | this.mousedown = ('undefined' !== typeof mousedown ) ? mousedown : null; 174 | this.click = ('undefined' !== typeof click ) ? click : null; 175 | this.dblclick = ('undefined' !== typeof dblclick ) ? dblclick : null; 176 | this.touchstart = ('undefined' !== typeof touchstart) ? touchstart : null; 177 | this.touchend = ('undefined' !== typeof touchend ) ? touchend : null; 178 | this.touchmove = ('undefined' !== typeof touchmove ) ? touchmove : null; 179 | this.keyup = ('undefined' !== typeof keyup ) ? keyup : null; 180 | this.keydown = ('undefined' !== typeof keydown ) ? keydown : null; 181 | // ... tbc ... 182 | 183 | this.registered = { 184 | pre : [], 185 | post : [], 186 | }; 187 | 188 | 189 | // 0) 190 | if(typeof user_cb === 'function'){ 191 | user_cb(this); 192 | } 193 | 194 | // 1) 195 | if(app.init) app.init(); 196 | this.createCanvas(); 197 | this.createWebglContext(); 198 | this.mouse.attach(this.canvas); 199 | 200 | // input events 201 | if(this.mousemove ) document .addEventListener('mousemove' , this.mousemove .bind(this), false); 202 | if(this.mouseup ) document .addEventListener('mouseup' , this.mouseup .bind(this), false); 203 | if(this.mousedown ) this.canvas.addEventListener('mousedown' , this.mousedown .bind(this), false); 204 | if(this.click ) this.canvas.addEventListener('click' , this.click .bind(this), false); 205 | if(this.dblclick ) this.canvas.addEventListener('dblclick' , this.dblclick .bind(this), false); 206 | if(this.touchstart) this.canvas.addEventListener('touchstart', this.touchstart.bind(this), false); 207 | if(this.touchend ) this.canvas.addEventListener('touchend' , this.touchend .bind(this), false); 208 | if(this.touchmove ) this.canvas.addEventListener('touchmove' , this.touchmove .bind(this), false); 209 | if(this.keyup ) window .addEventListener('keyup' , this.keyup .bind(this), false); 210 | if(this.keydown ) window .addEventListener('keydown' , this.keydown .bind(this), false); 211 | // ... tbc ... 212 | 213 | if(this.gl){ 214 | 215 | // 2) 216 | if(app.setup) app.setup(); 217 | 218 | // 3) 219 | if(app.draw){ 220 | 221 | var loop; 222 | 223 | (loop = function() { 224 | 225 | var pre = this.registered.pre; 226 | var post = this.registered.post; 227 | 228 | for(var i = 0; i < pre.length; i++){ 229 | pre[i](); 230 | } 231 | 232 | this.draw(); 233 | 234 | for(var i = 0; i < post.length; i++){ 235 | post[i](); 236 | } 237 | 238 | this.updateFramerate(); 239 | this.updateMouse(); 240 | 241 | requestAnimationFrame(loop); 242 | 243 | }.bind(this))(); 244 | 245 | } 246 | } else { 247 | this.init = null; 248 | this.setup = null; 249 | this.resize = null; 250 | this.draw = null; 251 | this.release = null; 252 | 253 | var parent = document.getElementById('sketch-stats'); 254 | parent.innerHTML = ">> Sorry, this Browser does not support "+this.webgl_names.join('|')+" <<"; 255 | } 256 | } 257 | 258 | 259 | setTitle(title){ 260 | this.title = title; 261 | // div 262 | var div_title = document.getElementById('sketch-title'); 263 | if(div_title){ 264 | div_title.textContent = title; 265 | } 266 | // tag 267 | var tag_title = document.getElementsByTagName('title'); 268 | if(tag_title.length){ 269 | tag_title[0].textContent = title; 270 | } else { 271 | tag_title = document.createElement('title'); 272 | document.head.appendChild(tag_title); 273 | tag_title.textContent = title; 274 | } 275 | } 276 | 277 | 278 | createCanvas(name, w, h){ 279 | if(this.canvas){ 280 | return; 281 | } 282 | name = name || 'Dw-Canvas'; 283 | var canvas = document.getElementById(name); 284 | if(!canvas){ 285 | canvas = document.createElement('canvas'); 286 | canvas.width = w || window.innerWidth; 287 | canvas.height = h || window.innerHeight; 288 | canvas.id = name; 289 | document.body.appendChild(canvas); 290 | } else { 291 | canvas.width = w || canvas.clientWidth; 292 | canvas.height = h || canvas.clientHeight; 293 | } 294 | 295 | canvas.resize = function(w_, h_){ 296 | this.width = w_ || this.clientWidth; 297 | this.height = h_ || this.clientHeight; 298 | }; 299 | 300 | canvas.resize(); 301 | 302 | this.canvas = canvas; 303 | 304 | return this.canvas; 305 | } 306 | 307 | 308 | createWebglContext(){ 309 | if(this.gl){ 310 | return; 311 | } 312 | var names = this.webgl_names; 313 | var gl = null; 314 | for (var i = 0; i < names.length; ++i) { 315 | try { 316 | gl = this.canvas.getContext(names[i], this.webgl_attributes); 317 | } catch(e) {} 318 | if (gl) { 319 | break; 320 | } 321 | } 322 | this.gl = gl; 323 | 324 | if(!!!gl){ 325 | console.log('sorry, no webgl available for: ' + names); 326 | } 327 | 328 | return gl; 329 | } 330 | 331 | updateFramerate(){ 332 | var time_now = performance.now(); 333 | this.frameduration = time_now - this.frametime; 334 | this.frametime = time_now; 335 | this.framerate = (this.framerate * this.smooth) + (1-this.smooth)*(1000/this.frameduration); 336 | this.framecount++; 337 | } 338 | 339 | updateMouse(){ 340 | this.mouse.px = this.mouse.x; 341 | this.mouse.py = this.mouse.y; 342 | } 343 | } 344 | 345 | 346 | 347 | 348 | out = (out !== undefined) ? out : {}; 349 | 350 | out.App = App; 351 | out.Mouse = Mouse; 352 | 353 | out.start = function(opt, user_cb){ 354 | return new App(opt, user_cb); 355 | } 356 | 357 | 358 | return out; 359 | 360 | 361 | })(Dw); 362 | 363 | -------------------------------------------------------------------------------- /dwgl/dw_orbit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * dw-webgl-sketchbook: https://github.com/diwi/dw-webgl-sketchbook 4 | * 5 | * Copyright 2018 by Thomas Diewald, https://www.thomasdiewald.com 6 | * 7 | * MIT License: https://opensource.org/licenses/MIT 8 | * 9 | */ 10 | 11 | 12 | 13 | 14 | var Dw = (function(out) { 15 | 16 | // simple wraper for damping a value 17 | class Damp { 18 | 19 | constructor(val, speed, damp, limit){ 20 | this.val_reset = val; 21 | this.val_start = val; 22 | this.val_now = val; 23 | this.val_end = val; 24 | 25 | this.limit = limit; 26 | 27 | this.speed = speed; 28 | this.damp = damp; 29 | this.state = null; 30 | } 31 | 32 | active(){ 33 | return this.state !== null; 34 | } 35 | 36 | start(state){ 37 | this.state = state; 38 | this.val_start = this.val_now; 39 | } 40 | 41 | drag(state){ 42 | if(this.active()){ 43 | var delta = this.state - state; 44 | this.val_end = this.val_start + delta * this.speed; 45 | if(this.limit){ 46 | this.val_end = Math.min(Math.max(this.val_end, this.limit[0]), this.limit[1]); 47 | } 48 | } 49 | } 50 | 51 | end(){ 52 | this.state = null; 53 | } 54 | 55 | update(){ 56 | this.val_now = this.val_end * this.damp + this.val_now * (1.0 - this.damp); 57 | } 58 | 59 | reset(val_new){ 60 | this.val_end = (val_new !== undefined) ? val_new : this.val_reset; 61 | } 62 | } 63 | 64 | 65 | 66 | 67 | // Most simple camera I could think off. 68 | // Provides some very basic Orbit (rotateX,rotateY) and Zoom (scale). 69 | class OrbitControl { 70 | 71 | constructor(parent){ 72 | this.parent = parent; 73 | this.active = true; 74 | this.rx = new Damp(0.0, +0.01, 0.07); 75 | this.ry = new Damp(0.0, +0.01, 0.07); 76 | this.zoom = new Damp(1000.0, -10, 0.07, [10, 10000]); 77 | var cam = this; 78 | 79 | parent.canvas.addEventListener('dblclick', function(e){ 80 | cam.reset(); 81 | }); 82 | parent.canvas.addEventListener('mousedown', function(e){ 83 | if(e.button === 0) cam.startOrbit(); 84 | if(e.button === 2) cam.startZoom(); 85 | }); 86 | document.addEventListener('mouseup', function(e){ 87 | if(e.button === 0) cam.endOrbit(); 88 | if(e.button === 2) cam.endZoom(); 89 | }); 90 | 91 | // if(parent.registered && parent.registered.pre){ 92 | // parent.registered.pre.push( function(){ cam.update(); }); 93 | // } 94 | } 95 | 96 | startOrbit(){ 97 | this.rx.start(this.parent.mouse.y); 98 | this.ry.start(this.parent.mouse.x); 99 | } 100 | 101 | startZoom(){ 102 | this.zoom.start(this.parent.mouse.y); 103 | } 104 | 105 | drag(){ 106 | this.zoom.drag(this.parent.mouse.y); 107 | this.rx.drag (this.parent.mouse.y); 108 | this.ry.drag (this.parent.mouse.x); 109 | } 110 | 111 | endOrbit(){ 112 | this.rx.end(); 113 | this.ry.end(); 114 | } 115 | 116 | endZoom(){ 117 | this.zoom.end(); 118 | } 119 | 120 | activate(active){ 121 | this.active = active; 122 | } 123 | 124 | reset(){ 125 | this.rx.reset(); 126 | this.ry.reset(); 127 | this.zoom.reset(); 128 | } 129 | 130 | update(){ 131 | if(this.active) { 132 | this.drag(); 133 | this.rx.update(); 134 | this.ry.update(); 135 | this.zoom.update(); 136 | } 137 | return this; 138 | } 139 | 140 | apply(m4){ 141 | mat4.translate(m4, m4, [0,0,-this.zoom.val_now]); 142 | mat4.rotateX(m4, m4, this.rx.val_now); 143 | mat4.rotateZ(m4, m4, this.ry.val_now); 144 | return this; 145 | } 146 | 147 | } 148 | 149 | 150 | 151 | 152 | out = (out !== undefined) ? out : {}; 153 | 154 | out.OrbitControl = OrbitControl; 155 | out.Damp = Damp; 156 | 157 | 158 | return out; 159 | 160 | 161 | })(Dw); 162 | 163 | -------------------------------------------------------------------------------- /dwgl/dw_utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * dw-webgl-sketchbook: https://github.com/diwi/dw-webgl-sketchbook 4 | * 5 | * Copyright 2018 by Thomas Diewald, https://www.thomasdiewald.com 6 | * 7 | * MIT License: https://opensource.org/licenses/MIT 8 | * 9 | */ 10 | 11 | 12 | 13 | 14 | 15 | var Dw = (function(out) { 16 | 17 | 18 | out = (out !== undefined) ? out : {}; 19 | 20 | out.PI = Math.PI; 21 | out.PI2 = Math.PI * 2.0; 22 | out.TO_RAD = Math.PI / 180.0; 23 | out.SQRT2 = Math.sqrt(2); 24 | out.GOLDEN_RATIO = (1.0 + Math.sqrt(5.0)) / 2.0; 25 | 26 | var random = function(){ 27 | var x = ++random.seed; 28 | var y = ++random.seed; 29 | var val = Math.sin(x * 12.9898 + y * 78.233) * 43758.545; 30 | return (val - Math.floor(val)); 31 | } 32 | random.seed = 0; 33 | 34 | out.random = random; 35 | 36 | out.logNceil = function(val, n){ 37 | return Math.ceil(Math.log(val)/Math.log(n)); 38 | } 39 | 40 | out.log2ceil = function(val){ 41 | return out.logNceil(val, 2.0); 42 | } 43 | 44 | out.log4ceil = function(val){ 45 | return out.logNceil(val, 4.0); 46 | } 47 | 48 | out.mix = function(a, b, t){ 49 | return a * (1.0-t) + b * (t); 50 | } 51 | 52 | out.clamp = function(a, lo, hi){ 53 | if(a < lo) return lo; else if(a > hi)return hi; else return a; 54 | } 55 | 56 | out.smoothstepn = function(x){ 57 | return x*x*(3 - 2*x); 58 | } 59 | 60 | out.smootherstepn = function(x){ 61 | return x*x*x*(x*(x*6 - 15) + 10); 62 | } 63 | 64 | out.smoothstep = function(edge0, edge1, x){ 65 | x = out.clamp((x - edge0)/(edge1 - edge0), 0.0, 1.0); // [0, 1] 66 | return out.smoothstepn(x); 67 | } 68 | 69 | out.smootherstep = function(edge0, edge1, x){ 70 | x = out.clamp((x - edge0)/(edge1 - edge0), 0.0, 1.0); // [0, 1] 71 | return out.smootherstepn(x); 72 | } 73 | 74 | out.map = function(val, a0, a1, b0, b1){ 75 | return b0 + (b1 - b0) * ((val - a0) / (a1 - a0)); 76 | } 77 | out.clampedmap = function(val, a0, a1, b0, b1){ 78 | return Dw.clamp(Dw.map(val,a0, a1, b0, b1), b0, b1); 79 | } 80 | 81 | return out; 82 | 83 | })(Dw); 84 | 85 | -------------------------------------------------------------------------------- /lib/dat.gui-0.6.5/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | ### 0.6.5 4 | * Add browserify support. #137 5 | 6 | ### 0.6.4 7 | * Fixed formatting issue on Windows. #136 8 | * Fixed issue with color selector getting chopped off at bottom of gui. #136 9 | 10 | ### 0.6.3 11 | * Added ability to put close button on top of the menu [ex: var gui = new dat.gui.GUI({closeOnTop:true})]. #106 #122 12 | * Fixed issue with layout not updating on page resize. 13 | * Fixed color picker showing in wrong position on user scroll (long menu). #105 14 | * Fixed checkbox weirdness while listening. #40 15 | * Fixed bower issues. #125 16 | 17 | ### 0.6.2 18 | * Fixed issue with color picker not returning correct values onFinishChange. #116 #117 19 | * Fixed issue with color picker not showing the correct label for color format. #117 20 | * Fixed NumberControllerBox onFinishChange event. #112 21 | * Fixed issue with GUI not being sized correct at start. #111 22 | 23 | ### 0.6.1 24 | * Fixed issue with color picker not working on a page that has scrolled. #37 25 | * Fixed issue with sliders created with min()/max() not remembering their name or to listen. #107 26 | 27 | ### 0.6.0 28 | * Ported to ES6 29 | * Exported using Universal Module Definition (UMD) for max compatibility (Commonjs, Requirejs, AMD, global var) 30 | * Now using webpack for build 31 | * Optional external CSS file (dat.gui.css) for use on CSP-enabled servers that block unsafe-inline 32 | * Added updateDisplay() to GUI, to update all controls in all folders - https://github.com/dataarts/dat.gui/pull/97 33 | * Fixed GUI.destroy() to remove all window eventListeners - https://github.com/dataarts/dat.gui/pull/88 34 | * Fixed performance issue when rotated on tablet/mobile - https://github.com/dataarts/dat.gui/pull/91 35 | * Fixed issue that prevented user from changing values of controls that are listening - https://github.com/dataarts/dat.gui/issues/100 36 | * Fixed issues with onFinishChange callbacks on revert - https://github.com/dataarts/dat.gui/pull/103 37 | * Fixed issues with color selector formatting - https://github.com/dataarts/dat.gui/issues/73 38 | * Fixed issues with step parameters in sliders - https://github.com/dataarts/dat.gui/issues/74 39 | * Fixed an issue with colors based on arrays - https://github.com/dataarts/dat.gui/pull/57 40 | * Fixed factory.js, Step param was not used - https://github.com/dataarts/dat.gui/pull/45 41 | 42 | ### 0.5 43 | * Moved to requirejs for dependency management. 44 | * Changed global namespace from *DAT* to *dat* (lowercase). 45 | * Added support for color controllers. See [Color Controllers](http://workshop.chromeexperiments.com/examples/gui/#4--Color-Controllers). 46 | * Added support for folders. See [Folders](http://workshop.chromeexperiments.com/examples/gui/#3--Folders). 47 | * Added support for saving named presets. See [Presets](http://workshop.chromeexperiments.com/examples/gui/examples/gui/#6--Presets). 48 | * Removed `height` parameter from GUI constructor. Scrollbar automatically induced when window is too short. 49 | * `dat.GUI.autoPlace` parameter removed. Use `new dat.GUI( { autoPlace: false } )`. See [Custom Placement](http://workshop.chromeexperiments.com/examples/gui/#9--Custom-Placement). 50 | * `gui.autoListen` and `gui.listenAll()` removed. See [Updating The Display Manually](http://workshop.chromeexperiments.com/examples/gui/#11--Updating-the-Display-Manually). 51 | * `dat.GUI.load` removed. See [Saving Values](http://workshop.chromeexperiments.com/examples/gui/#5--Saving-Values). 52 | * Made Controller code completely agnostic of GUI. Controllers can easily be created independent of a GUI panel. 53 | 54 | ### 0.4 55 | * Migrated from GitHub to Google Code. 56 | -------------------------------------------------------------------------------- /lib/dat.gui-0.6.5/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2014, Google Inc. 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /lib/dat.gui-0.6.5/dat.gui.css: -------------------------------------------------------------------------------- 1 | .dg { 2 | /** Clear list styles */ 3 | /* Auto-place container */ 4 | /* Auto-placed GUI's */ 5 | /* Line items that don't contain folders. */ 6 | /** Folder names */ 7 | /** Hides closed items */ 8 | /** Controller row */ 9 | /** Name-half (left) */ 10 | /** Controller-half (right) */ 11 | /** Controller placement */ 12 | /** Shorter number boxes when slider is present. */ 13 | /** Ensure the entire boolean and function row shows a hand */ 14 | /** allow overflow for color selector */ } 15 | .dg ul { 16 | list-style: none; 17 | margin: 0; 18 | padding: 0; 19 | width: 100%; 20 | clear: both; } 21 | .dg.ac { 22 | position: fixed; 23 | top: 0; 24 | left: 0; 25 | right: 0; 26 | height: 0; 27 | z-index: 0; } 28 | .dg:not(.ac) .main { 29 | /** Exclude mains in ac so that we don't hide close button */ 30 | overflow: hidden; } 31 | .dg.main { 32 | -webkit-transition: opacity 0.1s linear; 33 | -o-transition: opacity 0.1s linear; 34 | -moz-transition: opacity 0.1s linear; 35 | transition: opacity 0.1s linear; } 36 | .dg.main.taller-than-window { 37 | overflow-y: auto; } 38 | .dg.main.taller-than-window .close-button { 39 | opacity: 1; 40 | /* TODO, these are style notes */ 41 | margin-top: -1px; 42 | border-top: 1px solid #2c2c2c; } 43 | .dg.main ul.closed .close-button { 44 | opacity: 1 !important; } 45 | .dg.main:hover .close-button, 46 | .dg.main .close-button.drag { 47 | opacity: 1; } 48 | .dg.main .close-button { 49 | /*opacity: 0;*/ 50 | -webkit-transition: opacity 0.1s linear; 51 | -o-transition: opacity 0.1s linear; 52 | -moz-transition: opacity 0.1s linear; 53 | transition: opacity 0.1s linear; 54 | border: 0; 55 | line-height: 19px; 56 | height: 20px; 57 | /* TODO, these are style notes */ 58 | cursor: pointer; 59 | text-align: center; 60 | background-color: #000; } 61 | .dg.main .close-button.close-top { 62 | position: relative; } 63 | .dg.main .close-button.close-bottom { 64 | position: absolute; } 65 | .dg.main .close-button:hover { 66 | background-color: #111; } 67 | .dg.a { 68 | float: right; 69 | margin-right: 15px; 70 | overflow-y: visible; } 71 | .dg.a.has-save > ul.close-top { 72 | margin-top: 0; } 73 | .dg.a.has-save > ul.close-bottom { 74 | margin-top: 27px; } 75 | .dg.a.has-save > ul.closed { 76 | margin-top: 0; } 77 | .dg.a .save-row { 78 | top: 0; 79 | z-index: 1002; } 80 | .dg.a .save-row.close-top { 81 | position: relative; } 82 | .dg.a .save-row.close-bottom { 83 | position: fixed; } 84 | .dg li { 85 | -webkit-transition: height 0.1s ease-out; 86 | -o-transition: height 0.1s ease-out; 87 | -moz-transition: height 0.1s ease-out; 88 | transition: height 0.1s ease-out; 89 | -webkit-transition: overflow 0.1s linear; 90 | -o-transition: overflow 0.1s linear; 91 | -moz-transition: overflow 0.1s linear; 92 | transition: overflow 0.1s linear; } 93 | .dg li:not(.folder) { 94 | cursor: auto; 95 | height: 27px; 96 | line-height: 27px; 97 | padding: 0 4px 0 5px; } 98 | .dg li.folder { 99 | padding: 0; 100 | border-left: 4px solid transparent; } 101 | .dg li.title { 102 | cursor: pointer; 103 | margin-left: -4px; } 104 | .dg .closed li:not(.title), 105 | .dg .closed ul li, 106 | .dg .closed ul li > * { 107 | height: 0; 108 | overflow: hidden; 109 | border: 0; } 110 | .dg .cr { 111 | clear: both; 112 | padding-left: 3px; 113 | height: 27px; 114 | overflow: hidden; } 115 | .dg .property-name { 116 | cursor: default; 117 | float: left; 118 | clear: left; 119 | width: 40%; 120 | overflow: hidden; 121 | text-overflow: ellipsis; } 122 | .dg .c { 123 | float: left; 124 | width: 60%; 125 | position: relative; } 126 | .dg .c input[type=text] { 127 | border: 0; 128 | margin-top: 4px; 129 | padding: 3px; 130 | width: 100%; 131 | float: right; } 132 | .dg .has-slider input[type=text] { 133 | width: 30%; 134 | /*display: none;*/ 135 | margin-left: 0; } 136 | .dg .slider { 137 | float: left; 138 | width: 66%; 139 | margin-left: -5px; 140 | margin-right: 0; 141 | height: 19px; 142 | margin-top: 4px; } 143 | .dg .slider-fg { 144 | height: 100%; } 145 | .dg .c input[type=checkbox] { 146 | margin-top: 7px; } 147 | .dg .c select { 148 | margin-top: 5px; } 149 | .dg .cr.function, 150 | .dg .cr.function .property-name, 151 | .dg .cr.function *, 152 | .dg .cr.boolean, 153 | .dg .cr.boolean * { 154 | cursor: pointer; } 155 | .dg .cr.color { 156 | overflow: visible; } 157 | .dg .selector { 158 | display: none; 159 | position: absolute; 160 | margin-left: -9px; 161 | margin-top: 23px; 162 | z-index: 10; } 163 | .dg .c:hover .selector, 164 | .dg .selector.drag { 165 | display: block; } 166 | .dg li.save-row { 167 | padding: 0; } 168 | .dg li.save-row .button { 169 | display: inline-block; 170 | padding: 0px 6px; } 171 | .dg.dialogue { 172 | background-color: #222; 173 | width: 460px; 174 | padding: 15px; 175 | font-size: 13px; 176 | line-height: 15px; } 177 | 178 | /* TODO Separate style and structure */ 179 | #dg-new-constructor { 180 | padding: 10px; 181 | color: #222; 182 | font-family: Monaco, monospace; 183 | font-size: 10px; 184 | border: 0; 185 | resize: none; 186 | box-shadow: inset 1px 1px 1px #888; 187 | word-wrap: break-word; 188 | margin: 12px 0; 189 | display: block; 190 | width: 440px; 191 | overflow-y: scroll; 192 | height: 100px; 193 | position: relative; } 194 | 195 | #dg-local-explain { 196 | display: none; 197 | font-size: 11px; 198 | line-height: 17px; 199 | border-radius: 3px; 200 | background-color: #333; 201 | padding: 8px; 202 | margin-top: 10px; } 203 | #dg-local-explain code { 204 | font-size: 10px; } 205 | 206 | #dat-gui-save-locally { 207 | display: none; } 208 | 209 | /** Main type */ 210 | .dg { 211 | color: #eee; 212 | font: 11px 'Lucida Grande', sans-serif; 213 | text-shadow: 0 -1px 0 #111; 214 | /** Auto place */ 215 | /* Controller row,
30 | * [a, c, tx, 31 | * b, d, ty] 32 | *33 | * This is a short form for the 3x3 matrix: 34 | *
35 | * [a, c, tx, 36 | * b, d, ty, 37 | * 0, 0, 1] 38 | *39 | * The last row is ignored so the array is shorter and operations are faster. 40 | */ 41 | 42 | /** 43 | * Creates a new identity mat2d 44 | * 45 | * @returns {mat2d} a new 2x3 matrix 46 | */ 47 | export function create() { 48 | let out = new glMatrix.ARRAY_TYPE(6); 49 | out[0] = 1; 50 | out[1] = 0; 51 | out[2] = 0; 52 | out[3] = 1; 53 | out[4] = 0; 54 | out[5] = 0; 55 | return out; 56 | } 57 | 58 | /** 59 | * Creates a new mat2d initialized with values from an existing matrix 60 | * 61 | * @param {mat2d} a matrix to clone 62 | * @returns {mat2d} a new 2x3 matrix 63 | */ 64 | export function clone(a) { 65 | let out = new glMatrix.ARRAY_TYPE(6); 66 | out[0] = a[0]; 67 | out[1] = a[1]; 68 | out[2] = a[2]; 69 | out[3] = a[3]; 70 | out[4] = a[4]; 71 | out[5] = a[5]; 72 | return out; 73 | } 74 | 75 | /** 76 | * Copy the values from one mat2d to another 77 | * 78 | * @param {mat2d} out the receiving matrix 79 | * @param {mat2d} a the source matrix 80 | * @returns {mat2d} out 81 | */ 82 | export function copy(out, a) { 83 | out[0] = a[0]; 84 | out[1] = a[1]; 85 | out[2] = a[2]; 86 | out[3] = a[3]; 87 | out[4] = a[4]; 88 | out[5] = a[5]; 89 | return out; 90 | } 91 | 92 | /** 93 | * Set a mat2d to the identity matrix 94 | * 95 | * @param {mat2d} out the receiving matrix 96 | * @returns {mat2d} out 97 | */ 98 | export function identity(out) { 99 | out[0] = 1; 100 | out[1] = 0; 101 | out[2] = 0; 102 | out[3] = 1; 103 | out[4] = 0; 104 | out[5] = 0; 105 | return out; 106 | } 107 | 108 | /** 109 | * Create a new mat2d with the given values 110 | * 111 | * @param {Number} a Component A (index 0) 112 | * @param {Number} b Component B (index 1) 113 | * @param {Number} c Component C (index 2) 114 | * @param {Number} d Component D (index 3) 115 | * @param {Number} tx Component TX (index 4) 116 | * @param {Number} ty Component TY (index 5) 117 | * @returns {mat2d} A new mat2d 118 | */ 119 | export function fromValues(a, b, c, d, tx, ty) { 120 | let out = new glMatrix.ARRAY_TYPE(6); 121 | out[0] = a; 122 | out[1] = b; 123 | out[2] = c; 124 | out[3] = d; 125 | out[4] = tx; 126 | out[5] = ty; 127 | return out; 128 | } 129 | 130 | /** 131 | * Set the components of a mat2d to the given values 132 | * 133 | * @param {mat2d} out the receiving matrix 134 | * @param {Number} a Component A (index 0) 135 | * @param {Number} b Component B (index 1) 136 | * @param {Number} c Component C (index 2) 137 | * @param {Number} d Component D (index 3) 138 | * @param {Number} tx Component TX (index 4) 139 | * @param {Number} ty Component TY (index 5) 140 | * @returns {mat2d} out 141 | */ 142 | export function set(out, a, b, c, d, tx, ty) { 143 | out[0] = a; 144 | out[1] = b; 145 | out[2] = c; 146 | out[3] = d; 147 | out[4] = tx; 148 | out[5] = ty; 149 | return out; 150 | } 151 | 152 | /** 153 | * Inverts a mat2d 154 | * 155 | * @param {mat2d} out the receiving matrix 156 | * @param {mat2d} a the source matrix 157 | * @returns {mat2d} out 158 | */ 159 | export function invert(out, a) { 160 | let aa = a[0], ab = a[1], ac = a[2], ad = a[3]; 161 | let atx = a[4], aty = a[5]; 162 | 163 | let det = aa * ad - ab * ac; 164 | if(!det){ 165 | return null; 166 | } 167 | det = 1.0 / det; 168 | 169 | out[0] = ad * det; 170 | out[1] = -ab * det; 171 | out[2] = -ac * det; 172 | out[3] = aa * det; 173 | out[4] = (ac * aty - ad * atx) * det; 174 | out[5] = (ab * atx - aa * aty) * det; 175 | return out; 176 | } 177 | 178 | /** 179 | * Calculates the determinant of a mat2d 180 | * 181 | * @param {mat2d} a the source matrix 182 | * @returns {Number} determinant of a 183 | */ 184 | export function determinant(a) { 185 | return a[0] * a[3] - a[1] * a[2]; 186 | } 187 | 188 | /** 189 | * Multiplies two mat2d's 190 | * 191 | * @param {mat2d} out the receiving matrix 192 | * @param {mat2d} a the first operand 193 | * @param {mat2d} b the second operand 194 | * @returns {mat2d} out 195 | */ 196 | export function multiply(out, a, b) { 197 | let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; 198 | let b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5]; 199 | out[0] = a0 * b0 + a2 * b1; 200 | out[1] = a1 * b0 + a3 * b1; 201 | out[2] = a0 * b2 + a2 * b3; 202 | out[3] = a1 * b2 + a3 * b3; 203 | out[4] = a0 * b4 + a2 * b5 + a4; 204 | out[5] = a1 * b4 + a3 * b5 + a5; 205 | return out; 206 | } 207 | 208 | /** 209 | * Rotates a mat2d by the given angle 210 | * 211 | * @param {mat2d} out the receiving matrix 212 | * @param {mat2d} a the matrix to rotate 213 | * @param {Number} rad the angle to rotate the matrix by 214 | * @returns {mat2d} out 215 | */ 216 | export function rotate(out, a, rad) { 217 | let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; 218 | let s = Math.sin(rad); 219 | let c = Math.cos(rad); 220 | out[0] = a0 * c + a2 * s; 221 | out[1] = a1 * c + a3 * s; 222 | out[2] = a0 * -s + a2 * c; 223 | out[3] = a1 * -s + a3 * c; 224 | out[4] = a4; 225 | out[5] = a5; 226 | return out; 227 | } 228 | 229 | /** 230 | * Scales the mat2d by the dimensions in the given vec2 231 | * 232 | * @param {mat2d} out the receiving matrix 233 | * @param {mat2d} a the matrix to translate 234 | * @param {vec2} v the vec2 to scale the matrix by 235 | * @returns {mat2d} out 236 | **/ 237 | export function scale(out, a, v) { 238 | let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; 239 | let v0 = v[0], v1 = v[1]; 240 | out[0] = a0 * v0; 241 | out[1] = a1 * v0; 242 | out[2] = a2 * v1; 243 | out[3] = a3 * v1; 244 | out[4] = a4; 245 | out[5] = a5; 246 | return out; 247 | } 248 | 249 | /** 250 | * Translates the mat2d by the dimensions in the given vec2 251 | * 252 | * @param {mat2d} out the receiving matrix 253 | * @param {mat2d} a the matrix to translate 254 | * @param {vec2} v the vec2 to translate the matrix by 255 | * @returns {mat2d} out 256 | **/ 257 | export function translate(out, a, v) { 258 | let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; 259 | let v0 = v[0], v1 = v[1]; 260 | out[0] = a0; 261 | out[1] = a1; 262 | out[2] = a2; 263 | out[3] = a3; 264 | out[4] = a0 * v0 + a2 * v1 + a4; 265 | out[5] = a1 * v0 + a3 * v1 + a5; 266 | return out; 267 | } 268 | 269 | /** 270 | * Creates a matrix from a given angle 271 | * This is equivalent to (but much faster than): 272 | * 273 | * mat2d.identity(dest); 274 | * mat2d.rotate(dest, dest, rad); 275 | * 276 | * @param {mat2d} out mat2d receiving operation result 277 | * @param {Number} rad the angle to rotate the matrix by 278 | * @returns {mat2d} out 279 | */ 280 | export function fromRotation(out, rad) { 281 | let s = Math.sin(rad), c = Math.cos(rad); 282 | out[0] = c; 283 | out[1] = s; 284 | out[2] = -s; 285 | out[3] = c; 286 | out[4] = 0; 287 | out[5] = 0; 288 | return out; 289 | } 290 | 291 | /** 292 | * Creates a matrix from a vector scaling 293 | * This is equivalent to (but much faster than): 294 | * 295 | * mat2d.identity(dest); 296 | * mat2d.scale(dest, dest, vec); 297 | * 298 | * @param {mat2d} out mat2d receiving operation result 299 | * @param {vec2} v Scaling vector 300 | * @returns {mat2d} out 301 | */ 302 | export function fromScaling(out, v) { 303 | out[0] = v[0]; 304 | out[1] = 0; 305 | out[2] = 0; 306 | out[3] = v[1]; 307 | out[4] = 0; 308 | out[5] = 0; 309 | return out; 310 | } 311 | 312 | /** 313 | * Creates a matrix from a vector translation 314 | * This is equivalent to (but much faster than): 315 | * 316 | * mat2d.identity(dest); 317 | * mat2d.translate(dest, dest, vec); 318 | * 319 | * @param {mat2d} out mat2d receiving operation result 320 | * @param {vec2} v Translation vector 321 | * @returns {mat2d} out 322 | */ 323 | export function fromTranslation(out, v) { 324 | out[0] = 1; 325 | out[1] = 0; 326 | out[2] = 0; 327 | out[3] = 1; 328 | out[4] = v[0]; 329 | out[5] = v[1]; 330 | return out; 331 | } 332 | 333 | /** 334 | * Returns a string representation of a mat2d 335 | * 336 | * @param {mat2d} a matrix to represent as a string 337 | * @returns {String} string representation of the matrix 338 | */ 339 | export function str(a) { 340 | return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + 341 | a[3] + ', ' + a[4] + ', ' + a[5] + ')'; 342 | } 343 | 344 | /** 345 | * Returns Frobenius norm of a mat2d 346 | * 347 | * @param {mat2d} a the matrix to calculate Frobenius norm of 348 | * @returns {Number} Frobenius norm 349 | */ 350 | export function frob(a) { 351 | return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1)) 352 | } 353 | 354 | /** 355 | * Adds two mat2d's 356 | * 357 | * @param {mat2d} out the receiving matrix 358 | * @param {mat2d} a the first operand 359 | * @param {mat2d} b the second operand 360 | * @returns {mat2d} out 361 | */ 362 | export function add(out, a, b) { 363 | out[0] = a[0] + b[0]; 364 | out[1] = a[1] + b[1]; 365 | out[2] = a[2] + b[2]; 366 | out[3] = a[3] + b[3]; 367 | out[4] = a[4] + b[4]; 368 | out[5] = a[5] + b[5]; 369 | return out; 370 | } 371 | 372 | /** 373 | * Subtracts matrix b from matrix a 374 | * 375 | * @param {mat2d} out the receiving matrix 376 | * @param {mat2d} a the first operand 377 | * @param {mat2d} b the second operand 378 | * @returns {mat2d} out 379 | */ 380 | export function subtract(out, a, b) { 381 | out[0] = a[0] - b[0]; 382 | out[1] = a[1] - b[1]; 383 | out[2] = a[2] - b[2]; 384 | out[3] = a[3] - b[3]; 385 | out[4] = a[4] - b[4]; 386 | out[5] = a[5] - b[5]; 387 | return out; 388 | } 389 | 390 | /** 391 | * Multiply each element of the matrix by a scalar. 392 | * 393 | * @param {mat2d} out the receiving matrix 394 | * @param {mat2d} a the matrix to scale 395 | * @param {Number} b amount to scale the matrix's elements by 396 | * @returns {mat2d} out 397 | */ 398 | export function multiplyScalar(out, a, b) { 399 | out[0] = a[0] * b; 400 | out[1] = a[1] * b; 401 | out[2] = a[2] * b; 402 | out[3] = a[3] * b; 403 | out[4] = a[4] * b; 404 | out[5] = a[5] * b; 405 | return out; 406 | } 407 | 408 | /** 409 | * Adds two mat2d's after multiplying each element of the second operand by a scalar value. 410 | * 411 | * @param {mat2d} out the receiving vector 412 | * @param {mat2d} a the first operand 413 | * @param {mat2d} b the second operand 414 | * @param {Number} scale the amount to scale b's elements by before adding 415 | * @returns {mat2d} out 416 | */ 417 | export function multiplyScalarAndAdd(out, a, b, scale) { 418 | out[0] = a[0] + (b[0] * scale); 419 | out[1] = a[1] + (b[1] * scale); 420 | out[2] = a[2] + (b[2] * scale); 421 | out[3] = a[3] + (b[3] * scale); 422 | out[4] = a[4] + (b[4] * scale); 423 | out[5] = a[5] + (b[5] * scale); 424 | return out; 425 | } 426 | 427 | /** 428 | * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) 429 | * 430 | * @param {mat2d} a The first matrix. 431 | * @param {mat2d} b The second matrix. 432 | * @returns {Boolean} True if the matrices are equal, false otherwise. 433 | */ 434 | export function exactEquals(a, b) { 435 | return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5]; 436 | } 437 | 438 | /** 439 | * Returns whether or not the matrices have approximately the same elements in the same position. 440 | * 441 | * @param {mat2d} a The first matrix. 442 | * @param {mat2d} b The second matrix. 443 | * @returns {Boolean} True if the matrices are equal, false otherwise. 444 | */ 445 | export function equals(a, b) { 446 | let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5]; 447 | let b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5]; 448 | return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && 449 | Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1)) && 450 | Math.abs(a2 - b2) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a2), Math.abs(b2)) && 451 | Math.abs(a3 - b3) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a3), Math.abs(b3)) && 452 | Math.abs(a4 - b4) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a4), Math.abs(b4)) && 453 | Math.abs(a5 - b5) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a5), Math.abs(b5))); 454 | } 455 | 456 | /** 457 | * Alias for {@link mat2d.multiply} 458 | * @function 459 | */ 460 | export const mul = multiply; 461 | 462 | /** 463 | * Alias for {@link mat2d.subtract} 464 | * @function 465 | */ 466 | export const sub = subtract; 467 | -------------------------------------------------------------------------------- /lib/gl-matrix-2.4.0/src/gl-matrix/vec2.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. */ 20 | 21 | import * as glMatrix from "./common"; 22 | 23 | /** 24 | * 2 Dimensional Vector 25 | * @module vec2 26 | */ 27 | 28 | /** 29 | * Creates a new, empty vec2 30 | * 31 | * @returns {vec2} a new 2D vector 32 | */ 33 | export function create() { 34 | let out = new glMatrix.ARRAY_TYPE(2); 35 | out[0] = 0; 36 | out[1] = 0; 37 | return out; 38 | } 39 | 40 | /** 41 | * Creates a new vec2 initialized with values from an existing vector 42 | * 43 | * @param {vec2} a vector to clone 44 | * @returns {vec2} a new 2D vector 45 | */ 46 | export function clone(a) { 47 | let out = new glMatrix.ARRAY_TYPE(2); 48 | out[0] = a[0]; 49 | out[1] = a[1]; 50 | return out; 51 | } 52 | 53 | /** 54 | * Creates a new vec2 initialized with the given values 55 | * 56 | * @param {Number} x X component 57 | * @param {Number} y Y component 58 | * @returns {vec2} a new 2D vector 59 | */ 60 | export function fromValues(x, y) { 61 | let out = new glMatrix.ARRAY_TYPE(2); 62 | out[0] = x; 63 | out[1] = y; 64 | return out; 65 | } 66 | 67 | /** 68 | * Copy the values from one vec2 to another 69 | * 70 | * @param {vec2} out the receiving vector 71 | * @param {vec2} a the source vector 72 | * @returns {vec2} out 73 | */ 74 | export function copy(out, a) { 75 | out[0] = a[0]; 76 | out[1] = a[1]; 77 | return out; 78 | } 79 | 80 | /** 81 | * Set the components of a vec2 to the given values 82 | * 83 | * @param {vec2} out the receiving vector 84 | * @param {Number} x X component 85 | * @param {Number} y Y component 86 | * @returns {vec2} out 87 | */ 88 | export function set(out, x, y) { 89 | out[0] = x; 90 | out[1] = y; 91 | return out; 92 | } 93 | 94 | /** 95 | * Adds two vec2's 96 | * 97 | * @param {vec2} out the receiving vector 98 | * @param {vec2} a the first operand 99 | * @param {vec2} b the second operand 100 | * @returns {vec2} out 101 | */ 102 | export function add(out, a, b) { 103 | out[0] = a[0] + b[0]; 104 | out[1] = a[1] + b[1]; 105 | return out; 106 | } 107 | 108 | /** 109 | * Subtracts vector b from vector a 110 | * 111 | * @param {vec2} out the receiving vector 112 | * @param {vec2} a the first operand 113 | * @param {vec2} b the second operand 114 | * @returns {vec2} out 115 | */ 116 | export function subtract(out, a, b) { 117 | out[0] = a[0] - b[0]; 118 | out[1] = a[1] - b[1]; 119 | return out; 120 | } 121 | 122 | /** 123 | * Multiplies two vec2's 124 | * 125 | * @param {vec2} out the receiving vector 126 | * @param {vec2} a the first operand 127 | * @param {vec2} b the second operand 128 | * @returns {vec2} out 129 | */ 130 | export function multiply(out, a, b) { 131 | out[0] = a[0] * b[0]; 132 | out[1] = a[1] * b[1]; 133 | return out; 134 | }; 135 | 136 | /** 137 | * Divides two vec2's 138 | * 139 | * @param {vec2} out the receiving vector 140 | * @param {vec2} a the first operand 141 | * @param {vec2} b the second operand 142 | * @returns {vec2} out 143 | */ 144 | export function divide(out, a, b) { 145 | out[0] = a[0] / b[0]; 146 | out[1] = a[1] / b[1]; 147 | return out; 148 | }; 149 | 150 | /** 151 | * Math.ceil the components of a vec2 152 | * 153 | * @param {vec2} out the receiving vector 154 | * @param {vec2} a vector to ceil 155 | * @returns {vec2} out 156 | */ 157 | export function ceil(out, a) { 158 | out[0] = Math.ceil(a[0]); 159 | out[1] = Math.ceil(a[1]); 160 | return out; 161 | }; 162 | 163 | /** 164 | * Math.floor the components of a vec2 165 | * 166 | * @param {vec2} out the receiving vector 167 | * @param {vec2} a vector to floor 168 | * @returns {vec2} out 169 | */ 170 | export function floor(out, a) { 171 | out[0] = Math.floor(a[0]); 172 | out[1] = Math.floor(a[1]); 173 | return out; 174 | }; 175 | 176 | /** 177 | * Returns the minimum of two vec2's 178 | * 179 | * @param {vec2} out the receiving vector 180 | * @param {vec2} a the first operand 181 | * @param {vec2} b the second operand 182 | * @returns {vec2} out 183 | */ 184 | export function min(out, a, b) { 185 | out[0] = Math.min(a[0], b[0]); 186 | out[1] = Math.min(a[1], b[1]); 187 | return out; 188 | }; 189 | 190 | /** 191 | * Returns the maximum of two vec2's 192 | * 193 | * @param {vec2} out the receiving vector 194 | * @param {vec2} a the first operand 195 | * @param {vec2} b the second operand 196 | * @returns {vec2} out 197 | */ 198 | export function max(out, a, b) { 199 | out[0] = Math.max(a[0], b[0]); 200 | out[1] = Math.max(a[1], b[1]); 201 | return out; 202 | }; 203 | 204 | /** 205 | * Math.round the components of a vec2 206 | * 207 | * @param {vec2} out the receiving vector 208 | * @param {vec2} a vector to round 209 | * @returns {vec2} out 210 | */ 211 | export function round (out, a) { 212 | out[0] = Math.round(a[0]); 213 | out[1] = Math.round(a[1]); 214 | return out; 215 | }; 216 | 217 | /** 218 | * Scales a vec2 by a scalar number 219 | * 220 | * @param {vec2} out the receiving vector 221 | * @param {vec2} a the vector to scale 222 | * @param {Number} b amount to scale the vector by 223 | * @returns {vec2} out 224 | */ 225 | export function scale(out, a, b) { 226 | out[0] = a[0] * b; 227 | out[1] = a[1] * b; 228 | return out; 229 | }; 230 | 231 | /** 232 | * Adds two vec2's after scaling the second operand by a scalar value 233 | * 234 | * @param {vec2} out the receiving vector 235 | * @param {vec2} a the first operand 236 | * @param {vec2} b the second operand 237 | * @param {Number} scale the amount to scale b by before adding 238 | * @returns {vec2} out 239 | */ 240 | export function scaleAndAdd(out, a, b, scale) { 241 | out[0] = a[0] + (b[0] * scale); 242 | out[1] = a[1] + (b[1] * scale); 243 | return out; 244 | }; 245 | 246 | /** 247 | * Calculates the euclidian distance between two vec2's 248 | * 249 | * @param {vec2} a the first operand 250 | * @param {vec2} b the second operand 251 | * @returns {Number} distance between a and b 252 | */ 253 | export function distance(a, b) { 254 | var x = b[0] - a[0], 255 | y = b[1] - a[1]; 256 | return Math.sqrt(x*x + y*y); 257 | }; 258 | 259 | /** 260 | * Calculates the squared euclidian distance between two vec2's 261 | * 262 | * @param {vec2} a the first operand 263 | * @param {vec2} b the second operand 264 | * @returns {Number} squared distance between a and b 265 | */ 266 | export function squaredDistance(a, b) { 267 | var x = b[0] - a[0], 268 | y = b[1] - a[1]; 269 | return x*x + y*y; 270 | }; 271 | 272 | /** 273 | * Calculates the length of a vec2 274 | * 275 | * @param {vec2} a vector to calculate length of 276 | * @returns {Number} length of a 277 | */ 278 | export function length(a) { 279 | var x = a[0], 280 | y = a[1]; 281 | return Math.sqrt(x*x + y*y); 282 | }; 283 | 284 | /** 285 | * Calculates the squared length of a vec2 286 | * 287 | * @param {vec2} a vector to calculate squared length of 288 | * @returns {Number} squared length of a 289 | */ 290 | export function squaredLength (a) { 291 | var x = a[0], 292 | y = a[1]; 293 | return x*x + y*y; 294 | }; 295 | 296 | /** 297 | * Negates the components of a vec2 298 | * 299 | * @param {vec2} out the receiving vector 300 | * @param {vec2} a vector to negate 301 | * @returns {vec2} out 302 | */ 303 | export function negate(out, a) { 304 | out[0] = -a[0]; 305 | out[1] = -a[1]; 306 | return out; 307 | }; 308 | 309 | /** 310 | * Returns the inverse of the components of a vec2 311 | * 312 | * @param {vec2} out the receiving vector 313 | * @param {vec2} a vector to invert 314 | * @returns {vec2} out 315 | */ 316 | export function inverse(out, a) { 317 | out[0] = 1.0 / a[0]; 318 | out[1] = 1.0 / a[1]; 319 | return out; 320 | }; 321 | 322 | /** 323 | * Normalize a vec2 324 | * 325 | * @param {vec2} out the receiving vector 326 | * @param {vec2} a vector to normalize 327 | * @returns {vec2} out 328 | */ 329 | export function normalize(out, a) { 330 | var x = a[0], 331 | y = a[1]; 332 | var len = x*x + y*y; 333 | if (len > 0) { 334 | //TODO: evaluate use of glm_invsqrt here? 335 | len = 1 / Math.sqrt(len); 336 | out[0] = a[0] * len; 337 | out[1] = a[1] * len; 338 | } 339 | return out; 340 | }; 341 | 342 | /** 343 | * Calculates the dot product of two vec2's 344 | * 345 | * @param {vec2} a the first operand 346 | * @param {vec2} b the second operand 347 | * @returns {Number} dot product of a and b 348 | */ 349 | export function dot(a, b) { 350 | return a[0] * b[0] + a[1] * b[1]; 351 | }; 352 | 353 | /** 354 | * Computes the cross product of two vec2's 355 | * Note that the cross product must by definition produce a 3D vector 356 | * 357 | * @param {vec3} out the receiving vector 358 | * @param {vec2} a the first operand 359 | * @param {vec2} b the second operand 360 | * @returns {vec3} out 361 | */ 362 | export function cross(out, a, b) { 363 | var z = a[0] * b[1] - a[1] * b[0]; 364 | out[0] = out[1] = 0; 365 | out[2] = z; 366 | return out; 367 | }; 368 | 369 | /** 370 | * Performs a linear interpolation between two vec2's 371 | * 372 | * @param {vec2} out the receiving vector 373 | * @param {vec2} a the first operand 374 | * @param {vec2} b the second operand 375 | * @param {Number} t interpolation amount between the two inputs 376 | * @returns {vec2} out 377 | */ 378 | export function lerp(out, a, b, t) { 379 | var ax = a[0], 380 | ay = a[1]; 381 | out[0] = ax + t * (b[0] - ax); 382 | out[1] = ay + t * (b[1] - ay); 383 | return out; 384 | }; 385 | 386 | /** 387 | * Generates a random vector with the given scale 388 | * 389 | * @param {vec2} out the receiving vector 390 | * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned 391 | * @returns {vec2} out 392 | */ 393 | export function random(out, scale) { 394 | scale = scale || 1.0; 395 | var r = glMatrix.RANDOM() * 2.0 * Math.PI; 396 | out[0] = Math.cos(r) * scale; 397 | out[1] = Math.sin(r) * scale; 398 | return out; 399 | }; 400 | 401 | /** 402 | * Transforms the vec2 with a mat2 403 | * 404 | * @param {vec2} out the receiving vector 405 | * @param {vec2} a the vector to transform 406 | * @param {mat2} m matrix to transform with 407 | * @returns {vec2} out 408 | */ 409 | export function transformMat2(out, a, m) { 410 | var x = a[0], 411 | y = a[1]; 412 | out[0] = m[0] * x + m[2] * y; 413 | out[1] = m[1] * x + m[3] * y; 414 | return out; 415 | }; 416 | 417 | /** 418 | * Transforms the vec2 with a mat2d 419 | * 420 | * @param {vec2} out the receiving vector 421 | * @param {vec2} a the vector to transform 422 | * @param {mat2d} m matrix to transform with 423 | * @returns {vec2} out 424 | */ 425 | export function transformMat2d(out, a, m) { 426 | var x = a[0], 427 | y = a[1]; 428 | out[0] = m[0] * x + m[2] * y + m[4]; 429 | out[1] = m[1] * x + m[3] * y + m[5]; 430 | return out; 431 | }; 432 | 433 | /** 434 | * Transforms the vec2 with a mat3 435 | * 3rd vector component is implicitly '1' 436 | * 437 | * @param {vec2} out the receiving vector 438 | * @param {vec2} a the vector to transform 439 | * @param {mat3} m matrix to transform with 440 | * @returns {vec2} out 441 | */ 442 | export function transformMat3(out, a, m) { 443 | var x = a[0], 444 | y = a[1]; 445 | out[0] = m[0] * x + m[3] * y + m[6]; 446 | out[1] = m[1] * x + m[4] * y + m[7]; 447 | return out; 448 | }; 449 | 450 | /** 451 | * Transforms the vec2 with a mat4 452 | * 3rd vector component is implicitly '0' 453 | * 4th vector component is implicitly '1' 454 | * 455 | * @param {vec2} out the receiving vector 456 | * @param {vec2} a the vector to transform 457 | * @param {mat4} m matrix to transform with 458 | * @returns {vec2} out 459 | */ 460 | export function transformMat4(out, a, m) { 461 | let x = a[0]; 462 | let y = a[1]; 463 | out[0] = m[0] * x + m[4] * y + m[12]; 464 | out[1] = m[1] * x + m[5] * y + m[13]; 465 | return out; 466 | } 467 | 468 | /** 469 | * Returns a string representation of a vector 470 | * 471 | * @param {vec2} a vector to represent as a string 472 | * @returns {String} string representation of the vector 473 | */ 474 | export function str(a) { 475 | return 'vec2(' + a[0] + ', ' + a[1] + ')'; 476 | } 477 | 478 | /** 479 | * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) 480 | * 481 | * @param {vec2} a The first vector. 482 | * @param {vec2} b The second vector. 483 | * @returns {Boolean} True if the vectors are equal, false otherwise. 484 | */ 485 | export function exactEquals(a, b) { 486 | return a[0] === b[0] && a[1] === b[1]; 487 | } 488 | 489 | /** 490 | * Returns whether or not the vectors have approximately the same elements in the same position. 491 | * 492 | * @param {vec2} a The first vector. 493 | * @param {vec2} b The second vector. 494 | * @returns {Boolean} True if the vectors are equal, false otherwise. 495 | */ 496 | export function equals(a, b) { 497 | let a0 = a[0], a1 = a[1]; 498 | let b0 = b[0], b1 = b[1]; 499 | return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && 500 | Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1))); 501 | } 502 | 503 | /** 504 | * Alias for {@link vec2.length} 505 | * @function 506 | */ 507 | export const len = length; 508 | 509 | /** 510 | * Alias for {@link vec2.subtract} 511 | * @function 512 | */ 513 | export const sub = subtract; 514 | 515 | /** 516 | * Alias for {@link vec2.multiply} 517 | * @function 518 | */ 519 | export const mul = multiply; 520 | 521 | /** 522 | * Alias for {@link vec2.divide} 523 | * @function 524 | */ 525 | export const div = divide; 526 | 527 | /** 528 | * Alias for {@link vec2.distance} 529 | * @function 530 | */ 531 | export const dist = distance; 532 | 533 | /** 534 | * Alias for {@link vec2.squaredDistance} 535 | * @function 536 | */ 537 | export const sqrDist = squaredDistance; 538 | 539 | /** 540 | * Alias for {@link vec2.squaredLength} 541 | * @function 542 | */ 543 | export const sqrLen = squaredLength; 544 | 545 | /** 546 | * Perform some operation over an array of vec2s. 547 | * 548 | * @param {Array} a the array of vectors to iterate over 549 | * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed 550 | * @param {Number} offset Number of elements to skip at the beginning of the array 551 | * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array 552 | * @param {Function} fn Function to call for each vector in the array 553 | * @param {Object} [arg] additional argument to pass to fn 554 | * @returns {Array} a 555 | * @function 556 | */ 557 | export const forEach = (function() { 558 | let vec = create(); 559 | 560 | return function(a, stride, offset, count, fn, arg) { 561 | let i, l; 562 | if(!stride) { 563 | stride = 2; 564 | } 565 | 566 | if(!offset) { 567 | offset = 0; 568 | } 569 | 570 | if(count) { 571 | l = Math.min((count * stride) + offset, a.length); 572 | } else { 573 | l = a.length; 574 | } 575 | 576 | for(i = offset; i < l; i += stride) { 577 | vec[0] = a[i]; vec[1] = a[i+1]; 578 | fn(vec, vec, arg); 579 | a[i] = vec[0]; a[i+1] = vec[1]; 580 | } 581 | 582 | return a; 583 | }; 584 | })(); 585 | -------------------------------------------------------------------------------- /lib/gl-matrix-2.4.0/src/gl-matrix/vec4.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. */ 20 | 21 | import * as glMatrix from "./common"; 22 | 23 | /** 24 | * 4 Dimensional Vector 25 | * @module vec4 26 | */ 27 | 28 | /** 29 | * Creates a new, empty vec4 30 | * 31 | * @returns {vec4} a new 4D vector 32 | */ 33 | export function create() { 34 | let out = new glMatrix.ARRAY_TYPE(4); 35 | out[0] = 0; 36 | out[1] = 0; 37 | out[2] = 0; 38 | out[3] = 0; 39 | return out; 40 | } 41 | 42 | /** 43 | * Creates a new vec4 initialized with values from an existing vector 44 | * 45 | * @param {vec4} a vector to clone 46 | * @returns {vec4} a new 4D vector 47 | */ 48 | export function clone(a) { 49 | let out = new glMatrix.ARRAY_TYPE(4); 50 | out[0] = a[0]; 51 | out[1] = a[1]; 52 | out[2] = a[2]; 53 | out[3] = a[3]; 54 | return out; 55 | } 56 | 57 | /** 58 | * Creates a new vec4 initialized with the given values 59 | * 60 | * @param {Number} x X component 61 | * @param {Number} y Y component 62 | * @param {Number} z Z component 63 | * @param {Number} w W component 64 | * @returns {vec4} a new 4D vector 65 | */ 66 | export function fromValues(x, y, z, w) { 67 | let out = new glMatrix.ARRAY_TYPE(4); 68 | out[0] = x; 69 | out[1] = y; 70 | out[2] = z; 71 | out[3] = w; 72 | return out; 73 | } 74 | 75 | /** 76 | * Copy the values from one vec4 to another 77 | * 78 | * @param {vec4} out the receiving vector 79 | * @param {vec4} a the source vector 80 | * @returns {vec4} out 81 | */ 82 | export function copy(out, a) { 83 | out[0] = a[0]; 84 | out[1] = a[1]; 85 | out[2] = a[2]; 86 | out[3] = a[3]; 87 | return out; 88 | } 89 | 90 | /** 91 | * Set the components of a vec4 to the given values 92 | * 93 | * @param {vec4} out the receiving vector 94 | * @param {Number} x X component 95 | * @param {Number} y Y component 96 | * @param {Number} z Z component 97 | * @param {Number} w W component 98 | * @returns {vec4} out 99 | */ 100 | export function set(out, x, y, z, w) { 101 | out[0] = x; 102 | out[1] = y; 103 | out[2] = z; 104 | out[3] = w; 105 | return out; 106 | } 107 | 108 | /** 109 | * Adds two vec4's 110 | * 111 | * @param {vec4} out the receiving vector 112 | * @param {vec4} a the first operand 113 | * @param {vec4} b the second operand 114 | * @returns {vec4} out 115 | */ 116 | export function add(out, a, b) { 117 | out[0] = a[0] + b[0]; 118 | out[1] = a[1] + b[1]; 119 | out[2] = a[2] + b[2]; 120 | out[3] = a[3] + b[3]; 121 | return out; 122 | } 123 | 124 | /** 125 | * Subtracts vector b from vector a 126 | * 127 | * @param {vec4} out the receiving vector 128 | * @param {vec4} a the first operand 129 | * @param {vec4} b the second operand 130 | * @returns {vec4} out 131 | */ 132 | export function subtract(out, a, b) { 133 | out[0] = a[0] - b[0]; 134 | out[1] = a[1] - b[1]; 135 | out[2] = a[2] - b[2]; 136 | out[3] = a[3] - b[3]; 137 | return out; 138 | } 139 | 140 | /** 141 | * Multiplies two vec4's 142 | * 143 | * @param {vec4} out the receiving vector 144 | * @param {vec4} a the first operand 145 | * @param {vec4} b the second operand 146 | * @returns {vec4} out 147 | */ 148 | export function multiply(out, a, b) { 149 | out[0] = a[0] * b[0]; 150 | out[1] = a[1] * b[1]; 151 | out[2] = a[2] * b[2]; 152 | out[3] = a[3] * b[3]; 153 | return out; 154 | } 155 | 156 | /** 157 | * Divides two vec4's 158 | * 159 | * @param {vec4} out the receiving vector 160 | * @param {vec4} a the first operand 161 | * @param {vec4} b the second operand 162 | * @returns {vec4} out 163 | */ 164 | export function divide(out, a, b) { 165 | out[0] = a[0] / b[0]; 166 | out[1] = a[1] / b[1]; 167 | out[2] = a[2] / b[2]; 168 | out[3] = a[3] / b[3]; 169 | return out; 170 | } 171 | 172 | /** 173 | * Math.ceil the components of a vec4 174 | * 175 | * @param {vec4} out the receiving vector 176 | * @param {vec4} a vector to ceil 177 | * @returns {vec4} out 178 | */ 179 | export function ceil(out, a) { 180 | out[0] = Math.ceil(a[0]); 181 | out[1] = Math.ceil(a[1]); 182 | out[2] = Math.ceil(a[2]); 183 | out[3] = Math.ceil(a[3]); 184 | return out; 185 | } 186 | 187 | /** 188 | * Math.floor the components of a vec4 189 | * 190 | * @param {vec4} out the receiving vector 191 | * @param {vec4} a vector to floor 192 | * @returns {vec4} out 193 | */ 194 | export function floor(out, a) { 195 | out[0] = Math.floor(a[0]); 196 | out[1] = Math.floor(a[1]); 197 | out[2] = Math.floor(a[2]); 198 | out[3] = Math.floor(a[3]); 199 | return out; 200 | } 201 | 202 | /** 203 | * Returns the minimum of two vec4's 204 | * 205 | * @param {vec4} out the receiving vector 206 | * @param {vec4} a the first operand 207 | * @param {vec4} b the second operand 208 | * @returns {vec4} out 209 | */ 210 | export function min(out, a, b) { 211 | out[0] = Math.min(a[0], b[0]); 212 | out[1] = Math.min(a[1], b[1]); 213 | out[2] = Math.min(a[2], b[2]); 214 | out[3] = Math.min(a[3], b[3]); 215 | return out; 216 | } 217 | 218 | /** 219 | * Returns the maximum of two vec4's 220 | * 221 | * @param {vec4} out the receiving vector 222 | * @param {vec4} a the first operand 223 | * @param {vec4} b the second operand 224 | * @returns {vec4} out 225 | */ 226 | export function max(out, a, b) { 227 | out[0] = Math.max(a[0], b[0]); 228 | out[1] = Math.max(a[1], b[1]); 229 | out[2] = Math.max(a[2], b[2]); 230 | out[3] = Math.max(a[3], b[3]); 231 | return out; 232 | } 233 | 234 | /** 235 | * Math.round the components of a vec4 236 | * 237 | * @param {vec4} out the receiving vector 238 | * @param {vec4} a vector to round 239 | * @returns {vec4} out 240 | */ 241 | export function round(out, a) { 242 | out[0] = Math.round(a[0]); 243 | out[1] = Math.round(a[1]); 244 | out[2] = Math.round(a[2]); 245 | out[3] = Math.round(a[3]); 246 | return out; 247 | } 248 | 249 | /** 250 | * Scales a vec4 by a scalar number 251 | * 252 | * @param {vec4} out the receiving vector 253 | * @param {vec4} a the vector to scale 254 | * @param {Number} b amount to scale the vector by 255 | * @returns {vec4} out 256 | */ 257 | export function scale(out, a, b) { 258 | out[0] = a[0] * b; 259 | out[1] = a[1] * b; 260 | out[2] = a[2] * b; 261 | out[3] = a[3] * b; 262 | return out; 263 | } 264 | 265 | /** 266 | * Adds two vec4's after scaling the second operand by a scalar value 267 | * 268 | * @param {vec4} out the receiving vector 269 | * @param {vec4} a the first operand 270 | * @param {vec4} b the second operand 271 | * @param {Number} scale the amount to scale b by before adding 272 | * @returns {vec4} out 273 | */ 274 | export function scaleAndAdd(out, a, b, scale) { 275 | out[0] = a[0] + (b[0] * scale); 276 | out[1] = a[1] + (b[1] * scale); 277 | out[2] = a[2] + (b[2] * scale); 278 | out[3] = a[3] + (b[3] * scale); 279 | return out; 280 | } 281 | 282 | /** 283 | * Calculates the euclidian distance between two vec4's 284 | * 285 | * @param {vec4} a the first operand 286 | * @param {vec4} b the second operand 287 | * @returns {Number} distance between a and b 288 | */ 289 | export function distance(a, b) { 290 | let x = b[0] - a[0]; 291 | let y = b[1] - a[1]; 292 | let z = b[2] - a[2]; 293 | let w = b[3] - a[3]; 294 | return Math.sqrt(x*x + y*y + z*z + w*w); 295 | } 296 | 297 | /** 298 | * Calculates the squared euclidian distance between two vec4's 299 | * 300 | * @param {vec4} a the first operand 301 | * @param {vec4} b the second operand 302 | * @returns {Number} squared distance between a and b 303 | */ 304 | export function squaredDistance(a, b) { 305 | let x = b[0] - a[0]; 306 | let y = b[1] - a[1]; 307 | let z = b[2] - a[2]; 308 | let w = b[3] - a[3]; 309 | return x*x + y*y + z*z + w*w; 310 | } 311 | 312 | /** 313 | * Calculates the length of a vec4 314 | * 315 | * @param {vec4} a vector to calculate length of 316 | * @returns {Number} length of a 317 | */ 318 | export function length(a) { 319 | let x = a[0]; 320 | let y = a[1]; 321 | let z = a[2]; 322 | let w = a[3]; 323 | return Math.sqrt(x*x + y*y + z*z + w*w); 324 | } 325 | 326 | /** 327 | * Calculates the squared length of a vec4 328 | * 329 | * @param {vec4} a vector to calculate squared length of 330 | * @returns {Number} squared length of a 331 | */ 332 | export function squaredLength(a) { 333 | let x = a[0]; 334 | let y = a[1]; 335 | let z = a[2]; 336 | let w = a[3]; 337 | return x*x + y*y + z*z + w*w; 338 | } 339 | 340 | /** 341 | * Negates the components of a vec4 342 | * 343 | * @param {vec4} out the receiving vector 344 | * @param {vec4} a vector to negate 345 | * @returns {vec4} out 346 | */ 347 | export function negate(out, a) { 348 | out[0] = -a[0]; 349 | out[1] = -a[1]; 350 | out[2] = -a[2]; 351 | out[3] = -a[3]; 352 | return out; 353 | } 354 | 355 | /** 356 | * Returns the inverse of the components of a vec4 357 | * 358 | * @param {vec4} out the receiving vector 359 | * @param {vec4} a vector to invert 360 | * @returns {vec4} out 361 | */ 362 | export function inverse(out, a) { 363 | out[0] = 1.0 / a[0]; 364 | out[1] = 1.0 / a[1]; 365 | out[2] = 1.0 / a[2]; 366 | out[3] = 1.0 / a[3]; 367 | return out; 368 | } 369 | 370 | /** 371 | * Normalize a vec4 372 | * 373 | * @param {vec4} out the receiving vector 374 | * @param {vec4} a vector to normalize 375 | * @returns {vec4} out 376 | */ 377 | export function normalize(out, a) { 378 | let x = a[0]; 379 | let y = a[1]; 380 | let z = a[2]; 381 | let w = a[3]; 382 | let len = x*x + y*y + z*z + w*w; 383 | if (len > 0) { 384 | len = 1 / Math.sqrt(len); 385 | out[0] = x * len; 386 | out[1] = y * len; 387 | out[2] = z * len; 388 | out[3] = w * len; 389 | } 390 | return out; 391 | } 392 | 393 | /** 394 | * Calculates the dot product of two vec4's 395 | * 396 | * @param {vec4} a the first operand 397 | * @param {vec4} b the second operand 398 | * @returns {Number} dot product of a and b 399 | */ 400 | export function dot(a, b) { 401 | return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; 402 | } 403 | 404 | /** 405 | * Performs a linear interpolation between two vec4's 406 | * 407 | * @param {vec4} out the receiving vector 408 | * @param {vec4} a the first operand 409 | * @param {vec4} b the second operand 410 | * @param {Number} t interpolation amount between the two inputs 411 | * @returns {vec4} out 412 | */ 413 | export function lerp(out, a, b, t) { 414 | let ax = a[0]; 415 | let ay = a[1]; 416 | let az = a[2]; 417 | let aw = a[3]; 418 | out[0] = ax + t * (b[0] - ax); 419 | out[1] = ay + t * (b[1] - ay); 420 | out[2] = az + t * (b[2] - az); 421 | out[3] = aw + t * (b[3] - aw); 422 | return out; 423 | } 424 | 425 | /** 426 | * Generates a random vector with the given scale 427 | * 428 | * @param {vec4} out the receiving vector 429 | * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned 430 | * @returns {vec4} out 431 | */ 432 | export function random(out, vectorScale) { 433 | vectorScale = vectorScale || 1.0; 434 | 435 | //TODO: This is a pretty awful way of doing this. Find something better. 436 | out[0] = glMatrix.RANDOM(); 437 | out[1] = glMatrix.RANDOM(); 438 | out[2] = glMatrix.RANDOM(); 439 | out[3] = glMatrix.RANDOM(); 440 | normalize(out, out); 441 | scale(out, out, vectorScale); 442 | return out; 443 | } 444 | 445 | /** 446 | * Transforms the vec4 with a mat4. 447 | * 448 | * @param {vec4} out the receiving vector 449 | * @param {vec4} a the vector to transform 450 | * @param {mat4} m matrix to transform with 451 | * @returns {vec4} out 452 | */ 453 | export function transformMat4(out, a, m) { 454 | let x = a[0], y = a[1], z = a[2], w = a[3]; 455 | out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; 456 | out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; 457 | out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; 458 | out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; 459 | return out; 460 | } 461 | 462 | /** 463 | * Transforms the vec4 with a quat 464 | * 465 | * @param {vec4} out the receiving vector 466 | * @param {vec4} a the vector to transform 467 | * @param {quat} q quaternion to transform with 468 | * @returns {vec4} out 469 | */ 470 | export function transformQuat(out, a, q) { 471 | let x = a[0], y = a[1], z = a[2]; 472 | let qx = q[0], qy = q[1], qz = q[2], qw = q[3]; 473 | 474 | // calculate quat * vec 475 | let ix = qw * x + qy * z - qz * y; 476 | let iy = qw * y + qz * x - qx * z; 477 | let iz = qw * z + qx * y - qy * x; 478 | let iw = -qx * x - qy * y - qz * z; 479 | 480 | // calculate result * inverse quat 481 | out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; 482 | out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; 483 | out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; 484 | out[3] = a[3]; 485 | return out; 486 | } 487 | 488 | /** 489 | * Returns a string representation of a vector 490 | * 491 | * @param {vec4} a vector to represent as a string 492 | * @returns {String} string representation of the vector 493 | */ 494 | export function str(a) { 495 | return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; 496 | } 497 | 498 | /** 499 | * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) 500 | * 501 | * @param {vec4} a The first vector. 502 | * @param {vec4} b The second vector. 503 | * @returns {Boolean} True if the vectors are equal, false otherwise. 504 | */ 505 | export function exactEquals(a, b) { 506 | return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; 507 | } 508 | 509 | /** 510 | * Returns whether or not the vectors have approximately the same elements in the same position. 511 | * 512 | * @param {vec4} a The first vector. 513 | * @param {vec4} b The second vector. 514 | * @returns {Boolean} True if the vectors are equal, false otherwise. 515 | */ 516 | export function equals(a, b) { 517 | let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; 518 | let b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; 519 | return (Math.abs(a0 - b0) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a0), Math.abs(b0)) && 520 | Math.abs(a1 - b1) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a1), Math.abs(b1)) && 521 | Math.abs(a2 - b2) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a2), Math.abs(b2)) && 522 | Math.abs(a3 - b3) <= glMatrix.EPSILON*Math.max(1.0, Math.abs(a3), Math.abs(b3))); 523 | } 524 | 525 | /** 526 | * Alias for {@link vec4.subtract} 527 | * @function 528 | */ 529 | export const sub = subtract; 530 | 531 | /** 532 | * Alias for {@link vec4.multiply} 533 | * @function 534 | */ 535 | export const mul = multiply; 536 | 537 | /** 538 | * Alias for {@link vec4.divide} 539 | * @function 540 | */ 541 | export const div = divide; 542 | 543 | /** 544 | * Alias for {@link vec4.distance} 545 | * @function 546 | */ 547 | export const dist = distance; 548 | 549 | /** 550 | * Alias for {@link vec4.squaredDistance} 551 | * @function 552 | */ 553 | export const sqrDist = squaredDistance; 554 | 555 | /** 556 | * Alias for {@link vec4.length} 557 | * @function 558 | */ 559 | export const len = length; 560 | 561 | /** 562 | * Alias for {@link vec4.squaredLength} 563 | * @function 564 | */ 565 | export const sqrLen = squaredLength; 566 | 567 | /** 568 | * Perform some operation over an array of vec4s. 569 | * 570 | * @param {Array} a the array of vectors to iterate over 571 | * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed 572 | * @param {Number} offset Number of elements to skip at the beginning of the array 573 | * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array 574 | * @param {Function} fn Function to call for each vector in the array 575 | * @param {Object} [arg] additional argument to pass to fn 576 | * @returns {Array} a 577 | * @function 578 | */ 579 | export const forEach = (function() { 580 | let vec = create(); 581 | 582 | return function(a, stride, offset, count, fn, arg) { 583 | let i, l; 584 | if(!stride) { 585 | stride = 4; 586 | } 587 | 588 | if(!offset) { 589 | offset = 0; 590 | } 591 | 592 | if(count) { 593 | l = Math.min((count * stride) + offset, a.length); 594 | } else { 595 | l = a.length; 596 | } 597 | 598 | for(i = offset; i < l; i += stride) { 599 | vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; vec[3] = a[i+3]; 600 | fn(vec, vec, arg); 601 | a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; a[i+3] = vec[3]; 602 | } 603 | 604 | return a; 605 | }; 606 | })(); 607 | -------------------------------------------------------------------------------- /sketches/ConstructionCubes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 31 | 32 | 33 | 34 | 61 | 62 | 63 | 124 | 125 | 126 | 127 | 128 | 129 |