├── LICENSE.md ├── README.md ├── animation-worker.html ├── animation.html ├── gl-matrix ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── LICENSE.md ├── README.md ├── Rakefile ├── TESTING.md ├── VERSION ├── bower.json ├── dist │ ├── gl-matrix-min.js │ └── gl-matrix.js ├── jsdoc-template │ ├── allclasses.tmpl │ ├── allfiles.tmpl │ ├── class.tmpl │ ├── index.tmpl │ ├── publish.js │ ├── static │ │ ├── default.css │ │ ├── header.html │ │ └── index.html │ └── symbol.tmpl ├── package.json ├── spec │ ├── gl-matrix │ │ ├── common-spec.js │ │ ├── mat2-spec.js │ │ ├── mat2d-spec.js │ │ ├── mat3-spec.js │ │ ├── mat4-spec.js │ │ ├── quat-spec.js │ │ ├── vec2-spec.js │ │ ├── vec3-spec.js │ │ ├── vec4-spec.js │ │ └── worker-spec.js │ ├── helpers │ │ ├── node-helper.js │ │ └── spec-helper.js │ └── jasmine.yml ├── src │ ├── gl-matrix-manifest.js │ ├── gl-matrix.js.erb │ └── gl-matrix │ │ ├── common.js │ │ ├── mat2.js │ │ ├── mat2d.js │ │ ├── mat3.js │ │ ├── mat4.js │ │ ├── quat.js │ │ ├── vec2.js │ │ ├── vec3.js │ │ └── vec4.js └── tasks │ ├── build.rake │ ├── build │ ├── compile.rake │ └── minify.rake │ ├── default.rake │ ├── release.rake │ ├── support │ ├── gl-matrix.rb │ └── gl-matrix │ │ ├── release_helper.rb │ │ └── version.rb │ └── test │ ├── ci.rake │ ├── coverage.rake │ ├── jasmine.rake │ └── node.rake ├── mvp.vert ├── points.frag ├── webgl-shader-loader ├── .gitignore ├── LICENSE ├── README.md ├── debug.js ├── fragment.glsl ├── index.html ├── test.js ├── vertex.glsl ├── webGLShaderLoader.js └── webGLUtils.js └── worker.js /LICENSE.md: -------------------------------------------------------------------------------- 1 | #THE BEER-WARE LICENSE (Revision 42): 2 | wrote this file. As long as you retain this notice you 3 | can do whatever you want with this stuff. If we meet some day, and you think 4 | this stuff is worth it, you can buy me a beer in return. 5 | 6 | Nick Desaulniers 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebGL in Web Workers 2 | 3 | Set `gfx.offscreencanvas.enabled` to `true` in `about:config` in Firefox 44+. 4 | 5 | See also [MDN](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas). 6 | 7 | -------------------------------------------------------------------------------- /animation-worker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Colors here are tied to vertices. Fragment colors in between are interpolated.

9 | 10 | 11 | 12 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /animation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

Colors here are tied to vertices. Fragment colors in between are interpolated.

9 | 10 | 11 | 12 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /gl-matrix/.gitignore: -------------------------------------------------------------------------------- 1 | .rvmrc 2 | covershot 3 | .DS_Store 4 | tmp 5 | node_modules 6 | -------------------------------------------------------------------------------- /gl-matrix/Gemfile: -------------------------------------------------------------------------------- 1 | source :gemcutter 2 | 3 | # core ruby 4 | gem 'rake' 5 | 6 | # https://github.com/pivotal/jasmine-gem 7 | gem 'jasmine' 8 | 9 | # https://github.com/sstephenson/sprockets 10 | gem 'sprockets' 11 | 12 | # https://github.com/lautis/uglifier 13 | gem 'uglifier' 14 | 15 | # for jasmine:ci task 16 | gem 'json' 17 | 18 | # https://github.com/wycats/thor - for release debug 19 | gem 'thor' 20 | -------------------------------------------------------------------------------- /gl-matrix/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | childprocess (0.3.8) 5 | ffi (~> 1.0, >= 1.0.11) 6 | diff-lcs (1.1.3) 7 | execjs (1.4.0) 8 | multi_json (~> 1.0) 9 | ffi (1.4.0) 10 | hike (1.2.1) 11 | jasmine (1.2.1) 12 | jasmine-core (>= 1.2.0) 13 | rack (~> 1.0) 14 | rspec (>= 1.3.1) 15 | selenium-webdriver (>= 0.1.3) 16 | jasmine-core (1.2.0) 17 | json (1.7.4) 18 | multi_json (1.6.1) 19 | rack (1.5.1) 20 | rake (0.9.2.2) 21 | rspec (2.11.0) 22 | rspec-core (~> 2.11.0) 23 | rspec-expectations (~> 2.11.0) 24 | rspec-mocks (~> 2.11.0) 25 | rspec-core (2.11.1) 26 | rspec-expectations (2.11.2) 27 | diff-lcs (~> 1.1.3) 28 | rspec-mocks (2.11.2) 29 | rubyzip (0.9.9) 30 | selenium-webdriver (2.30.0) 31 | childprocess (>= 0.2.5) 32 | multi_json (~> 1.0) 33 | rubyzip 34 | websocket (~> 1.0.4) 35 | sprockets (2.8.2) 36 | hike (~> 1.2) 37 | multi_json (~> 1.0) 38 | rack (~> 1.0) 39 | tilt (~> 1.1, != 1.3.0) 40 | thor (0.14.6) 41 | tilt (1.3.3) 42 | uglifier (1.2.7) 43 | execjs (>= 0.3.0) 44 | multi_json (~> 1.3) 45 | websocket (1.0.7) 46 | 47 | PLATFORMS 48 | ruby 49 | 50 | DEPENDENCIES 51 | jasmine 52 | json 53 | rake 54 | sprockets 55 | thor 56 | uglifier 57 | -------------------------------------------------------------------------------- /gl-matrix/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 16 | 2. Altered source versions must be plainly marked as such, and must not 17 | be misrepresented as being the original software. 18 | 19 | 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- /gl-matrix/README.md: -------------------------------------------------------------------------------- 1 | glMatrix 2 | ======================= 3 | 4 | Javascript has evolved into a language capable of handling realtime 3D graphics, 5 | via WebGL, and computationally intensive tasks such as physics simulations. 6 | These types of applications demand high performance vector and matrix math, 7 | which is something that Javascript doesn't provide by default. 8 | glMatrix to the rescue! 9 | 10 | glMatrix is designed to perform vector and matrix operations stupidly fast! By 11 | hand-tuning each function for maximum performance and encouraging efficient 12 | usage patterns through API conventions, glMatrix will help you get the most out 13 | of your browsers Javascript engine. 14 | 15 | Learn More 16 | ---------------------- 17 | For documentation, news, tutorials, and more visit the [glMatrix Homepage](http://glmatrix.net/) 18 | 19 | Contributing 20 | ---------------------- 21 | Contributions are welcome! Please make pull requests agains the `dev` branch, 22 | and please provide unit tests for new functionality. (See TESTING.md for details) 23 | -------------------------------------------------------------------------------- /gl-matrix/Rakefile: -------------------------------------------------------------------------------- 1 | begin 2 | require 'bundler/setup' 3 | rescue LoadError 4 | puts "Couldn't find Bundler!" 5 | puts 6 | puts "Please run:" 7 | puts " gem install bundler" 8 | puts 9 | puts "...and then try again." 10 | puts 11 | exit 12 | end 13 | 14 | # dependencies 15 | require 'json' 16 | require 'rspec/core/rake_task' 17 | require 'uglifier' 18 | 19 | # helper module 20 | require File.expand_path('./tasks/support/gl-matrix', File.dirname(__FILE__)) 21 | include GLMatrix 22 | 23 | Dir[base_path.join './tasks/**/*.rake'].each do |f| 24 | load f 25 | end 26 | -------------------------------------------------------------------------------- /gl-matrix/TESTING.md: -------------------------------------------------------------------------------- 1 | Running the test suite 2 | ======================= 3 | 4 | The unit tests are built upon the following tools: 5 | 6 | * Jasmine -- the underlying test suite which executes the test and reports feedback 7 | * node.js -- used for testing at the command line, via the `jasmine-node` package 8 | * selenium -- used for automated in-browser testing via Ruby 9 | * jscoverage -- used for code coverage report generation 10 | 11 | If Ruby is installed, you can set up with: 12 | 13 | gem install bundler 14 | bundle install 15 | 16 | ...and then test with: 17 | 18 | rake 19 | 20 | Hint: also look at 21 | 22 | rake --tasks 23 | 24 | If Ruby is not installed, you must test with `jasmine-node` directly: 25 | 26 | NODE_PATH=$NODE_PATH:. \ 27 | node_modules/jasmine-node/bin/jasmine-node \ 28 | spec/helpers/node_helper.js -------------------------------------------------------------------------------- /gl-matrix/VERSION: -------------------------------------------------------------------------------- 1 | 2.1.0 -------------------------------------------------------------------------------- /gl-matrix/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gl-matrix", 3 | "version": "2.2.0", 4 | "homepage": "http://glmatrix.net", 5 | "authors": [ 6 | "Brandon Jones ", 7 | "Colin MacKenzie IV " 8 | ], 9 | "description": "Javascript Matrix and Vector library for High Performance WebGL apps", 10 | "main": "dist/gl-matrix.js", 11 | "ignore": [ 12 | "**/.*", 13 | "jsdoc-template", 14 | "spec", 15 | "src", 16 | "tasks", 17 | "Gemfile", 18 | "Gemfile.lock", 19 | "Rakefile", 20 | "TESTING.md" 21 | ], 22 | "keywords": [ 23 | "webGL", 24 | "matrix", 25 | "vector" 26 | ], 27 | "license": "BSD" 28 | } 29 | -------------------------------------------------------------------------------- /gl-matrix/jsdoc-template/allclasses.tmpl: -------------------------------------------------------------------------------- 1 |
{+new Link().toFile("index.html").withText("Class Index")+} 2 | | {+new Link().toFile("files.html").withText("File Index")+}
3 |
4 |

Classes

5 |
    6 | 7 |
  • {! 8 | if (thisClass.alias != "_global_") { 9 | output += new Link().toClass(thisClass.alias); 10 | } 11 | !}
  • 12 |
    13 |
14 |
-------------------------------------------------------------------------------- /gl-matrix/jsdoc-template/allfiles.tmpl: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | {! Link.base = ""; /* all generated links will be relative to this */ !} 7 | glMatrix - File Index 8 | 9 | 10 | 13 | 14 | 15 | 16 | {+include("static/header.html")+} 17 | 18 |
19 | 20 |
21 | {+publish.classesIndex+} 22 |
23 | 24 |
25 |

File Index

26 | 27 | 28 |
29 |

{+new Link().toSrc(item.alias).withText(item.name)+}

30 | {+resolveLinks(item.desc)+} 31 |
32 | 33 |
Author:
34 |
{+item.author+}
35 |
36 | 37 |
Version:
38 |
{+item.version+}
39 |
40 | {! var locations = item.comment.getTag('location').map(function($){return $.toString().replace(/(^\$ ?| ?\$$)/g, '').replace(/^HeadURL: https:/g, 'http:');}) !} 41 | 42 |
Location:
43 | 44 |
{+location+}
45 |
46 |
47 |
48 |
49 |
50 |
51 | 52 |
53 | 54 |
55 | 56 | ©{+JSDOC.opt.D.copyright+}
57 | Documentation generated by JsDoc Toolkit {+JSDOC.VERSION+} on {+new Date()+} 58 |

59 | Theme based on Github Pages template by orderedlist 60 |
61 |
62 | 63 |
64 | 65 | -------------------------------------------------------------------------------- /gl-matrix/jsdoc-template/class.tmpl: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | {! Link.base = "../"; /* all generated links will be relative to this */ !} 8 | glMatrix - {+data.alias+} 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | {+include("static/header.html")+} 19 | 20 | 21 |
22 | 23 |
24 | 25 | {+publish.classesIndex+} 26 | 27 |
28 | 29 |
30 | 31 |

32 | {! 33 | var classType = ""; 34 | 35 | if (data.isBuiltin()) { 36 | classType += "Built-In "; 37 | } 38 | 39 | if (data.isNamespace) { 40 | if (data.is('FUNCTION')) { 41 | classType += "Function "; 42 | } 43 | classType += "Namespace "; 44 | } 45 | else { 46 | classType += "Class "; 47 | } 48 | !} 49 | {+classType+}{+data.alias+} 50 |

51 | 52 | 53 |

54 |
Version 55 | {+ data.version +}.
56 |
57 |
Extends 58 | {+ 59 | data.augments 60 | .sort() 61 | .map( 62 | function($) { return new Link().toSymbol($); } 63 | ) 64 | .join(", ") 65 | +}.
66 |
67 | 68 | {+resolveLinks(data.classDesc)+} 69 | 70 | 71 |

{+resolveLinks(summarize(data.desc))+}
72 | 73 | 74 | {# isn't defined in any file #} 75 |
Defined in: {+new Link().toSrc(data.srcFile)+}. 76 |
77 |

78 | 79 | 80 | 81 | {! var ownProperties = data.properties.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !} 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 100 | 106 | 107 | 108 | 109 |
Field Summary
Field AttributesField Name and Description
{! 95 | if (member.isPrivate) output += "<private> "; 96 | if (member.isInner) output += "<inner> "; 97 | if (member.isStatic) output += "<static> "; 98 | if (member.isConstant) output += "<constant> "; 99 | !}  101 |
102 | {+member.memberOf+}.{+new Link().toSymbol(member.alias).withText(member.name)+} 103 |
104 |
{+resolveLinks(summarize(member.desc))+}
105 |
110 |
111 | 112 | 113 |
114 | {! 115 | var borrowedMembers = data.properties.filter(function($) {return $.memberOf != data.alias}); 116 | 117 | var contributers = []; 118 | borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)}); 119 | for (var i = 0, l = contributers.length; i < l; i++) { 120 | output += 121 | "
Fields borrowed from class "+new Link().toSymbol(contributers[i])+":
" 122 | + 123 | "
" + 124 | borrowedMembers 125 | .filter( 126 | function($) { return $.memberOf == contributers[i] } 127 | ) 128 | .sort(makeSortby("name")) 129 | .map( 130 | function($) { return new Link().toSymbol($.alias).withText($.name) } 131 | ) 132 | .join(", ") 133 | + 134 | "
"; 135 | } 136 | !} 137 |
138 |
139 |
140 | 141 | 142 | 143 | {! var ownMethods = data.methods.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !} 144 | 145 |

Methods

146 | 147 | 148 | 149 | 150 | 155 | 156 | 157 | 158 |
151 | {+member.memberOf+}.{+new Link().toSymbol(member.alias).withText(member.name.replace(/\^\d+$/, ''))+}{+makeSignature(member.params)+} 152 | 153 |
{+resolveLinks(summarize(member.desc))+}
154 |
159 |
160 |
161 | 162 | 163 | 164 |
165 | Field Detail 166 |
167 | 168 | 169 |
{! 170 | if (member.isPrivate) output += "<private> "; 171 | if (member.isInner) output += "<inner> "; 172 | if (member.isStatic) output += "<static> "; 173 | if (member.isConstant) output += "<constant> "; 174 | !} 175 | 176 | {{+new Link().toSymbol(member.type)+}} 177 | {+member.memberOf+}.{+member.name+} 178 | 179 |
180 |
181 | {+resolveLinks(member.desc)+} 182 | 183 |
184 | Defined in: {+new Link().toSrc(member.srcFile)+}. 185 |
186 |
Author: {+member.author+}.
187 |
188 | 189 | 190 | 191 |
{+example+}
192 |
193 |
194 | 195 | 196 |
197 |
Deprecated:
198 |
199 | {+ resolveLinks(member.deprecated) +} 200 |
201 |
202 |
203 | 204 |
205 |
Since:
206 |
{+ member.since +}
207 |
208 |
209 | 210 |
211 |
See:
212 | 213 |
{+ new Link().toSymbol(item) +}
214 |
215 |
216 |
217 | 218 |
219 |
Default Value:
220 |
221 | {+resolveLinks(member.defaultValue)+} 222 |
223 |
224 |
225 | 226 |
227 |
228 |
229 | 230 | 231 | 232 |

Method Detail

233 | 234 | 235 |

236 | {{+new Link().toSymbol(member.type)+}} 237 | {+member.memberOf+}.{+member.name.replace(/\^\d+$/, '')+}{+makeSignature(member.params)+} 238 |

239 | 240 |
241 |

242 | {+resolveLinks(member.desc)+} 243 | 244 |
245 | Defined in: {+new Link().toSrc(member.srcFile)+}. 246 |
247 |
Author: {+member.author+}.
248 |

249 | 250 | 251 | 252 |
{+example+}
253 |
254 |
255 | 256 | 257 |
258 |
Parameters:
259 | 260 |
261 | {+((item.type)?"{"+(new Link().toSymbol(item.type))+"} " : "")+}{+item.name+} 262 | Optional, Default: {+item.defaultValue+} 263 |
264 |
{+resolveLinks(item.desc)+}
265 |
266 |
267 |
268 | 269 |
270 |
Deprecated:
271 |
272 | {+ resolveLinks(member.deprecated) +} 273 |
274 |
275 |
276 | 277 |
278 |
Since:
279 |
{+ member.since +}
280 |
281 | 282 |
283 | 284 |
285 |
Throws:
286 | 287 |
288 | {+((item.type)?"{"+(new Link().toSymbol(item.type))+"} " : "")+} {+item.name+} 289 |
290 |
{+resolveLinks(item.desc)+}
291 |
292 |
293 |
294 | 295 |
296 |
Returns:
297 | 298 |
{+((item.type)?"{"+(new Link().toSymbol(item.type))+"} " : "")+}{+resolveLinks(item.desc)+}
299 |
300 |
301 |
302 | 303 |
304 |
Requires:
305 | 306 |
{+ resolveLinks(item) +}
307 |
308 |
309 |
310 | 311 |
312 |
See:
313 | 314 |
{+ new Link().toSymbol(item) +}
315 |
316 |
317 |
318 | 319 |
320 |
321 |
322 |
323 | 324 |
325 |
326 | 327 | 328 | 329 |
330 | 331 | ©{+JSDOC.opt.D.copyright+}
332 | Documentation generated by JsDoc Toolkit {+JSDOC.VERSION+} on {+new Date()+} 333 |

334 | Theme based on Github Pages template by orderedlist 335 |
336 |
337 | 338 |
339 | 340 | 341 | -------------------------------------------------------------------------------- /gl-matrix/jsdoc-template/index.tmpl: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | glMatrix - Index 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | {+include("static/header.html")+} 19 | 20 |
21 | 22 |
23 | {+publish.classesIndex+} 24 |
25 | 26 |
27 |

Class Index

28 | 29 | 30 | 31 |
32 |

{+(new Link().toSymbol(thisClass.alias))+}

33 | {+resolveLinks(summarize(thisClass.classDesc))+} 34 |
35 |
36 |
37 |
38 | 39 |
40 | 41 |
42 | 43 | ©{+JSDOC.opt.D.copyright+}
44 | Documentation generated by JsDoc Toolkit {+JSDOC.VERSION+} on {+new Date()+} 45 |

46 | Theme based on Github Pages template by orderedlist 47 |
48 |
49 | 50 |
51 | 52 | -------------------------------------------------------------------------------- /gl-matrix/jsdoc-template/publish.js: -------------------------------------------------------------------------------- 1 | /** Called automatically by JsDoc Toolkit. */ 2 | function publish(symbolSet) { 3 | publish.conf = { // trailing slash expected for dirs 4 | ext: ".html", 5 | outDir: JSDOC.opt.d || SYS.pwd+"../out/jsdoc/", 6 | templatesDir: JSDOC.opt.t || SYS.pwd+"../jsdoc-template/", 7 | symbolsDir: "symbols/", 8 | srcDir: "symbols/src/" 9 | }; 10 | 11 | // is source output is suppressed, just display the links to the source file 12 | if (JSDOC.opt.s && defined(Link) && Link.prototype._makeSrcLink) { 13 | Link.prototype._makeSrcLink = function(srcFilePath) { 14 | return "<"+srcFilePath+">"; 15 | } 16 | } 17 | 18 | // create the folders and subfolders to hold the output 19 | IO.mkPath((publish.conf.outDir+"symbols/src").split("/")); 20 | 21 | // used to allow Link to check the details of things being linked to 22 | Link.symbolSet = symbolSet; 23 | 24 | // create the required templates 25 | try { 26 | var classTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"class.tmpl"); 27 | var classesTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allclasses.tmpl"); 28 | } 29 | catch(e) { 30 | print("Couldn't create the required templates: "+e); 31 | quit(); 32 | } 33 | 34 | // some ustility filters 35 | function hasNoParent($) {return ($.memberOf == "")} 36 | function isaFile($) {return ($.is("FILE"))} 37 | function isaClass($) {return ($.is("CONSTRUCTOR") || $.isNamespace)} 38 | 39 | // get an array version of the symbolset, useful for filtering 40 | var symbols = symbolSet.toArray(); 41 | 42 | // create the hilited source code files 43 | var files = JSDOC.opt.srcFiles; 44 | for (var i = 0, l = files.length; i < l; i++) { 45 | var file = files[i]; 46 | var srcDir = publish.conf.outDir + "symbols/src/"; 47 | makeSrcFile(file, srcDir); 48 | } 49 | 50 | // get a list of all the classes in the symbolset 51 | var classes = symbols.filter(isaClass).sort(makeSortby("alias")); 52 | 53 | // create a filemap in which outfiles must be to be named uniquely, ignoring case 54 | if (JSDOC.opt.u) { 55 | var filemapCounts = {}; 56 | Link.filemap = {}; 57 | for (var i = 0, l = classes.length; i < l; i++) { 58 | var lcAlias = classes[i].alias.toLowerCase(); 59 | 60 | if (!filemapCounts[lcAlias]) filemapCounts[lcAlias] = 1; 61 | else filemapCounts[lcAlias]++; 62 | 63 | Link.filemap[classes[i].alias] = 64 | (filemapCounts[lcAlias] > 1)? 65 | lcAlias+"_"+filemapCounts[lcAlias] : lcAlias; 66 | } 67 | } 68 | 69 | // create a class index, displayed in the left-hand column of every class page 70 | Link.base = "../"; 71 | publish.classesIndex = classesTemplate.process(classes); // kept in memory 72 | 73 | // create each of the class pages 74 | for (var i = 0, l = classes.length; i < l; i++) { 75 | var symbol = classes[i]; 76 | 77 | symbol.events = symbol.getEvents(); // 1 order matters 78 | symbol.methods = symbol.getMethods(); // 2 79 | 80 | Link.currentSymbol= symbol; 81 | var output = ""; 82 | output = classTemplate.process(symbol); 83 | 84 | IO.saveFile(publish.conf.outDir+"symbols/", ((JSDOC.opt.u)? Link.filemap[symbol.alias] : symbol.alias) + publish.conf.ext, output); 85 | } 86 | 87 | // regenerate the index with different relative links, used in the index pages 88 | Link.base = ""; 89 | publish.classesIndex = classesTemplate.process(classes); 90 | 91 | // create the class index page 92 | try { 93 | var classesindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"index.tmpl"); 94 | } 95 | catch(e) { print(e.message); quit(); } 96 | 97 | var classesIndex = classesindexTemplate.process(classes); 98 | IO.saveFile(publish.conf.outDir, "index"+publish.conf.ext, classesIndex); 99 | classesindexTemplate = classesIndex = classes = null; 100 | 101 | // create the file index page 102 | try { 103 | var fileindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allfiles.tmpl"); 104 | } 105 | catch(e) { print(e.message); quit(); } 106 | 107 | var documentedFiles = symbols.filter(isaFile); // files that have file-level docs 108 | var allFiles = []; // not all files have file-level docs, but we need to list every one 109 | 110 | for (var i = 0; i < files.length; i++) { 111 | allFiles.push(new JSDOC.Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */"))); 112 | } 113 | 114 | for (var i = 0; i < documentedFiles.length; i++) { 115 | var offset = files.indexOf(documentedFiles[i].alias); 116 | allFiles[offset] = documentedFiles[i]; 117 | } 118 | 119 | allFiles = allFiles.sort(makeSortby("name")); 120 | 121 | // output the file index page 122 | var filesIndex = fileindexTemplate.process(allFiles); 123 | IO.saveFile(publish.conf.outDir, "files"+publish.conf.ext, filesIndex); 124 | fileindexTemplate = filesIndex = files = null; 125 | } 126 | 127 | 128 | /** Just the first sentence (up to a full stop). Should not break on dotted variable names. */ 129 | function summarize(desc) { 130 | if (typeof desc != "undefined") 131 | return desc.match(/([\w\W]+?\.)[^a-z0-9_$]/i)? RegExp.$1 : desc; 132 | } 133 | 134 | /** Make a symbol sorter by some attribute. */ 135 | function makeSortby(attribute) { 136 | return function(a, b) { 137 | if (a[attribute] != undefined && b[attribute] != undefined) { 138 | a = a[attribute].toLowerCase(); 139 | b = b[attribute].toLowerCase(); 140 | if (a < b) return -1; 141 | if (a > b) return 1; 142 | return 0; 143 | } 144 | } 145 | } 146 | 147 | /** Pull in the contents of an external file at the given path. */ 148 | function include(path) { 149 | var path = publish.conf.templatesDir+path; 150 | return IO.readFile(path); 151 | } 152 | 153 | /** Turn a raw source file into a code-hilited page in the docs. */ 154 | function makeSrcFile(path, srcDir, name) { 155 | if (JSDOC.opt.s) return; 156 | 157 | if (!name) { 158 | name = path.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_"); 159 | name = name.replace(/\:/g, "_"); 160 | } 161 | 162 | var src = {path: path, name:name, charset: IO.encoding, hilited: ""}; 163 | 164 | if (defined(JSDOC.PluginManager)) { 165 | JSDOC.PluginManager.run("onPublishSrc", src); 166 | } 167 | 168 | if (src.hilited) { 169 | IO.saveFile(srcDir, name+publish.conf.ext, src.hilited); 170 | } 171 | } 172 | 173 | /** Build output for displaying function parameters. */ 174 | function makeSignature(params) { 175 | if (!params) return "()"; 176 | var signature = "(" 177 | + 178 | params.filter( 179 | function($) { 180 | return $.name.indexOf(".") == -1; // don't show config params in signature 181 | } 182 | ).map( 183 | function($) { 184 | return $.name; 185 | } 186 | ).join(", ") 187 | + 188 | ")"; 189 | return signature; 190 | } 191 | 192 | /** Find symbol {@link ...} strings in text and turn into html links */ 193 | function resolveLinks(str, from) { 194 | str = str.replace(/\{@link ([^} ]+) ?\}/gi, 195 | function(match, symbolName) { 196 | return new Link().toSymbol(symbolName); 197 | } 198 | ); 199 | 200 | return str; 201 | } 202 | -------------------------------------------------------------------------------- /gl-matrix/jsdoc-template/static/default.css: -------------------------------------------------------------------------------- 1 | /* default.css */ 2 | 3 | /* 4 | 5 | body 6 | { 7 | font: 12px "Lucida Grande", Tahoma, Arial, Helvetica, sans-serif; 8 | width: 800px; 9 | } 10 | 11 | .header 12 | { 13 | clear: both; 14 | background-color: #ccc; 15 | padding: 8px; 16 | } 17 | 18 | h1 19 | { 20 | font-size: 150%; 21 | font-weight: bold; 22 | padding: 0; 23 | margin: 1em 0 0 .3em; 24 | } 25 | 26 | hr 27 | { 28 | border: none 0; 29 | border-top: 1px solid #7F8FB1; 30 | height: 1px; 31 | } 32 | 33 | pre.code 34 | { 35 | display: block; 36 | padding: 8px; 37 | border: 1px dashed #ccc; 38 | } 39 | 40 | #index 41 | { 42 | margin-top: 24px; 43 | float: left; 44 | width: 160px; 45 | position: absolute; 46 | left: 8px; 47 | background-color: #F3F3F3; 48 | padding: 8px; 49 | } 50 | 51 | #content 52 | { 53 | margin-left: 190px; 54 | width: 600px; 55 | } 56 | 57 | .classList 58 | { 59 | list-style-type: none; 60 | padding: 0; 61 | margin: 0 0 0 8px; 62 | font-family: arial, sans-serif; 63 | font-size: 1em; 64 | overflow: auto; 65 | } 66 | 67 | .classList li 68 | { 69 | padding: 0; 70 | margin: 0 0 8px 0; 71 | } 72 | 73 | .summaryTable { width: 100%; } 74 | 75 | h1.classTitle 76 | { 77 | font-size:170%; 78 | line-height:130%; 79 | } 80 | 81 | h2 { font-size: 110%; } 82 | caption, div.sectionTitle 83 | { 84 | background-color: #7F8FB1; 85 | color: #fff; 86 | font-size:130%; 87 | text-align: left; 88 | padding: 2px 6px 2px 6px; 89 | border: 1px #7F8FB1 solid; 90 | } 91 | 92 | div.sectionTitle { margin-bottom: 8px; } 93 | .summaryTable thead { display: none; } 94 | 95 | .summaryTable td 96 | { 97 | vertical-align: top; 98 | padding: 4px; 99 | border-bottom: 1px #7F8FB1 solid; 100 | border-right: 1px #7F8FB1 solid; 101 | border-left: 1px #7F8FB1 solid; 102 | } 103 | 104 | .summaryTable td.attributes 105 | { 106 | border-left: 1px #7F8FB1 solid; 107 | width: 140px; 108 | text-align: right; 109 | } 110 | 111 | td.attributes, .fixedFont 112 | { 113 | line-height: 15px; 114 | color: #002EBE; 115 | font-family: "Courier New",Courier,monospace; 116 | font-size: 13px; 117 | } 118 | 119 | .summaryTable td.nameDescription 120 | { 121 | text-align: left; 122 | font-size: 13px; 123 | line-height: 15px; 124 | } 125 | 126 | .summaryTable td.nameDescription, .description 127 | { 128 | line-height: 15px; 129 | padding: 4px; 130 | padding-left: 4px; 131 | } 132 | 133 | .summaryTable { margin-bottom: 8px; } 134 | 135 | ul.inheritsList 136 | { 137 | list-style: square; 138 | margin-left: 20px; 139 | padding-left: 0; 140 | } 141 | 142 | .detailList { 143 | margin-left: 20px; 144 | line-height: 15px; 145 | } 146 | .detailList dt { margin-left: 20px; } 147 | 148 | .detailList .heading 149 | { 150 | font-weight: bold; 151 | padding-bottom: 6px; 152 | margin-left: 0; 153 | } 154 | 155 | .light, td.attributes, .light a:link, .light a:visited 156 | { 157 | color: #777; 158 | font-style: italic; 159 | } 160 | 161 | .fineprint 162 | { 163 | text-align: right; 164 | font-size: 10px; 165 | } 166 | 167 | */ 168 | 169 | /* Copied from styles.css generated by Github Pages */ 170 | 171 | @import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700); 172 | 173 | body { 174 | padding:50px; 175 | font:14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; 176 | color:#777; 177 | font-weight:300; 178 | } 179 | 180 | h1, h2, h3, h4, h5, h6 { 181 | color:#222; 182 | margin:0 0 20px; 183 | } 184 | 185 | p, ul, ol, table, pre, dl { 186 | margin:0 0 20px; 187 | } 188 | 189 | h1, h2, h3 { 190 | line-height:1.1; 191 | } 192 | 193 | h1 { 194 | font-size:28px; 195 | } 196 | 197 | h2 { 198 | color:#393939; 199 | } 200 | 201 | h3, h4, h5, h6 { 202 | color:#494949; 203 | } 204 | 205 | a { 206 | color:#39c; 207 | font-weight:400; 208 | text-decoration:none; 209 | } 210 | 211 | a small { 212 | font-size:11px; 213 | color:#777; 214 | margin-top:-0.6em; 215 | display:block; 216 | } 217 | 218 | .wrapper { 219 | width:860px; 220 | margin:0 auto; 221 | } 222 | 223 | blockquote { 224 | border-left:1px solid #e5e5e5; 225 | margin:0; 226 | padding:0 0 0 20px; 227 | font-style:italic; 228 | } 229 | 230 | code, pre { 231 | font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; 232 | color:#333; 233 | font-size:12px; 234 | } 235 | 236 | pre { 237 | padding:8px 15px; 238 | background: #f8f8f8; 239 | border-radius:5px; 240 | border:1px solid #e5e5e5; 241 | overflow-x: auto; 242 | } 243 | 244 | table { 245 | width:100%; 246 | border-collapse:collapse; 247 | } 248 | 249 | th, td { 250 | text-align:left; 251 | padding:5px 10px; 252 | border-bottom:1px solid #e5e5e5; 253 | } 254 | 255 | dt { 256 | color:#444; 257 | font-weight:700; 258 | } 259 | 260 | th { 261 | color:#444; 262 | } 263 | 264 | img { 265 | max-width:100%; 266 | } 267 | 268 | header { 269 | width:270px; 270 | float:left; 271 | position:fixed; 272 | } 273 | 274 | header ul { 275 | list-style:none; 276 | padding:0; 277 | 278 | /*background: #eee; 279 | background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); 280 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); 281 | background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); 282 | background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); 283 | background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); 284 | background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%); 285 | 286 | border-radius:5px; 287 | border:1px solid #d2d2d2; 288 | box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0;*/ 289 | width:270px; 290 | } 291 | 292 | header li { 293 | width:89px; 294 | /*float:left; 295 | border-right:1px solid #d2d2d2; 296 | height:40px;*/ 297 | } 298 | 299 | header ul a { 300 | line-height:1; 301 | font-size:11px; 302 | color:#999; 303 | display:block; 304 | text-align:center; 305 | padding-top:6px; 306 | /*height:40px;*/ 307 | } 308 | 309 | strong { 310 | color:#222; 311 | font-weight:700; 312 | } 313 | 314 | /*header ul li + li { 315 | width:88px; 316 | border-left:1px solid #fff; 317 | } 318 | 319 | header ul li + li + li { 320 | border-right:none; 321 | width:89px; 322 | }*/ 323 | 324 | header ul a strong { 325 | font-size:14px; 326 | display:block; 327 | color:#222; 328 | } 329 | 330 | section { 331 | width:500px; 332 | float:right; 333 | padding-bottom:50px; 334 | } 335 | 336 | small { 337 | font-size:11px; 338 | } 339 | 340 | hr { 341 | border:0; 342 | background:#e5e5e5; 343 | height:1px; 344 | margin:0 0 20px; 345 | } 346 | 347 | footer { 348 | width:270px; 349 | float:left; 350 | position:fixed; 351 | bottom:50px; 352 | } 353 | 354 | @media print, screen and (max-width: 960px) { 355 | 356 | div.wrapper { 357 | width:auto; 358 | margin:0; 359 | } 360 | 361 | header, section, footer { 362 | float:none; 363 | position:static; 364 | width:auto; 365 | } 366 | 367 | header { 368 | /*padding-right:320px;*/ 369 | padding: 0; 370 | } 371 | 372 | section { 373 | border:1px solid #e5e5e5; 374 | border-width:1px 0; 375 | padding:20px 0; 376 | margin:0 0 20px; 377 | } 378 | 379 | header a small { 380 | display:inline; 381 | } 382 | 383 | header ul { 384 | position:static; 385 | height:40px; 386 | width: auto; 387 | } 388 | 389 | header ul li { 390 | float: left; 391 | } 392 | } 393 | 394 | @media print, screen and (max-width: 720px) { 395 | body { 396 | word-wrap:break-word; 397 | } 398 | 399 | header { 400 | padding:0; 401 | } 402 | 403 | header ul, header p.view { 404 | position:static; 405 | } 406 | 407 | pre, code { 408 | word-wrap:normal; 409 | } 410 | } 411 | 412 | @media print, screen and (max-width: 480px) { 413 | body { 414 | padding:15px; 415 | } 416 | 417 | /*header ul { 418 | display:none; 419 | }*/ 420 | } 421 | 422 | @media print { 423 | body { 424 | padding:0.4in; 425 | font-size:12pt; 426 | color:#444; 427 | } 428 | } 429 | -------------------------------------------------------------------------------- /gl-matrix/jsdoc-template/static/header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gl-matrix/jsdoc-template/static/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | glMatrix Documentation 7 | 8 | 9 | 10 | 11 | 12 | <body> 13 | <p> 14 | This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. 15 | </p> 16 | </body> 17 | 18 | 19 | -------------------------------------------------------------------------------- /gl-matrix/jsdoc-template/symbol.tmpl: -------------------------------------------------------------------------------- 1 | 2 | {+data.name+} 3 | {+data.memberOf+} 4 | {+data.isStatic+} 5 | {+data.isa+} 6 | {+data.desc+} 7 | {+data.classDesc+} 8 | 9 | 10 | 11 | {+method.name+} 12 | {+method.memberOf+} 13 | {+method.isStatic+} 14 | {+method.desc+} 15 | 16 | 17 | {+param.type+} 18 | {+param.name+} 19 | {+param.desc+} 20 | {+param.defaultValue+} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {+property.name+} 29 | {+property.memberOf+} 30 | {+property.isStatic+} 31 | {+property.desc+} 32 | {+property.type+} 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /gl-matrix/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gl-matrix", 3 | "description": "Javascript Matrix and Vector library for High Performance WebGL apps", 4 | "version": "2.2.1", 5 | "main": "dist/gl-matrix.js", 6 | "homepage": "http://glmatrix.net", 7 | "bugs": { 8 | "url": "https://github.com/toji/gl-matrix/issues" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/toji/gl-matrix.git" 13 | }, 14 | "contributors": [ 15 | { 16 | "name": "Brandon Jones", 17 | "email": "tojiro@gmail.com" 18 | }, 19 | { 20 | "name": "Colin MacKenzie IV", 21 | "email": "sinisterchipmunk@gmail.com" 22 | } 23 | ], 24 | "devDependencies" : { 25 | "covershot": "0.1.0", 26 | "node-jsmeter": "0.1.2", 27 | "jasmine-node": "1.2.2" 28 | }, 29 | "license": "BSD" 30 | } 31 | -------------------------------------------------------------------------------- /gl-matrix/spec/gl-matrix/common-spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * common.js unit test 3 | */ 4 | 5 | describe("glMatrix", function(){ 6 | var result; 7 | 8 | describe("toRadian", function(){ 9 | beforeEach(function(){ result = glMatrix.toRadian(180); }); 10 | it("should return a value of 3.141592654(Math.PI)", function(){ expect(result).toBeEqualish(Math.PI); }); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /gl-matrix/spec/gl-matrix/mat2-spec.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | describe("mat2", function() { 24 | var out, matA, matB, identity, result; 25 | 26 | beforeEach(function() { 27 | matA = [1, 2, 28 | 3, 4]; 29 | 30 | matB = [5, 6, 31 | 7, 8]; 32 | 33 | out = [0, 0, 34 | 0, 0]; 35 | 36 | identity = [1, 0, 37 | 0, 1]; 38 | }); 39 | 40 | describe("create", function() { 41 | beforeEach(function() { result = mat2.create(); }); 42 | it("should return a 4 element array initialized to a 2x2 identity matrix", function() { expect(result).toBeEqualish(identity); }); 43 | }); 44 | 45 | describe("clone", function() { 46 | beforeEach(function() { result = mat2.clone(matA); }); 47 | it("should return a 4 element array initialized to the values in matA", function() { expect(result).toBeEqualish(matA); }); 48 | }); 49 | 50 | describe("copy", function() { 51 | beforeEach(function() { result = mat2.copy(out, matA); }); 52 | it("should place values into out", function() { expect(out).toBeEqualish(matA); }); 53 | it("should return out", function() { expect(result).toBe(out); }); 54 | }); 55 | 56 | describe("identity", function() { 57 | beforeEach(function() { result = mat2.identity(out); }); 58 | it("should place values into out", function() { expect(result).toBeEqualish(identity); }); 59 | it("should return out", function() { expect(result).toBe(out); }); 60 | }); 61 | 62 | describe("transpose", function() { 63 | describe("with a separate output matrix", function() { 64 | beforeEach(function() { result = mat2.transpose(out, matA); }); 65 | 66 | it("should place values into out", function() { expect(out).toBeEqualish([1, 3, 2, 4]); }); 67 | it("should return out", function() { expect(result).toBe(out); }); 68 | it("should not modify matA", function() { expect(matA).toBeEqualish([1, 2, 3, 4]); }); 69 | }); 70 | 71 | describe("when matA is the output matrix", function() { 72 | beforeEach(function() { result = mat2.transpose(matA, matA); }); 73 | 74 | it("should place values into matA", function() { expect(matA).toBeEqualish([1, 3, 2, 4]); }); 75 | it("should return matA", function() { expect(result).toBe(matA); }); 76 | }); 77 | }); 78 | 79 | describe("invert", function() { 80 | describe("with a separate output matrix", function() { 81 | beforeEach(function() { result = mat2.invert(out, matA); }); 82 | 83 | it("should place values into out", function() { expect(out).toBeEqualish([-2, 1, 1.5, -0.5]); }); 84 | it("should return out", function() { expect(result).toBe(out); }); 85 | it("should not modify matA", function() { expect(matA).toBeEqualish([1, 2, 3, 4]); }); 86 | }); 87 | 88 | describe("when matA is the output matrix", function() { 89 | beforeEach(function() { result = mat2.invert(matA, matA); }); 90 | 91 | it("should place values into matA", function() { expect(matA).toBeEqualish([-2, 1, 1.5, -0.5]); }); 92 | it("should return matA", function() { expect(result).toBe(matA); }); 93 | }); 94 | }); 95 | 96 | describe("adjoint", function() { 97 | describe("with a separate output matrix", function() { 98 | beforeEach(function() { result = mat2.adjoint(out, matA); }); 99 | 100 | it("should place values into out", function() { expect(out).toBeEqualish([4, -2, -3, 1]); }); 101 | it("should return out", function() { expect(result).toBe(out); }); 102 | it("should not modify matA", function() { expect(matA).toBeEqualish([1, 2, 3, 4]); }); 103 | }); 104 | 105 | describe("when matA is the output matrix", function() { 106 | beforeEach(function() { result = mat2.adjoint(matA, matA); }); 107 | 108 | it("should place values into matA", function() { expect(matA).toBeEqualish([4, -2, -3, 1]); }); 109 | it("should return matA", function() { expect(result).toBe(matA); }); 110 | }); 111 | }); 112 | 113 | describe("determinant", function() { 114 | beforeEach(function() { result = mat2.determinant(matA); }); 115 | 116 | it("should return the determinant", function() { expect(result).toEqual(-2); }); 117 | }); 118 | 119 | describe("multiply", function() { 120 | it("should have an alias called 'mul'", function() { expect(mat2.mul).toEqual(mat2.multiply); }); 121 | 122 | describe("with a separate output matrix", function() { 123 | beforeEach(function() { result = mat2.multiply(out, matA, matB); }); 124 | 125 | it("should place values into out", function() { expect(out).toBeEqualish([23, 34, 31, 46]); }); 126 | it("should return out", function() { expect(result).toBe(out); }); 127 | it("should not modify matA", function() { expect(matA).toBeEqualish([1, 2, 3, 4]); }); 128 | it("should not modify matB", function() { expect(matB).toBeEqualish([5, 6, 7, 8]); }); 129 | }); 130 | 131 | describe("when matA is the output matrix", function() { 132 | beforeEach(function() { result = mat2.multiply(matA, matA, matB); }); 133 | 134 | it("should place values into matA", function() { expect(matA).toBeEqualish([23, 34, 31, 46]); }); 135 | it("should return matA", function() { expect(result).toBe(matA); }); 136 | it("should not modify matB", function() { expect(matB).toBeEqualish([5, 6, 7, 8]); }); 137 | }); 138 | 139 | describe("when matB is the output matrix", function() { 140 | beforeEach(function() { result = mat2.multiply(matB, matA, matB); }); 141 | 142 | it("should place values into matB", function() { expect(matB).toBeEqualish([23, 34, 31, 46]); }); 143 | it("should return matB", function() { expect(result).toBe(matB); }); 144 | it("should not modify matA", function() { expect(matA).toBeEqualish([1, 2, 3, 4]); }); 145 | }); 146 | }); 147 | 148 | describe("rotate", function() { 149 | describe("with a separate output matrix", function() { 150 | beforeEach(function() { result = mat2.rotate(out, matA, Math.PI * 0.5); }); 151 | 152 | it("should place values into out", function() { expect(out).toBeEqualish([3, 4, -1, -2]); }); 153 | it("should return out", function() { expect(result).toBe(out); }); 154 | it("should not modify matA", function() { expect(matA).toBeEqualish([1, 2, 3, 4]); }); 155 | }); 156 | 157 | describe("when matA is the output matrix", function() { 158 | beforeEach(function() { result = mat2.rotate(matA, matA, Math.PI * 0.5); }); 159 | 160 | it("should place values into matA", function() { expect(matA).toBeEqualish([3, 4, -1, -2]); }); 161 | it("should return matA", function() { expect(result).toBe(matA); }); 162 | }); 163 | }); 164 | 165 | describe("scale", function() { 166 | var vecA; 167 | beforeEach(function() { vecA = [2, 3]; }); 168 | 169 | describe("with a separate output matrix", function() { 170 | beforeEach(function() { result = mat2.scale(out, matA, vecA); }); 171 | 172 | it("should place values into out", function() { expect(out).toBeEqualish([2, 4, 9, 12]); }); 173 | it("should return out", function() { expect(result).toBe(out); }); 174 | it("should not modify matA", function() { expect(matA).toBeEqualish([1, 2, 3, 4]); }); 175 | }); 176 | 177 | describe("when matA is the output matrix", function() { 178 | beforeEach(function() { result = mat2.scale(matA, matA, vecA); }); 179 | 180 | it("should place values into matA", function() { expect(matA).toBeEqualish([2, 4, 9, 12]); }); 181 | it("should return matA", function() { expect(result).toBe(matA); }); 182 | }); 183 | }); 184 | 185 | describe("str", function() { 186 | beforeEach(function() { result = mat2.str(matA); }); 187 | 188 | it("should return a string representation of the matrix", function() { expect(result).toEqual("mat2(1, 2, 3, 4)"); }); 189 | }); 190 | 191 | describe("frob", function() { 192 | beforeEach(function() { result = mat2.frob(matA); }); 193 | it("should return the Frobenius Norm of the matrix", function() { expect(result).toEqual( Math.sqrt(Math.pow(1, 2) + Math.pow(2, 2) + Math.pow(3, 2) + Math.pow(4, 2))); }); 194 | }); 195 | 196 | describe("LDU", function() { 197 | beforeEach(function() {L = mat2.create(); D = mat2.create(); U = mat2.create(); result = mat2.LDU(L, D, U, [4,3,6,3]); 198 | L_result = mat2.create(); L_result[2] = 1.5; 199 | D_result = mat2.create(); 200 | U_result = mat2.create(); 201 | U_result[0] = 4; U_result[1] = 3; U_result[3] = -1.5; 202 | }); 203 | it("should return a lower triangular, a diagonal and an upper triangular matrix", function() { 204 | expect(result[0]).toBeEqualish(L_result); 205 | expect(result[1]).toBeEqualish(D_result); 206 | expect(result[2]).toBeEqualish(U_result); 207 | }); 208 | }); 209 | 210 | }); 211 | -------------------------------------------------------------------------------- /gl-matrix/spec/gl-matrix/mat2d-spec.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | describe("mat2d", function() { 24 | var out, matA, matB, identity, result; 25 | 26 | beforeEach(function() { 27 | matA = [1, 2, 28 | 3, 4, 29 | 5, 6]; 30 | 31 | oldA = [1, 2, 32 | 3, 4, 33 | 5, 6]; 34 | 35 | matB = [7, 8, 36 | 9, 10, 37 | 11, 12]; 38 | 39 | oldB = [7, 8, 40 | 9, 10, 41 | 11, 12]; 42 | 43 | out = [0, 0, 44 | 0, 0, 45 | 0, 0]; 46 | 47 | identity = [1, 0, 48 | 0, 1, 49 | 0, 0]; 50 | }); 51 | 52 | describe("create", function() { 53 | beforeEach(function() { result = mat2d.create(); }); 54 | it("should return a 6 element array initialized to a 2x3 identity matrix", function() { expect(result).toBeEqualish(identity); }); 55 | }); 56 | 57 | describe("clone", function() { 58 | beforeEach(function() { result = mat2d.clone(matA); }); 59 | it("should return a 6 element array initialized to the values in matA", function() { expect(result).toBeEqualish(matA); }); 60 | }); 61 | 62 | describe("copy", function() { 63 | beforeEach(function() { result = mat2d.copy(out, matA); }); 64 | it("should place values into out", function() { expect(out).toBeEqualish(matA); }); 65 | it("should return out", function() { expect(result).toBe(out); }); 66 | }); 67 | 68 | describe("identity", function() { 69 | beforeEach(function() { result = mat2d.identity(out); }); 70 | it("should place values into out", function() { expect(result).toBeEqualish(identity); }); 71 | it("should return out", function() { expect(result).toBe(out); }); 72 | }); 73 | 74 | describe("invert", function() { 75 | describe("with a separate output matrix", function() { 76 | beforeEach(function() { result = mat2d.invert(out, matA); }); 77 | 78 | it("should place values into out", function() { expect(out).toBeEqualish([ -2, 1, 1.5, -0.5, 1, -2 ]); }); 79 | it("should return out", function() { expect(result).toBe(out); }); 80 | it("should not modify matA", function() { expect(matA).toBeEqualish(oldA); }); 81 | }); 82 | 83 | describe("when matA is the output matrix", function() { 84 | beforeEach(function() { result = mat2d.invert(matA, matA); }); 85 | 86 | it("should place values into matA", function() { expect(matA).toBeEqualish([ -2, 1, 1.5, -0.5, 1, -2 ]); }); 87 | it("should return matA", function() { expect(result).toBe(matA); }); 88 | }); 89 | }); 90 | 91 | describe("determinant", function() { 92 | beforeEach(function() { result = mat2d.determinant(matA); }); 93 | 94 | it("should return the determinant", function() { expect(result).toEqual(-2); }); 95 | }); 96 | 97 | describe("multiply", function() { 98 | it("should have an alias called 'mul'", function() { expect(mat2d.mul).toEqual(mat2d.multiply); }); 99 | 100 | describe("with a separate output matrix", function() { 101 | beforeEach(function() { result = mat2d.multiply(out, matA, matB); }); 102 | 103 | it("should place values into out", function() { expect(out).toBeEqualish([31, 46, 39, 58, 52, 76]); }); 104 | it("should return out", function() { expect(result).toBe(out); }); 105 | it("should not modify matA", function() { expect(matA).toBeEqualish(oldA); }); 106 | it("should not modify matB", function() { expect(matB).toBeEqualish(oldB); }); 107 | }); 108 | 109 | describe("when matA is the output matrix", function() { 110 | beforeEach(function() { result = mat2d.multiply(matA, matA, matB); }); 111 | 112 | it("should place values into matA", function() { expect(matA).toBeEqualish([31, 46, 39, 58, 52, 76]); }); 113 | it("should return matA", function() { expect(result).toBe(matA); }); 114 | it("should not modify matB", function() { expect(matB).toBeEqualish(oldB); }); 115 | }); 116 | 117 | describe("when matB is the output matrix", function() { 118 | beforeEach(function() { result = mat2d.multiply(matB, matA, matB); }); 119 | 120 | it("should place values into matB", function() { expect(matB).toBeEqualish([31, 46, 39, 58, 52, 76]); }); 121 | it("should return matB", function() { expect(result).toBe(matB); }); 122 | it("should not modify matA", function() { expect(matA).toBeEqualish(oldA); }); 123 | }); 124 | }); 125 | 126 | describe("rotate", function() { 127 | describe("with a separate output matrix", function() { 128 | beforeEach(function() { result = mat2d.rotate(out, matA, Math.PI * 0.5); }); 129 | 130 | it("should place values into out", function() { expect(out).toBeEqualish([3, 4, -1, -2, 5, 6]); }); 131 | it("should return out", function() { expect(result).toBe(out); }); 132 | it("should not modify matA", function() { expect(matA).toBeEqualish(oldA); }); 133 | }); 134 | 135 | describe("when matA is the output matrix", function() { 136 | beforeEach(function() { result = mat2d.rotate(matA, matA, Math.PI * 0.5); }); 137 | 138 | it("should place values into matA", function() { expect(matA).toBeEqualish([3, 4, -1, -2, 5, 6]); }); 139 | it("should return matA", function() { expect(result).toBe(matA); }); 140 | }); 141 | }); 142 | 143 | describe("scale", function() { 144 | var vecA; 145 | beforeEach(function() { vecA = [2, 3]; }); 146 | 147 | describe("with a separate output matrix", function() { 148 | beforeEach(function() { result = mat2d.scale(out, matA, vecA); }); 149 | 150 | it("should place values into out", function() { expect(out).toBeEqualish([2, 4, 9, 12, 5, 6]); }); 151 | it("should return out", function() { expect(result).toBe(out); }); 152 | it("should not modify matA", function() { expect(matA).toBeEqualish(oldA); }); 153 | }); 154 | 155 | describe("when matA is the output matrix", function() { 156 | beforeEach(function() { result = mat2d.scale(matA, matA, vecA); }); 157 | 158 | it("should place values into matA", function() { expect(matA).toBeEqualish([2, 4, 9, 12, 5, 6]); }); 159 | it("should return matA", function() { expect(result).toBe(matA); }); 160 | }); 161 | }); 162 | 163 | describe("translate", function() { 164 | var vecA; 165 | beforeEach(function() { vecA = [2, 3]; }); 166 | 167 | describe("with a separate output matrix", function() { 168 | beforeEach(function() { result = mat2d.translate(out, matA, vecA); }); 169 | 170 | it("should place values into out", function() { expect(out).toBeEqualish([1, 2, 3, 4, 16, 22]); }); 171 | it("should return out", function() { expect(result).toBe(out); }); 172 | it("should not modify matA", function() { expect(matA).toBeEqualish(oldA); }); 173 | }); 174 | 175 | describe("when matA is the output matrix", function() { 176 | beforeEach(function() { result = mat2d.translate(matA, matA, vecA); }); 177 | 178 | it("should place values into matA", function() { expect(matA).toBeEqualish([1, 2, 3, 4, 16, 22]); }); 179 | it("should return matA", function() { expect(result).toBe(matA); }); 180 | }); 181 | }); 182 | 183 | describe("str", function() { 184 | beforeEach(function() { result = mat2d.str(matA); }); 185 | 186 | it("should return a string representation of the matrix", function() { expect(result).toEqual("mat2d(1, 2, 3, 4, 5, 6)"); }); 187 | }); 188 | 189 | describe("frob", function() { 190 | beforeEach(function() { result = mat2d.frob(matA); }); 191 | it("should return the Frobenius Norm of the matrix", function() { expect(result).toEqual( Math.sqrt(Math.pow(1, 2) + Math.pow(2, 2) + Math.pow(3, 2) + Math.pow(4, 2) + Math.pow(5, 2) + Math.pow(6, 2) + 1)); }); 192 | }); 193 | 194 | }); 195 | -------------------------------------------------------------------------------- /gl-matrix/spec/gl-matrix/mat3-spec.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | describe("mat3", function() { 24 | var out, matA, matB, identity, result; 25 | 26 | beforeEach(function() { 27 | matA = [1, 0, 0, 28 | 0, 1, 0, 29 | 1, 2, 1]; 30 | 31 | matB = [1, 0, 0, 32 | 0, 1, 0, 33 | 3, 4, 1]; 34 | 35 | out = [0, 0, 0, 36 | 0, 0, 0, 37 | 0, 0, 0]; 38 | 39 | identity = [1, 0, 0, 40 | 0, 1, 0, 41 | 0, 0, 1]; 42 | }); 43 | 44 | describe("normalFromMat4", function() { 45 | beforeEach(function() { 46 | matA = [1, 0, 0, 0, 47 | 0, 1, 0, 0, 48 | 0, 0, 1, 0, 49 | 0, 0, 0, 1]; 50 | result = mat3.normalFromMat4(out, matA); 51 | }); 52 | 53 | it("should return out", function() { expect(result).toBe(out); }); 54 | 55 | describe("with translation and rotation", function() { 56 | beforeEach(function() { 57 | mat4.translate(matA, matA, [2, 4, 6]); 58 | mat4.rotateX(matA, matA, Math.PI / 2); 59 | 60 | result = mat3.normalFromMat4(out, matA); 61 | }); 62 | 63 | it("should give rotated matrix", function() { 64 | expect(result).toBeEqualish([1, 0, 0, 65 | 0, 0, 1, 66 | 0,-1, 0]); 67 | }); 68 | 69 | describe("and scale", function() { 70 | beforeEach(function() { 71 | mat4.scale(matA, matA, [2, 3, 4]); 72 | 73 | result = mat3.normalFromMat4(out, matA); 74 | }); 75 | 76 | it("should give rotated matrix", function() { 77 | expect(result).toBeEqualish([0.5, 0, 0, 78 | 0, 0, 0.333333, 79 | 0, -0.25, 0]); 80 | }); 81 | }); 82 | }); 83 | }); 84 | 85 | describe("fromQuat", function() { 86 | var q; 87 | 88 | beforeEach(function() { 89 | q = [ 0, -0.7071067811865475, 0, 0.7071067811865475 ]; 90 | result = mat3.fromQuat(out, q); 91 | }); 92 | 93 | it("should return out", function() { expect(result).toBe(out); }); 94 | 95 | it("should rotate a vector the same as the original quat", function() { 96 | expect(vec3.transformMat3([], [0,0,-1], out)).toBeEqualish(vec3.transformQuat([], [0,0,-1], q)); 97 | }); 98 | 99 | it("should rotate a vector by PI/2 radians", function() { 100 | expect(vec3.transformMat3([], [0,0,-1], out)).toBeEqualish([1,0,0]); 101 | }); 102 | }); 103 | 104 | describe("fromMat4", function() { 105 | beforeEach(function() { 106 | result = mat3.fromMat4(out, [ 1, 2, 3, 4, 107 | 5, 6, 7, 8, 108 | 9,10,11,12, 109 | 13,14,15,16]); }); 110 | 111 | it("should return out", function() { expect(result).toBe(out); }); 112 | 113 | it("should calculate proper mat3", function() { 114 | expect(out).toBeEqualish([ 1, 2, 3, 115 | 5, 6, 7, 116 | 9,10,11]); 117 | }); 118 | }); 119 | 120 | describe("scale", function() { 121 | beforeEach(function() { result = mat3.scale(out, matA, [2,2]); }); 122 | it("should return out", function() { expect(result).toBe(out); }); 123 | it('should place proper values in out', function() { 124 | expect(out).toBeEqualish([ 2, 0, 0, 125 | 0, 2, 0, 126 | 1, 2, 1 ]); 127 | }); 128 | }); 129 | 130 | describe("create", function() { 131 | beforeEach(function() { result = mat3.create(); }); 132 | it("should return a 9 element array initialized to a 3x3 identity matrix", function() { expect(result).toBeEqualish(identity); }); 133 | }); 134 | 135 | describe("clone", function() { 136 | beforeEach(function() { result = mat3.clone(matA); }); 137 | it("should return a 9 element array initialized to the values in matA", function() { expect(result).toBeEqualish(matA); }); 138 | }); 139 | 140 | describe("copy", function() { 141 | beforeEach(function() { result = mat3.copy(out, matA); }); 142 | it("should place values into out", function() { expect(out).toBeEqualish(matA); }); 143 | it("should return out", function() { expect(result).toBe(out); }); 144 | }); 145 | 146 | describe("identity", function() { 147 | beforeEach(function() { result = mat3.identity(out); }); 148 | it("should place values into out", function() { expect(result).toBeEqualish(identity); }); 149 | it("should return out", function() { expect(result).toBe(out); }); 150 | }); 151 | 152 | describe("transpose", function() { 153 | describe("with a separate output matrix", function() { 154 | beforeEach(function() { result = mat3.transpose(out, matA); }); 155 | 156 | it("should place values into out", function() { 157 | expect(out).toBeEqualish([ 158 | 1, 0, 1, 159 | 0, 1, 2, 160 | 0, 0, 1 161 | ]); 162 | }); 163 | it("should return out", function() { expect(result).toBe(out); }); 164 | it("should not modify matA", function() { 165 | expect(matA).toBeEqualish([ 166 | 1, 0, 0, 167 | 0, 1, 0, 168 | 1, 2, 1 169 | ]); 170 | }); 171 | }); 172 | 173 | describe("when matA is the output matrix", function() { 174 | beforeEach(function() { result = mat3.transpose(matA, matA); }); 175 | 176 | it("should place values into matA", function() { 177 | expect(matA).toBeEqualish([ 178 | 1, 0, 1, 179 | 0, 1, 2, 180 | 0, 0, 1 181 | ]); 182 | }); 183 | it("should return matA", function() { expect(result).toBe(matA); }); 184 | }); 185 | }); 186 | 187 | describe("invert", function() { 188 | describe("with a separate output matrix", function() { 189 | beforeEach(function() { result = mat3.invert(out, matA); }); 190 | 191 | it("should place values into out", function() { 192 | expect(out).toBeEqualish([ 193 | 1, 0, 0, 194 | 0, 1, 0, 195 | -1, -2, 1 196 | ]); 197 | }); 198 | it("should return out", function() { expect(result).toBe(out); }); 199 | it("should not modify matA", function() { 200 | expect(matA).toBeEqualish([ 201 | 1, 0, 0, 202 | 0, 1, 0, 203 | 1, 2, 1 204 | ]); 205 | }); 206 | }); 207 | 208 | describe("when matA is the output matrix", function() { 209 | beforeEach(function() { result = mat3.invert(matA, matA); }); 210 | 211 | it("should place values into matA", function() { 212 | expect(matA).toBeEqualish([ 213 | 1, 0, 0, 214 | 0, 1, 0, 215 | -1, -2, 1 216 | ]); 217 | }); 218 | it("should return matA", function() { expect(result).toBe(matA); }); 219 | }); 220 | }); 221 | 222 | describe("adjoint", function() { 223 | describe("with a separate output matrix", function() { 224 | beforeEach(function() { result = mat3.adjoint(out, matA); }); 225 | 226 | it("should place values into out", function() { 227 | expect(out).toBeEqualish([ 228 | 1, 0, 0, 229 | 0, 1, 0, 230 | -1, -2, 1 231 | ]); 232 | }); 233 | it("should return out", function() { expect(result).toBe(out); }); 234 | it("should not modify matA", function() { 235 | expect(matA).toBeEqualish([ 236 | 1, 0, 0, 237 | 0, 1, 0, 238 | 1, 2, 1 239 | ]); 240 | }); 241 | }); 242 | 243 | describe("when matA is the output matrix", function() { 244 | beforeEach(function() { result = mat3.adjoint(matA, matA); }); 245 | 246 | it("should place values into matA", function() { 247 | expect(matA).toBeEqualish([ 248 | 1, 0, 0, 249 | 0, 1, 0, 250 | -1, -2, 1 251 | ]); 252 | }); 253 | it("should return matA", function() { expect(result).toBe(matA); }); 254 | }); 255 | }); 256 | 257 | describe("determinant", function() { 258 | beforeEach(function() { result = mat3.determinant(matA); }); 259 | 260 | it("should return the determinant", function() { expect(result).toEqual(1); }); 261 | }); 262 | 263 | describe("multiply", function() { 264 | it("should have an alias called 'mul'", function() { expect(mat3.mul).toEqual(mat3.multiply); }); 265 | 266 | describe("with a separate output matrix", function() { 267 | beforeEach(function() { result = mat3.multiply(out, matA, matB); }); 268 | 269 | it("should place values into out", function() { 270 | expect(out).toBeEqualish([ 271 | 1, 0, 0, 272 | 0, 1, 0, 273 | 4, 6, 1 274 | ]); 275 | }); 276 | it("should return out", function() { expect(result).toBe(out); }); 277 | it("should not modify matA", function() { 278 | expect(matA).toBeEqualish([ 279 | 1, 0, 0, 280 | 0, 1, 0, 281 | 1, 2, 1 282 | ]); 283 | }); 284 | it("should not modify matB", function() { 285 | expect(matB).toBeEqualish([ 286 | 1, 0, 0, 287 | 0, 1, 0, 288 | 3, 4, 1 289 | ]); 290 | }); 291 | }); 292 | 293 | describe("when matA is the output matrix", function() { 294 | beforeEach(function() { result = mat3.multiply(matA, matA, matB); }); 295 | 296 | it("should place values into matA", function() { 297 | expect(matA).toBeEqualish([ 298 | 1, 0, 0, 299 | 0, 1, 0, 300 | 4, 6, 1 301 | ]); 302 | }); 303 | it("should return matA", function() { expect(result).toBe(matA); }); 304 | it("should not modify matB", function() { 305 | expect(matB).toBeEqualish([ 306 | 1, 0, 0, 307 | 0, 1, 0, 308 | 3, 4, 1 309 | ]); 310 | }); 311 | }); 312 | 313 | describe("when matB is the output matrix", function() { 314 | beforeEach(function() { result = mat3.multiply(matB, matA, matB); }); 315 | 316 | it("should place values into matB", function() { 317 | expect(matB).toBeEqualish([ 318 | 1, 0, 0, 319 | 0, 1, 0, 320 | 4, 6, 1 321 | ]); 322 | }); 323 | it("should return matB", function() { expect(result).toBe(matB); }); 324 | it("should not modify matA", function() { 325 | expect(matA).toBeEqualish([ 326 | 1, 0, 0, 327 | 0, 1, 0, 328 | 1, 2, 1 329 | ]); 330 | }); 331 | }); 332 | }); 333 | 334 | describe("str", function() { 335 | beforeEach(function() { result = mat3.str(matA); }); 336 | 337 | it("should return a string representation of the matrix", function() { expect(result).toEqual("mat3(1, 0, 0, 0, 1, 0, 1, 2, 1)"); }); 338 | }); 339 | 340 | describe("frob", function() { 341 | beforeEach(function() { result = mat3.frob(matA); }); 342 | it("should return the Frobenius Norm of the matrix", function() { expect(result).toEqual( Math.sqrt(Math.pow(1, 2) + Math.pow(0, 2) + Math.pow(0, 2) + Math.pow(0, 2) + Math.pow(1, 2) + Math.pow(0, 2) + Math.pow(1, 2) + Math.pow(2, 2) + Math.pow(1, 2))); }); 343 | }); 344 | 345 | }); 346 | -------------------------------------------------------------------------------- /gl-matrix/spec/gl-matrix/worker-spec.js: -------------------------------------------------------------------------------- 1 | /* spec tests gl-matrix when embedded into a Web Worker */ 2 | 3 | // only test with workers if workers are available 4 | if (typeof(Worker) !== 'undefined') { 5 | describe("Embedded within Web Workers", function() { 6 | it("should initialize successfully", function() { 7 | var xhr = new XMLHttpRequest(); 8 | var source = null; 9 | xhr.onreadystatechange = function() { 10 | if (this.readyState == this.DONE) { 11 | if (this.status == 200) { 12 | source = this.responseText; 13 | } 14 | } 15 | }; 16 | xhr.open("GET", "/dist/gl-matrix.js"); 17 | xhr.send(); 18 | 19 | var result = null; 20 | 21 | waitsFor(function() { 22 | if (!source) return false; 23 | var blob = new Blob([ 24 | source, 25 | "self.postMessage(vec3.create());" 26 | ], 27 | {type: "application/javascript"} 28 | ); 29 | 30 | var worker = new Worker(URL.createObjectURL(blob)); 31 | worker.onmessage = function(e) { 32 | result = e.data; 33 | }; 34 | return true; 35 | }); 36 | 37 | waitsFor(function() { 38 | if (!result) return false; 39 | expect(result).toBeEqualish([0, 0, 0]); 40 | return true; 41 | }); 42 | }); 43 | }); 44 | } 45 | -------------------------------------------------------------------------------- /gl-matrix/spec/helpers/node-helper.js: -------------------------------------------------------------------------------- 1 | if (typeof(exports) !== 'undefined') { 2 | var glm; 3 | try { 4 | glm = require("../../tmp/coverage/manifest"); 5 | } catch(e) { 6 | if (e.code === "MODULE_NOT_FOUND" || 7 | e.toString().indexOf("Cannot find module") !== -1) 8 | glm = require("../../dist/gl-matrix"); 9 | else throw e; 10 | } 11 | for (var ns in glm) { 12 | global[ns] = glm[ns]; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gl-matrix/spec/helpers/spec-helper.js: -------------------------------------------------------------------------------- 1 | var HELPER_MATCHERS = (function() { 2 | var EPSILON = 0.00001; 3 | 4 | return { 5 | /* 6 | Returns true if `actual` has the same length as `expected`, and 7 | if each element of both arrays is within 0.000001 of each other. 8 | This is a way to check for "equal enough" conditions, as a way 9 | of working around floating point imprecision. 10 | */ 11 | toBeEqualish: function(expected) { 12 | if (typeof(this.actual) == 'number') 13 | return Math.abs(this.actual - expected) < EPSILON; 14 | 15 | if (this.actual.length != expected.length) return false; 16 | for (var i = 0; i < this.actual.length; i++) { 17 | if (isNaN(this.actual[i]) !== isNaN(expected[i])) 18 | return false; 19 | if (Math.abs(this.actual[i] - expected[i]) >= EPSILON) 20 | return false; 21 | } 22 | return true; 23 | } 24 | }; 25 | })(); 26 | 27 | beforeEach(function() { 28 | this.addMatchers(HELPER_MATCHERS); 29 | }); 30 | 31 | if (typeof(global) != 'undefined') 32 | global.HELPER_MATCHERS = HELPER_MATCHERS; 33 | -------------------------------------------------------------------------------- /gl-matrix/spec/jasmine.yml: -------------------------------------------------------------------------------- 1 | # src_files 2 | # 3 | # Return an array of filepaths relative to src_dir to include before jasmine specs. 4 | # Default: [] 5 | # 6 | # EXAMPLE: 7 | # 8 | # src_files: 9 | # - lib/source1.js 10 | # - lib/source2.js 11 | # - dist/**/*.js 12 | # 13 | src_files: 14 | - dist/gl-matrix.js 15 | 16 | # stylesheets 17 | # 18 | # Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs. 19 | # Default: [] 20 | # 21 | # EXAMPLE: 22 | # 23 | # stylesheets: 24 | # - css/style.css 25 | # - stylesheets/*.css 26 | # 27 | stylesheets: 28 | 29 | # helpers 30 | # 31 | # Return an array of filepaths relative to spec_dir to include before jasmine specs. 32 | # Default: ["helpers/**/*.js"] 33 | # 34 | # EXAMPLE: 35 | # 36 | # helpers: 37 | # - helpers/**/*.js 38 | # 39 | helpers: 40 | 41 | # spec_files 42 | # 43 | # Return an array of filepaths relative to spec_dir to include. 44 | # Default: ["**/*[sS]pec.js"] 45 | # 46 | # EXAMPLE: 47 | # 48 | # spec_files: 49 | # - **/*[sS]pec.js 50 | # 51 | spec_files: 52 | 53 | # src_dir 54 | # 55 | # Source directory path. Your src_files must be returned relative to this path. Will use root if left blank. 56 | # Default: project root 57 | # 58 | # EXAMPLE: 59 | # 60 | # src_dir: public 61 | # 62 | src_dir: 63 | 64 | # spec_dir 65 | # 66 | # Spec directory path. Your spec_files must be returned relative to this path. 67 | # Default: spec/javascripts 68 | # 69 | # EXAMPLE: 70 | # 71 | # spec_dir: spec/javascripts 72 | # 73 | spec_dir: spec 74 | -------------------------------------------------------------------------------- /gl-matrix/src/gl-matrix-manifest.js: -------------------------------------------------------------------------------- 1 | //= require 'gl-matrix/common.js' 2 | 3 | //= require 'gl-matrix/vec2.js' 4 | //= require 'gl-matrix/vec3.js' 5 | //= require 'gl-matrix/vec4.js' 6 | 7 | //= require 'gl-matrix/mat2.js' 8 | //= require 'gl-matrix/mat2d.js' 9 | //= require 'gl-matrix/mat3.js' 10 | //= require 'gl-matrix/mat4.js' 11 | 12 | //= require 'gl-matrix/quat.js' 13 | -------------------------------------------------------------------------------- /gl-matrix/src/gl-matrix.js.erb: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview gl-matrix - High performance matrix and vector operations 3 | * @author Brandon Jones 4 | * @author Colin MacKenzie IV 5 | * @version 2.2.1 6 | */ 7 | 8 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | * Redistributions of source code must retain the above copyright notice, this 14 | list of conditions and the following disclaimer. 15 | * Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | (function(_global) { 31 | "use strict"; 32 | 33 | var shim = {}; 34 | if (typeof(exports) === 'undefined') { 35 | if(typeof define == 'function' && typeof define.amd == 'object' && define.amd) { 36 | shim.exports = {}; 37 | define(function() { 38 | return shim.exports; 39 | }); 40 | } else { 41 | // gl-matrix lives in a browser, define its namespaces in global 42 | shim.exports = typeof(window) !== 'undefined' ? window : _global; 43 | } 44 | } 45 | else { 46 | // gl-matrix lives in commonjs, define its namespaces in exports 47 | shim.exports = exports; 48 | } 49 | 50 | (function(exports) { 51 | <%= GLMatrix.sprockets['gl-matrix-manifest.js'] %> 52 | })(shim.exports); 53 | })(this); 54 | -------------------------------------------------------------------------------- /gl-matrix/src/gl-matrix/common.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | if(!GLMAT_EPSILON) { 24 | var GLMAT_EPSILON = 0.000001; 25 | } 26 | 27 | if(!GLMAT_ARRAY_TYPE) { 28 | var GLMAT_ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array; 29 | } 30 | 31 | if(!GLMAT_RANDOM) { 32 | var GLMAT_RANDOM = Math.random; 33 | } 34 | 35 | /** 36 | * @class Common utilities 37 | * @name glMatrix 38 | */ 39 | var glMatrix = {}; 40 | 41 | /** 42 | * Sets the type of array used when creating new vectors and matricies 43 | * 44 | * @param {Type} type Array type, such as Float32Array or Array 45 | */ 46 | glMatrix.setMatrixArrayType = function(type) { 47 | GLMAT_ARRAY_TYPE = type; 48 | } 49 | 50 | if(typeof(exports) !== 'undefined') { 51 | exports.glMatrix = glMatrix; 52 | } 53 | 54 | var degree = Math.PI / 180; 55 | 56 | /** 57 | * Convert Degree To Radian 58 | * 59 | * @param {Number} Angle in Degrees 60 | */ 61 | glMatrix.toRadian = function(a){ 62 | return a * degree; 63 | } 64 | -------------------------------------------------------------------------------- /gl-matrix/src/gl-matrix/mat2.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | /** 24 | * @class 2x2 Matrix 25 | * @name mat2 26 | */ 27 | var mat2 = {}; 28 | 29 | /** 30 | * Creates a new identity mat2 31 | * 32 | * @returns {mat2} a new 2x2 matrix 33 | */ 34 | mat2.create = function() { 35 | var out = new GLMAT_ARRAY_TYPE(4); 36 | out[0] = 1; 37 | out[1] = 0; 38 | out[2] = 0; 39 | out[3] = 1; 40 | return out; 41 | }; 42 | 43 | /** 44 | * Creates a new mat2 initialized with values from an existing matrix 45 | * 46 | * @param {mat2} a matrix to clone 47 | * @returns {mat2} a new 2x2 matrix 48 | */ 49 | mat2.clone = function(a) { 50 | var out = new GLMAT_ARRAY_TYPE(4); 51 | out[0] = a[0]; 52 | out[1] = a[1]; 53 | out[2] = a[2]; 54 | out[3] = a[3]; 55 | return out; 56 | }; 57 | 58 | /** 59 | * Copy the values from one mat2 to another 60 | * 61 | * @param {mat2} out the receiving matrix 62 | * @param {mat2} a the source matrix 63 | * @returns {mat2} out 64 | */ 65 | mat2.copy = function(out, a) { 66 | out[0] = a[0]; 67 | out[1] = a[1]; 68 | out[2] = a[2]; 69 | out[3] = a[3]; 70 | return out; 71 | }; 72 | 73 | /** 74 | * Set a mat2 to the identity matrix 75 | * 76 | * @param {mat2} out the receiving matrix 77 | * @returns {mat2} out 78 | */ 79 | mat2.identity = function(out) { 80 | out[0] = 1; 81 | out[1] = 0; 82 | out[2] = 0; 83 | out[3] = 1; 84 | return out; 85 | }; 86 | 87 | /** 88 | * Transpose the values of a mat2 89 | * 90 | * @param {mat2} out the receiving matrix 91 | * @param {mat2} a the source matrix 92 | * @returns {mat2} out 93 | */ 94 | mat2.transpose = function(out, a) { 95 | // If we are transposing ourselves we can skip a few steps but have to cache some values 96 | if (out === a) { 97 | var a1 = a[1]; 98 | out[1] = a[2]; 99 | out[2] = a1; 100 | } else { 101 | out[0] = a[0]; 102 | out[1] = a[2]; 103 | out[2] = a[1]; 104 | out[3] = a[3]; 105 | } 106 | 107 | return out; 108 | }; 109 | 110 | /** 111 | * Inverts a mat2 112 | * 113 | * @param {mat2} out the receiving matrix 114 | * @param {mat2} a the source matrix 115 | * @returns {mat2} out 116 | */ 117 | mat2.invert = function(out, a) { 118 | var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], 119 | 120 | // Calculate the determinant 121 | det = a0 * a3 - a2 * a1; 122 | 123 | if (!det) { 124 | return null; 125 | } 126 | det = 1.0 / det; 127 | 128 | out[0] = a3 * det; 129 | out[1] = -a1 * det; 130 | out[2] = -a2 * det; 131 | out[3] = a0 * det; 132 | 133 | return out; 134 | }; 135 | 136 | /** 137 | * Calculates the adjugate of a mat2 138 | * 139 | * @param {mat2} out the receiving matrix 140 | * @param {mat2} a the source matrix 141 | * @returns {mat2} out 142 | */ 143 | mat2.adjoint = function(out, a) { 144 | // Caching this value is nessecary if out == a 145 | var a0 = a[0]; 146 | out[0] = a[3]; 147 | out[1] = -a[1]; 148 | out[2] = -a[2]; 149 | out[3] = a0; 150 | 151 | return out; 152 | }; 153 | 154 | /** 155 | * Calculates the determinant of a mat2 156 | * 157 | * @param {mat2} a the source matrix 158 | * @returns {Number} determinant of a 159 | */ 160 | mat2.determinant = function (a) { 161 | return a[0] * a[3] - a[2] * a[1]; 162 | }; 163 | 164 | /** 165 | * Multiplies two mat2's 166 | * 167 | * @param {mat2} out the receiving matrix 168 | * @param {mat2} a the first operand 169 | * @param {mat2} b the second operand 170 | * @returns {mat2} out 171 | */ 172 | mat2.multiply = function (out, a, b) { 173 | var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; 174 | var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; 175 | out[0] = a0 * b0 + a2 * b1; 176 | out[1] = a1 * b0 + a3 * b1; 177 | out[2] = a0 * b2 + a2 * b3; 178 | out[3] = a1 * b2 + a3 * b3; 179 | return out; 180 | }; 181 | 182 | /** 183 | * Alias for {@link mat2.multiply} 184 | * @function 185 | */ 186 | mat2.mul = mat2.multiply; 187 | 188 | /** 189 | * Rotates a mat2 by the given angle 190 | * 191 | * @param {mat2} out the receiving matrix 192 | * @param {mat2} a the matrix to rotate 193 | * @param {Number} rad the angle to rotate the matrix by 194 | * @returns {mat2} out 195 | */ 196 | mat2.rotate = function (out, a, rad) { 197 | var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], 198 | s = Math.sin(rad), 199 | c = Math.cos(rad); 200 | out[0] = a0 * c + a2 * s; 201 | out[1] = a1 * c + a3 * s; 202 | out[2] = a0 * -s + a2 * c; 203 | out[3] = a1 * -s + a3 * c; 204 | return out; 205 | }; 206 | 207 | /** 208 | * Scales the mat2 by the dimensions in the given vec2 209 | * 210 | * @param {mat2} out the receiving matrix 211 | * @param {mat2} a the matrix to rotate 212 | * @param {vec2} v the vec2 to scale the matrix by 213 | * @returns {mat2} out 214 | **/ 215 | mat2.scale = function(out, a, v) { 216 | var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], 217 | v0 = v[0], v1 = v[1]; 218 | out[0] = a0 * v0; 219 | out[1] = a1 * v0; 220 | out[2] = a2 * v1; 221 | out[3] = a3 * v1; 222 | return out; 223 | }; 224 | 225 | /** 226 | * Returns a string representation of a mat2 227 | * 228 | * @param {mat2} mat matrix to represent as a string 229 | * @returns {String} string representation of the matrix 230 | */ 231 | mat2.str = function (a) { 232 | return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; 233 | }; 234 | 235 | /** 236 | * Returns Frobenius norm of a mat2 237 | * 238 | * @param {mat2} a the matrix to calculate Frobenius norm of 239 | * @returns {Number} Frobenius norm 240 | */ 241 | mat2.frob = function (a) { 242 | return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2))) 243 | }; 244 | 245 | /** 246 | * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix 247 | * @param {mat2} L the lower triangular matrix 248 | * @param {mat2} D the diagonal matrix 249 | * @param {mat2} U the upper triangular matrix 250 | * @param {mat2} a the input matrix to factorize 251 | */ 252 | 253 | mat2.LDU = function (L, D, U, a) { 254 | L[2] = a[2]/a[0]; 255 | U[0] = a[0]; 256 | U[1] = a[1]; 257 | U[3] = a[3] - L[2] * U[1]; 258 | return [L, D, U]; 259 | }; 260 | 261 | if(typeof(exports) !== 'undefined') { 262 | exports.mat2 = mat2; 263 | } 264 | -------------------------------------------------------------------------------- /gl-matrix/src/gl-matrix/mat2d.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | /** 24 | * @class 2x3 Matrix 25 | * @name mat2d 26 | * 27 | * @description 28 | * A mat2d contains six elements defined as: 29 | *
 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 | var mat2d = {}; 42 | 43 | /** 44 | * Creates a new identity mat2d 45 | * 46 | * @returns {mat2d} a new 2x3 matrix 47 | */ 48 | mat2d.create = function() { 49 | var out = new GLMAT_ARRAY_TYPE(6); 50 | out[0] = 1; 51 | out[1] = 0; 52 | out[2] = 0; 53 | out[3] = 1; 54 | out[4] = 0; 55 | out[5] = 0; 56 | return out; 57 | }; 58 | 59 | /** 60 | * Creates a new mat2d initialized with values from an existing matrix 61 | * 62 | * @param {mat2d} a matrix to clone 63 | * @returns {mat2d} a new 2x3 matrix 64 | */ 65 | mat2d.clone = function(a) { 66 | var out = new GLMAT_ARRAY_TYPE(6); 67 | out[0] = a[0]; 68 | out[1] = a[1]; 69 | out[2] = a[2]; 70 | out[3] = a[3]; 71 | out[4] = a[4]; 72 | out[5] = a[5]; 73 | return out; 74 | }; 75 | 76 | /** 77 | * Copy the values from one mat2d to another 78 | * 79 | * @param {mat2d} out the receiving matrix 80 | * @param {mat2d} a the source matrix 81 | * @returns {mat2d} out 82 | */ 83 | mat2d.copy = function(out, a) { 84 | out[0] = a[0]; 85 | out[1] = a[1]; 86 | out[2] = a[2]; 87 | out[3] = a[3]; 88 | out[4] = a[4]; 89 | out[5] = a[5]; 90 | return out; 91 | }; 92 | 93 | /** 94 | * Set a mat2d to the identity matrix 95 | * 96 | * @param {mat2d} out the receiving matrix 97 | * @returns {mat2d} out 98 | */ 99 | mat2d.identity = function(out) { 100 | out[0] = 1; 101 | out[1] = 0; 102 | out[2] = 0; 103 | out[3] = 1; 104 | out[4] = 0; 105 | out[5] = 0; 106 | return out; 107 | }; 108 | 109 | /** 110 | * Inverts a mat2d 111 | * 112 | * @param {mat2d} out the receiving matrix 113 | * @param {mat2d} a the source matrix 114 | * @returns {mat2d} out 115 | */ 116 | mat2d.invert = function(out, a) { 117 | var aa = a[0], ab = a[1], ac = a[2], ad = a[3], 118 | atx = a[4], aty = a[5]; 119 | 120 | var det = aa * ad - ab * ac; 121 | if(!det){ 122 | return null; 123 | } 124 | det = 1.0 / det; 125 | 126 | out[0] = ad * det; 127 | out[1] = -ab * det; 128 | out[2] = -ac * det; 129 | out[3] = aa * det; 130 | out[4] = (ac * aty - ad * atx) * det; 131 | out[5] = (ab * atx - aa * aty) * det; 132 | return out; 133 | }; 134 | 135 | /** 136 | * Calculates the determinant of a mat2d 137 | * 138 | * @param {mat2d} a the source matrix 139 | * @returns {Number} determinant of a 140 | */ 141 | mat2d.determinant = function (a) { 142 | return a[0] * a[3] - a[1] * a[2]; 143 | }; 144 | 145 | /** 146 | * Multiplies two mat2d's 147 | * 148 | * @param {mat2d} out the receiving matrix 149 | * @param {mat2d} a the first operand 150 | * @param {mat2d} b the second operand 151 | * @returns {mat2d} out 152 | */ 153 | mat2d.multiply = function (out, a, b) { 154 | var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], 155 | b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5]; 156 | out[0] = a0 * b0 + a2 * b1; 157 | out[1] = a1 * b0 + a3 * b1; 158 | out[2] = a0 * b2 + a2 * b3; 159 | out[3] = a1 * b2 + a3 * b3; 160 | out[4] = a0 * b4 + a2 * b5 + a4; 161 | out[5] = a1 * b4 + a3 * b5 + a5; 162 | return out; 163 | }; 164 | 165 | /** 166 | * Alias for {@link mat2d.multiply} 167 | * @function 168 | */ 169 | mat2d.mul = mat2d.multiply; 170 | 171 | 172 | /** 173 | * Rotates a mat2d by the given angle 174 | * 175 | * @param {mat2d} out the receiving matrix 176 | * @param {mat2d} a the matrix to rotate 177 | * @param {Number} rad the angle to rotate the matrix by 178 | * @returns {mat2d} out 179 | */ 180 | mat2d.rotate = function (out, a, rad) { 181 | var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], 182 | s = Math.sin(rad), 183 | c = Math.cos(rad); 184 | out[0] = a0 * c + a2 * s; 185 | out[1] = a1 * c + a3 * s; 186 | out[2] = a0 * -s + a2 * c; 187 | out[3] = a1 * -s + a3 * c; 188 | out[4] = a4; 189 | out[5] = a5; 190 | return out; 191 | }; 192 | 193 | /** 194 | * Scales the mat2d by the dimensions in the given vec2 195 | * 196 | * @param {mat2d} out the receiving matrix 197 | * @param {mat2d} a the matrix to translate 198 | * @param {vec2} v the vec2 to scale the matrix by 199 | * @returns {mat2d} out 200 | **/ 201 | mat2d.scale = function(out, a, v) { 202 | var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], 203 | v0 = v[0], v1 = v[1]; 204 | out[0] = a0 * v0; 205 | out[1] = a1 * v0; 206 | out[2] = a2 * v1; 207 | out[3] = a3 * v1; 208 | out[4] = a4; 209 | out[5] = a5; 210 | return out; 211 | }; 212 | 213 | /** 214 | * Translates the mat2d by the dimensions in the given vec2 215 | * 216 | * @param {mat2d} out the receiving matrix 217 | * @param {mat2d} a the matrix to translate 218 | * @param {vec2} v the vec2 to translate the matrix by 219 | * @returns {mat2d} out 220 | **/ 221 | mat2d.translate = function(out, a, v) { 222 | var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5], 223 | v0 = v[0], v1 = v[1]; 224 | out[0] = a0; 225 | out[1] = a1; 226 | out[2] = a2; 227 | out[3] = a3; 228 | out[4] = a0 * v0 + a2 * v1 + a4; 229 | out[5] = a1 * v0 + a3 * v1 + a5; 230 | return out; 231 | }; 232 | 233 | /** 234 | * Returns a string representation of a mat2d 235 | * 236 | * @param {mat2d} a matrix to represent as a string 237 | * @returns {String} string representation of the matrix 238 | */ 239 | mat2d.str = function (a) { 240 | return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + 241 | a[3] + ', ' + a[4] + ', ' + a[5] + ')'; 242 | }; 243 | 244 | /** 245 | * Returns Frobenius norm of a mat2d 246 | * 247 | * @param {mat2d} a the matrix to calculate Frobenius norm of 248 | * @returns {Number} Frobenius norm 249 | */ 250 | mat2d.frob = function (a) { 251 | 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)) 252 | }; 253 | 254 | if(typeof(exports) !== 'undefined') { 255 | exports.mat2d = mat2d; 256 | } 257 | -------------------------------------------------------------------------------- /gl-matrix/src/gl-matrix/mat3.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | /** 24 | * @class 3x3 Matrix 25 | * @name mat3 26 | */ 27 | var mat3 = {}; 28 | 29 | /** 30 | * Creates a new identity mat3 31 | * 32 | * @returns {mat3} a new 3x3 matrix 33 | */ 34 | mat3.create = function() { 35 | var out = new GLMAT_ARRAY_TYPE(9); 36 | out[0] = 1; 37 | out[1] = 0; 38 | out[2] = 0; 39 | out[3] = 0; 40 | out[4] = 1; 41 | out[5] = 0; 42 | out[6] = 0; 43 | out[7] = 0; 44 | out[8] = 1; 45 | return out; 46 | }; 47 | 48 | /** 49 | * Copies the upper-left 3x3 values into the given mat3. 50 | * 51 | * @param {mat3} out the receiving 3x3 matrix 52 | * @param {mat4} a the source 4x4 matrix 53 | * @returns {mat3} out 54 | */ 55 | mat3.fromMat4 = function(out, a) { 56 | out[0] = a[0]; 57 | out[1] = a[1]; 58 | out[2] = a[2]; 59 | out[3] = a[4]; 60 | out[4] = a[5]; 61 | out[5] = a[6]; 62 | out[6] = a[8]; 63 | out[7] = a[9]; 64 | out[8] = a[10]; 65 | return out; 66 | }; 67 | 68 | /** 69 | * Creates a new mat3 initialized with values from an existing matrix 70 | * 71 | * @param {mat3} a matrix to clone 72 | * @returns {mat3} a new 3x3 matrix 73 | */ 74 | mat3.clone = function(a) { 75 | var out = new GLMAT_ARRAY_TYPE(9); 76 | out[0] = a[0]; 77 | out[1] = a[1]; 78 | out[2] = a[2]; 79 | out[3] = a[3]; 80 | out[4] = a[4]; 81 | out[5] = a[5]; 82 | out[6] = a[6]; 83 | out[7] = a[7]; 84 | out[8] = a[8]; 85 | return out; 86 | }; 87 | 88 | /** 89 | * Copy the values from one mat3 to another 90 | * 91 | * @param {mat3} out the receiving matrix 92 | * @param {mat3} a the source matrix 93 | * @returns {mat3} out 94 | */ 95 | mat3.copy = function(out, a) { 96 | out[0] = a[0]; 97 | out[1] = a[1]; 98 | out[2] = a[2]; 99 | out[3] = a[3]; 100 | out[4] = a[4]; 101 | out[5] = a[5]; 102 | out[6] = a[6]; 103 | out[7] = a[7]; 104 | out[8] = a[8]; 105 | return out; 106 | }; 107 | 108 | /** 109 | * Set a mat3 to the identity matrix 110 | * 111 | * @param {mat3} out the receiving matrix 112 | * @returns {mat3} out 113 | */ 114 | mat3.identity = function(out) { 115 | out[0] = 1; 116 | out[1] = 0; 117 | out[2] = 0; 118 | out[3] = 0; 119 | out[4] = 1; 120 | out[5] = 0; 121 | out[6] = 0; 122 | out[7] = 0; 123 | out[8] = 1; 124 | return out; 125 | }; 126 | 127 | /** 128 | * Transpose the values of a mat3 129 | * 130 | * @param {mat3} out the receiving matrix 131 | * @param {mat3} a the source matrix 132 | * @returns {mat3} out 133 | */ 134 | mat3.transpose = function(out, a) { 135 | // If we are transposing ourselves we can skip a few steps but have to cache some values 136 | if (out === a) { 137 | var a01 = a[1], a02 = a[2], a12 = a[5]; 138 | out[1] = a[3]; 139 | out[2] = a[6]; 140 | out[3] = a01; 141 | out[5] = a[7]; 142 | out[6] = a02; 143 | out[7] = a12; 144 | } else { 145 | out[0] = a[0]; 146 | out[1] = a[3]; 147 | out[2] = a[6]; 148 | out[3] = a[1]; 149 | out[4] = a[4]; 150 | out[5] = a[7]; 151 | out[6] = a[2]; 152 | out[7] = a[5]; 153 | out[8] = a[8]; 154 | } 155 | 156 | return out; 157 | }; 158 | 159 | /** 160 | * Inverts a mat3 161 | * 162 | * @param {mat3} out the receiving matrix 163 | * @param {mat3} a the source matrix 164 | * @returns {mat3} out 165 | */ 166 | mat3.invert = function(out, a) { 167 | var a00 = a[0], a01 = a[1], a02 = a[2], 168 | a10 = a[3], a11 = a[4], a12 = a[5], 169 | a20 = a[6], a21 = a[7], a22 = a[8], 170 | 171 | b01 = a22 * a11 - a12 * a21, 172 | b11 = -a22 * a10 + a12 * a20, 173 | b21 = a21 * a10 - a11 * a20, 174 | 175 | // Calculate the determinant 176 | det = a00 * b01 + a01 * b11 + a02 * b21; 177 | 178 | if (!det) { 179 | return null; 180 | } 181 | det = 1.0 / det; 182 | 183 | out[0] = b01 * det; 184 | out[1] = (-a22 * a01 + a02 * a21) * det; 185 | out[2] = (a12 * a01 - a02 * a11) * det; 186 | out[3] = b11 * det; 187 | out[4] = (a22 * a00 - a02 * a20) * det; 188 | out[5] = (-a12 * a00 + a02 * a10) * det; 189 | out[6] = b21 * det; 190 | out[7] = (-a21 * a00 + a01 * a20) * det; 191 | out[8] = (a11 * a00 - a01 * a10) * det; 192 | return out; 193 | }; 194 | 195 | /** 196 | * Calculates the adjugate of a mat3 197 | * 198 | * @param {mat3} out the receiving matrix 199 | * @param {mat3} a the source matrix 200 | * @returns {mat3} out 201 | */ 202 | mat3.adjoint = function(out, a) { 203 | var a00 = a[0], a01 = a[1], a02 = a[2], 204 | a10 = a[3], a11 = a[4], a12 = a[5], 205 | a20 = a[6], a21 = a[7], a22 = a[8]; 206 | 207 | out[0] = (a11 * a22 - a12 * a21); 208 | out[1] = (a02 * a21 - a01 * a22); 209 | out[2] = (a01 * a12 - a02 * a11); 210 | out[3] = (a12 * a20 - a10 * a22); 211 | out[4] = (a00 * a22 - a02 * a20); 212 | out[5] = (a02 * a10 - a00 * a12); 213 | out[6] = (a10 * a21 - a11 * a20); 214 | out[7] = (a01 * a20 - a00 * a21); 215 | out[8] = (a00 * a11 - a01 * a10); 216 | return out; 217 | }; 218 | 219 | /** 220 | * Calculates the determinant of a mat3 221 | * 222 | * @param {mat3} a the source matrix 223 | * @returns {Number} determinant of a 224 | */ 225 | mat3.determinant = function (a) { 226 | var a00 = a[0], a01 = a[1], a02 = a[2], 227 | a10 = a[3], a11 = a[4], a12 = a[5], 228 | a20 = a[6], a21 = a[7], a22 = a[8]; 229 | 230 | return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); 231 | }; 232 | 233 | /** 234 | * Multiplies two mat3's 235 | * 236 | * @param {mat3} out the receiving matrix 237 | * @param {mat3} a the first operand 238 | * @param {mat3} b the second operand 239 | * @returns {mat3} out 240 | */ 241 | mat3.multiply = function (out, a, b) { 242 | var a00 = a[0], a01 = a[1], a02 = a[2], 243 | a10 = a[3], a11 = a[4], a12 = a[5], 244 | a20 = a[6], a21 = a[7], a22 = a[8], 245 | 246 | b00 = b[0], b01 = b[1], b02 = b[2], 247 | b10 = b[3], b11 = b[4], b12 = b[5], 248 | b20 = b[6], b21 = b[7], b22 = b[8]; 249 | 250 | out[0] = b00 * a00 + b01 * a10 + b02 * a20; 251 | out[1] = b00 * a01 + b01 * a11 + b02 * a21; 252 | out[2] = b00 * a02 + b01 * a12 + b02 * a22; 253 | 254 | out[3] = b10 * a00 + b11 * a10 + b12 * a20; 255 | out[4] = b10 * a01 + b11 * a11 + b12 * a21; 256 | out[5] = b10 * a02 + b11 * a12 + b12 * a22; 257 | 258 | out[6] = b20 * a00 + b21 * a10 + b22 * a20; 259 | out[7] = b20 * a01 + b21 * a11 + b22 * a21; 260 | out[8] = b20 * a02 + b21 * a12 + b22 * a22; 261 | return out; 262 | }; 263 | 264 | /** 265 | * Alias for {@link mat3.multiply} 266 | * @function 267 | */ 268 | mat3.mul = mat3.multiply; 269 | 270 | /** 271 | * Translate a mat3 by the given vector 272 | * 273 | * @param {mat3} out the receiving matrix 274 | * @param {mat3} a the matrix to translate 275 | * @param {vec2} v vector to translate by 276 | * @returns {mat3} out 277 | */ 278 | mat3.translate = function(out, a, v) { 279 | var a00 = a[0], a01 = a[1], a02 = a[2], 280 | a10 = a[3], a11 = a[4], a12 = a[5], 281 | a20 = a[6], a21 = a[7], a22 = a[8], 282 | x = v[0], y = v[1]; 283 | 284 | out[0] = a00; 285 | out[1] = a01; 286 | out[2] = a02; 287 | 288 | out[3] = a10; 289 | out[4] = a11; 290 | out[5] = a12; 291 | 292 | out[6] = x * a00 + y * a10 + a20; 293 | out[7] = x * a01 + y * a11 + a21; 294 | out[8] = x * a02 + y * a12 + a22; 295 | return out; 296 | }; 297 | 298 | /** 299 | * Rotates a mat3 by the given angle 300 | * 301 | * @param {mat3} out the receiving matrix 302 | * @param {mat3} a the matrix to rotate 303 | * @param {Number} rad the angle to rotate the matrix by 304 | * @returns {mat3} out 305 | */ 306 | mat3.rotate = function (out, a, rad) { 307 | var a00 = a[0], a01 = a[1], a02 = a[2], 308 | a10 = a[3], a11 = a[4], a12 = a[5], 309 | a20 = a[6], a21 = a[7], a22 = a[8], 310 | 311 | s = Math.sin(rad), 312 | c = Math.cos(rad); 313 | 314 | out[0] = c * a00 + s * a10; 315 | out[1] = c * a01 + s * a11; 316 | out[2] = c * a02 + s * a12; 317 | 318 | out[3] = c * a10 - s * a00; 319 | out[4] = c * a11 - s * a01; 320 | out[5] = c * a12 - s * a02; 321 | 322 | out[6] = a20; 323 | out[7] = a21; 324 | out[8] = a22; 325 | return out; 326 | }; 327 | 328 | /** 329 | * Scales the mat3 by the dimensions in the given vec2 330 | * 331 | * @param {mat3} out the receiving matrix 332 | * @param {mat3} a the matrix to rotate 333 | * @param {vec2} v the vec2 to scale the matrix by 334 | * @returns {mat3} out 335 | **/ 336 | mat3.scale = function(out, a, v) { 337 | var x = v[0], y = v[1]; 338 | 339 | out[0] = x * a[0]; 340 | out[1] = x * a[1]; 341 | out[2] = x * a[2]; 342 | 343 | out[3] = y * a[3]; 344 | out[4] = y * a[4]; 345 | out[5] = y * a[5]; 346 | 347 | out[6] = a[6]; 348 | out[7] = a[7]; 349 | out[8] = a[8]; 350 | return out; 351 | }; 352 | 353 | /** 354 | * Copies the values from a mat2d into a mat3 355 | * 356 | * @param {mat3} out the receiving matrix 357 | * @param {mat2d} a the matrix to copy 358 | * @returns {mat3} out 359 | **/ 360 | mat3.fromMat2d = function(out, a) { 361 | out[0] = a[0]; 362 | out[1] = a[1]; 363 | out[2] = 0; 364 | 365 | out[3] = a[2]; 366 | out[4] = a[3]; 367 | out[5] = 0; 368 | 369 | out[6] = a[4]; 370 | out[7] = a[5]; 371 | out[8] = 1; 372 | return out; 373 | }; 374 | 375 | /** 376 | * Calculates a 3x3 matrix from the given quaternion 377 | * 378 | * @param {mat3} out mat3 receiving operation result 379 | * @param {quat} q Quaternion to create matrix from 380 | * 381 | * @returns {mat3} out 382 | */ 383 | mat3.fromQuat = function (out, q) { 384 | var x = q[0], y = q[1], z = q[2], w = q[3], 385 | x2 = x + x, 386 | y2 = y + y, 387 | z2 = z + z, 388 | 389 | xx = x * x2, 390 | yx = y * x2, 391 | yy = y * y2, 392 | zx = z * x2, 393 | zy = z * y2, 394 | zz = z * z2, 395 | wx = w * x2, 396 | wy = w * y2, 397 | wz = w * z2; 398 | 399 | out[0] = 1 - yy - zz; 400 | out[3] = yx - wz; 401 | out[6] = zx + wy; 402 | 403 | out[1] = yx + wz; 404 | out[4] = 1 - xx - zz; 405 | out[7] = zy - wx; 406 | 407 | out[2] = zx - wy; 408 | out[5] = zy + wx; 409 | out[8] = 1 - xx - yy; 410 | 411 | return out; 412 | }; 413 | 414 | /** 415 | * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix 416 | * 417 | * @param {mat3} out mat3 receiving operation result 418 | * @param {mat4} a Mat4 to derive the normal matrix from 419 | * 420 | * @returns {mat3} out 421 | */ 422 | mat3.normalFromMat4 = function (out, a) { 423 | var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], 424 | a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], 425 | a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], 426 | a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], 427 | 428 | b00 = a00 * a11 - a01 * a10, 429 | b01 = a00 * a12 - a02 * a10, 430 | b02 = a00 * a13 - a03 * a10, 431 | b03 = a01 * a12 - a02 * a11, 432 | b04 = a01 * a13 - a03 * a11, 433 | b05 = a02 * a13 - a03 * a12, 434 | b06 = a20 * a31 - a21 * a30, 435 | b07 = a20 * a32 - a22 * a30, 436 | b08 = a20 * a33 - a23 * a30, 437 | b09 = a21 * a32 - a22 * a31, 438 | b10 = a21 * a33 - a23 * a31, 439 | b11 = a22 * a33 - a23 * a32, 440 | 441 | // Calculate the determinant 442 | det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; 443 | 444 | if (!det) { 445 | return null; 446 | } 447 | det = 1.0 / det; 448 | 449 | out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; 450 | out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; 451 | out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; 452 | 453 | out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; 454 | out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; 455 | out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; 456 | 457 | out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; 458 | out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; 459 | out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; 460 | 461 | return out; 462 | }; 463 | 464 | /** 465 | * Returns a string representation of a mat3 466 | * 467 | * @param {mat3} mat matrix to represent as a string 468 | * @returns {String} string representation of the matrix 469 | */ 470 | mat3.str = function (a) { 471 | return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + 472 | a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + 473 | a[6] + ', ' + a[7] + ', ' + a[8] + ')'; 474 | }; 475 | 476 | /** 477 | * Returns Frobenius norm of a mat3 478 | * 479 | * @param {mat3} a the matrix to calculate Frobenius norm of 480 | * @returns {Number} Frobenius norm 481 | */ 482 | mat3.frob = function (a) { 483 | 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) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2))) 484 | }; 485 | 486 | 487 | if(typeof(exports) !== 'undefined') { 488 | exports.mat3 = mat3; 489 | } 490 | -------------------------------------------------------------------------------- /gl-matrix/src/gl-matrix/quat.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | /** 24 | * @class Quaternion 25 | * @name quat 26 | */ 27 | var quat = {}; 28 | 29 | /** 30 | * Creates a new identity quat 31 | * 32 | * @returns {quat} a new quaternion 33 | */ 34 | quat.create = function() { 35 | var out = new GLMAT_ARRAY_TYPE(4); 36 | out[0] = 0; 37 | out[1] = 0; 38 | out[2] = 0; 39 | out[3] = 1; 40 | return out; 41 | }; 42 | 43 | /** 44 | * Sets a quaternion to represent the shortest rotation from one 45 | * vector to another. 46 | * 47 | * Both vectors are assumed to be unit length. 48 | * 49 | * @param {quat} out the receiving quaternion. 50 | * @param {vec3} a the initial vector 51 | * @param {vec3} b the destination vector 52 | * @returns {quat} out 53 | */ 54 | quat.rotationTo = (function() { 55 | var tmpvec3 = vec3.create(); 56 | var xUnitVec3 = vec3.fromValues(1,0,0); 57 | var yUnitVec3 = vec3.fromValues(0,1,0); 58 | 59 | return function(out, a, b) { 60 | var dot = vec3.dot(a, b); 61 | if (dot < -0.999999) { 62 | vec3.cross(tmpvec3, xUnitVec3, a); 63 | if (vec3.length(tmpvec3) < 0.000001) 64 | vec3.cross(tmpvec3, yUnitVec3, a); 65 | vec3.normalize(tmpvec3, tmpvec3); 66 | quat.setAxisAngle(out, tmpvec3, Math.PI); 67 | return out; 68 | } else if (dot > 0.999999) { 69 | out[0] = 0; 70 | out[1] = 0; 71 | out[2] = 0; 72 | out[3] = 1; 73 | return out; 74 | } else { 75 | vec3.cross(tmpvec3, a, b); 76 | out[0] = tmpvec3[0]; 77 | out[1] = tmpvec3[1]; 78 | out[2] = tmpvec3[2]; 79 | out[3] = 1 + dot; 80 | return quat.normalize(out, out); 81 | } 82 | }; 83 | })(); 84 | 85 | /** 86 | * Sets the specified quaternion with values corresponding to the given 87 | * axes. Each axis is a vec3 and is expected to be unit length and 88 | * perpendicular to all other specified axes. 89 | * 90 | * @param {vec3} view the vector representing the viewing direction 91 | * @param {vec3} right the vector representing the local "right" direction 92 | * @param {vec3} up the vector representing the local "up" direction 93 | * @returns {quat} out 94 | */ 95 | quat.setAxes = (function() { 96 | var matr = mat3.create(); 97 | 98 | return function(out, view, right, up) { 99 | matr[0] = right[0]; 100 | matr[3] = right[1]; 101 | matr[6] = right[2]; 102 | 103 | matr[1] = up[0]; 104 | matr[4] = up[1]; 105 | matr[7] = up[2]; 106 | 107 | matr[2] = -view[0]; 108 | matr[5] = -view[1]; 109 | matr[8] = -view[2]; 110 | 111 | return quat.normalize(out, quat.fromMat3(out, matr)); 112 | }; 113 | })(); 114 | 115 | /** 116 | * Creates a new quat initialized with values from an existing quaternion 117 | * 118 | * @param {quat} a quaternion to clone 119 | * @returns {quat} a new quaternion 120 | * @function 121 | */ 122 | quat.clone = vec4.clone; 123 | 124 | /** 125 | * Creates a new quat initialized with the given values 126 | * 127 | * @param {Number} x X component 128 | * @param {Number} y Y component 129 | * @param {Number} z Z component 130 | * @param {Number} w W component 131 | * @returns {quat} a new quaternion 132 | * @function 133 | */ 134 | quat.fromValues = vec4.fromValues; 135 | 136 | /** 137 | * Copy the values from one quat to another 138 | * 139 | * @param {quat} out the receiving quaternion 140 | * @param {quat} a the source quaternion 141 | * @returns {quat} out 142 | * @function 143 | */ 144 | quat.copy = vec4.copy; 145 | 146 | /** 147 | * Set the components of a quat to the given values 148 | * 149 | * @param {quat} out the receiving quaternion 150 | * @param {Number} x X component 151 | * @param {Number} y Y component 152 | * @param {Number} z Z component 153 | * @param {Number} w W component 154 | * @returns {quat} out 155 | * @function 156 | */ 157 | quat.set = vec4.set; 158 | 159 | /** 160 | * Set a quat to the identity quaternion 161 | * 162 | * @param {quat} out the receiving quaternion 163 | * @returns {quat} out 164 | */ 165 | quat.identity = function(out) { 166 | out[0] = 0; 167 | out[1] = 0; 168 | out[2] = 0; 169 | out[3] = 1; 170 | return out; 171 | }; 172 | 173 | /** 174 | * Sets a quat from the given angle and rotation axis, 175 | * then returns it. 176 | * 177 | * @param {quat} out the receiving quaternion 178 | * @param {vec3} axis the axis around which to rotate 179 | * @param {Number} rad the angle in radians 180 | * @returns {quat} out 181 | **/ 182 | quat.setAxisAngle = function(out, axis, rad) { 183 | rad = rad * 0.5; 184 | var s = Math.sin(rad); 185 | out[0] = s * axis[0]; 186 | out[1] = s * axis[1]; 187 | out[2] = s * axis[2]; 188 | out[3] = Math.cos(rad); 189 | return out; 190 | }; 191 | 192 | /** 193 | * Adds two quat's 194 | * 195 | * @param {quat} out the receiving quaternion 196 | * @param {quat} a the first operand 197 | * @param {quat} b the second operand 198 | * @returns {quat} out 199 | * @function 200 | */ 201 | quat.add = vec4.add; 202 | 203 | /** 204 | * Multiplies two quat's 205 | * 206 | * @param {quat} out the receiving quaternion 207 | * @param {quat} a the first operand 208 | * @param {quat} b the second operand 209 | * @returns {quat} out 210 | */ 211 | quat.multiply = function(out, a, b) { 212 | var ax = a[0], ay = a[1], az = a[2], aw = a[3], 213 | bx = b[0], by = b[1], bz = b[2], bw = b[3]; 214 | 215 | out[0] = ax * bw + aw * bx + ay * bz - az * by; 216 | out[1] = ay * bw + aw * by + az * bx - ax * bz; 217 | out[2] = az * bw + aw * bz + ax * by - ay * bx; 218 | out[3] = aw * bw - ax * bx - ay * by - az * bz; 219 | return out; 220 | }; 221 | 222 | /** 223 | * Alias for {@link quat.multiply} 224 | * @function 225 | */ 226 | quat.mul = quat.multiply; 227 | 228 | /** 229 | * Scales a quat by a scalar number 230 | * 231 | * @param {quat} out the receiving vector 232 | * @param {quat} a the vector to scale 233 | * @param {Number} b amount to scale the vector by 234 | * @returns {quat} out 235 | * @function 236 | */ 237 | quat.scale = vec4.scale; 238 | 239 | /** 240 | * Rotates a quaternion by the given angle about the X axis 241 | * 242 | * @param {quat} out quat receiving operation result 243 | * @param {quat} a quat to rotate 244 | * @param {number} rad angle (in radians) to rotate 245 | * @returns {quat} out 246 | */ 247 | quat.rotateX = function (out, a, rad) { 248 | rad *= 0.5; 249 | 250 | var ax = a[0], ay = a[1], az = a[2], aw = a[3], 251 | bx = Math.sin(rad), bw = Math.cos(rad); 252 | 253 | out[0] = ax * bw + aw * bx; 254 | out[1] = ay * bw + az * bx; 255 | out[2] = az * bw - ay * bx; 256 | out[3] = aw * bw - ax * bx; 257 | return out; 258 | }; 259 | 260 | /** 261 | * Rotates a quaternion by the given angle about the Y axis 262 | * 263 | * @param {quat} out quat receiving operation result 264 | * @param {quat} a quat to rotate 265 | * @param {number} rad angle (in radians) to rotate 266 | * @returns {quat} out 267 | */ 268 | quat.rotateY = function (out, a, rad) { 269 | rad *= 0.5; 270 | 271 | var ax = a[0], ay = a[1], az = a[2], aw = a[3], 272 | by = Math.sin(rad), bw = Math.cos(rad); 273 | 274 | out[0] = ax * bw - az * by; 275 | out[1] = ay * bw + aw * by; 276 | out[2] = az * bw + ax * by; 277 | out[3] = aw * bw - ay * by; 278 | return out; 279 | }; 280 | 281 | /** 282 | * Rotates a quaternion by the given angle about the Z axis 283 | * 284 | * @param {quat} out quat receiving operation result 285 | * @param {quat} a quat to rotate 286 | * @param {number} rad angle (in radians) to rotate 287 | * @returns {quat} out 288 | */ 289 | quat.rotateZ = function (out, a, rad) { 290 | rad *= 0.5; 291 | 292 | var ax = a[0], ay = a[1], az = a[2], aw = a[3], 293 | bz = Math.sin(rad), bw = Math.cos(rad); 294 | 295 | out[0] = ax * bw + ay * bz; 296 | out[1] = ay * bw - ax * bz; 297 | out[2] = az * bw + aw * bz; 298 | out[3] = aw * bw - az * bz; 299 | return out; 300 | }; 301 | 302 | /** 303 | * Calculates the W component of a quat from the X, Y, and Z components. 304 | * Assumes that quaternion is 1 unit in length. 305 | * Any existing W component will be ignored. 306 | * 307 | * @param {quat} out the receiving quaternion 308 | * @param {quat} a quat to calculate W component of 309 | * @returns {quat} out 310 | */ 311 | quat.calculateW = function (out, a) { 312 | var x = a[0], y = a[1], z = a[2]; 313 | 314 | out[0] = x; 315 | out[1] = y; 316 | out[2] = z; 317 | out[3] = -Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z)); 318 | return out; 319 | }; 320 | 321 | /** 322 | * Calculates the dot product of two quat's 323 | * 324 | * @param {quat} a the first operand 325 | * @param {quat} b the second operand 326 | * @returns {Number} dot product of a and b 327 | * @function 328 | */ 329 | quat.dot = vec4.dot; 330 | 331 | /** 332 | * Performs a linear interpolation between two quat's 333 | * 334 | * @param {quat} out the receiving quaternion 335 | * @param {quat} a the first operand 336 | * @param {quat} b the second operand 337 | * @param {Number} t interpolation amount between the two inputs 338 | * @returns {quat} out 339 | * @function 340 | */ 341 | quat.lerp = vec4.lerp; 342 | 343 | /** 344 | * Performs a spherical linear interpolation between two quat 345 | * 346 | * @param {quat} out the receiving quaternion 347 | * @param {quat} a the first operand 348 | * @param {quat} b the second operand 349 | * @param {Number} t interpolation amount between the two inputs 350 | * @returns {quat} out 351 | */ 352 | quat.slerp = function (out, a, b, t) { 353 | // benchmarks: 354 | // http://jsperf.com/quaternion-slerp-implementations 355 | 356 | var ax = a[0], ay = a[1], az = a[2], aw = a[3], 357 | bx = b[0], by = b[1], bz = b[2], bw = b[3]; 358 | 359 | var omega, cosom, sinom, scale0, scale1; 360 | 361 | // calc cosine 362 | cosom = ax * bx + ay * by + az * bz + aw * bw; 363 | // adjust signs (if necessary) 364 | if ( cosom < 0.0 ) { 365 | cosom = -cosom; 366 | bx = - bx; 367 | by = - by; 368 | bz = - bz; 369 | bw = - bw; 370 | } 371 | // calculate coefficients 372 | if ( (1.0 - cosom) > 0.000001 ) { 373 | // standard case (slerp) 374 | omega = Math.acos(cosom); 375 | sinom = Math.sin(omega); 376 | scale0 = Math.sin((1.0 - t) * omega) / sinom; 377 | scale1 = Math.sin(t * omega) / sinom; 378 | } else { 379 | // "from" and "to" quaternions are very close 380 | // ... so we can do a linear interpolation 381 | scale0 = 1.0 - t; 382 | scale1 = t; 383 | } 384 | // calculate final values 385 | out[0] = scale0 * ax + scale1 * bx; 386 | out[1] = scale0 * ay + scale1 * by; 387 | out[2] = scale0 * az + scale1 * bz; 388 | out[3] = scale0 * aw + scale1 * bw; 389 | 390 | return out; 391 | }; 392 | 393 | /** 394 | * Calculates the inverse of a quat 395 | * 396 | * @param {quat} out the receiving quaternion 397 | * @param {quat} a quat to calculate inverse of 398 | * @returns {quat} out 399 | */ 400 | quat.invert = function(out, a) { 401 | var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], 402 | dot = a0*a0 + a1*a1 + a2*a2 + a3*a3, 403 | invDot = dot ? 1.0/dot : 0; 404 | 405 | // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 406 | 407 | out[0] = -a0*invDot; 408 | out[1] = -a1*invDot; 409 | out[2] = -a2*invDot; 410 | out[3] = a3*invDot; 411 | return out; 412 | }; 413 | 414 | /** 415 | * Calculates the conjugate of a quat 416 | * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. 417 | * 418 | * @param {quat} out the receiving quaternion 419 | * @param {quat} a quat to calculate conjugate of 420 | * @returns {quat} out 421 | */ 422 | quat.conjugate = function (out, a) { 423 | out[0] = -a[0]; 424 | out[1] = -a[1]; 425 | out[2] = -a[2]; 426 | out[3] = a[3]; 427 | return out; 428 | }; 429 | 430 | /** 431 | * Calculates the length of a quat 432 | * 433 | * @param {quat} a vector to calculate length of 434 | * @returns {Number} length of a 435 | * @function 436 | */ 437 | quat.length = vec4.length; 438 | 439 | /** 440 | * Alias for {@link quat.length} 441 | * @function 442 | */ 443 | quat.len = quat.length; 444 | 445 | /** 446 | * Calculates the squared length of a quat 447 | * 448 | * @param {quat} a vector to calculate squared length of 449 | * @returns {Number} squared length of a 450 | * @function 451 | */ 452 | quat.squaredLength = vec4.squaredLength; 453 | 454 | /** 455 | * Alias for {@link quat.squaredLength} 456 | * @function 457 | */ 458 | quat.sqrLen = quat.squaredLength; 459 | 460 | /** 461 | * Normalize a quat 462 | * 463 | * @param {quat} out the receiving quaternion 464 | * @param {quat} a quaternion to normalize 465 | * @returns {quat} out 466 | * @function 467 | */ 468 | quat.normalize = vec4.normalize; 469 | 470 | /** 471 | * Creates a quaternion from the given 3x3 rotation matrix. 472 | * 473 | * NOTE: The resultant quaternion is not normalized, so you should be sure 474 | * to renormalize the quaternion yourself where necessary. 475 | * 476 | * @param {quat} out the receiving quaternion 477 | * @param {mat3} m rotation matrix 478 | * @returns {quat} out 479 | * @function 480 | */ 481 | quat.fromMat3 = function(out, m) { 482 | // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes 483 | // article "Quaternion Calculus and Fast Animation". 484 | var fTrace = m[0] + m[4] + m[8]; 485 | var fRoot; 486 | 487 | if ( fTrace > 0.0 ) { 488 | // |w| > 1/2, may as well choose w > 1/2 489 | fRoot = Math.sqrt(fTrace + 1.0); // 2w 490 | out[3] = 0.5 * fRoot; 491 | fRoot = 0.5/fRoot; // 1/(4w) 492 | out[0] = (m[5]-m[7])*fRoot; 493 | out[1] = (m[6]-m[2])*fRoot; 494 | out[2] = (m[1]-m[3])*fRoot; 495 | } else { 496 | // |w| <= 1/2 497 | var i = 0; 498 | if ( m[4] > m[0] ) 499 | i = 1; 500 | if ( m[8] > m[i*3+i] ) 501 | i = 2; 502 | var j = (i+1)%3; 503 | var k = (i+2)%3; 504 | 505 | fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0); 506 | out[i] = 0.5 * fRoot; 507 | fRoot = 0.5 / fRoot; 508 | out[3] = (m[j*3+k] - m[k*3+j]) * fRoot; 509 | out[j] = (m[j*3+i] + m[i*3+j]) * fRoot; 510 | out[k] = (m[k*3+i] + m[i*3+k]) * fRoot; 511 | } 512 | 513 | return out; 514 | }; 515 | 516 | /** 517 | * Returns a string representation of a quatenion 518 | * 519 | * @param {quat} vec vector to represent as a string 520 | * @returns {String} string representation of the vector 521 | */ 522 | quat.str = function (a) { 523 | return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; 524 | }; 525 | 526 | if(typeof(exports) !== 'undefined') { 527 | exports.quat = quat; 528 | } 529 | -------------------------------------------------------------------------------- /gl-matrix/src/gl-matrix/vec2.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | /** 24 | * @class 2 Dimensional Vector 25 | * @name vec2 26 | */ 27 | var vec2 = {}; 28 | 29 | /** 30 | * Creates a new, empty vec2 31 | * 32 | * @returns {vec2} a new 2D vector 33 | */ 34 | vec2.create = function() { 35 | var out = new GLMAT_ARRAY_TYPE(2); 36 | out[0] = 0; 37 | out[1] = 0; 38 | return out; 39 | }; 40 | 41 | /** 42 | * Creates a new vec2 initialized with values from an existing vector 43 | * 44 | * @param {vec2} a vector to clone 45 | * @returns {vec2} a new 2D vector 46 | */ 47 | vec2.clone = function(a) { 48 | var out = new GLMAT_ARRAY_TYPE(2); 49 | out[0] = a[0]; 50 | out[1] = a[1]; 51 | return out; 52 | }; 53 | 54 | /** 55 | * Creates a new vec2 initialized with the given values 56 | * 57 | * @param {Number} x X component 58 | * @param {Number} y Y component 59 | * @returns {vec2} a new 2D vector 60 | */ 61 | vec2.fromValues = function(x, y) { 62 | var out = new GLMAT_ARRAY_TYPE(2); 63 | out[0] = x; 64 | out[1] = y; 65 | return out; 66 | }; 67 | 68 | /** 69 | * Copy the values from one vec2 to another 70 | * 71 | * @param {vec2} out the receiving vector 72 | * @param {vec2} a the source vector 73 | * @returns {vec2} out 74 | */ 75 | vec2.copy = function(out, a) { 76 | out[0] = a[0]; 77 | out[1] = a[1]; 78 | return out; 79 | }; 80 | 81 | /** 82 | * Set the components of a vec2 to the given values 83 | * 84 | * @param {vec2} out the receiving vector 85 | * @param {Number} x X component 86 | * @param {Number} y Y component 87 | * @returns {vec2} out 88 | */ 89 | vec2.set = function(out, x, y) { 90 | out[0] = x; 91 | out[1] = y; 92 | return out; 93 | }; 94 | 95 | /** 96 | * Adds two vec2's 97 | * 98 | * @param {vec2} out the receiving vector 99 | * @param {vec2} a the first operand 100 | * @param {vec2} b the second operand 101 | * @returns {vec2} out 102 | */ 103 | vec2.add = function(out, a, b) { 104 | out[0] = a[0] + b[0]; 105 | out[1] = a[1] + b[1]; 106 | return out; 107 | }; 108 | 109 | /** 110 | * Subtracts vector b from vector a 111 | * 112 | * @param {vec2} out the receiving vector 113 | * @param {vec2} a the first operand 114 | * @param {vec2} b the second operand 115 | * @returns {vec2} out 116 | */ 117 | vec2.subtract = function(out, a, b) { 118 | out[0] = a[0] - b[0]; 119 | out[1] = a[1] - b[1]; 120 | return out; 121 | }; 122 | 123 | /** 124 | * Alias for {@link vec2.subtract} 125 | * @function 126 | */ 127 | vec2.sub = vec2.subtract; 128 | 129 | /** 130 | * Multiplies two vec2's 131 | * 132 | * @param {vec2} out the receiving vector 133 | * @param {vec2} a the first operand 134 | * @param {vec2} b the second operand 135 | * @returns {vec2} out 136 | */ 137 | vec2.multiply = function(out, a, b) { 138 | out[0] = a[0] * b[0]; 139 | out[1] = a[1] * b[1]; 140 | return out; 141 | }; 142 | 143 | /** 144 | * Alias for {@link vec2.multiply} 145 | * @function 146 | */ 147 | vec2.mul = vec2.multiply; 148 | 149 | /** 150 | * Divides two vec2's 151 | * 152 | * @param {vec2} out the receiving vector 153 | * @param {vec2} a the first operand 154 | * @param {vec2} b the second operand 155 | * @returns {vec2} out 156 | */ 157 | vec2.divide = function(out, a, b) { 158 | out[0] = a[0] / b[0]; 159 | out[1] = a[1] / b[1]; 160 | return out; 161 | }; 162 | 163 | /** 164 | * Alias for {@link vec2.divide} 165 | * @function 166 | */ 167 | vec2.div = vec2.divide; 168 | 169 | /** 170 | * Returns the minimum of two vec2's 171 | * 172 | * @param {vec2} out the receiving vector 173 | * @param {vec2} a the first operand 174 | * @param {vec2} b the second operand 175 | * @returns {vec2} out 176 | */ 177 | vec2.min = function(out, a, b) { 178 | out[0] = Math.min(a[0], b[0]); 179 | out[1] = Math.min(a[1], b[1]); 180 | return out; 181 | }; 182 | 183 | /** 184 | * Returns the maximum of two vec2's 185 | * 186 | * @param {vec2} out the receiving vector 187 | * @param {vec2} a the first operand 188 | * @param {vec2} b the second operand 189 | * @returns {vec2} out 190 | */ 191 | vec2.max = function(out, a, b) { 192 | out[0] = Math.max(a[0], b[0]); 193 | out[1] = Math.max(a[1], b[1]); 194 | return out; 195 | }; 196 | 197 | /** 198 | * Scales a vec2 by a scalar number 199 | * 200 | * @param {vec2} out the receiving vector 201 | * @param {vec2} a the vector to scale 202 | * @param {Number} b amount to scale the vector by 203 | * @returns {vec2} out 204 | */ 205 | vec2.scale = function(out, a, b) { 206 | out[0] = a[0] * b; 207 | out[1] = a[1] * b; 208 | return out; 209 | }; 210 | 211 | /** 212 | * Adds two vec2's after scaling the second operand by a scalar value 213 | * 214 | * @param {vec2} out the receiving vector 215 | * @param {vec2} a the first operand 216 | * @param {vec2} b the second operand 217 | * @param {Number} scale the amount to scale b by before adding 218 | * @returns {vec2} out 219 | */ 220 | vec2.scaleAndAdd = function(out, a, b, scale) { 221 | out[0] = a[0] + (b[0] * scale); 222 | out[1] = a[1] + (b[1] * scale); 223 | return out; 224 | }; 225 | 226 | /** 227 | * Calculates the euclidian distance between two vec2's 228 | * 229 | * @param {vec2} a the first operand 230 | * @param {vec2} b the second operand 231 | * @returns {Number} distance between a and b 232 | */ 233 | vec2.distance = function(a, b) { 234 | var x = b[0] - a[0], 235 | y = b[1] - a[1]; 236 | return Math.sqrt(x*x + y*y); 237 | }; 238 | 239 | /** 240 | * Alias for {@link vec2.distance} 241 | * @function 242 | */ 243 | vec2.dist = vec2.distance; 244 | 245 | /** 246 | * Calculates the squared euclidian distance between two vec2's 247 | * 248 | * @param {vec2} a the first operand 249 | * @param {vec2} b the second operand 250 | * @returns {Number} squared distance between a and b 251 | */ 252 | vec2.squaredDistance = function(a, b) { 253 | var x = b[0] - a[0], 254 | y = b[1] - a[1]; 255 | return x*x + y*y; 256 | }; 257 | 258 | /** 259 | * Alias for {@link vec2.squaredDistance} 260 | * @function 261 | */ 262 | vec2.sqrDist = vec2.squaredDistance; 263 | 264 | /** 265 | * Calculates the length of a vec2 266 | * 267 | * @param {vec2} a vector to calculate length of 268 | * @returns {Number} length of a 269 | */ 270 | vec2.length = function (a) { 271 | var x = a[0], 272 | y = a[1]; 273 | return Math.sqrt(x*x + y*y); 274 | }; 275 | 276 | /** 277 | * Alias for {@link vec2.length} 278 | * @function 279 | */ 280 | vec2.len = vec2.length; 281 | 282 | /** 283 | * Calculates the squared length of a vec2 284 | * 285 | * @param {vec2} a vector to calculate squared length of 286 | * @returns {Number} squared length of a 287 | */ 288 | vec2.squaredLength = function (a) { 289 | var x = a[0], 290 | y = a[1]; 291 | return x*x + y*y; 292 | }; 293 | 294 | /** 295 | * Alias for {@link vec2.squaredLength} 296 | * @function 297 | */ 298 | vec2.sqrLen = vec2.squaredLength; 299 | 300 | /** 301 | * Negates the components of a vec2 302 | * 303 | * @param {vec2} out the receiving vector 304 | * @param {vec2} a vector to negate 305 | * @returns {vec2} out 306 | */ 307 | vec2.negate = function(out, a) { 308 | out[0] = -a[0]; 309 | out[1] = -a[1]; 310 | return out; 311 | }; 312 | 313 | /** 314 | * Returns the inverse of the components of a vec2 315 | * 316 | * @param {vec2} out the receiving vector 317 | * @param {vec2} a vector to invert 318 | * @returns {vec2} out 319 | */ 320 | vec2.inverse = function(out, a) { 321 | out[0] = 1.0 / a[0]; 322 | out[1] = 1.0 / a[1]; 323 | return out; 324 | }; 325 | 326 | /** 327 | * Normalize a vec2 328 | * 329 | * @param {vec2} out the receiving vector 330 | * @param {vec2} a vector to normalize 331 | * @returns {vec2} out 332 | */ 333 | vec2.normalize = function(out, a) { 334 | var x = a[0], 335 | y = a[1]; 336 | var len = x*x + y*y; 337 | if (len > 0) { 338 | //TODO: evaluate use of glm_invsqrt here? 339 | len = 1 / Math.sqrt(len); 340 | out[0] = a[0] * len; 341 | out[1] = a[1] * len; 342 | } 343 | return out; 344 | }; 345 | 346 | /** 347 | * Calculates the dot product of two vec2's 348 | * 349 | * @param {vec2} a the first operand 350 | * @param {vec2} b the second operand 351 | * @returns {Number} dot product of a and b 352 | */ 353 | vec2.dot = function (a, b) { 354 | return a[0] * b[0] + a[1] * b[1]; 355 | }; 356 | 357 | /** 358 | * Computes the cross product of two vec2's 359 | * Note that the cross product must by definition produce a 3D vector 360 | * 361 | * @param {vec3} out the receiving vector 362 | * @param {vec2} a the first operand 363 | * @param {vec2} b the second operand 364 | * @returns {vec3} out 365 | */ 366 | vec2.cross = function(out, a, b) { 367 | var z = a[0] * b[1] - a[1] * b[0]; 368 | out[0] = out[1] = 0; 369 | out[2] = z; 370 | return out; 371 | }; 372 | 373 | /** 374 | * Performs a linear interpolation between two vec2's 375 | * 376 | * @param {vec2} out the receiving vector 377 | * @param {vec2} a the first operand 378 | * @param {vec2} b the second operand 379 | * @param {Number} t interpolation amount between the two inputs 380 | * @returns {vec2} out 381 | */ 382 | vec2.lerp = function (out, a, b, t) { 383 | var ax = a[0], 384 | ay = a[1]; 385 | out[0] = ax + t * (b[0] - ax); 386 | out[1] = ay + t * (b[1] - ay); 387 | return out; 388 | }; 389 | 390 | /** 391 | * Generates a random vector with the given scale 392 | * 393 | * @param {vec2} out the receiving vector 394 | * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned 395 | * @returns {vec2} out 396 | */ 397 | vec2.random = function (out, scale) { 398 | scale = scale || 1.0; 399 | var r = GLMAT_RANDOM() * 2.0 * Math.PI; 400 | out[0] = Math.cos(r) * scale; 401 | out[1] = Math.sin(r) * scale; 402 | return out; 403 | }; 404 | 405 | /** 406 | * Transforms the vec2 with a mat2 407 | * 408 | * @param {vec2} out the receiving vector 409 | * @param {vec2} a the vector to transform 410 | * @param {mat2} m matrix to transform with 411 | * @returns {vec2} out 412 | */ 413 | vec2.transformMat2 = function(out, a, m) { 414 | var x = a[0], 415 | y = a[1]; 416 | out[0] = m[0] * x + m[2] * y; 417 | out[1] = m[1] * x + m[3] * y; 418 | return out; 419 | }; 420 | 421 | /** 422 | * Transforms the vec2 with a mat2d 423 | * 424 | * @param {vec2} out the receiving vector 425 | * @param {vec2} a the vector to transform 426 | * @param {mat2d} m matrix to transform with 427 | * @returns {vec2} out 428 | */ 429 | vec2.transformMat2d = function(out, a, m) { 430 | var x = a[0], 431 | y = a[1]; 432 | out[0] = m[0] * x + m[2] * y + m[4]; 433 | out[1] = m[1] * x + m[3] * y + m[5]; 434 | return out; 435 | }; 436 | 437 | /** 438 | * Transforms the vec2 with a mat3 439 | * 3rd vector component is implicitly '1' 440 | * 441 | * @param {vec2} out the receiving vector 442 | * @param {vec2} a the vector to transform 443 | * @param {mat3} m matrix to transform with 444 | * @returns {vec2} out 445 | */ 446 | vec2.transformMat3 = function(out, a, m) { 447 | var x = a[0], 448 | y = a[1]; 449 | out[0] = m[0] * x + m[3] * y + m[6]; 450 | out[1] = m[1] * x + m[4] * y + m[7]; 451 | return out; 452 | }; 453 | 454 | /** 455 | * Transforms the vec2 with a mat4 456 | * 3rd vector component is implicitly '0' 457 | * 4th vector component is implicitly '1' 458 | * 459 | * @param {vec2} out the receiving vector 460 | * @param {vec2} a the vector to transform 461 | * @param {mat4} m matrix to transform with 462 | * @returns {vec2} out 463 | */ 464 | vec2.transformMat4 = function(out, a, m) { 465 | var x = a[0], 466 | y = a[1]; 467 | out[0] = m[0] * x + m[4] * y + m[12]; 468 | out[1] = m[1] * x + m[5] * y + m[13]; 469 | return out; 470 | }; 471 | 472 | /** 473 | * Perform some operation over an array of vec2s. 474 | * 475 | * @param {Array} a the array of vectors to iterate over 476 | * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed 477 | * @param {Number} offset Number of elements to skip at the beginning of the array 478 | * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array 479 | * @param {Function} fn Function to call for each vector in the array 480 | * @param {Object} [arg] additional argument to pass to fn 481 | * @returns {Array} a 482 | * @function 483 | */ 484 | vec2.forEach = (function() { 485 | var vec = vec2.create(); 486 | 487 | return function(a, stride, offset, count, fn, arg) { 488 | var i, l; 489 | if(!stride) { 490 | stride = 2; 491 | } 492 | 493 | if(!offset) { 494 | offset = 0; 495 | } 496 | 497 | if(count) { 498 | l = Math.min((count * stride) + offset, a.length); 499 | } else { 500 | l = a.length; 501 | } 502 | 503 | for(i = offset; i < l; i += stride) { 504 | vec[0] = a[i]; vec[1] = a[i+1]; 505 | fn(vec, vec, arg); 506 | a[i] = vec[0]; a[i+1] = vec[1]; 507 | } 508 | 509 | return a; 510 | }; 511 | })(); 512 | 513 | /** 514 | * Returns a string representation of a vector 515 | * 516 | * @param {vec2} vec vector to represent as a string 517 | * @returns {String} string representation of the vector 518 | */ 519 | vec2.str = function (a) { 520 | return 'vec2(' + a[0] + ', ' + a[1] + ')'; 521 | }; 522 | 523 | if(typeof(exports) !== 'undefined') { 524 | exports.vec2 = vec2; 525 | } 526 | -------------------------------------------------------------------------------- /gl-matrix/src/gl-matrix/vec4.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013, Brandon Jones, Colin MacKenzie IV. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 22 | 23 | /** 24 | * @class 4 Dimensional Vector 25 | * @name vec4 26 | */ 27 | var vec4 = {}; 28 | 29 | /** 30 | * Creates a new, empty vec4 31 | * 32 | * @returns {vec4} a new 4D vector 33 | */ 34 | vec4.create = function() { 35 | var out = new GLMAT_ARRAY_TYPE(4); 36 | out[0] = 0; 37 | out[1] = 0; 38 | out[2] = 0; 39 | out[3] = 0; 40 | return out; 41 | }; 42 | 43 | /** 44 | * Creates a new vec4 initialized with values from an existing vector 45 | * 46 | * @param {vec4} a vector to clone 47 | * @returns {vec4} a new 4D vector 48 | */ 49 | vec4.clone = function(a) { 50 | var out = new GLMAT_ARRAY_TYPE(4); 51 | out[0] = a[0]; 52 | out[1] = a[1]; 53 | out[2] = a[2]; 54 | out[3] = a[3]; 55 | return out; 56 | }; 57 | 58 | /** 59 | * Creates a new vec4 initialized with the given values 60 | * 61 | * @param {Number} x X component 62 | * @param {Number} y Y component 63 | * @param {Number} z Z component 64 | * @param {Number} w W component 65 | * @returns {vec4} a new 4D vector 66 | */ 67 | vec4.fromValues = function(x, y, z, w) { 68 | var out = new GLMAT_ARRAY_TYPE(4); 69 | out[0] = x; 70 | out[1] = y; 71 | out[2] = z; 72 | out[3] = w; 73 | return out; 74 | }; 75 | 76 | /** 77 | * Copy the values from one vec4 to another 78 | * 79 | * @param {vec4} out the receiving vector 80 | * @param {vec4} a the source vector 81 | * @returns {vec4} out 82 | */ 83 | vec4.copy = function(out, a) { 84 | out[0] = a[0]; 85 | out[1] = a[1]; 86 | out[2] = a[2]; 87 | out[3] = a[3]; 88 | return out; 89 | }; 90 | 91 | /** 92 | * Set the components of a vec4 to the given values 93 | * 94 | * @param {vec4} out the receiving vector 95 | * @param {Number} x X component 96 | * @param {Number} y Y component 97 | * @param {Number} z Z component 98 | * @param {Number} w W component 99 | * @returns {vec4} out 100 | */ 101 | vec4.set = function(out, x, y, z, w) { 102 | out[0] = x; 103 | out[1] = y; 104 | out[2] = z; 105 | out[3] = w; 106 | return out; 107 | }; 108 | 109 | /** 110 | * Adds two vec4's 111 | * 112 | * @param {vec4} out the receiving vector 113 | * @param {vec4} a the first operand 114 | * @param {vec4} b the second operand 115 | * @returns {vec4} out 116 | */ 117 | vec4.add = function(out, a, b) { 118 | out[0] = a[0] + b[0]; 119 | out[1] = a[1] + b[1]; 120 | out[2] = a[2] + b[2]; 121 | out[3] = a[3] + b[3]; 122 | return out; 123 | }; 124 | 125 | /** 126 | * Subtracts vector b from vector a 127 | * 128 | * @param {vec4} out the receiving vector 129 | * @param {vec4} a the first operand 130 | * @param {vec4} b the second operand 131 | * @returns {vec4} out 132 | */ 133 | vec4.subtract = function(out, a, b) { 134 | out[0] = a[0] - b[0]; 135 | out[1] = a[1] - b[1]; 136 | out[2] = a[2] - b[2]; 137 | out[3] = a[3] - b[3]; 138 | return out; 139 | }; 140 | 141 | /** 142 | * Alias for {@link vec4.subtract} 143 | * @function 144 | */ 145 | vec4.sub = vec4.subtract; 146 | 147 | /** 148 | * Multiplies two vec4's 149 | * 150 | * @param {vec4} out the receiving vector 151 | * @param {vec4} a the first operand 152 | * @param {vec4} b the second operand 153 | * @returns {vec4} out 154 | */ 155 | vec4.multiply = function(out, a, b) { 156 | out[0] = a[0] * b[0]; 157 | out[1] = a[1] * b[1]; 158 | out[2] = a[2] * b[2]; 159 | out[3] = a[3] * b[3]; 160 | return out; 161 | }; 162 | 163 | /** 164 | * Alias for {@link vec4.multiply} 165 | * @function 166 | */ 167 | vec4.mul = vec4.multiply; 168 | 169 | /** 170 | * Divides two vec4's 171 | * 172 | * @param {vec4} out the receiving vector 173 | * @param {vec4} a the first operand 174 | * @param {vec4} b the second operand 175 | * @returns {vec4} out 176 | */ 177 | vec4.divide = function(out, a, b) { 178 | out[0] = a[0] / b[0]; 179 | out[1] = a[1] / b[1]; 180 | out[2] = a[2] / b[2]; 181 | out[3] = a[3] / b[3]; 182 | return out; 183 | }; 184 | 185 | /** 186 | * Alias for {@link vec4.divide} 187 | * @function 188 | */ 189 | vec4.div = vec4.divide; 190 | 191 | /** 192 | * Returns the minimum of two vec4's 193 | * 194 | * @param {vec4} out the receiving vector 195 | * @param {vec4} a the first operand 196 | * @param {vec4} b the second operand 197 | * @returns {vec4} out 198 | */ 199 | vec4.min = function(out, a, b) { 200 | out[0] = Math.min(a[0], b[0]); 201 | out[1] = Math.min(a[1], b[1]); 202 | out[2] = Math.min(a[2], b[2]); 203 | out[3] = Math.min(a[3], b[3]); 204 | return out; 205 | }; 206 | 207 | /** 208 | * Returns the maximum of two vec4's 209 | * 210 | * @param {vec4} out the receiving vector 211 | * @param {vec4} a the first operand 212 | * @param {vec4} b the second operand 213 | * @returns {vec4} out 214 | */ 215 | vec4.max = function(out, a, b) { 216 | out[0] = Math.max(a[0], b[0]); 217 | out[1] = Math.max(a[1], b[1]); 218 | out[2] = Math.max(a[2], b[2]); 219 | out[3] = Math.max(a[3], b[3]); 220 | return out; 221 | }; 222 | 223 | /** 224 | * Scales a vec4 by a scalar number 225 | * 226 | * @param {vec4} out the receiving vector 227 | * @param {vec4} a the vector to scale 228 | * @param {Number} b amount to scale the vector by 229 | * @returns {vec4} out 230 | */ 231 | vec4.scale = function(out, a, b) { 232 | out[0] = a[0] * b; 233 | out[1] = a[1] * b; 234 | out[2] = a[2] * b; 235 | out[3] = a[3] * b; 236 | return out; 237 | }; 238 | 239 | /** 240 | * Adds two vec4's after scaling the second operand by a scalar value 241 | * 242 | * @param {vec4} out the receiving vector 243 | * @param {vec4} a the first operand 244 | * @param {vec4} b the second operand 245 | * @param {Number} scale the amount to scale b by before adding 246 | * @returns {vec4} out 247 | */ 248 | vec4.scaleAndAdd = function(out, a, b, scale) { 249 | out[0] = a[0] + (b[0] * scale); 250 | out[1] = a[1] + (b[1] * scale); 251 | out[2] = a[2] + (b[2] * scale); 252 | out[3] = a[3] + (b[3] * scale); 253 | return out; 254 | }; 255 | 256 | /** 257 | * Calculates the euclidian distance between two vec4's 258 | * 259 | * @param {vec4} a the first operand 260 | * @param {vec4} b the second operand 261 | * @returns {Number} distance between a and b 262 | */ 263 | vec4.distance = function(a, b) { 264 | var x = b[0] - a[0], 265 | y = b[1] - a[1], 266 | z = b[2] - a[2], 267 | w = b[3] - a[3]; 268 | return Math.sqrt(x*x + y*y + z*z + w*w); 269 | }; 270 | 271 | /** 272 | * Alias for {@link vec4.distance} 273 | * @function 274 | */ 275 | vec4.dist = vec4.distance; 276 | 277 | /** 278 | * Calculates the squared euclidian distance between two vec4's 279 | * 280 | * @param {vec4} a the first operand 281 | * @param {vec4} b the second operand 282 | * @returns {Number} squared distance between a and b 283 | */ 284 | vec4.squaredDistance = function(a, b) { 285 | var x = b[0] - a[0], 286 | y = b[1] - a[1], 287 | z = b[2] - a[2], 288 | w = b[3] - a[3]; 289 | return x*x + y*y + z*z + w*w; 290 | }; 291 | 292 | /** 293 | * Alias for {@link vec4.squaredDistance} 294 | * @function 295 | */ 296 | vec4.sqrDist = vec4.squaredDistance; 297 | 298 | /** 299 | * Calculates the length of a vec4 300 | * 301 | * @param {vec4} a vector to calculate length of 302 | * @returns {Number} length of a 303 | */ 304 | vec4.length = function (a) { 305 | var x = a[0], 306 | y = a[1], 307 | z = a[2], 308 | w = a[3]; 309 | return Math.sqrt(x*x + y*y + z*z + w*w); 310 | }; 311 | 312 | /** 313 | * Alias for {@link vec4.length} 314 | * @function 315 | */ 316 | vec4.len = vec4.length; 317 | 318 | /** 319 | * Calculates the squared length of a vec4 320 | * 321 | * @param {vec4} a vector to calculate squared length of 322 | * @returns {Number} squared length of a 323 | */ 324 | vec4.squaredLength = function (a) { 325 | var x = a[0], 326 | y = a[1], 327 | z = a[2], 328 | w = a[3]; 329 | return x*x + y*y + z*z + w*w; 330 | }; 331 | 332 | /** 333 | * Alias for {@link vec4.squaredLength} 334 | * @function 335 | */ 336 | vec4.sqrLen = vec4.squaredLength; 337 | 338 | /** 339 | * Negates the components of a vec4 340 | * 341 | * @param {vec4} out the receiving vector 342 | * @param {vec4} a vector to negate 343 | * @returns {vec4} out 344 | */ 345 | vec4.negate = function(out, a) { 346 | out[0] = -a[0]; 347 | out[1] = -a[1]; 348 | out[2] = -a[2]; 349 | out[3] = -a[3]; 350 | return out; 351 | }; 352 | 353 | /** 354 | * Returns the inverse of the components of a vec4 355 | * 356 | * @param {vec4} out the receiving vector 357 | * @param {vec4} a vector to invert 358 | * @returns {vec4} out 359 | */ 360 | vec4.inverse = function(out, a) { 361 | out[0] = 1.0 / a[0]; 362 | out[1] = 1.0 / a[1]; 363 | out[2] = 1.0 / a[2]; 364 | out[3] = 1.0 / a[3]; 365 | return out; 366 | }; 367 | 368 | /** 369 | * Normalize a vec4 370 | * 371 | * @param {vec4} out the receiving vector 372 | * @param {vec4} a vector to normalize 373 | * @returns {vec4} out 374 | */ 375 | vec4.normalize = function(out, a) { 376 | var x = a[0], 377 | y = a[1], 378 | z = a[2], 379 | w = a[3]; 380 | var len = x*x + y*y + z*z + w*w; 381 | if (len > 0) { 382 | len = 1 / Math.sqrt(len); 383 | out[0] = a[0] * len; 384 | out[1] = a[1] * len; 385 | out[2] = a[2] * len; 386 | out[3] = a[3] * len; 387 | } 388 | return out; 389 | }; 390 | 391 | /** 392 | * Calculates the dot product of two vec4's 393 | * 394 | * @param {vec4} a the first operand 395 | * @param {vec4} b the second operand 396 | * @returns {Number} dot product of a and b 397 | */ 398 | vec4.dot = function (a, b) { 399 | return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; 400 | }; 401 | 402 | /** 403 | * Performs a linear interpolation between two vec4's 404 | * 405 | * @param {vec4} out the receiving vector 406 | * @param {vec4} a the first operand 407 | * @param {vec4} b the second operand 408 | * @param {Number} t interpolation amount between the two inputs 409 | * @returns {vec4} out 410 | */ 411 | vec4.lerp = function (out, a, b, t) { 412 | var ax = a[0], 413 | ay = a[1], 414 | az = a[2], 415 | aw = a[3]; 416 | out[0] = ax + t * (b[0] - ax); 417 | out[1] = ay + t * (b[1] - ay); 418 | out[2] = az + t * (b[2] - az); 419 | out[3] = aw + t * (b[3] - aw); 420 | return out; 421 | }; 422 | 423 | /** 424 | * Generates a random vector with the given scale 425 | * 426 | * @param {vec4} out the receiving vector 427 | * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned 428 | * @returns {vec4} out 429 | */ 430 | vec4.random = function (out, scale) { 431 | scale = scale || 1.0; 432 | 433 | //TODO: This is a pretty awful way of doing this. Find something better. 434 | out[0] = GLMAT_RANDOM(); 435 | out[1] = GLMAT_RANDOM(); 436 | out[2] = GLMAT_RANDOM(); 437 | out[3] = GLMAT_RANDOM(); 438 | vec4.normalize(out, out); 439 | vec4.scale(out, out, scale); 440 | return out; 441 | }; 442 | 443 | /** 444 | * Transforms the vec4 with a mat4. 445 | * 446 | * @param {vec4} out the receiving vector 447 | * @param {vec4} a the vector to transform 448 | * @param {mat4} m matrix to transform with 449 | * @returns {vec4} out 450 | */ 451 | vec4.transformMat4 = function(out, a, m) { 452 | var x = a[0], y = a[1], z = a[2], w = a[3]; 453 | out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; 454 | out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; 455 | out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; 456 | out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; 457 | return out; 458 | }; 459 | 460 | /** 461 | * Transforms the vec4 with a quat 462 | * 463 | * @param {vec4} out the receiving vector 464 | * @param {vec4} a the vector to transform 465 | * @param {quat} q quaternion to transform with 466 | * @returns {vec4} out 467 | */ 468 | vec4.transformQuat = function(out, a, q) { 469 | var x = a[0], y = a[1], z = a[2], 470 | qx = q[0], qy = q[1], qz = q[2], qw = q[3], 471 | 472 | // calculate quat * vec 473 | ix = qw * x + qy * z - qz * y, 474 | iy = qw * y + qz * x - qx * z, 475 | iz = qw * z + qx * y - qy * x, 476 | iw = -qx * x - qy * y - qz * z; 477 | 478 | // calculate result * inverse quat 479 | out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; 480 | out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; 481 | out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; 482 | return out; 483 | }; 484 | 485 | /** 486 | * Perform some operation over an array of vec4s. 487 | * 488 | * @param {Array} a the array of vectors to iterate over 489 | * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed 490 | * @param {Number} offset Number of elements to skip at the beginning of the array 491 | * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array 492 | * @param {Function} fn Function to call for each vector in the array 493 | * @param {Object} [arg] additional argument to pass to fn 494 | * @returns {Array} a 495 | * @function 496 | */ 497 | vec4.forEach = (function() { 498 | var vec = vec4.create(); 499 | 500 | return function(a, stride, offset, count, fn, arg) { 501 | var i, l; 502 | if(!stride) { 503 | stride = 4; 504 | } 505 | 506 | if(!offset) { 507 | offset = 0; 508 | } 509 | 510 | if(count) { 511 | l = Math.min((count * stride) + offset, a.length); 512 | } else { 513 | l = a.length; 514 | } 515 | 516 | for(i = offset; i < l; i += stride) { 517 | vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; vec[3] = a[i+3]; 518 | fn(vec, vec, arg); 519 | a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; a[i+3] = vec[3]; 520 | } 521 | 522 | return a; 523 | }; 524 | })(); 525 | 526 | /** 527 | * Returns a string representation of a vector 528 | * 529 | * @param {vec4} vec vector to represent as a string 530 | * @returns {String} string representation of the vector 531 | */ 532 | vec4.str = function (a) { 533 | return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; 534 | }; 535 | 536 | if(typeof(exports) !== 'undefined') { 537 | exports.vec4 = vec4; 538 | } 539 | -------------------------------------------------------------------------------- /gl-matrix/tasks/build.rake: -------------------------------------------------------------------------------- 1 | desc "compile & minify sources into a single file" 2 | task :build => ['build:compile', 'build:minify'] 3 | -------------------------------------------------------------------------------- /gl-matrix/tasks/build/compile.rake: -------------------------------------------------------------------------------- 1 | namespace :build do 2 | task :compile do 3 | compile 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /gl-matrix/tasks/build/minify.rake: -------------------------------------------------------------------------------- 1 | namespace :build do 2 | task :minify do 3 | minify 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /gl-matrix/tasks/default.rake: -------------------------------------------------------------------------------- 1 | task :default => ['test:node', 'test:ci'] 2 | -------------------------------------------------------------------------------- /gl-matrix/tasks/release.rake: -------------------------------------------------------------------------------- 1 | desc "tag and release gl-matrix v#{GLMatrix::VERSION}" 2 | task :release do 3 | require 'thor' 4 | Bundler.ui = Bundler::UI::Shell.new(Thor::Shell::Basic.new) 5 | Bundler.ui.debug! if ENV['DEBUG'] 6 | 7 | # Sanity check: rebuild files just in case dev forgot to. 8 | # If so, files will change and release will abort since changes 9 | # were not checked in. 10 | Rake::Task['build'].invoke 11 | 12 | release do 13 | # Put other release-related stuff here, such as publishing docs; 14 | # if anything fails, gl-matrix will be untagged and not pushed. 15 | # 16 | # Example: 17 | # 18 | # Rake::Task['doc:publish'].invoke 19 | # 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /gl-matrix/tasks/support/gl-matrix.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not 17 | # be misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source distribution. 20 | # 21 | $:.unshift File.expand_path('.', File.dirname(__FILE__)) 22 | require 'sprockets' 23 | require 'jasmine' 24 | 25 | class Jasmine::Config 26 | def simple_config_file 27 | File.expand_path GLMatrix.base_path.join('spec/jasmine.yml') 28 | end 29 | end 30 | 31 | class Rack::Jasmine::Runner 32 | alias_method :jasmine_call, :call 33 | def call(env) 34 | GLMatrix.compile 35 | jasmine_call env 36 | end 37 | end 38 | 39 | module GLMatrix 40 | autoload :ReleaseHelper, 'gl-matrix/release_helper' 41 | autoload :Version, 'gl-matrix/version' 42 | autoload :VERSION, 'gl-matrix/version' 43 | 44 | module_function 45 | 46 | def release(&block) 47 | GLMatrix::ReleaseHelper.release &block 48 | end 49 | 50 | def sprockets 51 | env = Sprockets::Environment.new base_path 52 | env.append_path base_path.join('src') 53 | env 54 | end 55 | 56 | def base_path 57 | Pathname.new File.expand_path('../..', File.dirname(__FILE__)) 58 | end 59 | 60 | # Compiles the source file to the dest file. If a block 61 | # is given, the source file is yielded and replaced with 62 | # the result. Returns the destination as a Pathname. 63 | def compile(source = 'gl-matrix.js', dest = 'dist/gl-matrix.js') 64 | dest = base_path.join dest 65 | js = sprockets[source] 66 | js = yield js if block_given? 67 | 68 | File.open dest, "w" do |f| 69 | f.puts js 70 | end 71 | 72 | puts "compiled #{source} to #{dest.relative_path_from base_path}" 73 | dest 74 | end 75 | 76 | def minify(source = 'gl-matrix.js', dest = 'dist/gl-matrix-min.js') 77 | dest = compile source, dest do |js| 78 | Uglifier.compile js 79 | end 80 | 81 | puts "minified #{source} to #{dest.relative_path_from base_path}" 82 | end 83 | 84 | end 85 | -------------------------------------------------------------------------------- /gl-matrix/tasks/support/gl-matrix/release_helper.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not 17 | # be misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source distribution. 20 | 21 | # Pretty much everything here was ripped from Bundler. 22 | # https://github.com/carlhuda/bundler/blob/master/lib/bundler/gem_helper.rb 23 | module GLMatrix::ReleaseHelper 24 | module_function 25 | 26 | def release 27 | guard_clean 28 | guard_already_tagged 29 | tag_version { 30 | yield if block_given? 31 | git_push 32 | } 33 | end 34 | 35 | def base 36 | GLMatrix.base_path.to_s 37 | end 38 | 39 | def git_push 40 | perform_git_push 41 | perform_git_push ' --tags' 42 | Bundler.ui.confirm "Pushed git commits and tags" 43 | end 44 | 45 | def perform_git_push(options = '') 46 | cmd = "git push #{options}" 47 | out, code = sh_with_code(cmd) 48 | raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0 49 | end 50 | 51 | def guard_already_tagged 52 | if sh('git tag').split(/\n/).include?(version_tag) 53 | raise("This tag has already been committed to the repo.") 54 | end 55 | end 56 | 57 | def guard_clean 58 | clean? or raise("There are files that need to be committed first.") 59 | end 60 | 61 | def clean? 62 | sh_with_code("git diff --exit-code")[1] == 0 63 | end 64 | 65 | def tag_version 66 | sh "git tag -a -m \"Version #{version}\" #{version_tag}" 67 | Bundler.ui.confirm "Tagged #{version_tag}" 68 | yield if block_given? 69 | rescue 70 | Bundler.ui.error "Untagged #{version_tag} due to error" 71 | sh_with_code "git tag -d #{version_tag}" 72 | raise 73 | end 74 | 75 | def version 76 | GLMatrix::VERSION 77 | end 78 | 79 | def version_tag 80 | "v#{version}" 81 | end 82 | 83 | def name 84 | "gl-matrix" 85 | end 86 | 87 | def sh(cmd, &block) 88 | out, code = sh_with_code(cmd, &block) 89 | code == 0 ? out : raise(out.empty? ? "Running `#{cmd}' failed. Run this command directly for more detailed output." : out) 90 | end 91 | 92 | def sh_with_code(cmd, &block) 93 | cmd << " 2>&1" 94 | outbuf = '' 95 | Bundler.ui.debug(cmd) 96 | Dir.chdir(base) { 97 | outbuf = `#{cmd}` 98 | if $? == 0 99 | block.call(outbuf) if block 100 | end 101 | } 102 | [outbuf, $?] 103 | end 104 | end 105 | -------------------------------------------------------------------------------- /gl-matrix/tasks/support/gl-matrix/version.rb: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV 2 | # 3 | # This software is provided 'as-is', without any express or implied 4 | # warranty. In no event will the authors be held liable for any damages 5 | # arising from the use of this software. 6 | # 7 | # Permission is granted to anyone to use this software for any purpose, 8 | # including commercial applications, and to alter it and redistribute it 9 | # freely, subject to the following restrictions: 10 | # 11 | # 1. The origin of this software must not be misrepresented; you must not 12 | # claim that you wrote the original software. If you use this software 13 | # in a product, an acknowledgment in the product documentation would be 14 | # appreciated but is not required. 15 | # 16 | # 2. Altered source versions must be plainly marked as such, and must not 17 | # be misrepresented as being the original software. 18 | # 19 | # 3. This notice may not be removed or altered from any source distribution. 20 | 21 | module GLMatrix 22 | module Version 23 | MAJOR, MINOR, PATCH, REL = *File.read(base_path.join 'VERSION').split(".") 24 | STRING = [MAJOR, MINOR, PATCH, REL].compact.join '.' 25 | end 26 | 27 | VERSION = Version::STRING 28 | end 29 | -------------------------------------------------------------------------------- /gl-matrix/tasks/test/ci.rake: -------------------------------------------------------------------------------- 1 | namespace :test do 2 | desc "Run continuous integration tests" 3 | RSpec::Core::RakeTask.new('ci' => :build) do |t| 4 | t.rspec_opts = ["--colour", "--format", ENV['JASMINE_SPEC_FORMAT'] || "progress"] 5 | t.verbose = true 6 | t.rspec_opts += ["-r #{base_path.join('tasks/support/gl-matrix')}"] 7 | t.pattern = [Jasmine.runner_filepath] 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /gl-matrix/tasks/test/coverage.rake: -------------------------------------------------------------------------------- 1 | desc "Generate JavaScript code coverage report in ./covershot" 2 | task :coverage => %w( 3 | coverage:dependencies 4 | coverage:clean 5 | coverage:prepare 6 | coverage:instrumentation 7 | coverage:write_manifest 8 | coverage:execute 9 | coverage:generate 10 | coverage:done 11 | ) 12 | 13 | namespace :coverage do 14 | task :dependencies do 15 | unless File.exist?(base_path.join('node_modules')) 16 | if %x[which npm].strip.length == 0 17 | raise <<-end_error 18 | Could not execute `npm`! Please make sure node.js and the Node Package 19 | Manager (NPM) are available and can be executed without root 20 | permissions. 21 | end_error 22 | else 23 | cmd = "npm install && bundle exec #{$0} #{ARGV.join ' '}" 24 | puts "Executing the following command:" 25 | puts 26 | puts " #{cmd}" 27 | puts 28 | puts 29 | Kernel.exec cmd 30 | end 31 | end 32 | end 33 | 34 | task :clean do 35 | rm_rf base_path.join('covershot') 36 | rm_rf base_path.join('tmp') 37 | end 38 | 39 | task :prepare do 40 | manifest = sprockets['gl-matrix-manifest.js'] 41 | coverage_path = base_path.join('tmp/coverage') 42 | 43 | manifest.dependencies.each do |part| 44 | path = coverage_path.join('lib').join(part.pathname.basename) 45 | mkdir_p(path.dirname) unless File.directory?(path.dirname) 46 | File.open(path, 'w') do |f| 47 | f.print part.body 48 | end 49 | end 50 | end 51 | 52 | task :instrumentation do 53 | bin = 'jscoverage' 54 | opts = [ '--no-highlight' ] 55 | input = base_path.join('tmp/coverage/lib').to_s 56 | output = base_path.join('tmp/coverage/lib-cov').to_s 57 | 58 | unless system *[bin, opts, input, output].flatten 59 | raise "Instrumentation failure. Please make sure `jscoverage` is installed." 60 | end 61 | end 62 | 63 | task :write_manifest do 64 | manifest = sprockets['gl-matrix-manifest.js'] 65 | coverage_path = base_path.join('tmp/coverage') 66 | 67 | File.open(coverage_path.join('manifest.js'), 'w') do |manifest_out| 68 | manifest_out.puts <<-end_script 69 | var covershot = require('covershot'); 70 | var csrequire = covershot.require.bind(null, require); 71 | 72 | function pull(str) { 73 | var exps = csrequire(str); 74 | for (var i in exps) { 75 | global[i] = exps[i]; 76 | } 77 | } 78 | 79 | global.GLMAT_EPSILON = 0.000001; 80 | global.GLMAT_ARRAY_TYPE = Float32Array; 81 | 82 | end_script 83 | manifest.dependencies.each do |part| 84 | path = coverage_path.join('lib-cov').join(part.pathname.basename) 85 | manifest_out.puts "pull('#{path}');" 86 | end 87 | manifest_out.puts <<-end_script 88 | function CoverageReporter() { 89 | this.reportRunnerResults = function(suite) { 90 | covershot.writeCoverage(); 91 | }; 92 | }; 93 | 94 | jasmine.getEnv().addReporter(new CoverageReporter()); 95 | end_script 96 | end 97 | end 98 | 99 | task :execute do 100 | jasmine_node = base_path.join('node_modules/jasmine-node/bin/jasmine-node').to_s 101 | spec = base_path.join('spec').to_s 102 | 103 | unless system jasmine_node, spec 104 | raise "jasmine-node tests failed. Coverage report not generated." 105 | end 106 | end 107 | 108 | task :generate do 109 | covershot = base_path.join('node_modules/covershot/bin/covershot').to_s 110 | data_dir = base_path.join('covershot/data').to_s 111 | format = 'html' 112 | 113 | unless system covershot, data_dir, '-f', format 114 | raise "Execution of covershot failed. Coverage report not generated." 115 | end 116 | end 117 | 118 | task :done do 119 | rm_rf base_path.join('tmp') 120 | puts 121 | puts 122 | puts "Coverage report generated in: #{base_path.join("covershot/index.html")}" 123 | puts 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /gl-matrix/tasks/test/jasmine.rake: -------------------------------------------------------------------------------- 1 | namespace :test do 2 | desc "Run specs via server" 3 | task :jasmine do 4 | port = ENV['JASMINE_PORT'] || 8888 5 | puts "your tests are here:" 6 | puts " http://localhost:#{port}/" 7 | Jasmine::Server.new(port).start 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /gl-matrix/tasks/test/node.rake: -------------------------------------------------------------------------------- 1 | namespace :test do 2 | desc "run test suite with node.js" 3 | task :node => :build do 4 | # make sure jasmine-node exists, and barf if it doesn't 5 | if %x['jasmine-node'] =~ /USAGE/ 6 | unless system 'jasmine-node', base_path.join('spec').to_s 7 | raise "node.js tests failed" 8 | end 9 | else 10 | puts "jasmine-node is not available" 11 | puts 12 | puts "Please run:" 13 | puts " npm install -g jasmine-node" 14 | puts 15 | puts "...and then try again." 16 | puts 17 | exit 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /mvp.vert: -------------------------------------------------------------------------------- 1 | attribute vec4 aPosition; 2 | attribute vec4 aColor; 3 | 4 | uniform mat4 uModelMatrix; 5 | uniform mat4 uViewMatrix; 6 | uniform mat4 uProjMatrix; 7 | 8 | varying vec4 vColor; 9 | 10 | void main () { 11 | // I wasted 2 days on this example because Matrix Multiplication is NOT 12 | // Communitive! 13 | gl_Position = uProjMatrix * uViewMatrix * uModelMatrix * aPosition; 14 | vColor = aColor; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /points.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | varying vec4 vColor; 4 | 5 | void main () { 6 | gl_FragColor = vColor; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /webgl-shader-loader/.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | *.swp 10 | 11 | pids 12 | logs 13 | results 14 | 15 | npm-debug.log 16 | node_modules 17 | -------------------------------------------------------------------------------- /webgl-shader-loader/LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | * ---------------------------------------------------------------------------- 3 | * "THE BEER-WARE LICENSE" (Revision 42): 4 | * wrote this file. As long as you retain this notice you 5 | * can do whatever you want with this stuff. If we meet some day, and you think 6 | * this stuff is worth it, you can buy me a beer in return Nick Desaulniers 7 | * ---------------------------------------------------------------------------- 8 | */ 9 | 10 | Mozilla Public License, version 2.0 11 | 12 | 1. Definitions 13 | 14 | 1.1. “Contributor” 15 | 16 | means each individual or legal entity that creates, contributes to the 17 | creation of, or owns Covered Software. 18 | 19 | 1.2. “Contributor Version” 20 | 21 | means the combination of the Contributions of others (if any) used by a 22 | Contributor and that particular Contributor’s Contribution. 23 | 24 | 1.3. “Contribution” 25 | 26 | means Covered Software of a particular Contributor. 27 | 28 | 1.4. “Covered Software” 29 | 30 | means Source Code Form to which the initial Contributor has attached the 31 | notice in Exhibit A, the Executable Form of such Source Code Form, and 32 | Modifications of such Source Code Form, in each case including portions 33 | thereof. 34 | 35 | 1.5. “Incompatible With Secondary Licenses” 36 | means 37 | 38 | a. that the initial Contributor has attached the notice described in 39 | Exhibit B to the Covered Software; or 40 | 41 | b. that the Covered Software was made available under the terms of version 42 | 1.1 or earlier of the License, but not also under the terms of a 43 | Secondary License. 44 | 45 | 1.6. “Executable Form” 46 | 47 | means any form of the work other than Source Code Form. 48 | 49 | 1.7. “Larger Work” 50 | 51 | means a work that combines Covered Software with other material, in a separate 52 | file or files, that is not Covered Software. 53 | 54 | 1.8. “License” 55 | 56 | means this document. 57 | 58 | 1.9. “Licensable” 59 | 60 | means having the right to grant, to the maximum extent possible, whether at the 61 | time of the initial grant or subsequently, any and all of the rights conveyed by 62 | this License. 63 | 64 | 1.10. “Modifications” 65 | 66 | means any of the following: 67 | 68 | a. any file in Source Code Form that results from an addition to, deletion 69 | from, or modification of the contents of Covered Software; or 70 | 71 | b. any new file in Source Code Form that contains any Covered Software. 72 | 73 | 1.11. “Patent Claims” of a Contributor 74 | 75 | means any patent claim(s), including without limitation, method, process, 76 | and apparatus claims, in any patent Licensable by such Contributor that 77 | would be infringed, but for the grant of the License, by the making, 78 | using, selling, offering for sale, having made, import, or transfer of 79 | either its Contributions or its Contributor Version. 80 | 81 | 1.12. “Secondary License” 82 | 83 | means either the GNU General Public License, Version 2.0, the GNU Lesser 84 | General Public License, Version 2.1, the GNU Affero General Public 85 | License, Version 3.0, or any later versions of those licenses. 86 | 87 | 1.13. “Source Code Form” 88 | 89 | means the form of the work preferred for making modifications. 90 | 91 | 1.14. “You” (or “Your”) 92 | 93 | means an individual or a legal entity exercising rights under this 94 | License. For legal entities, “You” includes any entity that controls, is 95 | controlled by, or is under common control with You. For purposes of this 96 | definition, “control” means (a) the power, direct or indirect, to cause 97 | the direction or management of such entity, whether by contract or 98 | otherwise, or (b) ownership of more than fifty percent (50%) of the 99 | outstanding shares or beneficial ownership of such entity. 100 | 101 | 102 | 2. License Grants and Conditions 103 | 104 | 2.1. Grants 105 | 106 | Each Contributor hereby grants You a world-wide, royalty-free, 107 | non-exclusive license: 108 | 109 | a. under intellectual property rights (other than patent or trademark) 110 | Licensable by such Contributor to use, reproduce, make available, 111 | modify, display, perform, distribute, and otherwise exploit its 112 | Contributions, either on an unmodified basis, with Modifications, or as 113 | part of a Larger Work; and 114 | 115 | b. under Patent Claims of such Contributor to make, use, sell, offer for 116 | sale, have made, import, and otherwise transfer either its Contributions 117 | or its Contributor Version. 118 | 119 | 2.2. Effective Date 120 | 121 | The licenses granted in Section 2.1 with respect to any Contribution become 122 | effective for each Contribution on the date the Contributor first distributes 123 | such Contribution. 124 | 125 | 2.3. Limitations on Grant Scope 126 | 127 | The licenses granted in this Section 2 are the only rights granted under this 128 | License. No additional rights or licenses will be implied from the distribution 129 | or licensing of Covered Software under this License. Notwithstanding Section 130 | 2.1(b) above, no patent license is granted by a Contributor: 131 | 132 | a. for any code that a Contributor has removed from Covered Software; or 133 | 134 | b. for infringements caused by: (i) Your and any other third party’s 135 | modifications of Covered Software, or (ii) the combination of its 136 | Contributions with other software (except as part of its Contributor 137 | Version); or 138 | 139 | c. under Patent Claims infringed by Covered Software in the absence of its 140 | Contributions. 141 | 142 | This License does not grant any rights in the trademarks, service marks, or 143 | logos of any Contributor (except as may be necessary to comply with the 144 | notice requirements in Section 3.4). 145 | 146 | 2.4. Subsequent Licenses 147 | 148 | No Contributor makes additional grants as a result of Your choice to 149 | distribute the Covered Software under a subsequent version of this License 150 | (see Section 10.2) or under the terms of a Secondary License (if permitted 151 | under the terms of Section 3.3). 152 | 153 | 2.5. Representation 154 | 155 | Each Contributor represents that the Contributor believes its Contributions 156 | are its original creation(s) or it has sufficient rights to grant the 157 | rights to its Contributions conveyed by this License. 158 | 159 | 2.6. Fair Use 160 | 161 | This License is not intended to limit any rights You have under applicable 162 | copyright doctrines of fair use, fair dealing, or other equivalents. 163 | 164 | 2.7. Conditions 165 | 166 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in 167 | Section 2.1. 168 | 169 | 170 | 3. Responsibilities 171 | 172 | 3.1. Distribution of Source Form 173 | 174 | All distribution of Covered Software in Source Code Form, including any 175 | Modifications that You create or to which You contribute, must be under the 176 | terms of this License. You must inform recipients that the Source Code Form 177 | of the Covered Software is governed by the terms of this License, and how 178 | they can obtain a copy of this License. You may not attempt to alter or 179 | restrict the recipients’ rights in the Source Code Form. 180 | 181 | 3.2. Distribution of Executable Form 182 | 183 | If You distribute Covered Software in Executable Form then: 184 | 185 | a. such Covered Software must also be made available in Source Code Form, 186 | as described in Section 3.1, and You must inform recipients of the 187 | Executable Form how they can obtain a copy of such Source Code Form by 188 | reasonable means in a timely manner, at a charge no more than the cost 189 | of distribution to the recipient; and 190 | 191 | b. You may distribute such Executable Form under the terms of this License, 192 | or sublicense it under different terms, provided that the license for 193 | the Executable Form does not attempt to limit or alter the recipients’ 194 | rights in the Source Code Form under this License. 195 | 196 | 3.3. Distribution of a Larger Work 197 | 198 | You may create and distribute a Larger Work under terms of Your choice, 199 | provided that You also comply with the requirements of this License for the 200 | Covered Software. If the Larger Work is a combination of Covered Software 201 | with a work governed by one or more Secondary Licenses, and the Covered 202 | Software is not Incompatible With Secondary Licenses, this License permits 203 | You to additionally distribute such Covered Software under the terms of 204 | such Secondary License(s), so that the recipient of the Larger Work may, at 205 | their option, further distribute the Covered Software under the terms of 206 | either this License or such Secondary License(s). 207 | 208 | 3.4. Notices 209 | 210 | You may not remove or alter the substance of any license notices (including 211 | copyright notices, patent notices, disclaimers of warranty, or limitations 212 | of liability) contained within the Source Code Form of the Covered 213 | Software, except that You may alter any license notices to the extent 214 | required to remedy known factual inaccuracies. 215 | 216 | 3.5. Application of Additional Terms 217 | 218 | You may choose to offer, and to charge a fee for, warranty, support, 219 | indemnity or liability obligations to one or more recipients of Covered 220 | Software. However, You may do so only on Your own behalf, and not on behalf 221 | of any Contributor. You must make it absolutely clear that any such 222 | warranty, support, indemnity, or liability obligation is offered by You 223 | alone, and You hereby agree to indemnify every Contributor for any 224 | liability incurred by such Contributor as a result of warranty, support, 225 | indemnity or liability terms You offer. You may include additional 226 | disclaimers of warranty and limitations of liability specific to any 227 | jurisdiction. 228 | 229 | 4. Inability to Comply Due to Statute or Regulation 230 | 231 | If it is impossible for You to comply with any of the terms of this License 232 | with respect to some or all of the Covered Software due to statute, judicial 233 | order, or regulation then You must: (a) comply with the terms of this License 234 | to the maximum extent possible; and (b) describe the limitations and the code 235 | they affect. Such description must be placed in a text file included with all 236 | distributions of the Covered Software under this License. Except to the 237 | extent prohibited by statute or regulation, such description must be 238 | sufficiently detailed for a recipient of ordinary skill to be able to 239 | understand it. 240 | 241 | 5. Termination 242 | 243 | 5.1. The rights granted under this License will terminate automatically if You 244 | fail to comply with any of its terms. However, if You become compliant, 245 | then the rights granted under this License from a particular Contributor 246 | are reinstated (a) provisionally, unless and until such Contributor 247 | explicitly and finally terminates Your grants, and (b) on an ongoing basis, 248 | if such Contributor fails to notify You of the non-compliance by some 249 | reasonable means prior to 60 days after You have come back into compliance. 250 | Moreover, Your grants from a particular Contributor are reinstated on an 251 | ongoing basis if such Contributor notifies You of the non-compliance by 252 | some reasonable means, this is the first time You have received notice of 253 | non-compliance with this License from such Contributor, and You become 254 | compliant prior to 30 days after Your receipt of the notice. 255 | 256 | 5.2. If You initiate litigation against any entity by asserting a patent 257 | infringement claim (excluding declaratory judgment actions, counter-claims, 258 | and cross-claims) alleging that a Contributor Version directly or 259 | indirectly infringes any patent, then the rights granted to You by any and 260 | all Contributors for the Covered Software under Section 2.1 of this License 261 | shall terminate. 262 | 263 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user 264 | license agreements (excluding distributors and resellers) which have been 265 | validly granted by You or Your distributors under this License prior to 266 | termination shall survive termination. 267 | 268 | 6. Disclaimer of Warranty 269 | 270 | Covered Software is provided under this License on an “as is” basis, without 271 | warranty of any kind, either expressed, implied, or statutory, including, 272 | without limitation, warranties that the Covered Software is free of defects, 273 | merchantable, fit for a particular purpose or non-infringing. The entire 274 | risk as to the quality and performance of the Covered Software is with You. 275 | Should any Covered Software prove defective in any respect, You (not any 276 | Contributor) assume the cost of any necessary servicing, repair, or 277 | correction. This disclaimer of warranty constitutes an essential part of this 278 | License. No use of any Covered Software is authorized under this License 279 | except under this disclaimer. 280 | 281 | 7. Limitation of Liability 282 | 283 | Under no circumstances and under no legal theory, whether tort (including 284 | negligence), contract, or otherwise, shall any Contributor, or anyone who 285 | distributes Covered Software as permitted above, be liable to You for any 286 | direct, indirect, special, incidental, or consequential damages of any 287 | character including, without limitation, damages for lost profits, loss of 288 | goodwill, work stoppage, computer failure or malfunction, or any and all 289 | other commercial damages or losses, even if such party shall have been 290 | informed of the possibility of such damages. This limitation of liability 291 | shall not apply to liability for death or personal injury resulting from such 292 | party’s negligence to the extent applicable law prohibits such limitation. 293 | Some jurisdictions do not allow the exclusion or limitation of incidental or 294 | consequential damages, so this exclusion and limitation may not apply to You. 295 | 296 | 8. Litigation 297 | 298 | Any litigation relating to this License may be brought only in the courts of 299 | a jurisdiction where the defendant maintains its principal place of business 300 | and such litigation shall be governed by laws of that jurisdiction, without 301 | reference to its conflict-of-law provisions. Nothing in this Section shall 302 | prevent a party’s ability to bring cross-claims or counter-claims. 303 | 304 | 9. Miscellaneous 305 | 306 | This License represents the complete agreement concerning the subject matter 307 | hereof. If any provision of this License is held to be unenforceable, such 308 | provision shall be reformed only to the extent necessary to make it 309 | enforceable. Any law or regulation which provides that the language of a 310 | contract shall be construed against the drafter shall not be used to construe 311 | this License against a Contributor. 312 | 313 | 314 | 10. Versions of the License 315 | 316 | 10.1. New Versions 317 | 318 | Mozilla Foundation is the license steward. Except as provided in Section 319 | 10.3, no one other than the license steward has the right to modify or 320 | publish new versions of this License. Each version will be given a 321 | distinguishing version number. 322 | 323 | 10.2. Effect of New Versions 324 | 325 | You may distribute the Covered Software under the terms of the version of 326 | the License under which You originally received the Covered Software, or 327 | under the terms of any subsequent version published by the license 328 | steward. 329 | 330 | 10.3. Modified Versions 331 | 332 | If you create software not governed by this License, and you want to 333 | create a new license for such software, you may create and use a modified 334 | version of this License if you rename the license and remove any 335 | references to the name of the license steward (except to note that such 336 | modified license differs from this License). 337 | 338 | 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses 339 | If You choose to distribute Source Code Form that is Incompatible With 340 | Secondary Licenses under the terms of this version of the License, the 341 | notice described in Exhibit B of this License must be attached. 342 | 343 | Exhibit A - Source Code Form License Notice 344 | 345 | This Source Code Form is subject to the 346 | terms of the Mozilla Public License, v. 347 | 2.0. If a copy of the MPL was not 348 | distributed with this file, You can 349 | obtain one at 350 | http://mozilla.org/MPL/2.0/. 351 | 352 | If it is not possible or desirable to put the notice in a particular file, then 353 | You may include the notice in a location (such as a LICENSE file in a relevant 354 | directory) where a recipient would be likely to look for such a notice. 355 | 356 | You may add additional accurate notices of copyright ownership. 357 | 358 | Exhibit B - “Incompatible With Secondary Licenses” Notice 359 | 360 | This Source Code Form is “Incompatible 361 | With Secondary Licenses”, as defined by 362 | the Mozilla Public License, v. 2.0. 363 | 364 | -------------------------------------------------------------------------------- /webgl-shader-loader/README.md: -------------------------------------------------------------------------------- 1 | webgl-shader-loader 2 | =================== 3 | 4 | Asynchronous load, compile, and link webgl shader programs 5 | 6 | ```html 7 | 8 | ``` 9 | 10 | ##Load WebGL Program From Shader String Literals 11 | ```javascript 12 | var loader = new WebGLShaderLoader(gl); 13 | loader.loadFromStr(vertexShaderStr, fragmentShaderStr, function (errors, program) { 14 | if (errors.length > 0) { 15 | console.error.apply(console, errors); 16 | return; 17 | } 18 | 19 | console.log(program); 20 | }); 21 | ``` 22 | 23 | ##Load WebGL Program From XHR'd Files 24 | ```javascript 25 | var loader = new WebGLShaderLoader(gl); 26 | loader.loadFromXHR(vertexShaderPath, fragmentShaderPath, function (errors, program) { 27 | if (errors.length > 0) { 28 | console.error.apply(console, errors); 29 | return; 30 | } 31 | 32 | console.log(program); 33 | }); 34 | ``` 35 | 36 | ###Notes 37 | * Look at test.js for further usage/example 38 | * errors is an array of strings of usage, compilation, and linkage errors, it's up to you to check these. 39 | 40 | ###License 41 | "THE BEER-WARE LICENSE" (Revision 42): 42 | wrote this file. As long as you retain this notice you 43 | can do whatever you want with this stuff. If we meet some day, and you think 44 | this stuff is worth it, you can buy me a beer in return. Nick Desaulniers 45 | 46 | -------------------------------------------------------------------------------- /webgl-shader-loader/debug.js: -------------------------------------------------------------------------------- 1 | function debugTriangle (a, b, c) { 2 | var str = "("; 3 | for (var i = 0; i < arguments.length; ++i) { 4 | str += "("; 5 | for (var j = 0; j < arguments[i].length; ++j) { 6 | str += arguments[i][j]; 7 | if (j !== arguments[i].length - 1) { 8 | str += ", "; 9 | } 10 | } 11 | str += ")"; 12 | } 13 | str += ")"; 14 | console.log(str); 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /webgl-shader-loader/fragment.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | void main () { 3 | gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 4 | } 5 | 6 | -------------------------------------------------------------------------------- /webgl-shader-loader/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /webgl-shader-loader/test.js: -------------------------------------------------------------------------------- 1 | var gl = document.createElement("canvas").getContext("webgl"); 2 | 3 | var vertexShaderStr = 4 | "void main () { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }"; 5 | 6 | var fragmentShaderStr = 7 | "precision mediump float; void main () { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }"; 8 | 9 | var loader = new WebGLShaderLoader(gl); 10 | 11 | loader.loadFromStr(vertexShaderStr, fragmentShaderStr, function (errors, program) { 12 | if (errors.length > 0) { 13 | console.error.apply(console, errors); 14 | return; 15 | } 16 | 17 | console.log(program); 18 | }); 19 | 20 | var vertexShaderPath = "vertex.glsl"; 21 | var fragmentShaderPath = "fragment.glsl"; 22 | 23 | loader.loadFromXHR(vertexShaderPath, fragmentShaderPath, function (errors, program) { 24 | if (errors.length > 0) { 25 | console.error.apply(console, errors); 26 | return; 27 | } 28 | 29 | console.log(program); 30 | }); 31 | 32 | -------------------------------------------------------------------------------- /webgl-shader-loader/vertex.glsl: -------------------------------------------------------------------------------- 1 | void main () { 2 | gl_Position = vec4(0.0, 0.0, 0.0, 1.0); 3 | } 4 | 5 | -------------------------------------------------------------------------------- /webgl-shader-loader/webGLShaderLoader.js: -------------------------------------------------------------------------------- 1 | var WebGLShaderLoader = (function () { 2 | var scope = this; 3 | var vertexShaderType = WebGLRenderingContext.prototype.VERTEX_SHADER; 4 | var fragmentShaderType = WebGLRenderingContext.prototype.FRAGMENT_SHADER; 5 | 6 | function WebGLShaderLoader (gl) { 7 | this.errors = []; 8 | if ('HTMLCanvasElement' in scope && gl instanceof HTMLCanvasElement || 9 | 'OffscreenCanvas' in scope && gl instanceof OffscreenCanvas) { 10 | this.gl = gl.getContext('webgl') || gl.getContext('experimental-webgl'); 11 | if (!this.gl) this.errors.push("webgl unsupported"); 12 | } else { 13 | this.gl = gl; 14 | } 15 | this.vertexShader = this.fragmentShader = null; 16 | }; 17 | 18 | WebGLShaderLoader.prototype = { 19 | loadFromStr: function (vertexShaderStr, fragmentShaderStr, cb) { 20 | if (typeof vertexShaderStr !== "string" || 21 | typeof fragmentShaderStr !== "string" || 22 | typeof cb !== "function") { 23 | this.errors.push("Usage: loaderInstance.loadFromStr('', '', function (errors, program));"); 24 | cb(this.errors, null, this.gl); 25 | } else if (vertexShaderStr.length === 0 || 26 | fragmentShaderStr.length === 0) { 27 | this.errors.push("empty shader string"); 28 | cb(this.errors, null, this.gl); 29 | } else { 30 | this.vertexShader = this.compile(vertexShaderType, vertexShaderStr); 31 | this.fragmentShader = this.compile(fragmentShaderType, fragmentShaderStr); 32 | 33 | cb(this.errors, this.link(), this.gl); 34 | } 35 | }, 36 | loadFromXHR: function (vertexShaderPath, fragmentShaderPath, cb) { 37 | if (typeof vertexShaderPath !== "string" || 38 | typeof fragmentShaderPath !== "string" || 39 | typeof cb !== "function") { 40 | this.errors.push("Usage: loaderInstance.loadFromXHR('', '', function (errors, program));"); 41 | cb(this.errors, null, this.gl); 42 | return; 43 | } 44 | 45 | if (vertexShaderPath.length === 0 || fragmentShaderPath.length === 0) { 46 | this.errors.push("empty shader path"); 47 | cb(this.errors, null, this.gl); 48 | return; 49 | } 50 | 51 | var numShadersLoaded = 0; 52 | var onload = function (shader, shaderType) { 53 | return function (twoHundredResponse, shaderStr) { 54 | if (!twoHundredResponse) { 55 | this.errors.push("xhr non 200 response code"); 56 | cb(this.errors, null, this.gl); 57 | return; 58 | } 59 | 60 | this[shader] = this.compile(shaderType, shaderStr); 61 | 62 | if (++numShadersLoaded > 1) { 63 | cb(this.errors, this.link(), this.gl); 64 | } 65 | }.bind(this); 66 | }.bind(this); 67 | this.fetch(vertexShaderPath, onload("vertexShader", vertexShaderType)); 68 | this.fetch(fragmentShaderPath, onload("fragmentShader", fragmentShaderType)); 69 | }, 70 | compile: function (type, shaderStr) { 71 | var shader = this.gl.createShader(type); 72 | this.gl.shaderSource(shader, shaderStr); 73 | this.gl.compileShader(shader); 74 | 75 | if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) { 76 | this.errors.push(this.gl.getShaderInfoLog(shader)); 77 | } 78 | 79 | return shader; 80 | }, 81 | link: function () { 82 | var program = this.gl.createProgram(); 83 | this.gl.attachShader(program, this.vertexShader); 84 | this.gl.attachShader(program, this.fragmentShader); 85 | this.gl.linkProgram(program); 86 | 87 | if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) { 88 | this.errors.push(this.gl.getProgramInfoLog(program)); 89 | } 90 | 91 | return program; 92 | }, 93 | fetch: function (path, cb) { 94 | var xhr = new XMLHttpRequest; 95 | xhr.open("GET", path); 96 | xhr.onload = function () { 97 | cb(xhr.status === 200, xhr.response); 98 | }; 99 | xhr.send(); 100 | }, 101 | }; 102 | 103 | return WebGLShaderLoader; 104 | })(); 105 | 106 | -------------------------------------------------------------------------------- /webgl-shader-loader/webGLUtils.js: -------------------------------------------------------------------------------- 1 | ;(function (global) { 2 | function getQualifiersPartial (parameter, storage) { 3 | var getActive = "getActive" + storage; 4 | var getLocation = "get" + storage + "Location"; 5 | return function (gl, program) { 6 | var len = gl.getProgramParameter(program, parameter); 7 | var qualifiers = {}; 8 | var qualifier = null; 9 | for (var i = 0; i < len; ++i) { 10 | qualifier = gl[getActive](program, i).name; 11 | qualifiers[qualifier] = gl[getLocation](program, qualifier); 12 | } 13 | return qualifiers; 14 | }; 15 | }; 16 | 17 | // num is number of components per attribute. ex. vec3 -> 3, mat4 -> 4 18 | function initBuffer (gl, data, num, attribute) { 19 | var buffer = gl.createBuffer(); 20 | if (!buffer) throw new Error("Failed to create buffer."); 21 | gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 22 | gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); 23 | gl.vertexAttribPointer(attribute, num, gl.FLOAT, false, 0, 0); 24 | gl.enableVertexAttribArray(attribute); 25 | return buffer; 26 | }; 27 | 28 | var webGLProto = WebGLRenderingContext.prototype; 29 | global.getAttributes = getQualifiersPartial(webGLProto.ACTIVE_ATTRIBUTES, "Attrib"); 30 | global.getUniforms = getQualifiersPartial(webGLProto.ACTIVE_UNIFORMS, "Uniform"); 31 | global.initBuffer = initBuffer; 32 | })(this); 33 | 34 | -------------------------------------------------------------------------------- /worker.js: -------------------------------------------------------------------------------- 1 | importScripts('webgl-shader-loader/webGLShaderLoader.js'); 2 | importScripts('webgl-shader-loader/webGLUtils.js'); 3 | importScripts('gl-matrix/dist/gl-matrix.js'); 4 | 5 | var render = null; 6 | 7 | function createContext (canvas) { 8 | var loader = new WebGLShaderLoader(canvas); 9 | loader.loadFromXHR('mvp.vert', 'points.frag', function (errors, program, gl) { 10 | if (errors.length > 1) return console.error.apply(console, errors); 11 | 12 | gl.useProgram(program); 13 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 14 | gl.enable(gl.DEPTH_TEST); 15 | 16 | var attributes = getAttributes(gl, program); 17 | var uniforms = getUniforms(gl, program); 18 | var n = initBuffers(gl, attributes); 19 | 20 | // world space -> camera space 21 | var eye = vec3.fromValues(0, 0, 3); 22 | var lookAt = vec3.fromValues(0, 0, 0); 23 | var up = vec3.fromValues(0, 1, 0); 24 | var viewMatrix = mat4.create(); 25 | mat4.lookAt(viewMatrix, eye, lookAt, up); 26 | gl.uniformMatrix4fv(uniforms.uViewMatrix, false, viewMatrix); 27 | 28 | // camera space -> screen 29 | var projMatrix = mat4.create(); 30 | mat4.perspective(projMatrix, 30 * Math.PI / 180, 31 | canvas.width / canvas.height, 1, 10); 32 | gl.uniformMatrix4fv(uniforms.uProjMatrix, false, projMatrix); 33 | 34 | render = createAnimate(gl, uniforms.uModelMatrix, n); 35 | }); 36 | }; 37 | 38 | onmessage = function (e) { 39 | if (e.data.rAF && render) { 40 | render(); 41 | } else if (e.data.canvas) { 42 | createContext(e.data.canvas); 43 | } 44 | }; 45 | 46 | // code that used to be on the main thread 47 | function initBuffers (gl, attributes) { 48 | var positions = new Float32Array([ 49 | 0.0, 0.5, 0.0, 50 | -0.5, -0.5, 0.0, 51 | 0.5, -0.5, 0.0, 52 | ]); 53 | var colors = new Float32Array([ 54 | 1.0, 0.0, 0.0, 55 | 1.0, 1.0, 0.0, 56 | 1.0, 0.0, 1.0, 57 | ]); 58 | 59 | initBuffer(gl, positions, 3, attributes.aPosition); 60 | initBuffer(gl, colors, 3, attributes.aColor); 61 | 62 | return 3; 63 | }; 64 | 65 | function createAnimate (gl, modelUniform, n) { 66 | var modelMatrix = mat4.create(); 67 | return function () { 68 | // update 69 | mat4.rotateY(modelMatrix, modelMatrix, Math.PI / 180); 70 | gl.uniformMatrix4fv(modelUniform, false, modelMatrix); 71 | // render 72 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 73 | gl.drawArrays(gl.TRIANGLES, 0, n); 74 | 75 | gl.commit(); // new for webgl in workers 76 | }; 77 | }; 78 | --------------------------------------------------------------------------------