├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── dist
├── glmw-browser.js
├── glmw-node.es.js
└── glmw-node.js
├── example
├── gl-matrix.min.js
└── index.html
├── interfaces
├── generate.js
├── ignore_this.txt
├── index.js
├── interfaces-special.json
├── interfaces.json
└── modules.js
├── package.json
├── rollup
├── compile.wasm.js
├── rollup.bundle.js
├── rollup.config.cjs.js
├── rollup.config.es.js
├── rollup.config.iife.js
└── rollup.config.js
└── src
├── gl-matrix
├── bridges
│ ├── mat4.js
│ ├── vec3.js
│ └── vec4.js
├── common.h
├── main.c
├── mat4.c
├── vec3.c
└── vec4.c
├── index.js
└── utils.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | src/module.js
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 |
13 | # Directory for instrumented libs generated by jscoverage/JSCover
14 | lib-cov
15 |
16 | # Coverage directory used by tools like istanbul
17 | coverage
18 |
19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
20 | .grunt
21 |
22 | # node-waf configuration
23 | .lock-wscript
24 |
25 | # Compiled binary addons (http://nodejs.org/api/addons.html)
26 | build/Release
27 |
28 | # Dependency directories
29 | node_modules
30 | jspm_packages
31 |
32 | # Optional npm cache directory
33 | .npm
34 |
35 | # Optional REPL history
36 | .node_repl_history
37 |
38 | # =========================
39 | # Operating System Files
40 | # =========================
41 |
42 | # OSX
43 | # =========================
44 |
45 | .DS_Store
46 | .AppleDouble
47 | .LSOverride
48 |
49 | # Thumbnails
50 | ._*
51 |
52 | # Files that might appear in the root of a volume
53 | .DocumentRevisions-V100
54 | .fseventsd
55 | .Spotlight-V100
56 | .TemporaryItems
57 | .Trashes
58 | .VolumeIcon.icns
59 |
60 | # Directories potentially created on remote AFP share
61 | .AppleDB
62 | .AppleDesktop
63 | Network Trash Folder
64 | Temporary Items
65 | .apdisk
66 |
67 | # Windows
68 | # =========================
69 |
70 | # Windows image file caches
71 | Thumbs.db
72 | ehthumbs.db
73 |
74 | # Folder config file
75 | Desktop.ini
76 |
77 | # Recycle Bin used on file shares
78 | $RECYCLE.BIN/
79 |
80 | # Windows Installer files
81 | *.cab
82 | *.msi
83 | *.msm
84 | *.msp
85 |
86 | # Windows shortcuts
87 | *.lnk
88 |
89 | www
90 |
91 | package-lock.json
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Felix Maier
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | GLMW - WebAssembly powered Matrix and Vector library
3 |
4 |
5 |
6 |
7 | ### Description
8 | This is an experimental near 1:1 port of [gl-matrix](https://github.com/toji/gl-matrix) [v2.4.0](https://github.com/toji/gl-matrix/blob/master/package.json#L4) to WebAssembly.
9 |
10 | ### Performance
11 | In many cases *glmw* runs more than twice as fast as *gl-matrix*.
12 |
13 | Some methods like ``*.str`` and ``*.equals`` are bridged and bring in some extra overhead.
14 |
15 | Creating views with ``*.view`` is cheap, because they return a typed ``subarray`` of the WebAssembly module's memory buffer.
16 |
17 | ### Benchmarks
18 | - [**mat4**](https://maierfelix.github.io/glmw/mat4/)
19 |
20 | ### Limitations
21 | - This library requires async instantiation, since WebAssembly has a [synchronous buffer instantiation size limitation](https://github.com/WebAssembly/design/issues/1190).
22 | - You need to manually free data, since there is no garbage collection yet (**be careful! :p**).
23 | - Methods like ``mat4.create`` and ``mat4.multiply`` return a numeric address. To get an view on your data you need to use e.g. ``mat4.view(address)``. This returns a ``Float32Array`` which is a direct view onto the allocated data in WebAssembly's memory. You can manually read/write from this view.
24 | - WebAssembly's memory cannot be directly shared with JavaScript's memory. This means that you cannot pass an JavaScript array into methods like ``vec3.sqrLength``. You first have to convert it into the given module type (e.g. ``vec3.fromValues``) which then gives you the memory address of the allocated data.
25 | - There is some overhead when calling from JavaScript->WebAssembly, but it seems acceptable. Slight performance drops are noticeable when calling a function more than ~15.000 times.
26 |
27 | ### Bridged methods
28 | - ``*.str`` so a *JavaScript String* is returned.
29 | - ``*.equals`` so a *JavaScript Boolean* is returned.
30 | - ``*.exactEquals`` (see ``*.equals``).
31 |
32 | ### New methods
33 | - ``*.view`` lets you create views onto your data in WebAssembly's memory.
34 | - ``*.free`` to free data from WebAssembly's memory.
35 |
36 | ### What is left
37 |
38 | #### API modules
39 | - ``mat2``
40 | - ``mat2d``
41 | - ``mat3``
42 | - ``vec2``
43 | - ``quat``
44 |
45 | ### Installation
46 | ````
47 | npm install glmw
48 | ````
49 | or the browser distribution from [here](//rawgit.com/maierfelix/glmw/master/dist/glmw-browser.js).
50 |
51 | ### Instantiation
52 | Before being able to use the library, you first have to call it's ``init`` method which then asynchronously compiles the WebAssembly module.
53 |
54 | If you call a ``glmw`` function before it got instantiated somewhere, then a ``TypeError`` is thrown, because the function is simply not compiled yet.
55 |
56 | #### Browser
57 | This builds and compiles the WebAssembly module.
58 | ````html
59 |
60 | ````
61 | ````js
62 | glmw.init().then(ready => {
63 | // glmw is now ready and can be used anywhere
64 | });
65 | ````
66 |
67 | #### ES
68 | Import and call the init method in your main file. Afterwards you can use ``glmw`` **anywhere**.
69 |
70 | *index.js*
71 | ````js
72 | import { init, vec3 } from "glmw";
73 | import calc from "./calc";
74 |
75 | init().then(ready => {
76 | // glmw is now ready and can be used anywhere
77 | calc();
78 | });
79 | ````
80 |
81 | *calc.js*
82 | ````js
83 | import { mat4 } from "glmw";
84 | export default function() {
85 | return mat4.create();
86 | };
87 | ````
88 |
89 | #### Node
90 | Require and call the init method in your main file. Afterwards you can use ``glmw`` **anywhere**.
91 |
92 | *index.js*
93 | ````js
94 | const { init, vec3 } = require("glmw");
95 | const calc = require("./calc");
96 |
97 | init().then(ready => {
98 | // glmw is now ready and can be used anywhere
99 | calc();
100 | });
101 | ````
102 |
103 | *calc.js*
104 | ````js
105 | const { mat4 } = require("glmw");
106 | module.exports = function() {
107 | return mat4.create();
108 | };
109 | ````
110 |
111 | ### Usage
112 |
113 | #### Simple example
114 | As you can see here, the API didn't really change.
115 | ````js
116 | let a = vec3.create();
117 | let b = vec3.fromValues(1.0, 2.0, 3.0);
118 | vec3.add(a, a, b);
119 | console.log( vec3.view(a) ); // Float32Array(3) [1, 2, 3]
120 | ````
121 |
122 | #### Creating views
123 | First, this is what *glmw* returns to you. Instead of references, only the numeric addresses are returned:
124 | ````js
125 | a = mat4.create(); // 65688
126 | b = mat4.create(); // 65760
127 | c = mat4.multiply(a, a, b); // 65688
128 | ````
129 | You can change data by hand this way:
130 | ````js
131 | vA = mat4.view(a); // Float32Array([1, 0, 0...])
132 | vA[0] = 2; // you can now read/write
133 | vA; // Float32Array([2, 0, 0...])
134 | ````
135 |
136 | #### Freeing data
137 | Since WebAssembly doesn't have garbage collection yet, you have to be careful when and where you allocate data.
138 | You can free data by calling ``*.free``:
139 | ````js
140 | a = mat4.create(); // allocate data for a
141 | mat4.free(a); // a's data is now freed
142 | ````
--------------------------------------------------------------------------------
/example/gl-matrix.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @fileoverview gl-matrix - High performance matrix and vector operations
3 | * @author Brandon Jones
4 | * @author Colin MacKenzie IV
5 | * @version 2.4.0
6 | */
7 |
8 | /* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in
18 | all copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 | THE SOFTWARE. */
27 |
28 | !function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define([],n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={i:a,l:!1,exports:{}};return t[a].call(e.exports,e,e.exports,n),e.l=!0,e.exports}var r={};return n.m=t,n.c=r,n.d=function(t,r,a){n.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:a})},n.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(r,"a",r),r},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=4)}([function(t,n,r){"use strict";function a(t){n.ARRAY_TYPE=i=t}function e(t){return t*s}function u(t,n){return Math.abs(t-n)<=o*Math.max(1,Math.abs(t),Math.abs(n))}Object.defineProperty(n,"__esModule",{value:!0}),n.setMatrixArrayType=a,n.toRadian=e,n.equals=u;var o=n.EPSILON=1e-6,i=n.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,s=(n.RANDOM=Math.random,Math.PI/180)},function(t,n,r){"use strict";function a(){var t=new g.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}function e(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t}function u(t){var n=new g.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n}function o(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t}function i(t,n,r,a,e,u,o,i,s){var c=new g.ARRAY_TYPE(9);return c[0]=t,c[1]=n,c[2]=r,c[3]=a,c[4]=e,c[5]=u,c[6]=o,c[7]=i,c[8]=s,c}function s(t,n,r,a,e,u,o,i,s,c){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t[4]=u,t[5]=o,t[6]=i,t[7]=s,t[8]=c,t}function c(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}function f(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t}function M(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],s=n[6],c=n[7],f=n[8],M=f*o-i*c,h=-f*u+i*s,l=c*u-o*s,v=r*M+a*h+e*l;return v?(v=1/v,t[0]=M*v,t[1]=(-f*a+e*c)*v,t[2]=(i*a-e*o)*v,t[3]=h*v,t[4]=(f*r-e*s)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-c*r+a*s)*v,t[8]=(o*r-a*u)*v,t):null}function h(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],s=n[6],c=n[7],f=n[8];return t[0]=o*f-i*c,t[1]=e*c-a*f,t[2]=a*i-e*o,t[3]=i*s-u*f,t[4]=r*f-e*s,t[5]=e*u-r*i,t[6]=u*c-o*s,t[7]=a*s-r*c,t[8]=r*o-a*u,t}function l(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],s=t[7],c=t[8];return n*(c*u-o*s)+r*(-c*e+o*i)+a*(s*e-u*i)}function v(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=n[6],f=n[7],M=n[8],h=r[0],l=r[1],v=r[2],d=r[3],b=r[4],m=r[5],p=r[6],P=r[7],E=r[8];return t[0]=h*a+l*o+v*c,t[1]=h*e+l*i+v*f,t[2]=h*u+l*s+v*M,t[3]=d*a+b*o+m*c,t[4]=d*e+b*i+m*f,t[5]=d*u+b*s+m*M,t[6]=p*a+P*o+E*c,t[7]=p*e+P*i+E*f,t[8]=p*u+P*s+E*M,t}function d(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=n[6],f=n[7],M=n[8],h=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=s,t[6]=h*a+l*o+c,t[7]=h*e+l*i+f,t[8]=h*u+l*s+M,t}function b(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=n[6],f=n[7],M=n[8],h=Math.sin(r),l=Math.cos(r);return t[0]=l*a+h*o,t[1]=l*e+h*i,t[2]=l*u+h*s,t[3]=l*o-h*a,t[4]=l*i-h*e,t[5]=l*s-h*u,t[6]=c,t[7]=f,t[8]=M,t}function m(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t}function p(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t}function P(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}function E(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t}function O(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t}function x(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,s=e+e,c=r*o,f=a*o,M=a*i,h=e*o,l=e*i,v=e*s,d=u*o,b=u*i,m=u*s;return t[0]=1-M-v,t[3]=f-m,t[6]=h+b,t[1]=f+m,t[4]=1-c-v,t[7]=l-d,t[2]=h-b,t[5]=l+d,t[8]=1-c-M,t}function A(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],s=n[6],c=n[7],f=n[8],M=n[9],h=n[10],l=n[11],v=n[12],d=n[13],b=n[14],m=n[15],p=r*i-a*o,P=r*s-e*o,E=r*c-u*o,O=a*s-e*i,x=a*c-u*i,A=e*c-u*s,q=f*d-M*v,y=f*b-h*v,w=f*m-l*v,R=M*b-h*d,L=M*m-l*d,S=h*m-l*b,_=p*S-P*L+E*R+O*w-x*y+A*q;return _?(_=1/_,t[0]=(i*S-s*L+c*R)*_,t[1]=(s*w-o*S-c*y)*_,t[2]=(o*L-i*w+c*q)*_,t[3]=(e*L-a*S-u*R)*_,t[4]=(r*S-e*w+u*y)*_,t[5]=(a*w-r*L-u*q)*_,t[6]=(d*A-b*x+m*O)*_,t[7]=(b*E-v*A-m*P)*_,t[8]=(v*x-d*E+m*p)*_,t):null}function q(t,n,r){return t[0]=2/n,t[1]=0,t[2]=0,t[3]=0,t[4]=-2/r,t[5]=0,t[6]=-1,t[7]=1,t[8]=1,t}function y(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"}function w(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))}function R(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t[4]=n[4]+r[4],t[5]=n[5]+r[5],t[6]=n[6]+r[6],t[7]=n[7]+r[7],t[8]=n[8]+r[8],t}function L(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t[4]=n[4]-r[4],t[5]=n[5]-r[5],t[6]=n[6]-r[6],t[7]=n[7]-r[7],t[8]=n[8]-r[8],t}function S(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t[4]=n[4]*r,t[5]=n[5]*r,t[6]=n[6]*r,t[7]=n[7]*r,t[8]=n[8]*r,t}function _(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t[4]=n[4]+r[4]*a,t[5]=n[5]+r[5]*a,t[6]=n[6]+r[6]*a,t[7]=n[7]+r[7]*a,t[8]=n[8]+r[8]*a,t}function I(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]&&t[8]===n[8]}function N(t,n){var r=t[0],a=t[1],e=t[2],u=t[3],o=t[4],i=t[5],s=t[6],c=t[7],f=t[8],M=n[0],h=n[1],l=n[2],v=n[3],d=n[4],b=n[5],m=n[6],p=n[7],P=n[8];return Math.abs(r-M)<=g.EPSILON*Math.max(1,Math.abs(r),Math.abs(M))&&Math.abs(a-h)<=g.EPSILON*Math.max(1,Math.abs(a),Math.abs(h))&&Math.abs(e-l)<=g.EPSILON*Math.max(1,Math.abs(e),Math.abs(l))&&Math.abs(u-v)<=g.EPSILON*Math.max(1,Math.abs(u),Math.abs(v))&&Math.abs(o-d)<=g.EPSILON*Math.max(1,Math.abs(o),Math.abs(d))&&Math.abs(i-b)<=g.EPSILON*Math.max(1,Math.abs(i),Math.abs(b))&&Math.abs(s-m)<=g.EPSILON*Math.max(1,Math.abs(s),Math.abs(m))&&Math.abs(c-p)<=g.EPSILON*Math.max(1,Math.abs(c),Math.abs(p))&&Math.abs(f-P)<=g.EPSILON*Math.max(1,Math.abs(f),Math.abs(P))}Object.defineProperty(n,"__esModule",{value:!0}),n.sub=n.mul=void 0,n.create=a,n.fromMat4=e,n.clone=u,n.copy=o,n.fromValues=i,n.set=s,n.identity=c,n.transpose=f,n.invert=M,n.adjoint=h,n.determinant=l,n.multiply=v,n.translate=d,n.rotate=b,n.scale=m,n.fromTranslation=p,n.fromRotation=P,n.fromScaling=E,n.fromMat2d=O,n.fromQuat=x,n.normalFromMat4=A,n.projection=q,n.str=y,n.frob=w,n.add=R,n.subtract=L,n.multiplyScalar=S,n.multiplyScalarAndAdd=_,n.exactEquals=I,n.equals=N;var Y=r(0),g=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(Y);n.mul=v,n.sub=L},function(t,n,r){"use strict";function a(){var t=new Z.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t}function e(t){var n=new Z.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n}function u(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)}function o(t,n,r){var a=new Z.ARRAY_TYPE(3);return a[0]=t,a[1]=n,a[2]=r,a}function i(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t}function s(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t}function c(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t}function f(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t}function M(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t}function h(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t}function l(t,n){return t[0]=Math.ceil(n[0]),t[1]=Math.ceil(n[1]),t[2]=Math.ceil(n[2]),t}function v(t,n){return t[0]=Math.floor(n[0]),t[1]=Math.floor(n[1]),t[2]=Math.floor(n[2]),t}function d(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t}function b(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t}function m(t,n){return t[0]=Math.round(n[0]),t[1]=Math.round(n[1]),t[2]=Math.round(n[2]),t}function p(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t}function P(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t}function E(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)}function O(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e}function x(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a}function A(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t}function q(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t}function y(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t}function w(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}function R(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],s=r[2];return t[0]=e*s-u*i,t[1]=u*o-a*s,t[2]=a*i-e*o,t}function L(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t}function S(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,s=o*(u-2)+u,c=o*(u-1),f=o*(3-2*u);return t[0]=n[0]*i+r[0]*s+a[0]*c+e[0]*f,t[1]=n[1]*i+r[1]*s+a[1]*c+e[1]*f,t[2]=n[2]*i+r[2]*s+a[2]*c+e[2]*f,t}function _(t,n,r,a,e,u){var o=1-u,i=o*o,s=u*u,c=i*o,f=3*u*i,M=3*s*o,h=s*u;return t[0]=n[0]*c+r[0]*f+a[0]*M+e[0]*h,t[1]=n[1]*c+r[1]*f+a[1]*M+e[1]*h,t[2]=n[2]*c+r[2]*f+a[2]*M+e[2]*h,t}function I(t,n){n=n||1;var r=2*Z.RANDOM()*Math.PI,a=2*Z.RANDOM()-1,e=Math.sqrt(1-a*a)*n;return t[0]=Math.cos(r)*e,t[1]=Math.sin(r)*e,t[2]=a*n,t}function N(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t}function Y(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t}function g(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],s=r[2],c=r[3],f=c*a+i*u-s*e,M=c*e+s*a-o*u,h=c*u+o*e-i*a,l=-o*a-i*e-s*u;return t[0]=f*c+l*-o+M*-s-h*-i,t[1]=M*c+l*-i+h*-o-f*-s,t[2]=h*c+l*-s+f*-i-M*-o,t}function T(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t}function j(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t}function D(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t}function V(t,n){var r=o(t[0],t[1],t[2]),a=o(n[0],n[1],n[2]);y(r,r),y(a,a);var e=w(r,a);return e>1?0:e<-1?Math.PI:Math.acos(e)}function z(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"}function F(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]}function Q(t,n){var r=t[0],a=t[1],e=t[2],u=n[0],o=n[1],i=n[2];return Math.abs(r-u)<=Z.EPSILON*Math.max(1,Math.abs(r),Math.abs(u))&&Math.abs(a-o)<=Z.EPSILON*Math.max(1,Math.abs(a),Math.abs(o))&&Math.abs(e-i)<=Z.EPSILON*Math.max(1,Math.abs(e),Math.abs(i))}Object.defineProperty(n,"__esModule",{value:!0}),n.forEach=n.sqrLen=n.len=n.sqrDist=n.dist=n.div=n.mul=n.sub=void 0,n.create=a,n.clone=e,n.length=u,n.fromValues=o,n.copy=i,n.set=s,n.add=c,n.subtract=f,n.multiply=M,n.divide=h,n.ceil=l,n.floor=v,n.min=d,n.max=b,n.round=m,n.scale=p,n.scaleAndAdd=P,n.distance=E,n.squaredDistance=O,n.squaredLength=x,n.negate=A,n.inverse=q,n.normalize=y,n.dot=w,n.cross=R,n.lerp=L,n.hermite=S,n.bezier=_,n.random=I,n.transformMat4=N,n.transformMat3=Y,n.transformQuat=g,n.rotateX=T,n.rotateY=j,n.rotateZ=D,n.angle=V,n.str=z,n.exactEquals=F,n.equals=Q;var X=r(0),Z=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(X);n.sub=f,n.mul=M,n.div=h,n.dist=E,n.sqrDist=O,n.len=u,n.sqrLen=x,n.forEach=function(){var t=a();return function(n,r,a,e,u,o){var i=void 0,s=void 0;for(r||(r=3),a||(a=0),s=e?Math.min(e*r+a,n.length):n.length,i=a;i0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t}function w(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]}function R(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t}function L(t,n){return n=n||1,t[0]=T.RANDOM(),t[1]=T.RANDOM(),t[2]=T.RANDOM(),t[3]=T.RANDOM(),y(t,t),m(t,t,n),t}function S(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t}function _(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],s=r[2],c=r[3],f=c*a+i*u-s*e,M=c*e+s*a-o*u,h=c*u+o*e-i*a,l=-o*a-i*e-s*u;return t[0]=f*c+l*-o+M*-s-h*-i,t[1]=M*c+l*-i+h*-o-f*-s,t[2]=h*c+l*-s+f*-i-M*-o,t[3]=n[3],t}function I(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"}function N(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]}function Y(t,n){var r=t[0],a=t[1],e=t[2],u=t[3],o=n[0],i=n[1],s=n[2],c=n[3];return Math.abs(r-o)<=T.EPSILON*Math.max(1,Math.abs(r),Math.abs(o))&&Math.abs(a-i)<=T.EPSILON*Math.max(1,Math.abs(a),Math.abs(i))&&Math.abs(e-s)<=T.EPSILON*Math.max(1,Math.abs(e),Math.abs(s))&&Math.abs(u-c)<=T.EPSILON*Math.max(1,Math.abs(u),Math.abs(c))}Object.defineProperty(n,"__esModule",{value:!0}),n.forEach=n.sqrLen=n.len=n.sqrDist=n.dist=n.div=n.mul=n.sub=void 0,n.create=a,n.clone=e,n.fromValues=u,n.copy=o,n.set=i,n.add=s,n.subtract=c,n.multiply=f,n.divide=M,n.ceil=h,n.floor=l,n.min=v,n.max=d,n.round=b,n.scale=m,n.scaleAndAdd=p,n.distance=P,n.squaredDistance=E,n.length=O,n.squaredLength=x,n.negate=A,n.inverse=q,n.normalize=y,n.dot=w,n.lerp=R,n.random=L,n.transformMat4=S,n.transformQuat=_,n.str=I,n.exactEquals=N,n.equals=Y;var g=r(0),T=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(g);n.sub=c,n.mul=f,n.div=M,n.dist=P,n.sqrDist=E,n.len=O,n.sqrLen=x,n.forEach=function(){var t=a();return function(n,r,a,e,u,o){var i=void 0,s=void 0;for(r||(r=4),a||(a=0),s=e?Math.min(e*r+a,n.length):n.length,i=a;i0?(a=2*Math.sqrt(r+1),t[3]=.25*a,t[0]=(n[6]-n[9])/a,t[1]=(n[8]-n[2])/a,t[2]=(n[1]-n[4])/a):n[0]>n[5]&n[0]>n[10]?(a=2*Math.sqrt(1+n[0]-n[5]-n[10]),t[3]=(n[6]-n[9])/a,t[0]=.25*a,t[1]=(n[1]+n[4])/a,t[2]=(n[8]+n[2])/a):n[5]>n[10]?(a=2*Math.sqrt(1+n[5]-n[0]-n[10]),t[3]=(n[8]-n[2])/a,t[0]=(n[1]+n[4])/a,t[1]=.25*a,t[2]=(n[6]+n[9])/a):(a=2*Math.sqrt(1+n[10]-n[0]-n[5]),t[3]=(n[1]-n[4])/a,t[0]=(n[8]+n[2])/a,t[1]=(n[6]+n[9])/a,t[2]=.25*a),t}function _(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],s=e+e,c=u+u,f=o+o,M=e*s,h=e*c,l=e*f,v=u*c,d=u*f,b=o*f,m=i*s,p=i*c,P=i*f,E=a[0],O=a[1],x=a[2];return t[0]=(1-(v+b))*E,t[1]=(h+P)*E,t[2]=(l-p)*E,t[3]=0,t[4]=(h-P)*O,t[5]=(1-(M+b))*O,t[6]=(d+m)*O,t[7]=0,t[8]=(l+p)*x,t[9]=(d-m)*x,t[10]=(1-(M+v))*x,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t}function I(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],s=n[3],c=u+u,f=o+o,M=i+i,h=u*c,l=u*f,v=u*M,d=o*f,b=o*M,m=i*M,p=s*c,P=s*f,E=s*M,O=a[0],x=a[1],A=a[2],q=e[0],y=e[1],w=e[2];return t[0]=(1-(d+m))*O,t[1]=(l+E)*O,t[2]=(v-P)*O,t[3]=0,t[4]=(l-E)*x,t[5]=(1-(h+m))*x,t[6]=(b+p)*x,t[7]=0,t[8]=(v+P)*A,t[9]=(b-p)*A,t[10]=(1-(h+d))*A,t[11]=0,t[12]=r[0]+q-(t[0]*q+t[4]*y+t[8]*w),t[13]=r[1]+y-(t[1]*q+t[5]*y+t[9]*w),t[14]=r[2]+w-(t[2]*q+t[6]*y+t[10]*w),t[15]=1,t}function N(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,s=e+e,c=r*o,f=a*o,M=a*i,h=e*o,l=e*i,v=e*s,d=u*o,b=u*i,m=u*s;return t[0]=1-M-v,t[1]=f+m,t[2]=h-b,t[3]=0,t[4]=f-m,t[5]=1-c-v,t[6]=l+d,t[7]=0,t[8]=h+b,t[9]=l-d,t[10]=1-c-M,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function Y(t,n,r,a,e,u,o){var i=1/(r-n),s=1/(e-a),c=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*s,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*s,t[10]=(o+u)*c,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*c,t[15]=0,t}function g(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t}function T(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),s=2/(o+i),c=2/(e+u);return t[0]=s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=c,t[6]=0,t[7]=0,t[8]=-(o-i)*s*.5,t[9]=(e-u)*c*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t}function j(t,n,r,a,e,u,o){var i=1/(n-r),s=1/(a-e),c=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*s,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*c,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*s,t[14]=(o+u)*c,t[15]=1,t}function D(t,n,r,a){var e=void 0,u=void 0,o=void 0,i=void 0,s=void 0,c=void 0,f=void 0,M=void 0,h=void 0,l=void 0,v=n[0],d=n[1],b=n[2],m=a[0],p=a[1],P=a[2],E=r[0],O=r[1],x=r[2];return Math.abs(v-E)0&&(l=1/Math.sqrt(l),f*=l,M*=l,h*=l);var v=s*h-c*M,d=c*f-i*h,b=i*M-s*f;return t[0]=v,t[1]=d,t[2]=b,t[3]=0,t[4]=M*b-h*d,t[5]=h*v-f*b,t[6]=f*d-M*v,t[7]=0,t[8]=f,t[9]=M,t[10]=h,t[11]=0,t[12]=e,t[13]=u,t[14]=o,t[15]=1,t}function z(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"}function F(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))}function Q(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t[4]=n[4]+r[4],t[5]=n[5]+r[5],t[6]=n[6]+r[6],t[7]=n[7]+r[7],t[8]=n[8]+r[8],t[9]=n[9]+r[9],t[10]=n[10]+r[10],t[11]=n[11]+r[11],t[12]=n[12]+r[12],t[13]=n[13]+r[13],t[14]=n[14]+r[14],t[15]=n[15]+r[15],t}function X(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t[4]=n[4]-r[4],t[5]=n[5]-r[5],t[6]=n[6]-r[6],t[7]=n[7]-r[7],t[8]=n[8]-r[8],t[9]=n[9]-r[9],t[10]=n[10]-r[10],t[11]=n[11]-r[11],t[12]=n[12]-r[12],t[13]=n[13]-r[13],t[14]=n[14]-r[14],t[15]=n[15]-r[15],t}function Z(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t[4]=n[4]*r,t[5]=n[5]*r,t[6]=n[6]*r,t[7]=n[7]*r,t[8]=n[8]*r,t[9]=n[9]*r,t[10]=n[10]*r,t[11]=n[11]*r,t[12]=n[12]*r,t[13]=n[13]*r,t[14]=n[14]*r,t[15]=n[15]*r,t}function k(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t[4]=n[4]+r[4]*a,t[5]=n[5]+r[5]*a,t[6]=n[6]+r[6]*a,t[7]=n[7]+r[7]*a,t[8]=n[8]+r[8]*a,t[9]=n[9]+r[9]*a,t[10]=n[10]+r[10]*a,t[11]=n[11]+r[11]*a,t[12]=n[12]+r[12]*a,t[13]=n[13]+r[13]*a,t[14]=n[14]+r[14]*a,t[15]=n[15]+r[15]*a,t}function U(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]&&t[8]===n[8]&&t[9]===n[9]&&t[10]===n[10]&&t[11]===n[11]&&t[12]===n[12]&&t[13]===n[13]&&t[14]===n[14]&&t[15]===n[15]}function W(t,n){var r=t[0],a=t[1],e=t[2],u=t[3],o=t[4],i=t[5],s=t[6],c=t[7],f=t[8],M=t[9],h=t[10],l=t[11],v=t[12],d=t[13],b=t[14],m=t[15],p=n[0],P=n[1],E=n[2],O=n[3],x=n[4],A=n[5],q=n[6],y=n[7],w=n[8],R=n[9],L=n[10],S=n[11],_=n[12],I=n[13],N=n[14],Y=n[15];return Math.abs(r-p)<=C.EPSILON*Math.max(1,Math.abs(r),Math.abs(p))&&Math.abs(a-P)<=C.EPSILON*Math.max(1,Math.abs(a),Math.abs(P))&&Math.abs(e-E)<=C.EPSILON*Math.max(1,Math.abs(e),Math.abs(E))&&Math.abs(u-O)<=C.EPSILON*Math.max(1,Math.abs(u),Math.abs(O))&&Math.abs(o-x)<=C.EPSILON*Math.max(1,Math.abs(o),Math.abs(x))&&Math.abs(i-A)<=C.EPSILON*Math.max(1,Math.abs(i),Math.abs(A))&&Math.abs(s-q)<=C.EPSILON*Math.max(1,Math.abs(s),Math.abs(q))&&Math.abs(c-y)<=C.EPSILON*Math.max(1,Math.abs(c),Math.abs(y))&&Math.abs(f-w)<=C.EPSILON*Math.max(1,Math.abs(f),Math.abs(w))&&Math.abs(M-R)<=C.EPSILON*Math.max(1,Math.abs(M),Math.abs(R))&&Math.abs(h-L)<=C.EPSILON*Math.max(1,Math.abs(h),Math.abs(L))&&Math.abs(l-S)<=C.EPSILON*Math.max(1,Math.abs(l),Math.abs(S))&&Math.abs(v-_)<=C.EPSILON*Math.max(1,Math.abs(v),Math.abs(_))&&Math.abs(d-I)<=C.EPSILON*Math.max(1,Math.abs(d),Math.abs(I))&&Math.abs(b-N)<=C.EPSILON*Math.max(1,Math.abs(b),Math.abs(N))&&Math.abs(m-Y)<=C.EPSILON*Math.max(1,Math.abs(m),Math.abs(Y))}Object.defineProperty(n,"__esModule",{value:!0}),n.sub=n.mul=void 0,n.create=a,n.clone=e,n.copy=u,n.fromValues=o,n.set=i,n.identity=s,n.transpose=c,n.invert=f,n.adjoint=M,n.determinant=h,n.multiply=l,n.translate=v,n.scale=d,n.rotate=b,n.rotateX=m,n.rotateY=p,n.rotateZ=P,n.fromTranslation=E,n.fromScaling=O,n.fromRotation=x,n.fromXRotation=A,n.fromYRotation=q,n.fromZRotation=y,n.fromRotationTranslation=w,n.getTranslation=R,n.getScaling=L,n.getRotation=S,n.fromRotationTranslationScale=_,n.fromRotationTranslationScaleOrigin=I,n.fromQuat=N,n.frustum=Y,n.perspective=g,n.perspectiveFromFieldOfView=T,n.ortho=j,n.lookAt=D,n.targetTo=V,n.str=z,n.frob=F,n.add=Q,n.subtract=X,n.multiplyScalar=Z,n.multiplyScalarAndAdd=k,n.exactEquals=U,n.equals=W;var B=r(0),C=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(B);n.mul=l,n.sub=X},function(t,n,r){"use strict";function a(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}function e(){var t=new E.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t}function u(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t}function o(t,n,r){r*=.5;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t}function i(t,n){var r=2*Math.acos(n[3]),a=Math.sin(r/2);return 0!=a?(t[0]=n[0]/a,t[1]=n[1]/a,t[2]=n[2]/a):(t[0]=1,t[1]=0,t[2]=0),r}function s(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],s=r[1],c=r[2],f=r[3];return t[0]=a*f+o*i+e*c-u*s,t[1]=e*f+o*s+u*i-a*c,t[2]=u*f+o*c+a*s-e*i,t[3]=o*f-a*i-e*s-u*c,t}function c(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),s=Math.cos(r);return t[0]=a*s+o*i,t[1]=e*s+u*i,t[2]=u*s-e*i,t[3]=o*s-a*i,t}function f(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),s=Math.cos(r);return t[0]=a*s-u*i,t[1]=e*s+o*i,t[2]=u*s+a*i,t[3]=o*s-e*i,t}function M(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),s=Math.cos(r);return t[0]=a*s+e*i,t[1]=e*s-a*i,t[2]=u*s+o*i,t[3]=o*s-u*i,t}function h(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t}function l(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],s=r[0],c=r[1],f=r[2],M=r[3],h=void 0,l=void 0,v=void 0,d=void 0,b=void 0;return l=e*s+u*c+o*f+i*M,l<0&&(l=-l,s=-s,c=-c,f=-f,M=-M),1-l>1e-6?(h=Math.acos(l),v=Math.sin(h),d=Math.sin((1-a)*h)/v,b=Math.sin(a*h)/v):(d=1-a,b=a),t[0]=d*e+b*s,t[1]=d*u+b*c,t[2]=d*o+b*f,t[3]=d*i+b*M,t}function v(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t}function d(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t}function b(t,n){var r=n[0]+n[4]+n[8],a=void 0;if(r>0)a=Math.sqrt(r+1),t[3]=.5*a,a=.5/a,t[0]=(n[5]-n[7])*a,t[1]=(n[6]-n[2])*a,t[2]=(n[1]-n[3])*a;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;a=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*a,a=.5/a,t[3]=(n[3*u+o]-n[3*o+u])*a,t[u]=(n[3*u+e]+n[3*e+u])*a,t[o]=(n[3*o+e]+n[3*e+o])*a}return t}function m(t,n,r,a){var e=.5*Math.PI/180;n*=e,r*=e,a*=e;var u=Math.sin(n),o=Math.cos(n),i=Math.sin(r),s=Math.cos(r),c=Math.sin(a),f=Math.cos(a);return t[0]=u*s*f-o*i*c,t[1]=o*i*f+u*s*c,t[2]=o*s*c-u*i*f,t[3]=o*s*f+u*i*c,t}function p(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"}Object.defineProperty(n,"__esModule",{value:!0}),n.setAxes=n.sqlerp=n.rotationTo=n.equals=n.exactEquals=n.normalize=n.sqrLen=n.squaredLength=n.len=n.length=n.lerp=n.dot=n.scale=n.mul=n.add=n.set=n.copy=n.fromValues=n.clone=void 0,n.create=e,n.identity=u,n.setAxisAngle=o,n.getAxisAngle=i,n.multiply=s,n.rotateX=c,n.rotateY=f,n.rotateZ=M,n.calculateW=h,n.slerp=l,n.invert=v,n.conjugate=d,n.fromMat3=b,n.fromEuler=m,n.str=p;var P=r(0),E=a(P),O=r(1),x=a(O),A=r(2),q=a(A),y=r(3),w=a(y),R=(n.clone=w.clone,n.fromValues=w.fromValues,n.copy=w.copy,n.set=w.set,n.add=w.add,n.mul=s,n.scale=w.scale,n.dot=w.dot,n.lerp=w.lerp,n.length=w.length),L=(n.len=R,n.squaredLength=w.squaredLength),S=(n.sqrLen=L,n.normalize=w.normalize);n.exactEquals=w.exactEquals,n.equals=w.equals,n.rotationTo=function(){var t=q.create(),n=q.fromValues(1,0,0),r=q.fromValues(0,1,0);return function(a,e,u){var i=q.dot(e,u);return i<-.999999?(q.cross(t,n,e),q.len(t)<1e-6&&q.cross(t,r,e),q.normalize(t,t),o(a,t,Math.PI),a):i>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(q.cross(t,e,u),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+i,S(a,a))}}(),n.sqlerp=function(){var t=e(),n=e();return function(r,a,e,u,o,i){return l(t,a,o,i),l(n,e,u,i),l(r,t,n,2*i*(1-i)),r}}(),n.setAxes=function(){var t=x.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],S(n,b(n,t))}}()},function(t,n,r){"use strict";function a(){var t=new V.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t}function e(t){var n=new V.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n}function u(t,n){var r=new V.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r}function o(t,n){return t[0]=n[0],t[1]=n[1],t}function i(t,n,r){return t[0]=n,t[1]=r,t}function s(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t}function c(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t}function f(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t}function M(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t}function h(t,n){return t[0]=Math.ceil(n[0]),t[1]=Math.ceil(n[1]),t}function l(t,n){return t[0]=Math.floor(n[0]),t[1]=Math.floor(n[1]),t}function v(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t}function d(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t}function b(t,n){return t[0]=Math.round(n[0]),t[1]=Math.round(n[1]),t}function m(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t}function p(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t}function P(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)}function E(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a}function O(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)}function x(t){var n=t[0],r=t[1];return n*n+r*r}function A(t,n){return t[0]=-n[0],t[1]=-n[1],t}function q(t,n){return t[0]=1/n[0],t[1]=1/n[1],t}function y(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t}function w(t,n){return t[0]*n[0]+t[1]*n[1]}function R(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t}function L(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t}function S(t,n){n=n||1;var r=2*V.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t}function _(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t}function I(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t}function N(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t}function Y(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t}function g(t){return"vec2("+t[0]+", "+t[1]+")"}function T(t,n){return t[0]===n[0]&&t[1]===n[1]}function j(t,n){var r=t[0],a=t[1],e=n[0],u=n[1];return Math.abs(r-e)<=V.EPSILON*Math.max(1,Math.abs(r),Math.abs(e))&&Math.abs(a-u)<=V.EPSILON*Math.max(1,Math.abs(a),Math.abs(u))}Object.defineProperty(n,"__esModule",{value:!0}),n.forEach=n.sqrLen=n.sqrDist=n.dist=n.div=n.mul=n.sub=n.len=void 0,n.create=a,n.clone=e,n.fromValues=u,n.copy=o,n.set=i,n.add=s,n.subtract=c,n.multiply=f,n.divide=M,n.ceil=h,n.floor=l,n.min=v,n.max=d,n.round=b,n.scale=m,n.scaleAndAdd=p,n.distance=P,n.squaredDistance=E,n.length=O,n.squaredLength=x,n.negate=A,n.inverse=q,n.normalize=y,n.dot=w,n.cross=R,n.lerp=L,n.random=S,n.transformMat2=_,n.transformMat2d=I,n.transformMat3=N,n.transformMat4=Y,n.str=g,n.exactEquals=T,n.equals=j;var D=r(0),V=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(D);n.len=O,n.sub=c,n.mul=f,n.div=M,n.dist=P,n.sqrDist=E,n.sqrLen=x,n.forEach=function(){var t=a();return function(n,r,a,e,u,o){var i=void 0,s=void 0;for(r||(r=2),a||(a=0),s=e?Math.min(e*r+a,n.length):n.length,i=a;i
2 |
3 |
4 |
--------------------------------------------------------------------------------
/interfaces/generate.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const acorn = require("acorn");
3 | let walker = require("acorn/dist/walk");
4 |
5 | let options = {
6 | ecmaVersion: 7,
7 | allowImportExportEverywhere: true
8 | };
9 |
10 | function findReturn(node) {
11 | let ret = null;
12 | walker.simple(node, {
13 | ReturnStatement(child) {
14 | ret = child;
15 | }
16 | });
17 | return ret;
18 | };
19 |
20 | function findAllocation(node) {
21 | let ret = null;
22 | walker.simple(node, {
23 | NewExpression(child) {
24 | let callee = child.callee;
25 | let args = child.arguments;
26 | let object = callee.object;
27 | let property = callee.property;
28 | let computed = callee.computed;
29 | if (
30 | !computed &&
31 | object.type === "Identifier" &&
32 | object.name === "glMatrix" &&
33 | property.type === "Identifier" &&
34 | property.name === "ARRAY_TYPE"
35 | ) {
36 | let size = args[0];
37 | if (
38 | size &&
39 | size.type === "Literal"
40 | ) {
41 | ret = size.value;
42 | }
43 | }
44 | }
45 | });
46 | return ret;
47 | };
48 |
49 | function getReturnType(node) {
50 | let type = node.type;
51 | if (type === "Identifier") return "out";
52 | return type;
53 | };
54 |
55 | function getExport(node) {
56 | let decl = node.declaration;
57 | if (decl.type === "FunctionDeclaration") {
58 | let declName = decl.id.name;
59 | let ret = findReturn(node);
60 | let retType = getReturnType(ret.argument);
61 | let allocation = findAllocation(node);
62 | let result = {
63 | id: declName,
64 | returns: retType
65 | };
66 | if (allocation) result.allocation = allocation;
67 | return result;
68 | }
69 | };
70 |
71 | function isCustomInterfaceRequired(moduleInterface) {
72 | return (
73 | (moduleInterface.returns !== "out") ||
74 | (moduleInterface.allocation !== void 0)
75 | );
76 | };
77 |
78 | function processComment(comment) {
79 | let arg = {
80 | arguments: [],
81 | returns: null
82 | };
83 | let split = comment.split("\n");
84 | split.map(line => {
85 | if (line.match("@param")) {
86 | let start = line.indexOf("{") + 1;
87 | let end = line.lastIndexOf("}");
88 | let type = line.substr(start, end - start);
89 | }
90 | else if (line.match("@return")) {
91 | let start = line.indexOf("{") + 1;
92 | let end = line.lastIndexOf("}");
93 | let type = line.substr(start, end - start);
94 | console.log(type);
95 | }
96 | });
97 | return arg;
98 | };
99 |
100 | module.exports = function(source) {
101 |
102 | let cmnts = [];
103 | options.onComment = cmnts;
104 |
105 | let ast = acorn.parse(source, options);
106 | let program = ast;
107 |
108 | let table = {};
109 | for (let ii = 0; ii < program.body.length; ++ii) {
110 | let node = program.body[ii];
111 | if (node.type === "ExportNamedDeclaration") {
112 | let decl = getExport(node);
113 | if (!decl) continue;
114 | decl.specialInterface = isCustomInterfaceRequired(decl);
115 | table[decl.id] = decl;
116 | }
117 | };
118 |
119 | let comments = [];
120 | for (let ii = 0; ii < cmnts.length; ++ii) {
121 | let comment = cmnts[ii].value;
122 | if (
123 | cmnts[ii].type === "Block" &&
124 | (comment.match("@returns ") !== null || comment.match("@return ") !== null)
125 | ) {
126 | comments.push(processComment(comment));
127 | }
128 | };
129 |
130 | return table;
131 |
132 | };
133 |
--------------------------------------------------------------------------------
/interfaces/ignore_this.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maierfelix/glmw/4b1b39868f1038ded299f4a983adf8882104124d/interfaces/ignore_this.txt
--------------------------------------------------------------------------------
/interfaces/index.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const glMatrix = require("../static/gl-matrix.min.js");
3 | const generate = require("./generate");
4 |
5 | let sourceDir = __dirname + "/../gl-matrix/";
6 | let moduleSources = require(__dirname + "/modules");
7 |
8 | //let baseTablePath = __dirname + "/base-table.js";
9 |
10 | let interfaces = {};
11 | let specialInterfaces = {};
12 | moduleSources.map(moduleName => {
13 | let file = fs.readFileSync(sourceDir + moduleName + ".js", "utf-8");
14 | let table = generate(file);
15 | // full interface
16 | {
17 | interfaces[moduleName] = {};
18 | let interface = interfaces[moduleName];
19 | for (let name in table) {
20 | let method = table[name];
21 | interface[name] = method;
22 | };
23 | }
24 | // special interface
25 | {
26 | specialInterfaces[moduleName] = {};
27 | let interface = specialInterfaces[moduleName];
28 | for (let name in table) {
29 | let method = table[name];
30 | if (method.specialInterface) interface[name] = method;
31 | };
32 | }
33 | });
34 |
35 | let stubs = {
36 |
37 | };
38 |
39 | for (let key in interfaces) {
40 | let methods = interfaces[key];
41 | for (let key in methods) {
42 | let method = methods[key];
43 | if (!method.specialInterface) {
44 | let stub = function(out, a, b) {
45 |
46 | };
47 | }
48 | };
49 | };
50 |
51 | //fs.writeFileSync(__dirname + "/interfaces.json", JSON.stringify(interfaces, null, 2), "utf-8");
52 | //fs.writeFileSync(__dirname + "/interfaces-special.json", JSON.stringify(specialInterfaces, null, 2), "utf-8");
53 |
--------------------------------------------------------------------------------
/interfaces/interfaces-special.json:
--------------------------------------------------------------------------------
1 | {
2 | "mat2": {
3 | "create": {
4 | "id": "create",
5 | "returns": "out",
6 | "allocation": 4,
7 | "specialInterface": true
8 | },
9 | "clone": {
10 | "id": "clone",
11 | "returns": "out",
12 | "allocation": 4,
13 | "specialInterface": true
14 | },
15 | "fromValues": {
16 | "id": "fromValues",
17 | "returns": "out",
18 | "allocation": 4,
19 | "specialInterface": true
20 | },
21 | "determinant": {
22 | "id": "determinant",
23 | "returns": "BinaryExpression",
24 | "specialInterface": true
25 | },
26 | "str": {
27 | "id": "str",
28 | "returns": "BinaryExpression",
29 | "specialInterface": true
30 | },
31 | "frob": {
32 | "id": "frob",
33 | "returns": "CallExpression",
34 | "specialInterface": true
35 | },
36 | "LDU": {
37 | "id": "LDU",
38 | "returns": "ArrayExpression",
39 | "specialInterface": true
40 | },
41 | "exactEquals": {
42 | "id": "exactEquals",
43 | "returns": "LogicalExpression",
44 | "specialInterface": true
45 | },
46 | "equals": {
47 | "id": "equals",
48 | "returns": "LogicalExpression",
49 | "specialInterface": true
50 | }
51 | },
52 | "mat2d": {
53 | "create": {
54 | "id": "create",
55 | "returns": "out",
56 | "allocation": 6,
57 | "specialInterface": true
58 | },
59 | "clone": {
60 | "id": "clone",
61 | "returns": "out",
62 | "allocation": 6,
63 | "specialInterface": true
64 | },
65 | "fromValues": {
66 | "id": "fromValues",
67 | "returns": "out",
68 | "allocation": 6,
69 | "specialInterface": true
70 | },
71 | "determinant": {
72 | "id": "determinant",
73 | "returns": "BinaryExpression",
74 | "specialInterface": true
75 | },
76 | "str": {
77 | "id": "str",
78 | "returns": "BinaryExpression",
79 | "specialInterface": true
80 | },
81 | "frob": {
82 | "id": "frob",
83 | "returns": "CallExpression",
84 | "specialInterface": true
85 | },
86 | "exactEquals": {
87 | "id": "exactEquals",
88 | "returns": "LogicalExpression",
89 | "specialInterface": true
90 | },
91 | "equals": {
92 | "id": "equals",
93 | "returns": "LogicalExpression",
94 | "specialInterface": true
95 | }
96 | },
97 | "mat3": {
98 | "create": {
99 | "id": "create",
100 | "returns": "out",
101 | "allocation": 9,
102 | "specialInterface": true
103 | },
104 | "clone": {
105 | "id": "clone",
106 | "returns": "out",
107 | "allocation": 9,
108 | "specialInterface": true
109 | },
110 | "fromValues": {
111 | "id": "fromValues",
112 | "returns": "out",
113 | "allocation": 9,
114 | "specialInterface": true
115 | },
116 | "determinant": {
117 | "id": "determinant",
118 | "returns": "BinaryExpression",
119 | "specialInterface": true
120 | },
121 | "str": {
122 | "id": "str",
123 | "returns": "BinaryExpression",
124 | "specialInterface": true
125 | },
126 | "frob": {
127 | "id": "frob",
128 | "returns": "CallExpression",
129 | "specialInterface": true
130 | },
131 | "exactEquals": {
132 | "id": "exactEquals",
133 | "returns": "LogicalExpression",
134 | "specialInterface": true
135 | },
136 | "equals": {
137 | "id": "equals",
138 | "returns": "LogicalExpression",
139 | "specialInterface": true
140 | }
141 | },
142 | "mat4": {
143 | "create": {
144 | "id": "create",
145 | "returns": "out",
146 | "allocation": 16,
147 | "specialInterface": true
148 | },
149 | "clone": {
150 | "id": "clone",
151 | "returns": "out",
152 | "allocation": 16,
153 | "specialInterface": true
154 | },
155 | "fromValues": {
156 | "id": "fromValues",
157 | "returns": "out",
158 | "allocation": 16,
159 | "specialInterface": true
160 | },
161 | "determinant": {
162 | "id": "determinant",
163 | "returns": "BinaryExpression",
164 | "specialInterface": true
165 | },
166 | "str": {
167 | "id": "str",
168 | "returns": "BinaryExpression",
169 | "specialInterface": true
170 | },
171 | "frob": {
172 | "id": "frob",
173 | "returns": "CallExpression",
174 | "specialInterface": true
175 | },
176 | "exactEquals": {
177 | "id": "exactEquals",
178 | "returns": "LogicalExpression",
179 | "specialInterface": true
180 | },
181 | "equals": {
182 | "id": "equals",
183 | "returns": "LogicalExpression",
184 | "specialInterface": true
185 | }
186 | },
187 | "quat": {
188 | "create": {
189 | "id": "create",
190 | "returns": "out",
191 | "allocation": 4,
192 | "specialInterface": true
193 | },
194 | "str": {
195 | "id": "str",
196 | "returns": "BinaryExpression",
197 | "specialInterface": true
198 | }
199 | },
200 | "vec2": {
201 | "create": {
202 | "id": "create",
203 | "returns": "out",
204 | "allocation": 2,
205 | "specialInterface": true
206 | },
207 | "clone": {
208 | "id": "clone",
209 | "returns": "out",
210 | "allocation": 2,
211 | "specialInterface": true
212 | },
213 | "fromValues": {
214 | "id": "fromValues",
215 | "returns": "out",
216 | "allocation": 2,
217 | "specialInterface": true
218 | },
219 | "distance": {
220 | "id": "distance",
221 | "returns": "CallExpression",
222 | "specialInterface": true
223 | },
224 | "squaredDistance": {
225 | "id": "squaredDistance",
226 | "returns": "BinaryExpression",
227 | "specialInterface": true
228 | },
229 | "length": {
230 | "id": "length",
231 | "returns": "CallExpression",
232 | "specialInterface": true
233 | },
234 | "squaredLength": {
235 | "id": "squaredLength",
236 | "returns": "BinaryExpression",
237 | "specialInterface": true
238 | },
239 | "dot": {
240 | "id": "dot",
241 | "returns": "BinaryExpression",
242 | "specialInterface": true
243 | },
244 | "str": {
245 | "id": "str",
246 | "returns": "BinaryExpression",
247 | "specialInterface": true
248 | },
249 | "exactEquals": {
250 | "id": "exactEquals",
251 | "returns": "LogicalExpression",
252 | "specialInterface": true
253 | },
254 | "equals": {
255 | "id": "equals",
256 | "returns": "LogicalExpression",
257 | "specialInterface": true
258 | }
259 | },
260 | "vec3": {
261 | "create": {
262 | "id": "create",
263 | "returns": "out",
264 | "allocation": 3,
265 | "specialInterface": true
266 | },
267 | "clone": {
268 | "id": "clone",
269 | "returns": "out",
270 | "allocation": 3,
271 | "specialInterface": true
272 | },
273 | "length": {
274 | "id": "length",
275 | "returns": "CallExpression",
276 | "specialInterface": true
277 | },
278 | "fromValues": {
279 | "id": "fromValues",
280 | "returns": "out",
281 | "allocation": 3,
282 | "specialInterface": true
283 | },
284 | "distance": {
285 | "id": "distance",
286 | "returns": "CallExpression",
287 | "specialInterface": true
288 | },
289 | "squaredDistance": {
290 | "id": "squaredDistance",
291 | "returns": "BinaryExpression",
292 | "specialInterface": true
293 | },
294 | "squaredLength": {
295 | "id": "squaredLength",
296 | "returns": "BinaryExpression",
297 | "specialInterface": true
298 | },
299 | "dot": {
300 | "id": "dot",
301 | "returns": "BinaryExpression",
302 | "specialInterface": true
303 | },
304 | "angle": {
305 | "id": "angle",
306 | "returns": "CallExpression",
307 | "specialInterface": true
308 | },
309 | "str": {
310 | "id": "str",
311 | "returns": "BinaryExpression",
312 | "specialInterface": true
313 | },
314 | "exactEquals": {
315 | "id": "exactEquals",
316 | "returns": "LogicalExpression",
317 | "specialInterface": true
318 | },
319 | "equals": {
320 | "id": "equals",
321 | "returns": "LogicalExpression",
322 | "specialInterface": true
323 | }
324 | },
325 | "vec4": {
326 | "create": {
327 | "id": "create",
328 | "returns": "out",
329 | "allocation": 4,
330 | "specialInterface": true
331 | },
332 | "clone": {
333 | "id": "clone",
334 | "returns": "out",
335 | "allocation": 4,
336 | "specialInterface": true
337 | },
338 | "fromValues": {
339 | "id": "fromValues",
340 | "returns": "out",
341 | "allocation": 4,
342 | "specialInterface": true
343 | },
344 | "distance": {
345 | "id": "distance",
346 | "returns": "CallExpression",
347 | "specialInterface": true
348 | },
349 | "squaredDistance": {
350 | "id": "squaredDistance",
351 | "returns": "BinaryExpression",
352 | "specialInterface": true
353 | },
354 | "length": {
355 | "id": "length",
356 | "returns": "CallExpression",
357 | "specialInterface": true
358 | },
359 | "squaredLength": {
360 | "id": "squaredLength",
361 | "returns": "BinaryExpression",
362 | "specialInterface": true
363 | },
364 | "dot": {
365 | "id": "dot",
366 | "returns": "BinaryExpression",
367 | "specialInterface": true
368 | },
369 | "str": {
370 | "id": "str",
371 | "returns": "BinaryExpression",
372 | "specialInterface": true
373 | },
374 | "exactEquals": {
375 | "id": "exactEquals",
376 | "returns": "LogicalExpression",
377 | "specialInterface": true
378 | },
379 | "equals": {
380 | "id": "equals",
381 | "returns": "LogicalExpression",
382 | "specialInterface": true
383 | }
384 | }
385 | }
--------------------------------------------------------------------------------
/interfaces/interfaces.json:
--------------------------------------------------------------------------------
1 | {
2 | "mat2": {
3 | "create": {
4 | "id": "create",
5 | "returns": "out",
6 | "allocation": 4,
7 | "specialInterface": true
8 | },
9 | "clone": {
10 | "id": "clone",
11 | "returns": "out",
12 | "allocation": 4,
13 | "specialInterface": true
14 | },
15 | "copy": {
16 | "id": "copy",
17 | "returns": "out",
18 | "specialInterface": false
19 | },
20 | "identity": {
21 | "id": "identity",
22 | "returns": "out",
23 | "specialInterface": false
24 | },
25 | "fromValues": {
26 | "id": "fromValues",
27 | "returns": "out",
28 | "allocation": 4,
29 | "specialInterface": true
30 | },
31 | "set": {
32 | "id": "set",
33 | "returns": "out",
34 | "specialInterface": false
35 | },
36 | "transpose": {
37 | "id": "transpose",
38 | "returns": "out",
39 | "specialInterface": false
40 | },
41 | "invert": {
42 | "id": "invert",
43 | "returns": "out",
44 | "specialInterface": false
45 | },
46 | "adjoint": {
47 | "id": "adjoint",
48 | "returns": "out",
49 | "specialInterface": false
50 | },
51 | "determinant": {
52 | "id": "determinant",
53 | "returns": "BinaryExpression",
54 | "specialInterface": true
55 | },
56 | "multiply": {
57 | "id": "multiply",
58 | "returns": "out",
59 | "specialInterface": false
60 | },
61 | "rotate": {
62 | "id": "rotate",
63 | "returns": "out",
64 | "specialInterface": false
65 | },
66 | "scale": {
67 | "id": "scale",
68 | "returns": "out",
69 | "specialInterface": false
70 | },
71 | "fromRotation": {
72 | "id": "fromRotation",
73 | "returns": "out",
74 | "specialInterface": false
75 | },
76 | "fromScaling": {
77 | "id": "fromScaling",
78 | "returns": "out",
79 | "specialInterface": false
80 | },
81 | "str": {
82 | "id": "str",
83 | "returns": "BinaryExpression",
84 | "specialInterface": true
85 | },
86 | "frob": {
87 | "id": "frob",
88 | "returns": "CallExpression",
89 | "specialInterface": true
90 | },
91 | "LDU": {
92 | "id": "LDU",
93 | "returns": "ArrayExpression",
94 | "specialInterface": true
95 | },
96 | "add": {
97 | "id": "add",
98 | "returns": "out",
99 | "specialInterface": false
100 | },
101 | "subtract": {
102 | "id": "subtract",
103 | "returns": "out",
104 | "specialInterface": false
105 | },
106 | "exactEquals": {
107 | "id": "exactEquals",
108 | "returns": "LogicalExpression",
109 | "specialInterface": true
110 | },
111 | "equals": {
112 | "id": "equals",
113 | "returns": "LogicalExpression",
114 | "specialInterface": true
115 | },
116 | "multiplyScalar": {
117 | "id": "multiplyScalar",
118 | "returns": "out",
119 | "specialInterface": false
120 | },
121 | "multiplyScalarAndAdd": {
122 | "id": "multiplyScalarAndAdd",
123 | "returns": "out",
124 | "specialInterface": false
125 | }
126 | },
127 | "mat2d": {
128 | "create": {
129 | "id": "create",
130 | "returns": "out",
131 | "allocation": 6,
132 | "specialInterface": true
133 | },
134 | "clone": {
135 | "id": "clone",
136 | "returns": "out",
137 | "allocation": 6,
138 | "specialInterface": true
139 | },
140 | "copy": {
141 | "id": "copy",
142 | "returns": "out",
143 | "specialInterface": false
144 | },
145 | "identity": {
146 | "id": "identity",
147 | "returns": "out",
148 | "specialInterface": false
149 | },
150 | "fromValues": {
151 | "id": "fromValues",
152 | "returns": "out",
153 | "allocation": 6,
154 | "specialInterface": true
155 | },
156 | "set": {
157 | "id": "set",
158 | "returns": "out",
159 | "specialInterface": false
160 | },
161 | "invert": {
162 | "id": "invert",
163 | "returns": "out",
164 | "specialInterface": false
165 | },
166 | "determinant": {
167 | "id": "determinant",
168 | "returns": "BinaryExpression",
169 | "specialInterface": true
170 | },
171 | "multiply": {
172 | "id": "multiply",
173 | "returns": "out",
174 | "specialInterface": false
175 | },
176 | "rotate": {
177 | "id": "rotate",
178 | "returns": "out",
179 | "specialInterface": false
180 | },
181 | "scale": {
182 | "id": "scale",
183 | "returns": "out",
184 | "specialInterface": false
185 | },
186 | "translate": {
187 | "id": "translate",
188 | "returns": "out",
189 | "specialInterface": false
190 | },
191 | "fromRotation": {
192 | "id": "fromRotation",
193 | "returns": "out",
194 | "specialInterface": false
195 | },
196 | "fromScaling": {
197 | "id": "fromScaling",
198 | "returns": "out",
199 | "specialInterface": false
200 | },
201 | "fromTranslation": {
202 | "id": "fromTranslation",
203 | "returns": "out",
204 | "specialInterface": false
205 | },
206 | "str": {
207 | "id": "str",
208 | "returns": "BinaryExpression",
209 | "specialInterface": true
210 | },
211 | "frob": {
212 | "id": "frob",
213 | "returns": "CallExpression",
214 | "specialInterface": true
215 | },
216 | "add": {
217 | "id": "add",
218 | "returns": "out",
219 | "specialInterface": false
220 | },
221 | "subtract": {
222 | "id": "subtract",
223 | "returns": "out",
224 | "specialInterface": false
225 | },
226 | "multiplyScalar": {
227 | "id": "multiplyScalar",
228 | "returns": "out",
229 | "specialInterface": false
230 | },
231 | "multiplyScalarAndAdd": {
232 | "id": "multiplyScalarAndAdd",
233 | "returns": "out",
234 | "specialInterface": false
235 | },
236 | "exactEquals": {
237 | "id": "exactEquals",
238 | "returns": "LogicalExpression",
239 | "specialInterface": true
240 | },
241 | "equals": {
242 | "id": "equals",
243 | "returns": "LogicalExpression",
244 | "specialInterface": true
245 | }
246 | },
247 | "mat3": {
248 | "create": {
249 | "id": "create",
250 | "returns": "out",
251 | "allocation": 9,
252 | "specialInterface": true
253 | },
254 | "fromMat4": {
255 | "id": "fromMat4",
256 | "returns": "out",
257 | "specialInterface": false
258 | },
259 | "clone": {
260 | "id": "clone",
261 | "returns": "out",
262 | "allocation": 9,
263 | "specialInterface": true
264 | },
265 | "copy": {
266 | "id": "copy",
267 | "returns": "out",
268 | "specialInterface": false
269 | },
270 | "fromValues": {
271 | "id": "fromValues",
272 | "returns": "out",
273 | "allocation": 9,
274 | "specialInterface": true
275 | },
276 | "set": {
277 | "id": "set",
278 | "returns": "out",
279 | "specialInterface": false
280 | },
281 | "identity": {
282 | "id": "identity",
283 | "returns": "out",
284 | "specialInterface": false
285 | },
286 | "transpose": {
287 | "id": "transpose",
288 | "returns": "out",
289 | "specialInterface": false
290 | },
291 | "invert": {
292 | "id": "invert",
293 | "returns": "out",
294 | "specialInterface": false
295 | },
296 | "adjoint": {
297 | "id": "adjoint",
298 | "returns": "out",
299 | "specialInterface": false
300 | },
301 | "determinant": {
302 | "id": "determinant",
303 | "returns": "BinaryExpression",
304 | "specialInterface": true
305 | },
306 | "multiply": {
307 | "id": "multiply",
308 | "returns": "out",
309 | "specialInterface": false
310 | },
311 | "translate": {
312 | "id": "translate",
313 | "returns": "out",
314 | "specialInterface": false
315 | },
316 | "rotate": {
317 | "id": "rotate",
318 | "returns": "out",
319 | "specialInterface": false
320 | },
321 | "scale": {
322 | "id": "scale",
323 | "returns": "out",
324 | "specialInterface": false
325 | },
326 | "fromTranslation": {
327 | "id": "fromTranslation",
328 | "returns": "out",
329 | "specialInterface": false
330 | },
331 | "fromRotation": {
332 | "id": "fromRotation",
333 | "returns": "out",
334 | "specialInterface": false
335 | },
336 | "fromScaling": {
337 | "id": "fromScaling",
338 | "returns": "out",
339 | "specialInterface": false
340 | },
341 | "fromMat2d": {
342 | "id": "fromMat2d",
343 | "returns": "out",
344 | "specialInterface": false
345 | },
346 | "fromQuat": {
347 | "id": "fromQuat",
348 | "returns": "out",
349 | "specialInterface": false
350 | },
351 | "normalFromMat4": {
352 | "id": "normalFromMat4",
353 | "returns": "out",
354 | "specialInterface": false
355 | },
356 | "projection": {
357 | "id": "projection",
358 | "returns": "out",
359 | "specialInterface": false
360 | },
361 | "str": {
362 | "id": "str",
363 | "returns": "BinaryExpression",
364 | "specialInterface": true
365 | },
366 | "frob": {
367 | "id": "frob",
368 | "returns": "CallExpression",
369 | "specialInterface": true
370 | },
371 | "add": {
372 | "id": "add",
373 | "returns": "out",
374 | "specialInterface": false
375 | },
376 | "subtract": {
377 | "id": "subtract",
378 | "returns": "out",
379 | "specialInterface": false
380 | },
381 | "multiplyScalar": {
382 | "id": "multiplyScalar",
383 | "returns": "out",
384 | "specialInterface": false
385 | },
386 | "multiplyScalarAndAdd": {
387 | "id": "multiplyScalarAndAdd",
388 | "returns": "out",
389 | "specialInterface": false
390 | },
391 | "exactEquals": {
392 | "id": "exactEquals",
393 | "returns": "LogicalExpression",
394 | "specialInterface": true
395 | },
396 | "equals": {
397 | "id": "equals",
398 | "returns": "LogicalExpression",
399 | "specialInterface": true
400 | }
401 | },
402 | "mat4": {
403 | "create": {
404 | "id": "create",
405 | "returns": "out",
406 | "allocation": 16,
407 | "specialInterface": true
408 | },
409 | "clone": {
410 | "id": "clone",
411 | "returns": "out",
412 | "allocation": 16,
413 | "specialInterface": true
414 | },
415 | "copy": {
416 | "id": "copy",
417 | "returns": "out",
418 | "specialInterface": false
419 | },
420 | "fromValues": {
421 | "id": "fromValues",
422 | "returns": "out",
423 | "allocation": 16,
424 | "specialInterface": true
425 | },
426 | "set": {
427 | "id": "set",
428 | "returns": "out",
429 | "specialInterface": false
430 | },
431 | "identity": {
432 | "id": "identity",
433 | "returns": "out",
434 | "specialInterface": false
435 | },
436 | "transpose": {
437 | "id": "transpose",
438 | "returns": "out",
439 | "specialInterface": false
440 | },
441 | "invert": {
442 | "id": "invert",
443 | "returns": "out",
444 | "specialInterface": false
445 | },
446 | "adjoint": {
447 | "id": "adjoint",
448 | "returns": "out",
449 | "specialInterface": false
450 | },
451 | "determinant": {
452 | "id": "determinant",
453 | "returns": "BinaryExpression",
454 | "specialInterface": true
455 | },
456 | "multiply": {
457 | "id": "multiply",
458 | "returns": "out",
459 | "specialInterface": false
460 | },
461 | "translate": {
462 | "id": "translate",
463 | "returns": "out",
464 | "specialInterface": false
465 | },
466 | "scale": {
467 | "id": "scale",
468 | "returns": "out",
469 | "specialInterface": false
470 | },
471 | "rotate": {
472 | "id": "rotate",
473 | "returns": "out",
474 | "specialInterface": false
475 | },
476 | "rotateX": {
477 | "id": "rotateX",
478 | "returns": "out",
479 | "specialInterface": false
480 | },
481 | "rotateY": {
482 | "id": "rotateY",
483 | "returns": "out",
484 | "specialInterface": false
485 | },
486 | "rotateZ": {
487 | "id": "rotateZ",
488 | "returns": "out",
489 | "specialInterface": false
490 | },
491 | "fromTranslation": {
492 | "id": "fromTranslation",
493 | "returns": "out",
494 | "specialInterface": false
495 | },
496 | "fromScaling": {
497 | "id": "fromScaling",
498 | "returns": "out",
499 | "specialInterface": false
500 | },
501 | "fromRotation": {
502 | "id": "fromRotation",
503 | "returns": "out",
504 | "specialInterface": false
505 | },
506 | "fromXRotation": {
507 | "id": "fromXRotation",
508 | "returns": "out",
509 | "specialInterface": false
510 | },
511 | "fromYRotation": {
512 | "id": "fromYRotation",
513 | "returns": "out",
514 | "specialInterface": false
515 | },
516 | "fromZRotation": {
517 | "id": "fromZRotation",
518 | "returns": "out",
519 | "specialInterface": false
520 | },
521 | "fromRotationTranslation": {
522 | "id": "fromRotationTranslation",
523 | "returns": "out",
524 | "specialInterface": false
525 | },
526 | "getTranslation": {
527 | "id": "getTranslation",
528 | "returns": "out",
529 | "specialInterface": false
530 | },
531 | "getScaling": {
532 | "id": "getScaling",
533 | "returns": "out",
534 | "specialInterface": false
535 | },
536 | "getRotation": {
537 | "id": "getRotation",
538 | "returns": "out",
539 | "specialInterface": false
540 | },
541 | "fromRotationTranslationScale": {
542 | "id": "fromRotationTranslationScale",
543 | "returns": "out",
544 | "specialInterface": false
545 | },
546 | "fromRotationTranslationScaleOrigin": {
547 | "id": "fromRotationTranslationScaleOrigin",
548 | "returns": "out",
549 | "specialInterface": false
550 | },
551 | "fromQuat": {
552 | "id": "fromQuat",
553 | "returns": "out",
554 | "specialInterface": false
555 | },
556 | "frustum": {
557 | "id": "frustum",
558 | "returns": "out",
559 | "specialInterface": false
560 | },
561 | "perspective": {
562 | "id": "perspective",
563 | "returns": "out",
564 | "specialInterface": false
565 | },
566 | "perspectiveFromFieldOfView": {
567 | "id": "perspectiveFromFieldOfView",
568 | "returns": "out",
569 | "specialInterface": false
570 | },
571 | "ortho": {
572 | "id": "ortho",
573 | "returns": "out",
574 | "specialInterface": false
575 | },
576 | "lookAt": {
577 | "id": "lookAt",
578 | "returns": "out",
579 | "specialInterface": false
580 | },
581 | "targetTo": {
582 | "id": "targetTo",
583 | "returns": "out",
584 | "specialInterface": false
585 | },
586 | "str": {
587 | "id": "str",
588 | "returns": "BinaryExpression",
589 | "specialInterface": true
590 | },
591 | "frob": {
592 | "id": "frob",
593 | "returns": "CallExpression",
594 | "specialInterface": true
595 | },
596 | "add": {
597 | "id": "add",
598 | "returns": "out",
599 | "specialInterface": false
600 | },
601 | "subtract": {
602 | "id": "subtract",
603 | "returns": "out",
604 | "specialInterface": false
605 | },
606 | "multiplyScalar": {
607 | "id": "multiplyScalar",
608 | "returns": "out",
609 | "specialInterface": false
610 | },
611 | "multiplyScalarAndAdd": {
612 | "id": "multiplyScalarAndAdd",
613 | "returns": "out",
614 | "specialInterface": false
615 | },
616 | "exactEquals": {
617 | "id": "exactEquals",
618 | "returns": "LogicalExpression",
619 | "specialInterface": true
620 | },
621 | "equals": {
622 | "id": "equals",
623 | "returns": "LogicalExpression",
624 | "specialInterface": true
625 | }
626 | },
627 | "quat": {
628 | "create": {
629 | "id": "create",
630 | "returns": "out",
631 | "allocation": 4,
632 | "specialInterface": true
633 | },
634 | "identity": {
635 | "id": "identity",
636 | "returns": "out",
637 | "specialInterface": false
638 | },
639 | "setAxisAngle": {
640 | "id": "setAxisAngle",
641 | "returns": "out",
642 | "specialInterface": false
643 | },
644 | "getAxisAngle": {
645 | "id": "getAxisAngle",
646 | "returns": "out",
647 | "specialInterface": false
648 | },
649 | "multiply": {
650 | "id": "multiply",
651 | "returns": "out",
652 | "specialInterface": false
653 | },
654 | "rotateX": {
655 | "id": "rotateX",
656 | "returns": "out",
657 | "specialInterface": false
658 | },
659 | "rotateY": {
660 | "id": "rotateY",
661 | "returns": "out",
662 | "specialInterface": false
663 | },
664 | "rotateZ": {
665 | "id": "rotateZ",
666 | "returns": "out",
667 | "specialInterface": false
668 | },
669 | "calculateW": {
670 | "id": "calculateW",
671 | "returns": "out",
672 | "specialInterface": false
673 | },
674 | "slerp": {
675 | "id": "slerp",
676 | "returns": "out",
677 | "specialInterface": false
678 | },
679 | "invert": {
680 | "id": "invert",
681 | "returns": "out",
682 | "specialInterface": false
683 | },
684 | "conjugate": {
685 | "id": "conjugate",
686 | "returns": "out",
687 | "specialInterface": false
688 | },
689 | "fromMat3": {
690 | "id": "fromMat3",
691 | "returns": "out",
692 | "specialInterface": false
693 | },
694 | "fromEuler": {
695 | "id": "fromEuler",
696 | "returns": "out",
697 | "specialInterface": false
698 | },
699 | "str": {
700 | "id": "str",
701 | "returns": "BinaryExpression",
702 | "specialInterface": true
703 | }
704 | },
705 | "vec2": {
706 | "create": {
707 | "id": "create",
708 | "returns": "out",
709 | "allocation": 2,
710 | "specialInterface": true
711 | },
712 | "clone": {
713 | "id": "clone",
714 | "returns": "out",
715 | "allocation": 2,
716 | "specialInterface": true
717 | },
718 | "fromValues": {
719 | "id": "fromValues",
720 | "returns": "out",
721 | "allocation": 2,
722 | "specialInterface": true
723 | },
724 | "copy": {
725 | "id": "copy",
726 | "returns": "out",
727 | "specialInterface": false
728 | },
729 | "set": {
730 | "id": "set",
731 | "returns": "out",
732 | "specialInterface": false
733 | },
734 | "add": {
735 | "id": "add",
736 | "returns": "out",
737 | "specialInterface": false
738 | },
739 | "subtract": {
740 | "id": "subtract",
741 | "returns": "out",
742 | "specialInterface": false
743 | },
744 | "multiply": {
745 | "id": "multiply",
746 | "returns": "out",
747 | "specialInterface": false
748 | },
749 | "divide": {
750 | "id": "divide",
751 | "returns": "out",
752 | "specialInterface": false
753 | },
754 | "ceil": {
755 | "id": "ceil",
756 | "returns": "out",
757 | "specialInterface": false
758 | },
759 | "floor": {
760 | "id": "floor",
761 | "returns": "out",
762 | "specialInterface": false
763 | },
764 | "min": {
765 | "id": "min",
766 | "returns": "out",
767 | "specialInterface": false
768 | },
769 | "max": {
770 | "id": "max",
771 | "returns": "out",
772 | "specialInterface": false
773 | },
774 | "round": {
775 | "id": "round",
776 | "returns": "out",
777 | "specialInterface": false
778 | },
779 | "scale": {
780 | "id": "scale",
781 | "returns": "out",
782 | "specialInterface": false
783 | },
784 | "scaleAndAdd": {
785 | "id": "scaleAndAdd",
786 | "returns": "out",
787 | "specialInterface": false
788 | },
789 | "distance": {
790 | "id": "distance",
791 | "returns": "CallExpression",
792 | "specialInterface": true
793 | },
794 | "squaredDistance": {
795 | "id": "squaredDistance",
796 | "returns": "BinaryExpression",
797 | "specialInterface": true
798 | },
799 | "length": {
800 | "id": "length",
801 | "returns": "CallExpression",
802 | "specialInterface": true
803 | },
804 | "squaredLength": {
805 | "id": "squaredLength",
806 | "returns": "BinaryExpression",
807 | "specialInterface": true
808 | },
809 | "negate": {
810 | "id": "negate",
811 | "returns": "out",
812 | "specialInterface": false
813 | },
814 | "inverse": {
815 | "id": "inverse",
816 | "returns": "out",
817 | "specialInterface": false
818 | },
819 | "normalize": {
820 | "id": "normalize",
821 | "returns": "out",
822 | "specialInterface": false
823 | },
824 | "dot": {
825 | "id": "dot",
826 | "returns": "BinaryExpression",
827 | "specialInterface": true
828 | },
829 | "cross": {
830 | "id": "cross",
831 | "returns": "out",
832 | "specialInterface": false
833 | },
834 | "lerp": {
835 | "id": "lerp",
836 | "returns": "out",
837 | "specialInterface": false
838 | },
839 | "random": {
840 | "id": "random",
841 | "returns": "out",
842 | "specialInterface": false
843 | },
844 | "transformMat2": {
845 | "id": "transformMat2",
846 | "returns": "out",
847 | "specialInterface": false
848 | },
849 | "transformMat2d": {
850 | "id": "transformMat2d",
851 | "returns": "out",
852 | "specialInterface": false
853 | },
854 | "transformMat3": {
855 | "id": "transformMat3",
856 | "returns": "out",
857 | "specialInterface": false
858 | },
859 | "transformMat4": {
860 | "id": "transformMat4",
861 | "returns": "out",
862 | "specialInterface": false
863 | },
864 | "str": {
865 | "id": "str",
866 | "returns": "BinaryExpression",
867 | "specialInterface": true
868 | },
869 | "exactEquals": {
870 | "id": "exactEquals",
871 | "returns": "LogicalExpression",
872 | "specialInterface": true
873 | },
874 | "equals": {
875 | "id": "equals",
876 | "returns": "LogicalExpression",
877 | "specialInterface": true
878 | }
879 | },
880 | "vec3": {
881 | "create": {
882 | "id": "create",
883 | "returns": "out",
884 | "allocation": 3,
885 | "specialInterface": true
886 | },
887 | "clone": {
888 | "id": "clone",
889 | "returns": "out",
890 | "allocation": 3,
891 | "specialInterface": true
892 | },
893 | "length": {
894 | "id": "length",
895 | "returns": "CallExpression",
896 | "specialInterface": true
897 | },
898 | "fromValues": {
899 | "id": "fromValues",
900 | "returns": "out",
901 | "allocation": 3,
902 | "specialInterface": true
903 | },
904 | "copy": {
905 | "id": "copy",
906 | "returns": "out",
907 | "specialInterface": false
908 | },
909 | "set": {
910 | "id": "set",
911 | "returns": "out",
912 | "specialInterface": false
913 | },
914 | "add": {
915 | "id": "add",
916 | "returns": "out",
917 | "specialInterface": false
918 | },
919 | "subtract": {
920 | "id": "subtract",
921 | "returns": "out",
922 | "specialInterface": false
923 | },
924 | "multiply": {
925 | "id": "multiply",
926 | "returns": "out",
927 | "specialInterface": false
928 | },
929 | "divide": {
930 | "id": "divide",
931 | "returns": "out",
932 | "specialInterface": false
933 | },
934 | "ceil": {
935 | "id": "ceil",
936 | "returns": "out",
937 | "specialInterface": false
938 | },
939 | "floor": {
940 | "id": "floor",
941 | "returns": "out",
942 | "specialInterface": false
943 | },
944 | "min": {
945 | "id": "min",
946 | "returns": "out",
947 | "specialInterface": false
948 | },
949 | "max": {
950 | "id": "max",
951 | "returns": "out",
952 | "specialInterface": false
953 | },
954 | "round": {
955 | "id": "round",
956 | "returns": "out",
957 | "specialInterface": false
958 | },
959 | "scale": {
960 | "id": "scale",
961 | "returns": "out",
962 | "specialInterface": false
963 | },
964 | "scaleAndAdd": {
965 | "id": "scaleAndAdd",
966 | "returns": "out",
967 | "specialInterface": false
968 | },
969 | "distance": {
970 | "id": "distance",
971 | "returns": "CallExpression",
972 | "specialInterface": true
973 | },
974 | "squaredDistance": {
975 | "id": "squaredDistance",
976 | "returns": "BinaryExpression",
977 | "specialInterface": true
978 | },
979 | "squaredLength": {
980 | "id": "squaredLength",
981 | "returns": "BinaryExpression",
982 | "specialInterface": true
983 | },
984 | "negate": {
985 | "id": "negate",
986 | "returns": "out",
987 | "specialInterface": false
988 | },
989 | "inverse": {
990 | "id": "inverse",
991 | "returns": "out",
992 | "specialInterface": false
993 | },
994 | "normalize": {
995 | "id": "normalize",
996 | "returns": "out",
997 | "specialInterface": false
998 | },
999 | "dot": {
1000 | "id": "dot",
1001 | "returns": "BinaryExpression",
1002 | "specialInterface": true
1003 | },
1004 | "cross": {
1005 | "id": "cross",
1006 | "returns": "out",
1007 | "specialInterface": false
1008 | },
1009 | "lerp": {
1010 | "id": "lerp",
1011 | "returns": "out",
1012 | "specialInterface": false
1013 | },
1014 | "hermite": {
1015 | "id": "hermite",
1016 | "returns": "out",
1017 | "specialInterface": false
1018 | },
1019 | "bezier": {
1020 | "id": "bezier",
1021 | "returns": "out",
1022 | "specialInterface": false
1023 | },
1024 | "random": {
1025 | "id": "random",
1026 | "returns": "out",
1027 | "specialInterface": false
1028 | },
1029 | "transformMat4": {
1030 | "id": "transformMat4",
1031 | "returns": "out",
1032 | "specialInterface": false
1033 | },
1034 | "transformMat3": {
1035 | "id": "transformMat3",
1036 | "returns": "out",
1037 | "specialInterface": false
1038 | },
1039 | "transformQuat": {
1040 | "id": "transformQuat",
1041 | "returns": "out",
1042 | "specialInterface": false
1043 | },
1044 | "rotateX": {
1045 | "id": "rotateX",
1046 | "returns": "out",
1047 | "specialInterface": false
1048 | },
1049 | "rotateY": {
1050 | "id": "rotateY",
1051 | "returns": "out",
1052 | "specialInterface": false
1053 | },
1054 | "rotateZ": {
1055 | "id": "rotateZ",
1056 | "returns": "out",
1057 | "specialInterface": false
1058 | },
1059 | "angle": {
1060 | "id": "angle",
1061 | "returns": "CallExpression",
1062 | "specialInterface": true
1063 | },
1064 | "str": {
1065 | "id": "str",
1066 | "returns": "BinaryExpression",
1067 | "specialInterface": true
1068 | },
1069 | "exactEquals": {
1070 | "id": "exactEquals",
1071 | "returns": "LogicalExpression",
1072 | "specialInterface": true
1073 | },
1074 | "equals": {
1075 | "id": "equals",
1076 | "returns": "LogicalExpression",
1077 | "specialInterface": true
1078 | }
1079 | },
1080 | "vec4": {
1081 | "create": {
1082 | "id": "create",
1083 | "returns": "out",
1084 | "allocation": 4,
1085 | "specialInterface": true
1086 | },
1087 | "clone": {
1088 | "id": "clone",
1089 | "returns": "out",
1090 | "allocation": 4,
1091 | "specialInterface": true
1092 | },
1093 | "fromValues": {
1094 | "id": "fromValues",
1095 | "returns": "out",
1096 | "allocation": 4,
1097 | "specialInterface": true
1098 | },
1099 | "copy": {
1100 | "id": "copy",
1101 | "returns": "out",
1102 | "specialInterface": false
1103 | },
1104 | "set": {
1105 | "id": "set",
1106 | "returns": "out",
1107 | "specialInterface": false
1108 | },
1109 | "add": {
1110 | "id": "add",
1111 | "returns": "out",
1112 | "specialInterface": false
1113 | },
1114 | "subtract": {
1115 | "id": "subtract",
1116 | "returns": "out",
1117 | "specialInterface": false
1118 | },
1119 | "multiply": {
1120 | "id": "multiply",
1121 | "returns": "out",
1122 | "specialInterface": false
1123 | },
1124 | "divide": {
1125 | "id": "divide",
1126 | "returns": "out",
1127 | "specialInterface": false
1128 | },
1129 | "ceil": {
1130 | "id": "ceil",
1131 | "returns": "out",
1132 | "specialInterface": false
1133 | },
1134 | "floor": {
1135 | "id": "floor",
1136 | "returns": "out",
1137 | "specialInterface": false
1138 | },
1139 | "min": {
1140 | "id": "min",
1141 | "returns": "out",
1142 | "specialInterface": false
1143 | },
1144 | "max": {
1145 | "id": "max",
1146 | "returns": "out",
1147 | "specialInterface": false
1148 | },
1149 | "round": {
1150 | "id": "round",
1151 | "returns": "out",
1152 | "specialInterface": false
1153 | },
1154 | "scale": {
1155 | "id": "scale",
1156 | "returns": "out",
1157 | "specialInterface": false
1158 | },
1159 | "scaleAndAdd": {
1160 | "id": "scaleAndAdd",
1161 | "returns": "out",
1162 | "specialInterface": false
1163 | },
1164 | "distance": {
1165 | "id": "distance",
1166 | "returns": "CallExpression",
1167 | "specialInterface": true
1168 | },
1169 | "squaredDistance": {
1170 | "id": "squaredDistance",
1171 | "returns": "BinaryExpression",
1172 | "specialInterface": true
1173 | },
1174 | "length": {
1175 | "id": "length",
1176 | "returns": "CallExpression",
1177 | "specialInterface": true
1178 | },
1179 | "squaredLength": {
1180 | "id": "squaredLength",
1181 | "returns": "BinaryExpression",
1182 | "specialInterface": true
1183 | },
1184 | "negate": {
1185 | "id": "negate",
1186 | "returns": "out",
1187 | "specialInterface": false
1188 | },
1189 | "inverse": {
1190 | "id": "inverse",
1191 | "returns": "out",
1192 | "specialInterface": false
1193 | },
1194 | "normalize": {
1195 | "id": "normalize",
1196 | "returns": "out",
1197 | "specialInterface": false
1198 | },
1199 | "dot": {
1200 | "id": "dot",
1201 | "returns": "BinaryExpression",
1202 | "specialInterface": true
1203 | },
1204 | "lerp": {
1205 | "id": "lerp",
1206 | "returns": "out",
1207 | "specialInterface": false
1208 | },
1209 | "random": {
1210 | "id": "random",
1211 | "returns": "out",
1212 | "specialInterface": false
1213 | },
1214 | "transformMat4": {
1215 | "id": "transformMat4",
1216 | "returns": "out",
1217 | "specialInterface": false
1218 | },
1219 | "transformQuat": {
1220 | "id": "transformQuat",
1221 | "returns": "out",
1222 | "specialInterface": false
1223 | },
1224 | "str": {
1225 | "id": "str",
1226 | "returns": "BinaryExpression",
1227 | "specialInterface": true
1228 | },
1229 | "exactEquals": {
1230 | "id": "exactEquals",
1231 | "returns": "LogicalExpression",
1232 | "specialInterface": true
1233 | },
1234 | "equals": {
1235 | "id": "equals",
1236 | "returns": "LogicalExpression",
1237 | "specialInterface": true
1238 | }
1239 | }
1240 | }
--------------------------------------------------------------------------------
/interfaces/modules.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | "mat2",
3 | "mat2d",
4 | "mat3",
5 | "mat4",
6 | "quat",
7 | "vec2",
8 | "vec3",
9 | "vec4"
10 | ];
11 |
12 | module.exports = [
13 | "mat4"
14 | ];
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "glmw",
3 | "version": "0.1.3",
4 | "description": "WebAssembly powered Matrix and Vector library",
5 | "license": "MIT",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+ssh://git@github.com/maierfelix/glmw.git"
9 | },
10 | "main": "dist/glmw-node.js",
11 | "module": "dist/glmw-node.es.js",
12 | "keywords": [
13 | "matrix",
14 | "vector",
15 | "webgl",
16 | "webassembly",
17 | "wasm"
18 | ],
19 | "homepage": "http://maierfelix.github.io/glmw/",
20 | "author": "Felix Maier ",
21 | "contributors": [
22 | "Felix Maier (https://github.com/maierfelix)"
23 | ],
24 | "bugs": {
25 | "url": "https://github.com/maierfelix/glmw/issues"
26 | },
27 | "engines": {
28 | "node": ">= 6.x"
29 | },
30 | "scripts": {
31 | "dist": "npm run browser && npm run build",
32 | "build": "rollup -c rollup/rollup.config.cjs.js && rollup -c rollup/rollup.config.es.js",
33 | "browser": "node rollup/rollup.bundle.js"
34 | },
35 | "devDependencies": {
36 | "rollup": "^0.47.2",
37 | "rollup-plugin-buble": "^0.15.0",
38 | "rollup-plugin-commonjs": "^8.1.0",
39 | "rollup-plugin-json": "^2.3.0",
40 | "rollup-plugin-node-resolve": "^3.0.0",
41 | "webassembly": "^0.11.0"
42 | },
43 | "dependencies": {}
44 | }
45 |
--------------------------------------------------------------------------------
/rollup/compile.wasm.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const compiler = require("webassembly/cli/compiler");
3 |
4 | let source = `src/gl-matrix/`;
5 |
6 | let args = [
7 | "-q",
8 | "-O3",
9 | source + "main.c",
10 | "-o", "./wasm_tmp.wasm",
11 | "-i", source + "mat4.c",
12 | "-i", source + "vec3.c",
13 | "-i", source + "vec4.c"
14 | ];
15 |
16 | module.exports = function() {
17 | return new Promise((resolve) => {
18 | compiler.main(args, (e, path) => {
19 | if (e) throw e;
20 | let data = fs.readFileSync(path);
21 | let code = `
22 | let binary = new Uint8Array([${new Uint8Array(data).toString()}]);
23 | export default binary;
24 | `;
25 | fs.unlinkSync(path);
26 | fs.writeFileSync("src/module.js", code, "utf-8");
27 | resolve();
28 | });
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/rollup/rollup.bundle.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const pkg = require("../package.json");
3 | const wasm = require("./compile.wasm");
4 |
5 | const rollup = require("rollup");
6 | const json = require("rollup-plugin-json");
7 | const buble = require("rollup-plugin-buble");
8 | const resolve = require("rollup-plugin-node-resolve");
9 | const commonjs = require("rollup-plugin-commonjs");
10 |
11 | let config = {};
12 | config.entry = "src/index.js";
13 | config.moduleName = "glmw";
14 | config.useStrict = true;
15 | config.format = "iife";
16 | config.dest = pkg.browser;
17 | config.external = [];
18 | config.plugins = [
19 | json(),
20 | buble(),
21 | resolve({
22 | browser: true
23 | }),
24 | commonjs()
25 | ];
26 |
27 | const outputOptions = {};
28 |
29 | async function build() {
30 |
31 | await wasm();
32 |
33 | const bundle = await rollup.rollup(config);
34 |
35 | const { code, map } = await bundle.generate(config);
36 | fs.writeFileSync("dist/glmw-browser.js", code, "utf-8");
37 |
38 | }
39 |
40 | build();
41 |
--------------------------------------------------------------------------------
/rollup/rollup.config.cjs.js:
--------------------------------------------------------------------------------
1 | const pkg = require("../package.json");
2 | import config from "./rollup.config";
3 |
4 | config.format = "cjs";
5 | config.dest = pkg.main;
6 | config.paths = {};
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/rollup/rollup.config.es.js:
--------------------------------------------------------------------------------
1 | const pkg = require("../package.json");
2 | import config from "./rollup.config";
3 |
4 | config.format = "es";
5 | config.dest = pkg.module;
6 |
7 | export default config;
8 |
--------------------------------------------------------------------------------
/rollup/rollup.config.iife.js:
--------------------------------------------------------------------------------
1 | const pkg = require("../package.json");
2 | import config from "./rollup.config";
3 | import json from "rollup-plugin-json";
4 | import buble from "rollup-plugin-buble";
5 | import resolve from "rollup-plugin-node-resolve";
6 | import commonjs from "rollup-plugin-commonjs";
7 |
8 | config.format = "iife";
9 | config.dest = pkg.browser;
10 | config.external = [];
11 | config.plugins = [
12 | json(),
13 | buble(),
14 | resolve({
15 | jsnext: true,
16 | browser: true
17 | }),
18 | commonjs({
19 | namedExports: {}
20 | })
21 | ];
22 |
23 | export default config;
24 |
--------------------------------------------------------------------------------
/rollup/rollup.config.js:
--------------------------------------------------------------------------------
1 | import json from "rollup-plugin-json";
2 |
3 | export default {
4 | entry: "src/index.js",
5 | moduleName: "iroh",
6 | external: [],
7 | plugins: [
8 | json()
9 | ]
10 | };
11 |
--------------------------------------------------------------------------------
/src/gl-matrix/bridges/mat4.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The following methods need to be bridged
3 | * within js which results in some overhead
4 | */
5 | export default function(module, memory) {
6 | // @str
7 | module.str = function(address) {
8 | let view = memory.F32.subarray(address >> 2, (address >> 2) + 16);
9 | let out = "";
10 | for (let ii = 0; ii < 16; ++ii) {
11 | if (ii + 1 < 16) out += view[ii] + ", ";
12 | else out += view[ii];
13 | };
14 | return "mat4(" + out + ")";
15 | };
16 | // @view
17 | module.view = function(address) {
18 | let view = memory.F32.subarray(address >> 2, (address >> 2) + 16);
19 | //view.address = address;
20 | return view;
21 | };
22 | // @exactEquals
23 | let _exactEquals = module.exactEquals;
24 | module.exactEquals = function(a, b) {
25 | return !!_exactEquals(a, b);
26 | };
27 | // @equals
28 | let _equals = module.equals;
29 | module.equals = function(a, b) {
30 | return !!_equals(a, b);
31 | };
32 | };
33 |
--------------------------------------------------------------------------------
/src/gl-matrix/bridges/vec3.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The following methods need to be bridged
3 | * within js which results in some overhead
4 | */
5 | export default function(module, memory) {
6 | // @str
7 | module.str = function(address) {
8 | let view = memory.F32.subarray(address >> 2, (address >> 2) + 3);
9 | return `vec3(${ view[0] }, ${ view[1] }, ${ view[2] })`;
10 | };
11 | // @view
12 | module.view = function(address) {
13 | let view = memory.F32.subarray(address >> 2, (address >> 2) + 3);
14 | //view.address = address;
15 | return view;
16 | };
17 | // @exactEquals
18 | let _exactEquals = module.exactEquals;
19 | module.exactEquals = function(a, b) {
20 | return !!_exactEquals(a, b);
21 | };
22 | // @equals
23 | let _equals = module.equals;
24 | module.equals = function(a, b) {
25 | return !!_equals(a, b);
26 | };
27 | };
28 |
--------------------------------------------------------------------------------
/src/gl-matrix/bridges/vec4.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The following methods need to be bridged
3 | * within js which results in some overhead
4 | */
5 | export default function(module, memory) {
6 | // @str
7 | module.str = function(address) {
8 | let view = memory.F32.subarray(address >> 2, (address >> 2) + 4);
9 | return `vec4(${ view[0] }, ${ view[1] }, ${ view[2] }, ${ view[3] })`;
10 | };
11 | // @view
12 | module.view = function(address) {
13 | let view = memory.F32.subarray(address >> 2, (address >> 2) + 4);
14 | //view.address = address;
15 | return view;
16 | };
17 | // @exactEquals
18 | let _exactEquals = module.exactEquals;
19 | module.exactEquals = function(a, b) {
20 | return !!_exactEquals(a, b);
21 | };
22 | // @equals
23 | let _equals = module.equals;
24 | module.equals = function(a, b) {
25 | return !!_equals(a, b);
26 | };
27 | };
28 |
--------------------------------------------------------------------------------
/src/gl-matrix/common.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #ifndef FOO_H_
4 | #define FOO_H_
5 |
6 | import float randf();
7 |
8 | float const PI = 3.141592653589793;
9 |
10 | float const degree = PI / 180.0;
11 |
12 | float toRadian(a) {
13 | return a * degree;
14 | };
15 |
16 | float const EPSILON = 0.000001;
17 |
18 | // sizes
19 | int const VEC_SIZE_3 = 3;
20 | int const VEC_SIZE_4 = 4;
21 | int const MAT_SIZE_4 = 4 * 4;
22 |
23 | #endif
24 |
--------------------------------------------------------------------------------
/src/gl-matrix/main.c:
--------------------------------------------------------------------------------
1 | // entry
2 |
--------------------------------------------------------------------------------
/src/gl-matrix/mat4.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "common.h"
4 |
5 | #define mat4(x) mat4_##x
6 |
7 | /**
8 | * Frees a mat4
9 | */
10 | export float *mat4(free)(float *a) {
11 | free(a);
12 | return NULL;
13 | };
14 |
15 | /**
16 | * Creates a new identity mat4
17 | *
18 | * @returns {mat4} a new 4x4 matrix
19 | */
20 | export float *mat4(create)() {
21 | float *out = malloc(MAT_SIZE_4 * sizeof(*out));
22 | out[0] = 1;
23 | out[1] = 0;
24 | out[2] = 0;
25 | out[3] = 0;
26 | out[4] = 0;
27 | out[5] = 1;
28 | out[6] = 0;
29 | out[7] = 0;
30 | out[8] = 0;
31 | out[9] = 0;
32 | out[10] = 1;
33 | out[11] = 0;
34 | out[12] = 0;
35 | out[13] = 0;
36 | out[14] = 0;
37 | out[15] = 1;
38 | return out;
39 | };
40 |
41 | /**
42 | * Creates a new mat4 initialized with values from an existing matrix
43 | *
44 | * @param {mat4} a matrix to clone
45 | * @returns {mat4} a new 4x4 matrix
46 | */
47 | export float *mat4(clone)(float *a) {
48 | float *out = malloc(MAT_SIZE_4 * sizeof(float));
49 | out[0] = a[0];
50 | out[1] = a[1];
51 | out[2] = a[2];
52 | out[3] = a[3];
53 | out[4] = a[4];
54 | out[5] = a[5];
55 | out[6] = a[6];
56 | out[7] = a[7];
57 | out[8] = a[8];
58 | out[9] = a[9];
59 | out[10] = a[10];
60 | out[11] = a[11];
61 | out[12] = a[12];
62 | out[13] = a[13];
63 | out[14] = a[14];
64 | out[15] = a[15];
65 | return out;
66 | };
67 |
68 | /**
69 | * Copy the values from one mat4 to another
70 | *
71 | * @param {mat4} out the receiving matrix
72 | * @param {mat4} a the source matrix
73 | * @returns {mat4} out
74 | */
75 | export float *mat4(copy)(float *out, float *a) {
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 | out[9] = a[9];
86 | out[10] = a[10];
87 | out[11] = a[11];
88 | out[12] = a[12];
89 | out[13] = a[13];
90 | out[14] = a[14];
91 | out[15] = a[15];
92 | return out;
93 | };
94 |
95 | /**
96 | * Create a new mat4 with the given values
97 | *
98 | * @param {Number} m00 Component in column 0, row 0 position (index 0)
99 | * @param {Number} m01 Component in column 0, row 1 position (index 1)
100 | * @param {Number} m02 Component in column 0, row 2 position (index 2)
101 | * @param {Number} m03 Component in column 0, row 3 position (index 3)
102 | * @param {Number} m10 Component in column 1, row 0 position (index 4)
103 | * @param {Number} m11 Component in column 1, row 1 position (index 5)
104 | * @param {Number} m12 Component in column 1, row 2 position (index 6)
105 | * @param {Number} m13 Component in column 1, row 3 position (index 7)
106 | * @param {Number} m20 Component in column 2, row 0 position (index 8)
107 | * @param {Number} m21 Component in column 2, row 1 position (index 9)
108 | * @param {Number} m22 Component in column 2, row 2 position (index 10)
109 | * @param {Number} m23 Component in column 2, row 3 position (index 11)
110 | * @param {Number} m30 Component in column 3, row 0 position (index 12)
111 | * @param {Number} m31 Component in column 3, row 1 position (index 13)
112 | * @param {Number} m32 Component in column 3, row 2 position (index 14)
113 | * @param {Number} m33 Component in column 3, row 3 position (index 15)
114 | * @returns {mat4} A new mat4
115 | */
116 | export float *mat4(fromValues)(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33) {
117 | float *out = malloc(MAT_SIZE_4 * sizeof(*out));
118 | out[0] = m00;
119 | out[1] = m01;
120 | out[2] = m02;
121 | out[3] = m03;
122 | out[4] = m10;
123 | out[5] = m11;
124 | out[6] = m12;
125 | out[7] = m13;
126 | out[8] = m20;
127 | out[9] = m21;
128 | out[10] = m22;
129 | out[11] = m23;
130 | out[12] = m30;
131 | out[13] = m31;
132 | out[14] = m32;
133 | out[15] = m33;
134 | return out;
135 | };
136 |
137 | /**
138 | * Set the components of a mat4 to the given values
139 | *
140 | * @param {mat4} out the receiving matrix
141 | * @param {Number} m00 Component in column 0, row 0 position (index 0)
142 | * @param {Number} m01 Component in column 0, row 1 position (index 1)
143 | * @param {Number} m02 Component in column 0, row 2 position (index 2)
144 | * @param {Number} m03 Component in column 0, row 3 position (index 3)
145 | * @param {Number} m10 Component in column 1, row 0 position (index 4)
146 | * @param {Number} m11 Component in column 1, row 1 position (index 5)
147 | * @param {Number} m12 Component in column 1, row 2 position (index 6)
148 | * @param {Number} m13 Component in column 1, row 3 position (index 7)
149 | * @param {Number} m20 Component in column 2, row 0 position (index 8)
150 | * @param {Number} m21 Component in column 2, row 1 position (index 9)
151 | * @param {Number} m22 Component in column 2, row 2 position (index 10)
152 | * @param {Number} m23 Component in column 2, row 3 position (index 11)
153 | * @param {Number} m30 Component in column 3, row 0 position (index 12)
154 | * @param {Number} m31 Component in column 3, row 1 position (index 13)
155 | * @param {Number} m32 Component in column 3, row 2 position (index 14)
156 | * @param {Number} m33 Component in column 3, row 3 position (index 15)
157 | * @returns {mat4} out
158 | */
159 | export float *mat4(set)(float *out, float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33) {
160 | out[0] = m00;
161 | out[1] = m01;
162 | out[2] = m02;
163 | out[3] = m03;
164 | out[4] = m10;
165 | out[5] = m11;
166 | out[6] = m12;
167 | out[7] = m13;
168 | out[8] = m20;
169 | out[9] = m21;
170 | out[10] = m22;
171 | out[11] = m23;
172 | out[12] = m30;
173 | out[13] = m31;
174 | out[14] = m32;
175 | out[15] = m33;
176 | return out;
177 | };
178 |
179 | /**
180 | * Set a mat4 to the identity matrix
181 | *
182 | * @param {mat4} out the receiving matrix
183 | * @returns {mat4} out
184 | */
185 | export float *mat4(identity)(float *out) {
186 | out[0] = 1;
187 | out[1] = 0;
188 | out[2] = 0;
189 | out[3] = 0;
190 | out[4] = 0;
191 | out[5] = 1;
192 | out[6] = 0;
193 | out[7] = 0;
194 | out[8] = 0;
195 | out[9] = 0;
196 | out[10] = 1;
197 | out[11] = 0;
198 | out[12] = 0;
199 | out[13] = 0;
200 | out[14] = 0;
201 | out[15] = 1;
202 | return out;
203 | };
204 |
205 | /**
206 | * Transpose the values of a mat4
207 | *
208 | * @param {mat4} out the receiving matrix
209 | * @param {mat4} a the source matrix
210 | * @returns {mat4} out
211 | */
212 | export float *mat4(transpose)(float *out, float *a) {
213 | // If we are transposing ourselves we can skip a few steps but have to cache some values
214 | if (out == a) {
215 | float a01 = a[1], a02 = a[2], a03 = a[3];
216 | float a12 = a[6], a13 = a[7];
217 | float a23 = a[11];
218 |
219 | out[1] = a[4];
220 | out[2] = a[8];
221 | out[3] = a[12];
222 | out[4] = a01;
223 | out[6] = a[9];
224 | out[7] = a[13];
225 | out[8] = a02;
226 | out[9] = a12;
227 | out[11] = a[14];
228 | out[12] = a03;
229 | out[13] = a13;
230 | out[14] = a23;
231 | } else {
232 | out[0] = a[0];
233 | out[1] = a[4];
234 | out[2] = a[8];
235 | out[3] = a[12];
236 | out[4] = a[1];
237 | out[5] = a[5];
238 | out[6] = a[9];
239 | out[7] = a[13];
240 | out[8] = a[2];
241 | out[9] = a[6];
242 | out[10] = a[10];
243 | out[11] = a[14];
244 | out[12] = a[3];
245 | out[13] = a[7];
246 | out[14] = a[11];
247 | out[15] = a[15];
248 | }
249 |
250 | return out;
251 | };
252 |
253 | /**
254 | * Inverts a mat4
255 | *
256 | * @param {mat4} out the receiving matrix
257 | * @param {mat4} a the source matrix
258 | * @returns {mat4} out
259 | */
260 | export float *mat4(invert)(float *out, float *a) {
261 | float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
262 | float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
263 | float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
264 | float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
265 |
266 | float b00 = a00 * a11 - a01 * a10;
267 | float b01 = a00 * a12 - a02 * a10;
268 | float b02 = a00 * a13 - a03 * a10;
269 | float b03 = a01 * a12 - a02 * a11;
270 | float b04 = a01 * a13 - a03 * a11;
271 | float b05 = a02 * a13 - a03 * a12;
272 | float b06 = a20 * a31 - a21 * a30;
273 | float b07 = a20 * a32 - a22 * a30;
274 | float b08 = a20 * a33 - a23 * a30;
275 | float b09 = a21 * a32 - a22 * a31;
276 | float b10 = a21 * a33 - a23 * a31;
277 | float b11 = a22 * a33 - a23 * a32;
278 |
279 | // Calculate the determinant
280 | float det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
281 |
282 | if (!det) {
283 | return NULL;
284 | }
285 | det = 1.0 / det;
286 |
287 | out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
288 | out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
289 | out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
290 | out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
291 | out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
292 | out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
293 | out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
294 | out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
295 | out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
296 | out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
297 | out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
298 | out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
299 | out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
300 | out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
301 | out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
302 | out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
303 |
304 | return out;
305 | };
306 |
307 | /**
308 | * Calculates the adjugate of a mat4
309 | *
310 | * @param {mat4} out the receiving matrix
311 | * @param {mat4} a the source matrix
312 | * @returns {mat4} out
313 | */
314 | export float *mat4(adjoint)(float *out, float *a) {
315 | float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
316 | float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
317 | float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
318 | float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
319 |
320 | out[0] = (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22));
321 | out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
322 | out[2] = (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12));
323 | out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
324 | out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
325 | out[5] = (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22));
326 | out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
327 | out[7] = (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12));
328 | out[8] = (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21));
329 | out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
330 | out[10] = (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11));
331 | out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
332 | out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
333 | out[13] = (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21));
334 | out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
335 | out[15] = (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11));
336 | return out;
337 | };
338 |
339 | /**
340 | * Calculates the determinant of a mat4
341 | *
342 | * @param {mat4} a the source matrix
343 | * @returns {Number} determinant of a
344 | */
345 | export float mat4(determinant)(float *a) {
346 | float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
347 | float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
348 | float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
349 | float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
350 |
351 | float b00 = a00 * a11 - a01 * a10;
352 | float b01 = a00 * a12 - a02 * a10;
353 | float b02 = a00 * a13 - a03 * a10;
354 | float b03 = a01 * a12 - a02 * a11;
355 | float b04 = a01 * a13 - a03 * a11;
356 | float b05 = a02 * a13 - a03 * a12;
357 | float b06 = a20 * a31 - a21 * a30;
358 | float b07 = a20 * a32 - a22 * a30;
359 | float b08 = a20 * a33 - a23 * a30;
360 | float b09 = a21 * a32 - a22 * a31;
361 | float b10 = a21 * a33 - a23 * a31;
362 | float b11 = a22 * a33 - a23 * a32;
363 |
364 | // Calculate the determinant
365 | return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
366 | };
367 |
368 | /**
369 | * Multiplies two mat4s
370 | *
371 | * @param {mat4} out the receiving matrix
372 | * @param {mat4} a the first operand
373 | * @param {mat4} b the second operand
374 | * @returns {mat4} out
375 | */
376 | export float *mat4(multiply)(float *out, float *a, float *b) {
377 | float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
378 | float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
379 | float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
380 | float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
381 |
382 | // Cache only the current line of the second matrix
383 | float b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
384 | out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
385 | out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
386 | out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
387 | out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
388 |
389 | b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
390 | out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
391 | out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
392 | out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
393 | out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
394 |
395 | b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
396 | out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
397 | out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
398 | out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
399 | out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
400 |
401 | b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
402 | out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
403 | out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
404 | out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
405 | out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
406 | return out;
407 | };
408 |
409 | /**
410 | * Translate a mat4 by the given vector
411 | *
412 | * @param {mat4} out the receiving matrix
413 | * @param {mat4} a the matrix to translate
414 | * @param {vec3} v vector to translate by
415 | * @returns {mat4} out
416 | */
417 | export float *mat4(translate)(float *out, float *a, float *v) {
418 | float x = v[0], y = v[1], z = v[2];
419 | float a00, a01, a02, a03;
420 | float a10, a11, a12, a13;
421 | float a20, a21, a22, a23;
422 |
423 | if (a == out) {
424 | out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
425 | out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
426 | out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
427 | out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
428 | } else {
429 | a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
430 | a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
431 | a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
432 |
433 | out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
434 | out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
435 | out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;
436 |
437 | out[12] = a00 * x + a10 * y + a20 * z + a[12];
438 | out[13] = a01 * x + a11 * y + a21 * z + a[13];
439 | out[14] = a02 * x + a12 * y + a22 * z + a[14];
440 | out[15] = a03 * x + a13 * y + a23 * z + a[15];
441 | }
442 |
443 | return out;
444 | };
445 |
446 | /**
447 | * Scales the mat4 by the dimensions in the given vec3 not using vectorization
448 | *
449 | * @param {mat4} out the receiving matrix
450 | * @param {mat4} a the matrix to scale
451 | * @param {vec3} v the vec3 to scale the matrix by
452 | * @returns {mat4} out
453 | **/
454 | export float *mat4(scale)(float *out, float *a, float *v) {
455 | float x = v[0], y = v[1], z = v[2];
456 |
457 | out[0] = a[0] * x;
458 | out[1] = a[1] * x;
459 | out[2] = a[2] * x;
460 | out[3] = a[3] * x;
461 | out[4] = a[4] * y;
462 | out[5] = a[5] * y;
463 | out[6] = a[6] * y;
464 | out[7] = a[7] * y;
465 | out[8] = a[8] * z;
466 | out[9] = a[9] * z;
467 | out[10] = a[10] * z;
468 | out[11] = a[11] * z;
469 | out[12] = a[12];
470 | out[13] = a[13];
471 | out[14] = a[14];
472 | out[15] = a[15];
473 | return out;
474 | };
475 |
476 | /**
477 | * Rotates a mat4 by the given angle around the given axis
478 | *
479 | * @param {mat4} out the receiving matrix
480 | * @param {mat4} a the matrix to rotate
481 | * @param {Number} rad the angle to rotate the matrix by
482 | * @param {vec3} axis the axis to rotate around
483 | * @returns {mat4} out
484 | */
485 | export float *mat4(rotate)(float *out, float *a, float rad, float *axis) {
486 | float x = axis[0], y = axis[1], z = axis[2];
487 | float len = sqrtf(x * x + y * y + z * z);
488 | float s, c, t;
489 | float a00, a01, a02, a03;
490 | float a10, a11, a12, a13;
491 | float a20, a21, a22, a23;
492 | float b00, b01, b02;
493 | float b10, b11, b12;
494 | float b20, b21, b22;
495 |
496 | if (fabs(len) < EPSILON) { return NULL; }
497 |
498 | len = 1.0 / len;
499 | x *= len;
500 | y *= len;
501 | z *= len;
502 |
503 | s = sinf(rad);
504 | c = cosf(rad);
505 | t = 1 - c;
506 |
507 | a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
508 | a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
509 | a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
510 |
511 | // Construct the elements of the rotation matrix
512 | b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
513 | b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
514 | b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;
515 |
516 | // Perform rotation-specific matrix multiplication
517 | out[0] = a00 * b00 + a10 * b01 + a20 * b02;
518 | out[1] = a01 * b00 + a11 * b01 + a21 * b02;
519 | out[2] = a02 * b00 + a12 * b01 + a22 * b02;
520 | out[3] = a03 * b00 + a13 * b01 + a23 * b02;
521 | out[4] = a00 * b10 + a10 * b11 + a20 * b12;
522 | out[5] = a01 * b10 + a11 * b11 + a21 * b12;
523 | out[6] = a02 * b10 + a12 * b11 + a22 * b12;
524 | out[7] = a03 * b10 + a13 * b11 + a23 * b12;
525 | out[8] = a00 * b20 + a10 * b21 + a20 * b22;
526 | out[9] = a01 * b20 + a11 * b21 + a21 * b22;
527 | out[10] = a02 * b20 + a12 * b21 + a22 * b22;
528 | out[11] = a03 * b20 + a13 * b21 + a23 * b22;
529 |
530 | if (a != out) { // If the source and destination differ, copy the unchanged last row
531 | out[12] = a[12];
532 | out[13] = a[13];
533 | out[14] = a[14];
534 | out[15] = a[15];
535 | }
536 | return out;
537 | };
538 |
539 | /**
540 | * Rotates a matrix by the given angle around the X axis
541 | *
542 | * @param {mat4} out the receiving matrix
543 | * @param {mat4} a the matrix to rotate
544 | * @param {Number} rad the angle to rotate the matrix by
545 | * @returns {mat4} out
546 | */
547 | export float *mat4(rotateX)(float *out, float *a, float rad) {
548 | float s = sinf(rad);
549 | float c = cosf(rad);
550 | float a10 = a[4];
551 | float a11 = a[5];
552 | float a12 = a[6];
553 | float a13 = a[7];
554 | float a20 = a[8];
555 | float a21 = a[9];
556 | float a22 = a[10];
557 | float a23 = a[11];
558 |
559 | if (a != out) { // If the source and destination differ, copy the unchanged rows
560 | out[0] = a[0];
561 | out[1] = a[1];
562 | out[2] = a[2];
563 | out[3] = a[3];
564 | out[12] = a[12];
565 | out[13] = a[13];
566 | out[14] = a[14];
567 | out[15] = a[15];
568 | }
569 |
570 | // Perform axis-specific matrix multiplication
571 | out[4] = a10 * c + a20 * s;
572 | out[5] = a11 * c + a21 * s;
573 | out[6] = a12 * c + a22 * s;
574 | out[7] = a13 * c + a23 * s;
575 | out[8] = a20 * c - a10 * s;
576 | out[9] = a21 * c - a11 * s;
577 | out[10] = a22 * c - a12 * s;
578 | out[11] = a23 * c - a13 * s;
579 | return out;
580 | };
581 |
582 | /**
583 | * Rotates a matrix by the given angle around the Y axis
584 | *
585 | * @param {mat4} out the receiving matrix
586 | * @param {mat4} a the matrix to rotate
587 | * @param {Number} rad the angle to rotate the matrix by
588 | * @returns {mat4} out
589 | */
590 | export float *mat4(rotateY)(float *out, float *a, float rad) {
591 | float s = sinf(rad);
592 | float c = cosf(rad);
593 | float a00 = a[0];
594 | float a01 = a[1];
595 | float a02 = a[2];
596 | float a03 = a[3];
597 | float a20 = a[8];
598 | float a21 = a[9];
599 | float a22 = a[10];
600 | float a23 = a[11];
601 |
602 | if (a != out) { // If the source and destination differ, copy the unchanged rows
603 | out[4] = a[4];
604 | out[5] = a[5];
605 | out[6] = a[6];
606 | out[7] = a[7];
607 | out[12] = a[12];
608 | out[13] = a[13];
609 | out[14] = a[14];
610 | out[15] = a[15];
611 | }
612 |
613 | // Perform axis-specific matrix multiplication
614 | out[0] = a00 * c - a20 * s;
615 | out[1] = a01 * c - a21 * s;
616 | out[2] = a02 * c - a22 * s;
617 | out[3] = a03 * c - a23 * s;
618 | out[8] = a00 * s + a20 * c;
619 | out[9] = a01 * s + a21 * c;
620 | out[10] = a02 * s + a22 * c;
621 | out[11] = a03 * s + a23 * c;
622 | return out;
623 | };
624 |
625 | /**
626 | * Rotates a matrix by the given angle around the Z axis
627 | *
628 | * @param {mat4} out the receiving matrix
629 | * @param {mat4} a the matrix to rotate
630 | * @param {Number} rad the angle to rotate the matrix by
631 | * @returns {mat4} out
632 | */
633 | export float *mat4(rotateZ)(float *out, float *a, float rad) {
634 | float s = sinf(rad);
635 | float c = cosf(rad);
636 | float a00 = a[0];
637 | float a01 = a[1];
638 | float a02 = a[2];
639 | float a03 = a[3];
640 | float a10 = a[4];
641 | float a11 = a[5];
642 | float a12 = a[6];
643 | float a13 = a[7];
644 |
645 | if (a != out) { // If the source and destination differ, copy the unchanged last row
646 | out[8] = a[8];
647 | out[9] = a[9];
648 | out[10] = a[10];
649 | out[11] = a[11];
650 | out[12] = a[12];
651 | out[13] = a[13];
652 | out[14] = a[14];
653 | out[15] = a[15];
654 | }
655 |
656 | // Perform axis-specific matrix multiplication
657 | out[0] = a00 * c + a10 * s;
658 | out[1] = a01 * c + a11 * s;
659 | out[2] = a02 * c + a12 * s;
660 | out[3] = a03 * c + a13 * s;
661 | out[4] = a10 * c - a00 * s;
662 | out[5] = a11 * c - a01 * s;
663 | out[6] = a12 * c - a02 * s;
664 | out[7] = a13 * c - a03 * s;
665 | return out;
666 | };
667 |
668 | /**
669 | * Creates a matrix from a vector translation
670 | * This is equivalent to (but much faster than):
671 | *
672 | * mat4.identity(dest);
673 | * mat4.translate(dest, dest, vec);
674 | *
675 | * @param {mat4} out mat4 receiving operation result
676 | * @param {vec3} v Translation vector
677 | * @returns {mat4} out
678 | */
679 | export float *mat4(fromTranslation)(float *out, float *v) {
680 | out[0] = 1;
681 | out[1] = 0;
682 | out[2] = 0;
683 | out[3] = 0;
684 | out[4] = 0;
685 | out[5] = 1;
686 | out[6] = 0;
687 | out[7] = 0;
688 | out[8] = 0;
689 | out[9] = 0;
690 | out[10] = 1;
691 | out[11] = 0;
692 | out[12] = v[0];
693 | out[13] = v[1];
694 | out[14] = v[2];
695 | out[15] = 1;
696 | return out;
697 | };
698 |
699 | /**
700 | * Creates a matrix from a vector scaling
701 | * This is equivalent to (but much faster than):
702 | *
703 | * mat4.identity(dest);
704 | * mat4.scale(dest, dest, vec);
705 | *
706 | * @param {mat4} out mat4 receiving operation result
707 | * @param {vec3} v Scaling vector
708 | * @returns {mat4} out
709 | */
710 | export float *mat4(fromScaling)(float *out, float *v) {
711 | out[0] = v[0];
712 | out[1] = 0;
713 | out[2] = 0;
714 | out[3] = 0;
715 | out[4] = 0;
716 | out[5] = v[1];
717 | out[6] = 0;
718 | out[7] = 0;
719 | out[8] = 0;
720 | out[9] = 0;
721 | out[10] = v[2];
722 | out[11] = 0;
723 | out[12] = 0;
724 | out[13] = 0;
725 | out[14] = 0;
726 | out[15] = 1;
727 | return out;
728 | };
729 |
730 | /**
731 | * Creates a matrix from a given angle around a given axis
732 | * This is equivalent to (but much faster than):
733 | *
734 | * mat4.identity(dest);
735 | * mat4.rotate(dest, dest, rad, axis);
736 | *
737 | * @param {mat4} out mat4 receiving operation result
738 | * @param {Number} rad the angle to rotate the matrix by
739 | * @param {vec3} axis the axis to rotate around
740 | * @returns {mat4} out
741 | */
742 | export float *mat4(fromRotation)(float *out, float rad, float *axis) {
743 | float x = axis[0], y = axis[1], z = axis[2];
744 | float len = sqrtf(x * x + y * y + z * z);
745 | float s, c, t;
746 |
747 | if (fabs(len) < EPSILON) { return NULL; }
748 |
749 | len = 1.0 / len;
750 | x *= len;
751 | y *= len;
752 | z *= len;
753 |
754 | s = sinf(rad);
755 | c = cosf(rad);
756 | t = 1 - c;
757 |
758 | // Perform rotation-specific matrix multiplication
759 | out[0] = x * x * t + c;
760 | out[1] = y * x * t + z * s;
761 | out[2] = z * x * t - y * s;
762 | out[3] = 0;
763 | out[4] = x * y * t - z * s;
764 | out[5] = y * y * t + c;
765 | out[6] = z * y * t + x * s;
766 | out[7] = 0;
767 | out[8] = x * z * t + y * s;
768 | out[9] = y * z * t - x * s;
769 | out[10] = z * z * t + c;
770 | out[11] = 0;
771 | out[12] = 0;
772 | out[13] = 0;
773 | out[14] = 0;
774 | out[15] = 1;
775 | return out;
776 | };
777 |
778 | /**
779 | * Creates a matrix from the given angle around the X axis
780 | * This is equivalent to (but much faster than):
781 | *
782 | * mat4.identity(dest);
783 | * mat4.rotateX(dest, dest, rad);
784 | *
785 | * @param {mat4} out mat4 receiving operation result
786 | * @param {Number} rad the angle to rotate the matrix by
787 | * @returns {mat4} out
788 | */
789 | export float *mat4(fromXRotation)(float *out, float rad) {
790 | float s = sinf(rad);
791 | float c = cosf(rad);
792 |
793 | // Perform axis-specific matrix multiplication
794 | out[0] = 1;
795 | out[1] = 0;
796 | out[2] = 0;
797 | out[3] = 0;
798 | out[4] = 0;
799 | out[5] = c;
800 | out[6] = s;
801 | out[7] = 0;
802 | out[8] = 0;
803 | out[9] = -s;
804 | out[10] = c;
805 | out[11] = 0;
806 | out[12] = 0;
807 | out[13] = 0;
808 | out[14] = 0;
809 | out[15] = 1;
810 | return out;
811 | };
812 |
813 | /**
814 | * Creates a matrix from the given angle around the Y axis
815 | * This is equivalent to (but much faster than):
816 | *
817 | * mat4.identity(dest);
818 | * mat4.rotateY(dest, dest, rad);
819 | *
820 | * @param {mat4} out mat4 receiving operation result
821 | * @param {Number} rad the angle to rotate the matrix by
822 | * @returns {mat4} out
823 | */
824 | export float *mat4(fromYRotation)(float *out, float rad) {
825 | float s = sinf(rad);
826 | float c = cosf(rad);
827 |
828 | // Perform axis-specific matrix multiplication
829 | out[0] = c;
830 | out[1] = 0;
831 | out[2] = -s;
832 | out[3] = 0;
833 | out[4] = 0;
834 | out[5] = 1;
835 | out[6] = 0;
836 | out[7] = 0;
837 | out[8] = s;
838 | out[9] = 0;
839 | out[10] = c;
840 | out[11] = 0;
841 | out[12] = 0;
842 | out[13] = 0;
843 | out[14] = 0;
844 | out[15] = 1;
845 | return out;
846 | };
847 |
848 | /**
849 | * Creates a matrix from the given angle around the Z axis
850 | * This is equivalent to (but much faster than):
851 | *
852 | * mat4.identity(dest);
853 | * mat4.rotateZ(dest, dest, rad);
854 | *
855 | * @param {mat4} out mat4 receiving operation result
856 | * @param {Number} rad the angle to rotate the matrix by
857 | * @returns {mat4} out
858 | */
859 | export float *mat4(fromZRotation)(float *out, float rad) {
860 | float s = sinf(rad);
861 | float c = cosf(rad);
862 |
863 | // Perform axis-specific matrix multiplication
864 | out[0] = c;
865 | out[1] = s;
866 | out[2] = 0;
867 | out[3] = 0;
868 | out[4] = -s;
869 | out[5] = c;
870 | out[6] = 0;
871 | out[7] = 0;
872 | out[8] = 0;
873 | out[9] = 0;
874 | out[10] = 1;
875 | out[11] = 0;
876 | out[12] = 0;
877 | out[13] = 0;
878 | out[14] = 0;
879 | out[15] = 1;
880 | return out;
881 | };
882 |
883 | /**
884 | * Creates a matrix from a quaternion rotation and vector translation
885 | * This is equivalent to (but much faster than):
886 | *
887 | * mat4.identity(dest);
888 | * mat4.translate(dest, vec);
889 | * let quatMat = mat4.create();
890 | * quat4.toMat4(quat, quatMat);
891 | * mat4.multiply(dest, quatMat);
892 | *
893 | * @param {mat4} out mat4 receiving operation result
894 | * @param {quat4} q Rotation quaternion
895 | * @param {vec3} v Translation vector
896 | * @returns {mat4} out
897 | */
898 | export float *mat4(fromRotationTranslation)(float *out, float *q, float *v) {
899 | // Quaternion math
900 | float x = q[0], y = q[1], z = q[2], w = q[3];
901 | float x2 = x + x;
902 | float y2 = y + y;
903 | float z2 = z + z;
904 |
905 | float xx = x * x2;
906 | float xy = x * y2;
907 | float xz = x * z2;
908 | float yy = y * y2;
909 | float yz = y * z2;
910 | float zz = z * z2;
911 | float wx = w * x2;
912 | float wy = w * y2;
913 | float wz = w * z2;
914 |
915 | out[0] = 1 - (yy + zz);
916 | out[1] = xy + wz;
917 | out[2] = xz - wy;
918 | out[3] = 0;
919 | out[4] = xy - wz;
920 | out[5] = 1 - (xx + zz);
921 | out[6] = yz + wx;
922 | out[7] = 0;
923 | out[8] = xz + wy;
924 | out[9] = yz - wx;
925 | out[10] = 1 - (xx + yy);
926 | out[11] = 0;
927 | out[12] = v[0];
928 | out[13] = v[1];
929 | out[14] = v[2];
930 | out[15] = 1;
931 |
932 | return out;
933 | };
934 |
935 | /**
936 | * Returns the translation vector component of a transformation
937 | * matrix. If a matrix is built with fromRotationTranslation,
938 | * the returned vector will be the same as the translation vector
939 | * originally supplied.
940 | * @param {vec3} out Vector to receive translation component
941 | * @param {mat4} mat Matrix to be decomposed (input)
942 | * @return {vec3} out
943 | */
944 | export float *mat4(getTranslation)(float *out, float *mat) {
945 | out[0] = mat[12];
946 | out[1] = mat[13];
947 | out[2] = mat[14];
948 |
949 | return out;
950 | };
951 |
952 | /**
953 | * Returns the scaling factor component of a transformation
954 | * matrix. If a matrix is built with fromRotationTranslationScale
955 | * with a normalized Quaternion paramter, the returned vector will be
956 | * the same as the scaling vector
957 | * originally supplied.
958 | * @param {vec3} out Vector to receive scaling factor component
959 | * @param {mat4} mat Matrix to be decomposed (input)
960 | * @return {vec3} out
961 | */
962 | export float *mat4(getScaling)(float *out, float *mat) {
963 | float m11 = mat[0];
964 | float m12 = mat[1];
965 | float m13 = mat[2];
966 | float m21 = mat[4];
967 | float m22 = mat[5];
968 | float m23 = mat[6];
969 | float m31 = mat[8];
970 | float m32 = mat[9];
971 | float m33 = mat[10];
972 |
973 | out[0] = sqrtf(m11 * m11 + m12 * m12 + m13 * m13);
974 | out[1] = sqrtf(m21 * m21 + m22 * m22 + m23 * m23);
975 | out[2] = sqrtf(m31 * m31 + m32 * m32 + m33 * m33);
976 |
977 | return out;
978 | };
979 |
980 | /**
981 | * Returns a quaternion representing the rotational component
982 | * of a transformation matrix. If a matrix is built with
983 | * fromRotationTranslation, the returned quaternion will be the
984 | * same as the quaternion originally supplied.
985 | * @param {quat} out Quaternion to receive the rotation component
986 | * @param {mat4} mat Matrix to be decomposed (input)
987 | * @return {quat} out
988 | */
989 | export float *mat4(getRotation)(float *out, float *mat) {
990 | // Algorithm taken from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
991 | float trace = mat[0] + mat[5] + mat[10];
992 | float S = 0;
993 |
994 | if (trace > 0) {
995 | S = sqrtf(trace + 1.0) * 2;
996 | out[3] = 0.25 * S;
997 | out[0] = (mat[6] - mat[9]) / S;
998 | out[1] = (mat[8] - mat[2]) / S;
999 | out[2] = (mat[1] - mat[4]) / S;
1000 | } else if ((mat[0] > mat[5])&(mat[0] > mat[10])) {
1001 | S = sqrtf(1.0 + mat[0] - mat[5] - mat[10]) * 2;
1002 | out[3] = (mat[6] - mat[9]) / S;
1003 | out[0] = 0.25 * S;
1004 | out[1] = (mat[1] + mat[4]) / S;
1005 | out[2] = (mat[8] + mat[2]) / S;
1006 | } else if (mat[5] > mat[10]) {
1007 | S = sqrtf(1.0 + mat[5] - mat[0] - mat[10]) * 2;
1008 | out[3] = (mat[8] - mat[2]) / S;
1009 | out[0] = (mat[1] + mat[4]) / S;
1010 | out[1] = 0.25 * S;
1011 | out[2] = (mat[6] + mat[9]) / S;
1012 | } else {
1013 | S = sqrtf(1.0 + mat[10] - mat[0] - mat[5]) * 2;
1014 | out[3] = (mat[1] - mat[4]) / S;
1015 | out[0] = (mat[8] + mat[2]) / S;
1016 | out[1] = (mat[6] + mat[9]) / S;
1017 | out[2] = 0.25 * S;
1018 | }
1019 |
1020 | return out;
1021 | };
1022 |
1023 | /**
1024 | * Creates a matrix from a quaternion rotation, vector translation and vector scale
1025 | * This is equivalent to (but much faster than):
1026 | *
1027 | * mat4.identity(dest);
1028 | * mat4.translate(dest, vec);
1029 | * let quatMat = mat4.create();
1030 | * quat4.toMat4(quat, quatMat);
1031 | * mat4.multiply(dest, quatMat);
1032 | * mat4.scale(dest, scale)
1033 | *
1034 | * @param {mat4} out mat4 receiving operation result
1035 | * @param {quat4} q Rotation quaternion
1036 | * @param {vec3} v Translation vector
1037 | * @param {vec3} s Scaling vector
1038 | * @returns {mat4} out
1039 | */
1040 | export float *mat4(fromRotationTranslationScale)(float *out, float *q, float *v, float *s) {
1041 | // Quaternion math
1042 | float x = q[0], y = q[1], z = q[2], w = q[3];
1043 | float x2 = x + x;
1044 | float y2 = y + y;
1045 | float z2 = z + z;
1046 |
1047 | float xx = x * x2;
1048 | float xy = x * y2;
1049 | float xz = x * z2;
1050 | float yy = y * y2;
1051 | float yz = y * z2;
1052 | float zz = z * z2;
1053 | float wx = w * x2;
1054 | float wy = w * y2;
1055 | float wz = w * z2;
1056 | float sx = s[0];
1057 | float sy = s[1];
1058 | float sz = s[2];
1059 |
1060 | out[0] = (1 - (yy + zz)) * sx;
1061 | out[1] = (xy + wz) * sx;
1062 | out[2] = (xz - wy) * sx;
1063 | out[3] = 0;
1064 | out[4] = (xy - wz) * sy;
1065 | out[5] = (1 - (xx + zz)) * sy;
1066 | out[6] = (yz + wx) * sy;
1067 | out[7] = 0;
1068 | out[8] = (xz + wy) * sz;
1069 | out[9] = (yz - wx) * sz;
1070 | out[10] = (1 - (xx + yy)) * sz;
1071 | out[11] = 0;
1072 | out[12] = v[0];
1073 | out[13] = v[1];
1074 | out[14] = v[2];
1075 | out[15] = 1;
1076 |
1077 | return out;
1078 | };
1079 |
1080 | /**
1081 | * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin
1082 | * This is equivalent to (but much faster than):
1083 | *
1084 | * mat4.identity(dest);
1085 | * mat4.translate(dest, vec);
1086 | * mat4.translate(dest, origin);
1087 | * let quatMat = mat4.create();
1088 | * quat4.toMat4(quat, quatMat);
1089 | * mat4.multiply(dest, quatMat);
1090 | * mat4.scale(dest, scale)
1091 | * mat4.translate(dest, negativeOrigin);
1092 | *
1093 | * @param {mat4} out mat4 receiving operation result
1094 | * @param {quat4} q Rotation quaternion
1095 | * @param {vec3} v Translation vector
1096 | * @param {vec3} s Scaling vector
1097 | * @param {vec3} o The origin vector around which to scale and rotate
1098 | * @returns {mat4} out
1099 | */
1100 | export float *mat4(fromRotationTranslationScaleOrigin)(float *out, float *q, float *v, float *s, float *o) {
1101 | // Quaternion math
1102 | float x = q[0], y = q[1], z = q[2], w = q[3];
1103 | float x2 = x + x;
1104 | float y2 = y + y;
1105 | float z2 = z + z;
1106 |
1107 | float xx = x * x2;
1108 | float xy = x * y2;
1109 | float xz = x * z2;
1110 | float yy = y * y2;
1111 | float yz = y * z2;
1112 | float zz = z * z2;
1113 | float wx = w * x2;
1114 | float wy = w * y2;
1115 | float wz = w * z2;
1116 |
1117 | float sx = s[0];
1118 | float sy = s[1];
1119 | float sz = s[2];
1120 |
1121 | float ox = o[0];
1122 | float oy = o[1];
1123 | float oz = o[2];
1124 |
1125 | out[0] = (1 - (yy + zz)) * sx;
1126 | out[1] = (xy + wz) * sx;
1127 | out[2] = (xz - wy) * sx;
1128 | out[3] = 0;
1129 | out[4] = (xy - wz) * sy;
1130 | out[5] = (1 - (xx + zz)) * sy;
1131 | out[6] = (yz + wx) * sy;
1132 | out[7] = 0;
1133 | out[8] = (xz + wy) * sz;
1134 | out[9] = (yz - wx) * sz;
1135 | out[10] = (1 - (xx + yy)) * sz;
1136 | out[11] = 0;
1137 | out[12] = v[0] + ox - (out[0] * ox + out[4] * oy + out[8] * oz);
1138 | out[13] = v[1] + oy - (out[1] * ox + out[5] * oy + out[9] * oz);
1139 | out[14] = v[2] + oz - (out[2] * ox + out[6] * oy + out[10] * oz);
1140 | out[15] = 1;
1141 |
1142 | return out;
1143 | };
1144 |
1145 | /**
1146 | * Calculates a 4x4 matrix from the given quaternion
1147 | *
1148 | * @param {mat4} out mat4 receiving operation result
1149 | * @param {quat} q Quaternion to create matrix from
1150 | *
1151 | * @returns {mat4} out
1152 | */
1153 | export float *mat4(fromQuat)(float *out, float *q) {
1154 | float x = q[0], y = q[1], z = q[2], w = q[3];
1155 | float x2 = x + x;
1156 | float y2 = y + y;
1157 | float z2 = z + z;
1158 |
1159 | float xx = x * x2;
1160 | float yx = y * x2;
1161 | float yy = y * y2;
1162 | float zx = z * x2;
1163 | float zy = z * y2;
1164 | float zz = z * z2;
1165 | float wx = w * x2;
1166 | float wy = w * y2;
1167 | float wz = w * z2;
1168 |
1169 | out[0] = 1 - yy - zz;
1170 | out[1] = yx + wz;
1171 | out[2] = zx - wy;
1172 | out[3] = 0;
1173 |
1174 | out[4] = yx - wz;
1175 | out[5] = 1 - xx - zz;
1176 | out[6] = zy + wx;
1177 | out[7] = 0;
1178 |
1179 | out[8] = zx + wy;
1180 | out[9] = zy - wx;
1181 | out[10] = 1 - xx - yy;
1182 | out[11] = 0;
1183 |
1184 | out[12] = 0;
1185 | out[13] = 0;
1186 | out[14] = 0;
1187 | out[15] = 1;
1188 |
1189 | return out;
1190 | };
1191 |
1192 | /**
1193 | * Generates a frustum matrix with the given bounds
1194 | *
1195 | * @param {mat4} out mat4 frustum matrix will be written into
1196 | * @param {Number} left Left bound of the frustum
1197 | * @param {Number} right Right bound of the frustum
1198 | * @param {Number} bottom Bottom bound of the frustum
1199 | * @param {Number} top Top bound of the frustum
1200 | * @param {Number} near Near bound of the frustum
1201 | * @param {Number} far Far bound of the frustum
1202 | * @returns {mat4} out
1203 | */
1204 | export float *mat4(frustum)(float *out, float left, float right, float bottom, float top, float near, float far) {
1205 | float rl = 1.0 / (right - left);
1206 | float tb = 1.0 / (top - bottom);
1207 | float nf = 1.0 / (near - far);
1208 | out[0] = (near * 2) * rl;
1209 | out[1] = 0;
1210 | out[2] = 0;
1211 | out[3] = 0;
1212 | out[4] = 0;
1213 | out[5] = (near * 2) * tb;
1214 | out[6] = 0;
1215 | out[7] = 0;
1216 | out[8] = (right + left) * rl;
1217 | out[9] = (top + bottom) * tb;
1218 | out[10] = (far + near) * nf;
1219 | out[11] = -1;
1220 | out[12] = 0;
1221 | out[13] = 0;
1222 | out[14] = (far * near * 2) * nf;
1223 | out[15] = 0;
1224 | return out;
1225 | };
1226 |
1227 | /**
1228 | * Generates a perspective projection matrix with the given bounds
1229 | *
1230 | * @param {mat4} out mat4 frustum matrix will be written into
1231 | * @param {number} fovy Vertical field of view in radians
1232 | * @param {number} aspect Aspect ratio. typically viewport width/height
1233 | * @param {number} near Near bound of the frustum
1234 | * @param {number} far Far bound of the frustum
1235 | * @returns {mat4} out
1236 | */
1237 | export float *mat4(perspective)(float *out, float fovy, float aspect, float near, float far) {
1238 | float f = 1.0 / tanf(fovy / 2);
1239 | float nf = 1.0 / (near - far);
1240 | out[0] = f / aspect;
1241 | out[1] = 0;
1242 | out[2] = 0;
1243 | out[3] = 0;
1244 | out[4] = 0;
1245 | out[5] = f;
1246 | out[6] = 0;
1247 | out[7] = 0;
1248 | out[8] = 0;
1249 | out[9] = 0;
1250 | out[10] = (far + near) * nf;
1251 | out[11] = -1;
1252 | out[12] = 0;
1253 | out[13] = 0;
1254 | out[14] = (2 * far * near) * nf;
1255 | out[15] = 0;
1256 | return out;
1257 | };
1258 |
1259 | /**
1260 | * Generates a perspective projection matrix with the given field of view.
1261 | * This is primarily useful for generating projection matrices to be used
1262 | * with the still experiemental WebVR API.
1263 | *
1264 | * @param {mat4} out mat4 frustum matrix will be written into
1265 | * @param {number} upDegrees Property of Object "fov"
1266 | * @param {number} downDegrees Property of Object "fov"
1267 | * @param {number} leftDegrees Property of Object "fov"
1268 | * @param {number} rightDegrees Property of Object "fov"
1269 | * @param {number} near Near bound of the frustum
1270 | * @param {number} far Far bound of the frustum
1271 | * @returns {mat4} out
1272 | */
1273 | export float *mat4(perspectiveFromFieldOfView)(float *out, float upDegrees, float downDegrees, float leftDegrees, float rightDegrees, float near, float far) {
1274 | float upTan = tanf(upDegrees * M_PI/180.0);
1275 | float downTan = tanf(downDegrees * M_PI/180.0);
1276 | float leftTan = tanf(leftDegrees * M_PI/180.0);
1277 | float rightTan = tanf(rightDegrees * M_PI/180.0);
1278 | float xScale = 2.0 / (leftTan + rightTan);
1279 | float yScale = 2.0 / (upTan + downTan);
1280 |
1281 | out[0] = xScale;
1282 | out[1] = 0.0;
1283 | out[2] = 0.0;
1284 | out[3] = 0.0;
1285 | out[4] = 0.0;
1286 | out[5] = yScale;
1287 | out[6] = 0.0;
1288 | out[7] = 0.0;
1289 | out[8] = -((leftTan - rightTan) * xScale * 0.5);
1290 | out[9] = ((upTan - downTan) * yScale * 0.5);
1291 | out[10] = far / (near - far);
1292 | out[11] = -1.0;
1293 | out[12] = 0.0;
1294 | out[13] = 0.0;
1295 | out[14] = (far * near) / (near - far);
1296 | out[15] = 0.0;
1297 | return out;
1298 | };
1299 |
1300 | /**
1301 | * Generates a orthogonal projection matrix with the given bounds
1302 | *
1303 | * @param {mat4} out mat4 frustum matrix will be written into
1304 | * @param {number} left Left bound of the frustum
1305 | * @param {number} right Right bound of the frustum
1306 | * @param {number} bottom Bottom bound of the frustum
1307 | * @param {number} top Top bound of the frustum
1308 | * @param {number} near Near bound of the frustum
1309 | * @param {number} far Far bound of the frustum
1310 | * @returns {mat4} out
1311 | */
1312 | export float *mat4(ortho)(float *out, float left, float right, float bottom, float top, float near, float far) {
1313 | float lr = 1.0 / (left - right);
1314 | float bt = 1.0 / (bottom - top);
1315 | float nf = 1.0 / (near - far);
1316 | out[0] = -2 * lr;
1317 | out[1] = 0;
1318 | out[2] = 0;
1319 | out[3] = 0;
1320 | out[4] = 0;
1321 | out[5] = -2 * bt;
1322 | out[6] = 0;
1323 | out[7] = 0;
1324 | out[8] = 0;
1325 | out[9] = 0;
1326 | out[10] = 2 * nf;
1327 | out[11] = 0;
1328 | out[12] = (left + right) * lr;
1329 | out[13] = (top + bottom) * bt;
1330 | out[14] = (far + near) * nf;
1331 | out[15] = 1;
1332 | return out;
1333 | };
1334 |
1335 | /**
1336 | * Generates a look-at matrix with the given eye position, focal point, and up axis
1337 | *
1338 | * @param {mat4} out mat4 frustum matrix will be written into
1339 | * @param {vec3} eye Position of the viewer
1340 | * @param {vec3} center Point the viewer is looking at
1341 | * @param {vec3} up vec3 pointing up
1342 | * @returns {mat4} out
1343 | */
1344 | export float *mat4(lookAt)(float *out, float *eye, float *center, float *up) {
1345 | float x0, x1, x2, y0, y1, y2, z0, z1, z2, len;
1346 | float eyex = eye[0];
1347 | float eyey = eye[1];
1348 | float eyez = eye[2];
1349 | float upx = up[0];
1350 | float upy = up[1];
1351 | float upz = up[2];
1352 | float centerx = center[0];
1353 | float centery = center[1];
1354 | float centerz = center[2];
1355 |
1356 | if (fabs(eyex - centerx) < EPSILON &&
1357 | fabs(eyey - centery) < EPSILON &&
1358 | fabs(eyez - centerz) < EPSILON) {
1359 | return mat4(identity)(out);
1360 | }
1361 |
1362 | z0 = eyex - centerx;
1363 | z1 = eyey - centery;
1364 | z2 = eyez - centerz;
1365 |
1366 | len = 1.0 / sqrtf(z0 * z0 + z1 * z1 + z2 * z2);
1367 | z0 *= len;
1368 | z1 *= len;
1369 | z2 *= len;
1370 |
1371 | x0 = upy * z2 - upz * z1;
1372 | x1 = upz * z0 - upx * z2;
1373 | x2 = upx * z1 - upy * z0;
1374 | len = sqrtf(x0 * x0 + x1 * x1 + x2 * x2);
1375 | if (!len) {
1376 | x0 = 0;
1377 | x1 = 0;
1378 | x2 = 0;
1379 | } else {
1380 | len = 1.0 / len;
1381 | x0 *= len;
1382 | x1 *= len;
1383 | x2 *= len;
1384 | }
1385 |
1386 | y0 = z1 * x2 - z2 * x1;
1387 | y1 = z2 * x0 - z0 * x2;
1388 | y2 = z0 * x1 - z1 * x0;
1389 |
1390 | len = sqrtf(y0 * y0 + y1 * y1 + y2 * y2);
1391 | if (!len) {
1392 | y0 = 0;
1393 | y1 = 0;
1394 | y2 = 0;
1395 | } else {
1396 | len = 1.0 / len;
1397 | y0 *= len;
1398 | y1 *= len;
1399 | y2 *= len;
1400 | }
1401 |
1402 | out[0] = x0;
1403 | out[1] = y0;
1404 | out[2] = z0;
1405 | out[3] = 0;
1406 | out[4] = x1;
1407 | out[5] = y1;
1408 | out[6] = z1;
1409 | out[7] = 0;
1410 | out[8] = x2;
1411 | out[9] = y2;
1412 | out[10] = z2;
1413 | out[11] = 0;
1414 | out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
1415 | out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
1416 | out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
1417 | out[15] = 1;
1418 |
1419 | return out;
1420 | };
1421 |
1422 | /**
1423 | * Generates a matrix that makes something look at something else.
1424 | *
1425 | * @param {mat4} out mat4 frustum matrix will be written into
1426 | * @param {vec3} eye Position of the viewer
1427 | * @param {vec3} target Point the viewer is looking at
1428 | * @param {vec3} up vec3 pointing up
1429 | * @returns {mat4} out
1430 | */
1431 | export float *mat4(targetTo)(float *out, float *eye, float *target, float *up) {
1432 | float eyex = eye[0],
1433 | eyey = eye[1],
1434 | eyez = eye[2],
1435 | upx = up[0],
1436 | upy = up[1],
1437 | upz = up[2];
1438 |
1439 | float z0 = eyex - target[0],
1440 | z1 = eyey - target[1],
1441 | z2 = eyez - target[2];
1442 |
1443 | float len = z0*z0 + z1*z1 + z2*z2;
1444 | if (len > 0) {
1445 | len = 1.0 / sqrtf(len);
1446 | z0 *= len;
1447 | z1 *= len;
1448 | z2 *= len;
1449 | }
1450 |
1451 | float x0 = upy * z2 - upz * z1,
1452 | x1 = upz * z0 - upx * z2,
1453 | x2 = upx * z1 - upy * z0;
1454 |
1455 | out[0] = x0;
1456 | out[1] = x1;
1457 | out[2] = x2;
1458 | out[3] = 0;
1459 | out[4] = z1 * x2 - z2 * x1;
1460 | out[5] = z2 * x0 - z0 * x2;
1461 | out[6] = z0 * x1 - z1 * x0;
1462 | out[7] = 0;
1463 | out[8] = z0;
1464 | out[9] = z1;
1465 | out[10] = z2;
1466 | out[11] = 0;
1467 | out[12] = eyex;
1468 | out[13] = eyey;
1469 | out[14] = eyez;
1470 | out[15] = 1;
1471 | return out;
1472 | };
1473 |
1474 | /**
1475 | * Returns a string representation of a mat4
1476 | *
1477 | * @param {mat4} a matrix to represent as a string
1478 | * @returns {String} string representation of the matrix
1479 | */
1480 | export float *mat4(str)(float *a) {
1481 | return a;
1482 | };
1483 |
1484 | /**
1485 | * Returns Frobenius norm of a mat4
1486 | *
1487 | * @param {mat4} a the matrix to calculate Frobenius norm of
1488 | * @returns {Number} Frobenius norm
1489 | */
1490 | export float mat4(frob)(float *a) {
1491 | return(sqrt(
1492 | powf(a[0], 2) +
1493 | powf(a[1], 2) +
1494 | powf(a[2], 2) +
1495 | powf(a[3], 2) +
1496 | powf(a[4], 2) +
1497 | powf(a[5], 2) +
1498 | powf(a[6], 2) +
1499 | powf(a[7], 2) +
1500 | powf(a[8], 2) +
1501 | powf(a[9], 2) +
1502 | powf(a[10], 2) +
1503 | powf(a[11], 2) +
1504 | powf(a[12], 2) +
1505 | powf(a[13], 2) +
1506 | powf(a[14], 2) +
1507 | powf(a[15], 2) ));
1508 | };
1509 |
1510 | /**
1511 | * Adds two mat4's
1512 | *
1513 | * @param {mat4} out the receiving matrix
1514 | * @param {mat4} a the first operand
1515 | * @param {mat4} b the second operand
1516 | * @returns {mat4} out
1517 | */
1518 | export float *mat4(add)(float *out, float *a, float *b) {
1519 | out[0] = a[0] + b[0];
1520 | out[1] = a[1] + b[1];
1521 | out[2] = a[2] + b[2];
1522 | out[3] = a[3] + b[3];
1523 | out[4] = a[4] + b[4];
1524 | out[5] = a[5] + b[5];
1525 | out[6] = a[6] + b[6];
1526 | out[7] = a[7] + b[7];
1527 | out[8] = a[8] + b[8];
1528 | out[9] = a[9] + b[9];
1529 | out[10] = a[10] + b[10];
1530 | out[11] = a[11] + b[11];
1531 | out[12] = a[12] + b[12];
1532 | out[13] = a[13] + b[13];
1533 | out[14] = a[14] + b[14];
1534 | out[15] = a[15] + b[15];
1535 | return out;
1536 | };
1537 |
1538 | /**
1539 | * Subtracts matrix b from matrix a
1540 | *
1541 | * @param {mat4} out the receiving matrix
1542 | * @param {mat4} a the first operand
1543 | * @param {mat4} b the second operand
1544 | * @returns {mat4} out
1545 | */
1546 | export float *mat4(subtract)(float *out, float *a, float *b) {
1547 | out[0] = a[0] - b[0];
1548 | out[1] = a[1] - b[1];
1549 | out[2] = a[2] - b[2];
1550 | out[3] = a[3] - b[3];
1551 | out[4] = a[4] - b[4];
1552 | out[5] = a[5] - b[5];
1553 | out[6] = a[6] - b[6];
1554 | out[7] = a[7] - b[7];
1555 | out[8] = a[8] - b[8];
1556 | out[9] = a[9] - b[9];
1557 | out[10] = a[10] - b[10];
1558 | out[11] = a[11] - b[11];
1559 | out[12] = a[12] - b[12];
1560 | out[13] = a[13] - b[13];
1561 | out[14] = a[14] - b[14];
1562 | out[15] = a[15] - b[15];
1563 | return out;
1564 | };
1565 |
1566 | /**
1567 | * Multiply each element of the matrix by a scalar.
1568 | *
1569 | * @param {mat4} out the receiving matrix
1570 | * @param {mat4} a the matrix to scale
1571 | * @param {Number} b amount to scale the matrix's elements by
1572 | * @returns {mat4} out
1573 | */
1574 | export float *mat4(multiplyScalar)(float *out, float *a, float b) {
1575 | out[0] = a[0] * b;
1576 | out[1] = a[1] * b;
1577 | out[2] = a[2] * b;
1578 | out[3] = a[3] * b;
1579 | out[4] = a[4] * b;
1580 | out[5] = a[5] * b;
1581 | out[6] = a[6] * b;
1582 | out[7] = a[7] * b;
1583 | out[8] = a[8] * b;
1584 | out[9] = a[9] * b;
1585 | out[10] = a[10] * b;
1586 | out[11] = a[11] * b;
1587 | out[12] = a[12] * b;
1588 | out[13] = a[13] * b;
1589 | out[14] = a[14] * b;
1590 | out[15] = a[15] * b;
1591 | return out;
1592 | };
1593 |
1594 | /**
1595 | * Adds two mat4's after multiplying each element of the second operand by a scalar value.
1596 | *
1597 | * @param {mat4} out the receiving vector
1598 | * @param {mat4} a the first operand
1599 | * @param {mat4} b the second operand
1600 | * @param {Number} scale the amount to scale b's elements by before adding
1601 | * @returns {mat4} out
1602 | */
1603 | export float *mat4(multiplyScalarAndAdd)(float *out, float *a, float *b, float scale) {
1604 | out[0] = a[0] + (b[0] * scale);
1605 | out[1] = a[1] + (b[1] * scale);
1606 | out[2] = a[2] + (b[2] * scale);
1607 | out[3] = a[3] + (b[3] * scale);
1608 | out[4] = a[4] + (b[4] * scale);
1609 | out[5] = a[5] + (b[5] * scale);
1610 | out[6] = a[6] + (b[6] * scale);
1611 | out[7] = a[7] + (b[7] * scale);
1612 | out[8] = a[8] + (b[8] * scale);
1613 | out[9] = a[9] + (b[9] * scale);
1614 | out[10] = a[10] + (b[10] * scale);
1615 | out[11] = a[11] + (b[11] * scale);
1616 | out[12] = a[12] + (b[12] * scale);
1617 | out[13] = a[13] + (b[13] * scale);
1618 | out[14] = a[14] + (b[14] * scale);
1619 | out[15] = a[15] + (b[15] * scale);
1620 | return out;
1621 | };
1622 |
1623 | /**
1624 | * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
1625 | *
1626 | * @param {mat4} a The first matrix.
1627 | * @param {mat4} b The second matrix.
1628 | * @returns {Boolean} True if the matrices are equal, false otherwise.
1629 | */
1630 | export int mat4(exactEquals)(float *a, float *b) {
1631 | return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3] &&
1632 | a[4] == b[4] && a[5] == b[5] && a[6] == b[6] && a[7] == b[7] &&
1633 | a[8] == b[8] && a[9] == b[9] && a[10] == b[10] && a[11] == b[11] &&
1634 | a[12] == b[12] && a[13] == b[13] && a[14] == b[14] && a[15] == b[15];
1635 | };
1636 |
1637 | /**
1638 | * Returns whether or not the matrices have approximately the same elements in the same position.
1639 | *
1640 | * @param {mat4} a The first matrix.
1641 | * @param {mat4} b The second matrix.
1642 | * @returns {Boolean} True if the matrices are equal, false otherwise.
1643 | */
1644 | export int mat4(equals)(float *a, float *b) {
1645 | float a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
1646 | float a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7];
1647 | float a8 = a[8], a9 = a[9], a10 = a[10], a11 = a[11];
1648 | float a12 = a[12], a13 = a[13], a14 = a[14], a15 = a[15];
1649 |
1650 | float b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
1651 | float b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7];
1652 | float b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11];
1653 | float b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15];
1654 |
1655 | return (fabs(a0 - b0) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a0), fabs(b0))) &&
1656 | fabs(a1 - b1) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a1), fabs(b1))) &&
1657 | fabs(a2 - b2) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a2), fabs(b2))) &&
1658 | fabs(a3 - b3) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a3), fabs(b3))) &&
1659 | fabs(a4 - b4) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a4), fabs(b4))) &&
1660 | fabs(a5 - b5) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a5), fabs(b5))) &&
1661 | fabs(a6 - b6) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a6), fabs(b6))) &&
1662 | fabs(a7 - b7) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a7), fabs(b7))) &&
1663 | fabs(a8 - b8) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a8), fabs(b8))) &&
1664 | fabs(a9 - b9) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a9), fabs(b9))) &&
1665 | fabs(a10 - b10) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a10), fabs(b10))) &&
1666 | fabs(a11 - b11) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a11), fabs(b11))) &&
1667 | fabs(a12 - b12) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a12), fabs(b12))) &&
1668 | fabs(a13 - b13) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a13), fabs(b13))) &&
1669 | fabs(a14 - b14) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a14), fabs(b14))) &&
1670 | fabs(a15 - b15) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a15), fabs(b15))));
1671 | };
1672 |
1673 | /**
1674 | * Alias for {@link mat4.multiply}
1675 | * @function
1676 | */
1677 | export float *mat4(mul)(float *out, float *a, float *b) {
1678 | return mat4(multiply)(out, a, b);
1679 | };
1680 |
1681 | /**
1682 | * Alias for {@link mat4.subtract}
1683 | * @function
1684 | */
1685 | export float *mat4(sub)(float *out, float *a, float *b) {
1686 | return mat4(subtract)(out, a, b);
1687 | };
1688 |
--------------------------------------------------------------------------------
/src/gl-matrix/vec3.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "common.h"
4 |
5 | #define vec3(x) vec3_##x
6 |
7 | /**
8 | * Frees a vec3
9 | */
10 | export float *vec3(free)(float *a) {
11 | free(a);
12 | return NULL;
13 | };
14 |
15 | /**
16 | * Creates a new, empty vec3
17 | *
18 | * @returns {vec3} a new 3D vector
19 | */
20 | export float *vec3(create)() {
21 | float *out = malloc(VEC_SIZE_3 * sizeof(*out));
22 | out[0] = 0;
23 | out[1] = 0;
24 | out[2] = 0;
25 | return out;
26 | };
27 |
28 | /**
29 | * Creates a new vec3 initialized with values from an existing vector
30 | *
31 | * @param {vec3} a vector to clone
32 | * @returns {vec3} a new 3D vector
33 | */
34 | export float *vec3(clone)(float *a) {
35 | float *out = malloc(VEC_SIZE_3 * sizeof(*out));
36 | out[0] = a[0];
37 | out[1] = a[1];
38 | out[2] = a[2];
39 | return out;
40 | };
41 |
42 | /**
43 | * Calculates the length of a vec3
44 | *
45 | * @param {vec3} a vector to calculate length of
46 | * @returns {Number} length of a
47 | */
48 | export float vec3(length)(float *a) {
49 | float x = a[0];
50 | float y = a[1];
51 | float z = a[2];
52 | return sqrtf(x*x + y*y + z*z);
53 | };
54 |
55 | /**
56 | * Creates a new vec3 initialized with the given values
57 | *
58 | * @param {Number} x X component
59 | * @param {Number} y Y component
60 | * @param {Number} z Z component
61 | * @returns {vec3} a new 3D vector
62 | */
63 | export float *vec3(fromValues)(float x, float y, float z) {
64 | float *out = malloc(VEC_SIZE_3 * sizeof(*out));
65 | out[0] = x;
66 | out[1] = y;
67 | out[2] = z;
68 | return out;
69 | };
70 |
71 | /**
72 | * Copy the values from one vec3 to another
73 | *
74 | * @param {vec3} out the receiving vector
75 | * @param {vec3} a the source vector
76 | * @returns {vec3} out
77 | */
78 | export float *vec3(copy)(float *out, float *a) {
79 | out[0] = a[0];
80 | out[1] = a[1];
81 | out[2] = a[2];
82 | return out;
83 | };
84 |
85 | /**
86 | * Set the components of a vec3 to the given values
87 | *
88 | * @param {vec3} out the receiving vector
89 | * @param {Number} x X component
90 | * @param {Number} y Y component
91 | * @param {Number} z Z component
92 | * @returns {vec3} out
93 | */
94 | export float *vec3(set)(float *out, float x, float y, float z) {
95 | out[0] = x;
96 | out[1] = y;
97 | out[2] = z;
98 | return out;
99 | };
100 |
101 | /**
102 | * Adds two vec3's
103 | *
104 | * @param {vec3} out the receiving vector
105 | * @param {vec3} a the first operand
106 | * @param {vec3} b the second operand
107 | * @returns {vec3} out
108 | */
109 | export float *vec3(add)(float *out, float *a, float *b) {
110 | out[0] = a[0] + b[0];
111 | out[1] = a[1] + b[1];
112 | out[2] = a[2] + b[2];
113 | return out;
114 | };
115 |
116 | /**
117 | * Subtracts vector b from vector a
118 | *
119 | * @param {vec3} out the receiving vector
120 | * @param {vec3} a the first operand
121 | * @param {vec3} b the second operand
122 | * @returns {vec3} out
123 | */
124 | export float *vec3(subtract)(float *out, float *a, float *b) {
125 | out[0] = a[0] - b[0];
126 | out[1] = a[1] - b[1];
127 | out[2] = a[2] - b[2];
128 | return out;
129 | };
130 |
131 | /**
132 | * Multiplies two vec3's
133 | *
134 | * @param {vec3} out the receiving vector
135 | * @param {vec3} a the first operand
136 | * @param {vec3} b the second operand
137 | * @returns {vec3} out
138 | */
139 | export float *vec3(multiply)(float *out, float *a, float *b) {
140 | out[0] = a[0] * b[0];
141 | out[1] = a[1] * b[1];
142 | out[2] = a[2] * b[2];
143 | return out;
144 | };
145 |
146 | /**
147 | * Divides two vec3's
148 | *
149 | * @param {vec3} out the receiving vector
150 | * @param {vec3} a the first operand
151 | * @param {vec3} b the second operand
152 | * @returns {vec3} out
153 | */
154 | export float *vec3(divide)(float *out, float *a, float *b) {
155 | out[0] = a[0] / b[0];
156 | out[1] = a[1] / b[1];
157 | out[2] = a[2] / b[2];
158 | return out;
159 | };
160 |
161 | /**
162 | * Math.ceil the components of a vec3
163 | *
164 | * @param {vec3} out the receiving vector
165 | * @param {vec3} a vector to ceil
166 | * @returns {vec3} out
167 | */
168 | export float *vec3(ceil)(float *out, float *a) {
169 | out[0] = ceilf(a[0]);
170 | out[1] = ceilf(a[1]);
171 | out[2] = ceilf(a[2]);
172 | return out;
173 | };
174 |
175 | /**
176 | * Math.floor the components of a vec3
177 | *
178 | * @param {vec3} out the receiving vector
179 | * @param {vec3} a vector to floor
180 | * @returns {vec3} out
181 | */
182 | export float *vec3(floor)(float *out, float *a) {
183 | out[0] = floorf(a[0]);
184 | out[1] = floorf(a[1]);
185 | out[2] = floorf(a[2]);
186 | return out;
187 | };
188 |
189 | /**
190 | * Returns the minimum of two vec3's
191 | *
192 | * @param {vec3} out the receiving vector
193 | * @param {vec3} a the first operand
194 | * @param {vec3} b the second operand
195 | * @returns {vec3} out
196 | */
197 | export float *vec3(min)(float *out, float *a, float *b) {
198 | out[0] = fminf(a[0], b[0]);
199 | out[1] = fminf(a[1], b[1]);
200 | out[2] = fminf(a[2], b[2]);
201 | return out;
202 | };
203 |
204 | /**
205 | * Returns the maximum of two vec3's
206 | *
207 | * @param {vec3} out the receiving vector
208 | * @param {vec3} a the first operand
209 | * @param {vec3} b the second operand
210 | * @returns {vec3} out
211 | */
212 | export float *vec3(max)(float *out, float *a, float *b) {
213 | out[0] = fmaxf(a[0], b[0]);
214 | out[1] = fmaxf(a[1], b[1]);
215 | out[2] = fmaxf(a[2], b[2]);
216 | return out;
217 | };
218 |
219 | /**
220 | * Math.round the components of a vec3
221 | *
222 | * @param {vec3} out the receiving vector
223 | * @param {vec3} a vector to round
224 | * @returns {vec3} out
225 | */
226 | export float *vec3(round)(float *out, float *a) {
227 | out[0] = roundf(a[0]);
228 | out[1] = roundf(a[1]);
229 | out[2] = roundf(a[2]);
230 | return out;
231 | };
232 |
233 | /**
234 | * Scales a vec3 by a scalar number
235 | *
236 | * @param {vec3} out the receiving vector
237 | * @param {vec3} a the vector to scale
238 | * @param {Number} b amount to scale the vector by
239 | * @returns {vec3} out
240 | */
241 | export float *vec3(scale)(float *out, float *a, float b) {
242 | out[0] = a[0] * b;
243 | out[1] = a[1] * b;
244 | out[2] = a[2] * b;
245 | return out;
246 | };
247 |
248 | /**
249 | * Adds two vec3's after scaling the second operand by a scalar value
250 | *
251 | * @param {vec3} out the receiving vector
252 | * @param {vec3} a the first operand
253 | * @param {vec3} b the second operand
254 | * @param {Number} scale the amount to scale b by before adding
255 | * @returns {vec3} out
256 | */
257 | export float *vec3(scaleAndAdd)(float *out, float *a, float *b, float scale) {
258 | out[0] = a[0] + (b[0] * scale);
259 | out[1] = a[1] + (b[1] * scale);
260 | out[2] = a[2] + (b[2] * scale);
261 | return out;
262 | };
263 |
264 | /**
265 | * Calculates the euclidian distance between two vec3's
266 | *
267 | * @param {vec3} a the first operand
268 | * @param {vec3} b the second operand
269 | * @returns {Number} distance between a and b
270 | */
271 | export float vec3(distance)(float *a, float *b) {
272 | float x = b[0] - a[0];
273 | float y = b[1] - a[1];
274 | float z = b[2] - a[2];
275 | return sqrtf(x*x + y*y + z*z);
276 | };
277 |
278 | /**
279 | * Calculates the squared euclidian distance between two vec3's
280 | *
281 | * @param {vec3} a the first operand
282 | * @param {vec3} b the second operand
283 | * @returns {Number} squared distance between a and b
284 | */
285 | export float vec3(squaredDistance)(float *a, float *b) {
286 | float x = b[0] - a[0];
287 | float y = b[1] - a[1];
288 | float z = b[2] - a[2];
289 | return x*x + y*y + z*z;
290 | };
291 |
292 | /**
293 | * Calculates the squared length of a vec3
294 | *
295 | * @param {vec3} a vector to calculate squared length of
296 | * @returns {Number} squared length of a
297 | */
298 | export float vec3(squaredLength)(float *a) {
299 | float x = a[0];
300 | float y = a[1];
301 | float z = a[2];
302 | return x*x + y*y + z*z;
303 | };
304 |
305 | /**
306 | * Negates the components of a vec3
307 | *
308 | * @param {vec3} out the receiving vector
309 | * @param {vec3} a vector to negate
310 | * @returns {vec3} out
311 | */
312 | export float *vec3(negate)(float *out, float *a) {
313 | out[0] = -a[0];
314 | out[1] = -a[1];
315 | out[2] = -a[2];
316 | return out;
317 | };
318 |
319 | /**
320 | * Returns the inverse of the components of a vec3
321 | *
322 | * @param {vec3} out the receiving vector
323 | * @param {vec3} a vector to invert
324 | * @returns {vec3} out
325 | */
326 | export float *vec3(inverse)(float *out, float *a) {
327 | out[0] = 1.0 / a[0];
328 | out[1] = 1.0 / a[1];
329 | out[2] = 1.0 / a[2];
330 | return out;
331 | };
332 |
333 | /**
334 | * Normalize a vec3
335 | *
336 | * @param {vec3} out the receiving vector
337 | * @param {vec3} a vector to normalize
338 | * @returns {vec3} out
339 | */
340 | export float *vec3(normalize)(float *out, float *a) {
341 | float x = a[0];
342 | float y = a[1];
343 | float z = a[2];
344 | float len = x*x + y*y + z*z;
345 | if (len > 0) {
346 | //TODO: evaluate use of glm_invsqrt here?
347 | len = 1 / sqrtf(len);
348 | out[0] = a[0] * len;
349 | out[1] = a[1] * len;
350 | out[2] = a[2] * len;
351 | }
352 | return out;
353 | };
354 |
355 | /**
356 | * Calculates the dot product of two vec3's
357 | *
358 | * @param {vec3} a the first operand
359 | * @param {vec3} b the second operand
360 | * @returns {Number} dot product of a and b
361 | */
362 | export float vec3(dot)(float *a, float *b) {
363 | return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
364 | };
365 |
366 | /**
367 | * Computes the cross product of two vec3's
368 | *
369 | * @param {vec3} out the receiving vector
370 | * @param {vec3} a the first operand
371 | * @param {vec3} b the second operand
372 | * @returns {vec3} out
373 | */
374 | export float *vec3(cross)(float *out, float *a, float *b) {
375 | float ax = a[0], ay = a[1], az = a[2];
376 | float bx = b[0], by = b[1], bz = b[2];
377 | out[0] = ay * bz - az * by;
378 | out[1] = az * bx - ax * bz;
379 | out[2] = ax * by - ay * bx;
380 | return out;
381 | };
382 |
383 | /**
384 | * Performs a linear interpolation between two vec3's
385 | *
386 | * @param {vec3} out the receiving vector
387 | * @param {vec3} a the first operand
388 | * @param {vec3} b the second operand
389 | * @param {Number} t interpolation amount between the two inputs
390 | * @returns {vec3} out
391 | */
392 | export float *vec3(lerp)(float *out, float *a, float *b, float t) {
393 | float ax = a[0];
394 | float ay = a[1];
395 | float az = a[2];
396 | out[0] = ax + t * (b[0] - ax);
397 | out[1] = ay + t * (b[1] - ay);
398 | out[2] = az + t * (b[2] - az);
399 | return out;
400 | };
401 |
402 | /**
403 | * Performs a hermite interpolation with two control points
404 | *
405 | * @param {vec3} out the receiving vector
406 | * @param {vec3} a the first operand
407 | * @param {vec3} b the second operand
408 | * @param {vec3} c the third operand
409 | * @param {vec3} d the fourth operand
410 | * @param {Number} t interpolation amount between the two inputs
411 | * @returns {vec3} out
412 | */
413 | export float *vec3(hermite)(float *out, float *a, float *b, float *c, float *d, float t) {
414 | float factorTimes2 = t * t;
415 | float factor1 = factorTimes2 * (2 * t - 3) + 1;
416 | float factor2 = factorTimes2 * (t - 2) + t;
417 | float factor3 = factorTimes2 * (t - 1);
418 | float factor4 = factorTimes2 * (3 - 2 * t);
419 | out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
420 | out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
421 | out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
422 | return out;
423 | };
424 |
425 | /**
426 | * Performs a bezier interpolation with two control points
427 | *
428 | * @param {vec3} out the receiving vector
429 | * @param {vec3} a the first operand
430 | * @param {vec3} b the second operand
431 | * @param {vec3} c the third operand
432 | * @param {vec3} d the fourth operand
433 | * @param {Number} t interpolation amount between the two inputs
434 | * @returns {vec3} out
435 | */
436 | export float *vec3(bezier)(float *out, float *a, float *b, float *c, float *d, float t) {
437 | float inverseFactor = 1 - t;
438 | float inverseFactorTimesTwo = inverseFactor * inverseFactor;
439 | float factorTimes2 = t * t;
440 | float factor1 = inverseFactorTimesTwo * inverseFactor;
441 | float factor2 = 3 * t * inverseFactorTimesTwo;
442 | float factor3 = 3 * factorTimes2 * inverseFactor;
443 | float factor4 = factorTimes2 * t;
444 | out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
445 | out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
446 | out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
447 | return out;
448 | };
449 |
450 | /**
451 | * Generates a random vector with the given scale
452 | *
453 | * @param {vec3} out the receiving vector
454 | * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
455 | * @returns {vec3} out
456 | */
457 | export float *vec3(random)(float *out, float scale) {
458 | float r = randf() * 2.0 * PI;
459 | float z = (randf() * 2.0) - 1.0;
460 | float zScale = sqrtf(1.0-z*z) * scale;
461 | out[0] = cosf(r) * zScale;
462 | out[1] = sinf(r) * zScale;
463 | out[2] = z * scale;
464 | return out;
465 | };
466 |
467 | /**
468 | * Transforms the vec3 with a mat4.
469 | * 4th vector component is implicitly '1'
470 | *
471 | * @param {vec3} out the receiving vector
472 | * @param {vec3} a the vector to transform
473 | * @param {mat4} m matrix to transform with
474 | * @returns {vec3} out
475 | */
476 | export float *vec3(transformMat4)(float *out, float *a, float *m) {
477 | float x = a[0], y = a[1], z = a[2];
478 | float w = m[3] * x + m[7] * y + m[11] * z + m[15];
479 | if (!w) w = w || 1.0;
480 | out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
481 | out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
482 | out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
483 | return out;
484 | };
485 |
486 | /**
487 | * Transforms the vec3 with a mat3.
488 | *
489 | * @param {vec3} out the receiving vector
490 | * @param {vec3} a the vector to transform
491 | * @param {mat3} m the 3x3 matrix to transform with
492 | * @returns {vec3} out
493 | */
494 | export float *vec3(transformMat3)(float *out, float *a, float *m) {
495 | float x = a[0], y = a[1], z = a[2];
496 | out[0] = x * m[0] + y * m[3] + z * m[6];
497 | out[1] = x * m[1] + y * m[4] + z * m[7];
498 | out[2] = x * m[2] + y * m[5] + z * m[8];
499 | return out;
500 | };
501 |
502 | /**
503 | * Transforms the vec3 with a quat
504 | *
505 | * @param {vec3} out the receiving vector
506 | * @param {vec3} a the vector to transform
507 | * @param {quat} q quaternion to transform with
508 | * @returns {vec3} out
509 | */
510 | export float *vec3(transformQuat)(float *out, float *a, float *q) {
511 | // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations
512 | float x = a[0], y = a[1], z = a[2];
513 | float qx = q[0], qy = q[1], qz = q[2], qw = q[3];
514 | // calculate quat * vec
515 | float ix = qw * x + qy * z - qz * y;
516 | float iy = qw * y + qz * x - qx * z;
517 | float iz = qw * z + qx * y - qy * x;
518 | float iw = -qx * x - qy * y - qz * z;
519 | // calculate result * inverse quat
520 | out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
521 | out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
522 | out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
523 | return out;
524 | };
525 |
526 | /**
527 | * Rotate a 3D vector around the x-axis
528 | * @param {vec3} out The receiving vec3
529 | * @param {vec3} a The vec3 point to rotate
530 | * @param {vec3} b The origin of the rotation
531 | * @param {Number} c The angle of rotation
532 | * @returns {vec3} out
533 | */
534 | export float *vec3(rotateX)(float *out, float *a, float *b, float c) {
535 | float p0, p1, p2;
536 | float r0, r1, r2;
537 | //Translate point to the origin
538 | p0 = a[0] - b[0];
539 | p1 = a[1] - b[1];
540 | p2 = a[2] - b[2];
541 | //perform rotation
542 | r0 = p0;
543 | r1 = p1*cosf(c) - p2*sinf(c);
544 | r2 = p2*sinf(c) + p2*cosf(c);
545 | //translate to correct position
546 | out[0] = r0 + b[0];
547 | out[1] = r1 + b[1];
548 | out[2] = r2 + b[2];
549 | return out;
550 | };
551 |
552 | /**
553 | * Rotate a 3D vector around the y-axis
554 | * @param {vec3} out The receiving vec3
555 | * @param {vec3} a The vec3 point to rotate
556 | * @param {vec3} b The origin of the rotation
557 | * @param {Number} c The angle of rotation
558 | * @returns {vec3} out
559 | */
560 | export float *vec3(rotateY)(float *out, float *a, float *b, float c) {
561 | float p0, p1, p2;
562 | float r0, r1, r2;
563 | //Translate point to the origin
564 | p0 = a[0] - b[0];
565 | p1 = a[1] - b[1];
566 | p2 = a[2] - b[2];
567 | //perform rotation
568 | r0 = p2*sinf(c) + p0*cosf(c);
569 | r1 = p1;
570 | r2 = p2*cosf(c) - p1*sinf(c);
571 | //translate to correct position
572 | out[0] = r0 + b[0];
573 | out[1] = r1 + b[1];
574 | out[2] = r2 + b[2];
575 | return out;
576 | };
577 |
578 | /**
579 | * Rotate a 3D vector around the z-axis
580 | * @param {vec3} out The receiving vec3
581 | * @param {vec3} a The vec3 point to rotate
582 | * @param {vec3} b The origin of the rotation
583 | * @param {Number} c The angle of rotation
584 | * @returns {vec3} out
585 | */
586 | export float *vec3(rotateZ)(float *out, float *a, float *b, float c) {
587 | float p0, p1, p2;
588 | float r0, r1, r2;
589 | //Translate point to the origin
590 | p0 = a[0] - b[0];
591 | p1 = a[1] - b[1];
592 | p2 = a[2] - b[2];
593 | //perform rotation
594 | r0 = p0*cosf(c) - p1*sinf(c);
595 | r1 = p0*sinf(c) + p1*cosf(c);
596 | r2 = p2;
597 | //translate to correct position
598 | out[0] = r0 + b[0];
599 | out[1] = r1 + b[1];
600 | out[2] = r2 + b[2];
601 | return out;
602 | };
603 |
604 | float aH0[VEC_SIZE_3] = { 0.0, 0.0, 0.0 };
605 | float aH1[VEC_SIZE_3] = { 0.0, 0.0, 0.0 };
606 | /**
607 | * Get the angle between two 3D vectors
608 | * @param {vec3} a The first operand
609 | * @param {vec3} b The second operand
610 | * @returns {Number} The angle in radians
611 | */
612 | export float vec3(angle)(float *a, float *b) {
613 | // hacky helper to avoid allocation
614 | // but remain self api usage
615 | aH0[0] = a[0]; aH0[1] = a[1]; aH0[2] = a[2];
616 | aH1[0] = b[0]; aH1[1] = b[1]; aH1[2] = b[2];
617 | float *tempA = aH0;
618 | float *tempB = aH1;
619 | vec3(normalize)(tempA, tempA);
620 | vec3(normalize)(tempB, tempB);
621 | float cosine = vec3(dot)(tempA, tempB);
622 | if(cosine > 1.0) {
623 | return 0;
624 | }
625 | else if(cosine < -1.0) {
626 | return PI;
627 | } else {
628 | return acosf(cosine);
629 | }
630 | };
631 |
632 | /**
633 | * Returns a string representation of a vector
634 | *
635 | * @param {vec3} a vector to represent as a string
636 | * @returns {String} string representation of the vector
637 | */
638 | export float *vec3(str)(float *a) {
639 | return a;
640 | };
641 |
642 | /**
643 | * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)
644 | *
645 | * @param {vec3} a The first vector.
646 | * @param {vec3} b The second vector.
647 | * @returns {Boolean} True if the vectors are equal, false otherwise.
648 | */
649 | export int vec3(exactEquals)(float *a, float *b) {
650 | return a[0] == b[0] && a[1] == b[1] && a[2] == b[2];
651 | };
652 |
653 | /**
654 | * Returns whether or not the vectors have approximately the same elements in the same position.
655 | *
656 | * @param {vec3} a The first vector.
657 | * @param {vec3} b The second vector.
658 | * @returns {Boolean} True if the vectors are equal, false otherwise.
659 | */
660 | export int vec3(equals)(float *a, float *b) {
661 | float a0 = a[0], a1 = a[1], a2 = a[2];
662 | float b0 = b[0], b1 = b[1], b2 = b[2];
663 | return (fabs(a0 - b0) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a0), fabs(b0))) &&
664 | fabs(a1 - b1) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a1), fabs(b1))) &&
665 | fabs(a2 - b2) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a2), fabs(b2))));
666 | };
667 |
668 | /**
669 | * Alias for {@link vec3.subtract}
670 | * @function
671 | */
672 | export float *vec3(sub)(float *out, float *a, float *b) {
673 | return vec3(subtract)(out, a, b);
674 | };
675 |
676 | /**
677 | * Alias for {@link vec3.multiply}
678 | * @function
679 | */
680 | export float *vec3(mul)(float *out, float *a, float *b) {
681 | return vec3(multiply)(out, a, b);
682 | };
683 |
684 | /**
685 | * Alias for {@link vec3.divide}
686 | * @function
687 | */
688 | export float *vec3(div)(float *out, float *a, float *b) {
689 | return vec3(divide)(out, a, b);
690 | };
691 |
692 | /**
693 | * Alias for {@link vec3.distance}
694 | * @function
695 | */
696 | export float vec3(dist)(float *a, float *b) {
697 | return vec3(distance)(a, b);
698 | };
699 |
700 | /**
701 | * Alias for {@link vec3.squaredDistance}
702 | * @function
703 | */
704 | export float vec3(sqrDist)(float *a, float *b) {
705 | return vec3(squaredDistance)(a, b);
706 | };
707 |
708 | /**
709 | * Alias for {@link vec3.length}
710 | * @function
711 | */
712 | export float vec3(len)(float *a) {
713 | return vec3(length)(a);
714 | };
715 |
716 | /**
717 | * Alias for {@link vec3.squaredLength}
718 | * @function
719 | */
720 | export float vec3(sqrLen)(float *a) {
721 | return vec3(squaredLength)(a);
722 | };
723 |
--------------------------------------------------------------------------------
/src/gl-matrix/vec4.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "common.h"
4 |
5 | #define vec4(x) vec4_##x
6 |
7 | /**
8 | * Frees a vec4
9 | */
10 | export float *vec4(free)(float *a) {
11 | free(a);
12 | return NULL;
13 | };
14 |
15 | /**
16 | * Creates a new, empty vec4
17 | *
18 | * @returns {vec4} a new 3D vector
19 | */
20 | export float *vec4(create)() {
21 | float *out = malloc(VEC_SIZE_4 * sizeof(*out));
22 | out[0] = 0;
23 | out[1] = 0;
24 | out[2] = 0;
25 | out[3] = 0;
26 | return out;
27 | };
28 |
29 | /**
30 | * Creates a new vec4 initialized with values from an existing vector
31 | *
32 | * @param {vec4} a vector to clone
33 | * @returns {vec4} a new 4D vector
34 | */
35 | export float *vec4(clone)(float *a) {
36 | float *out = malloc(VEC_SIZE_4 * sizeof(*out));
37 | out[0] = a[0];
38 | out[1] = a[1];
39 | out[2] = a[2];
40 | out[3] = a[3];
41 | return out;
42 | };
43 |
44 | /**
45 | * Creates a new vec4 initialized with the given values
46 | *
47 | * @param {Number} x X component
48 | * @param {Number} y Y component
49 | * @param {Number} z Z component
50 | * @param {Number} w W component
51 | * @returns {vec4} a new 4D vector
52 | */
53 | export float *vec4(fromValues)(float x, float y, float z, float w) {
54 | float *out = malloc(VEC_SIZE_4 * sizeof(*out));
55 | out[0] = x;
56 | out[1] = y;
57 | out[2] = z;
58 | out[3] = w;
59 | return out;
60 | };
61 |
62 | /**
63 | * Copy the values from one vec4 to another
64 | *
65 | * @param {vec4} out the receiving vector
66 | * @param {vec4} a the source vector
67 | * @returns {vec4} out
68 | */
69 | export float *vec4(copy)(float *out, float *a) {
70 | out[0] = a[0];
71 | out[1] = a[1];
72 | out[2] = a[2];
73 | out[3] = a[3];
74 | return out;
75 | };
76 |
77 | /**
78 | * Set the components of a vec4 to the given values
79 | *
80 | * @param {vec4} out the receiving vector
81 | * @param {Number} x X component
82 | * @param {Number} y Y component
83 | * @param {Number} z Z component
84 | * @param {Number} w W component
85 | * @returns {vec4} out
86 | */
87 | export float *vec4(set)(float *out, float x, float y, float z, float w) {
88 | out[0] = x;
89 | out[1] = y;
90 | out[2] = z;
91 | out[3] = w;
92 | return out;
93 | };
94 |
95 | /**
96 | * Adds two vec4's
97 | *
98 | * @param {vec4} out the receiving vector
99 | * @param {vec4} a the first operand
100 | * @param {vec4} b the second operand
101 | * @returns {vec4} out
102 | */
103 | export float *vec4(add)(float *out, float *a, float *b) {
104 | out[0] = a[0] + b[0];
105 | out[1] = a[1] + b[1];
106 | out[2] = a[2] + b[2];
107 | out[3] = a[3] + b[3];
108 | return out;
109 | };
110 |
111 | /**
112 | * Subtracts vector b from vector a
113 | *
114 | * @param {vec4} out the receiving vector
115 | * @param {vec4} a the first operand
116 | * @param {vec4} b the second operand
117 | * @returns {vec4} out
118 | */
119 | export float *vec4(subtract)(float *out, float *a, float *b) {
120 | out[0] = a[0] - b[0];
121 | out[1] = a[1] - b[1];
122 | out[2] = a[2] - b[2];
123 | out[3] = a[3] - b[3];
124 | return out;
125 | };
126 |
127 | /**
128 | * Multiplies two vec4's
129 | *
130 | * @param {vec4} out the receiving vector
131 | * @param {vec4} a the first operand
132 | * @param {vec4} b the second operand
133 | * @returns {vec4} out
134 | */
135 | export float *vec4(multiply)(float *out, float *a, float *b) {
136 | out[0] = a[0] * b[0];
137 | out[1] = a[1] * b[1];
138 | out[2] = a[2] * b[2];
139 | out[3] = a[3] * b[3];
140 | return out;
141 | };
142 |
143 | /**
144 | * Divides two vec4's
145 | *
146 | * @param {vec4} out the receiving vector
147 | * @param {vec4} a the first operand
148 | * @param {vec4} b the second operand
149 | * @returns {vec4} out
150 | */
151 | export float *vec4(divide)(float *out, float *a, float *b) {
152 | out[0] = a[0] / b[0];
153 | out[1] = a[1] / b[1];
154 | out[2] = a[2] / b[2];
155 | out[3] = a[3] / b[3];
156 | return out;
157 | };
158 |
159 | /**
160 | * Math.ceil the components of a vec4
161 | *
162 | * @param {vec4} out the receiving vector
163 | * @param {vec4} a vector to ceil
164 | * @returns {vec4} out
165 | */
166 | export float *vec4(ceil)(float *out, float *a) {
167 | out[0] = ceilf(a[0]);
168 | out[1] = ceilf(a[1]);
169 | out[2] = ceilf(a[2]);
170 | out[3] = ceilf(a[3]);
171 | return out;
172 | };
173 |
174 | /**
175 | * Math.floor the components of a vec4
176 | *
177 | * @param {vec4} out the receiving vector
178 | * @param {vec4} a vector to floor
179 | * @returns {vec4} out
180 | */
181 | export float *vec4(floor)(float *out, float *a) {
182 | out[0] = floorf(a[0]);
183 | out[1] = floorf(a[1]);
184 | out[2] = floorf(a[2]);
185 | out[3] = floorf(a[3]);
186 | return out;
187 | };
188 |
189 | /**
190 | * Returns the minimum of two vec4's
191 | *
192 | * @param {vec4} out the receiving vector
193 | * @param {vec4} a the first operand
194 | * @param {vec4} b the second operand
195 | * @returns {vec4} out
196 | */
197 | export float *vec4(min)(float *out, float *a, float *b) {
198 | out[0] = fminf(a[0], b[0]);
199 | out[1] = fminf(a[1], b[1]);
200 | out[2] = fminf(a[2], b[2]);
201 | out[3] = fminf(a[3], b[3]);
202 | return out;
203 | };
204 |
205 | /**
206 | * Returns the maximum of two vec4's
207 | *
208 | * @param {vec4} out the receiving vector
209 | * @param {vec4} a the first operand
210 | * @param {vec4} b the second operand
211 | * @returns {vec4} out
212 | */
213 | export float *vec4(max)(float *out, float *a, float *b) {
214 | out[0] = fmaxf(a[0], b[0]);
215 | out[1] = fmaxf(a[1], b[1]);
216 | out[2] = fmaxf(a[2], b[2]);
217 | out[3] = fmaxf(a[3], b[3]);
218 | return out;
219 | };
220 |
221 | /**
222 | * Math.round the components of a vec4
223 | *
224 | * @param {vec4} out the receiving vector
225 | * @param {vec4} a vector to round
226 | * @returns {vec4} out
227 | */
228 | export float *vec4(round)(float *out, float *a) {
229 | out[0] = roundf(a[0]);
230 | out[1] = roundf(a[1]);
231 | out[2] = roundf(a[2]);
232 | out[3] = roundf(a[3]);
233 | return out;
234 | };
235 |
236 | /**
237 | * Scales a vec4 by a scalar number
238 | *
239 | * @param {vec4} out the receiving vector
240 | * @param {vec4} a the vector to scale
241 | * @param {Number} b amount to scale the vector by
242 | * @returns {vec4} out
243 | */
244 | export float *vec4(scale)(float *out, float *a, float b) {
245 | out[0] = a[0] * b;
246 | out[1] = a[1] * b;
247 | out[2] = a[2] * b;
248 | out[3] = a[3] * b;
249 | return out;
250 | };
251 |
252 | /**
253 | * Adds two vec4's after scaling the second operand by a scalar value
254 | *
255 | * @param {vec4} out the receiving vector
256 | * @param {vec4} a the first operand
257 | * @param {vec4} b the second operand
258 | * @param {Number} scale the amount to scale b by before adding
259 | * @returns {vec4} out
260 | */
261 | export float *vec4(scaleAndAdd)(float *out, float *a, float *b, float scale) {
262 | out[0] = a[0] + (b[0] * scale);
263 | out[1] = a[1] + (b[1] * scale);
264 | out[2] = a[2] + (b[2] * scale);
265 | out[3] = a[3] + (b[3] * scale);
266 | return out;
267 | };
268 |
269 | /**
270 | * Calculates the euclidian distance between two vec4's
271 | *
272 | * @param {vec4} a the first operand
273 | * @param {vec4} b the second operand
274 | * @returns {Number} distance between a and b
275 | */
276 | export float vec4(distance)(float *a, float *b) {
277 | float x = b[0] - a[0];
278 | float y = b[1] - a[1];
279 | float z = b[2] - a[2];
280 | float w = b[3] - a[3];
281 | return sqrtf(x*x + y*y + z*z + w*w);
282 | };
283 |
284 | /**
285 | * Calculates the squared euclidian distance between two vec4's
286 | *
287 | * @param {vec4} a the first operand
288 | * @param {vec4} b the second operand
289 | * @returns {Number} squared distance between a and b
290 | */
291 | export float vec4(squaredDistance)(float *a, float *b) {
292 | float x = b[0] - a[0];
293 | float y = b[1] - a[1];
294 | float z = b[2] - a[2];
295 | float w = b[3] - a[3];
296 | return x*x + y*y + z*z + w*w;
297 | };
298 |
299 | /**
300 | * Calculates the length of a vec4
301 | *
302 | * @param {vec4} a vector to calculate length of
303 | * @returns {Number} length of a
304 | */
305 | export float vec4(length)(float *a) {
306 | float x = a[0];
307 | float y = a[1];
308 | float z = a[2];
309 | float w = a[3];
310 | return sqrtf(x*x + y*y + z*z + w*w);
311 | };
312 |
313 | /**
314 | * Calculates the squared length of a vec4
315 | *
316 | * @param {vec4} a vector to calculate squared length of
317 | * @returns {Number} squared length of a
318 | */
319 | export float vec4(squaredLength)(float *a) {
320 | float x = a[0];
321 | float y = a[1];
322 | float z = a[2];
323 | float w = a[3];
324 | return x*x + y*y + z*z + w*w;
325 | };
326 |
327 | /**
328 | * Negates the components of a vec4
329 | *
330 | * @param {vec4} out the receiving vector
331 | * @param {vec4} a vector to negate
332 | * @returns {vec4} out
333 | */
334 | export float *vec4(negate)(float *out, float *a) {
335 | out[0] = -a[0];
336 | out[1] = -a[1];
337 | out[2] = -a[2];
338 | out[3] = -a[3];
339 | return out;
340 | };
341 |
342 | /**
343 | * Returns the inverse of the components of a vec4
344 | *
345 | * @param {vec4} out the receiving vector
346 | * @param {vec4} a vector to invert
347 | * @returns {vec4} out
348 | */
349 | export float *vec4(inverse)(float *out, float *a) {
350 | out[0] = 1.0 / a[0];
351 | out[1] = 1.0 / a[1];
352 | out[2] = 1.0 / a[2];
353 | out[3] = 1.0 / a[3];
354 | return out;
355 | };
356 |
357 | /**
358 | * Normalize a vec4
359 | *
360 | * @param {vec4} out the receiving vector
361 | * @param {vec4} a vector to normalize
362 | * @returns {vec4} out
363 | */
364 | export float *vec4(normalize)(float *out, float *a) {
365 | float x = a[0];
366 | float y = a[1];
367 | float z = a[2];
368 | float w = a[3];
369 | float len = x*x + y*y + z*z + w*w;
370 | if (len > 0) {
371 | len = 1 / sqrtf(len);
372 | out[0] = x * len;
373 | out[1] = y * len;
374 | out[2] = z * len;
375 | out[3] = w * len;
376 | }
377 | return out;
378 | };
379 |
380 | /**
381 | * Calculates the dot product of two vec4's
382 | *
383 | * @param {vec4} a the first operand
384 | * @param {vec4} b the second operand
385 | * @returns {Number} dot product of a and b
386 | */
387 | export float vec4(dot)(float *a, float *b) {
388 | return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
389 | };
390 |
391 | /**
392 | * Performs a linear interpolation between two vec4's
393 | *
394 | * @param {vec4} out the receiving vector
395 | * @param {vec4} a the first operand
396 | * @param {vec4} b the second operand
397 | * @param {Number} t interpolation amount between the two inputs
398 | * @returns {vec4} out
399 | */
400 | export float *vec4(lerp)(float *out, float *a, float *b, float t) {
401 | float ax = a[0];
402 | float ay = a[1];
403 | float az = a[2];
404 | float aw = a[3];
405 | out[0] = ax + t * (b[0] - ax);
406 | out[1] = ay + t * (b[1] - ay);
407 | out[2] = az + t * (b[2] - az);
408 | out[3] = aw + t * (b[3] - aw);
409 | return out;
410 | };
411 |
412 | /**
413 | * Generates a random vector with the given scale
414 | *
415 | * @param {vec4} out the receiving vector
416 | * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
417 | * @returns {vec4} out
418 | */
419 | export float *vec4(random)(float *out, float scale) {
420 | //vectorScale = vectorScale || 1.0;
421 | //TODO: This is a pretty awful way of doing this. Find something better.
422 | out[0] = randf();
423 | out[1] = randf();
424 | out[2] = randf();
425 | out[3] = randf();
426 | vec3(normalize)(out, out);
427 | vec3(scale)(out, out, scale);
428 | return out;
429 | };
430 |
431 | /**
432 | * Transforms the vec4 with a mat4.
433 | *
434 | * @param {vec4} out the receiving vector
435 | * @param {vec4} a the vector to transform
436 | * @param {mat4} m matrix to transform with
437 | * @returns {vec4} out
438 | */
439 | export float *vec4(transformMat4)(float *out, float *a, float *m) {
440 | float x = a[0], y = a[1], z = a[2], w = a[3];
441 | out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
442 | out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
443 | out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
444 | out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
445 | return out;
446 | };
447 |
448 | /**
449 | * Transforms the vec4 with a quat
450 | *
451 | * @param {vec4} out the receiving vector
452 | * @param {vec4} a the vector to transform
453 | * @param {quat} q quaternion to transform with
454 | * @returns {vec4} out
455 | */
456 | export float *vec4(transformQuat)(float *out, float *a, float *q) {
457 | float x = a[0], y = a[1], z = a[2];
458 | float qx = q[0], qy = q[1], qz = q[2], qw = q[3];
459 | // calculate quat * vec
460 | float ix = qw * x + qy * z - qz * y;
461 | float iy = qw * y + qz * x - qx * z;
462 | float iz = qw * z + qx * y - qy * x;
463 | float iw = -qx * x - qy * y - qz * z;
464 | // calculate result * inverse quat
465 | out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
466 | out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
467 | out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
468 | out[3] = a[3];
469 | return out;
470 | };
471 |
472 | /**
473 | * Returns a string representation of a vector
474 | *
475 | * @param {vec4} a vector to represent as a string
476 | * @returns {String} string representation of the vector
477 | */
478 | export float *vec4(str)(float *a) {
479 | return a;
480 | };
481 |
482 | /**
483 | * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)
484 | *
485 | * @param {vec4} a The first vector.
486 | * @param {vec4} b The second vector.
487 | * @returns {Boolean} True if the vectors are equal, false otherwise.
488 | */
489 | export int vec4(exactEquals)(float *a, float *b) {
490 | return a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3];
491 | };
492 |
493 | /**
494 | * Returns whether or not the vectors have approximately the same elements in the same position.
495 | *
496 | * @param {vec4} a The first vector.
497 | * @param {vec4} b The second vector.
498 | * @returns {Boolean} True if the vectors are equal, false otherwise.
499 | */
500 | export int vec4(equals)(float *a, float *b) {
501 | float a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
502 | float b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
503 | return (fabs(a0 - b0) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a0), fabs(b0))) &&
504 | fabs(a1 - b1) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a1), fabs(b1))) &&
505 | fabs(a2 - b2) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a2), fabs(b2))) &&
506 | fabs(a3 - b3) <= EPSILON*fmaxf(1.0, fmaxf(fabs(a3), fabs(b3))));
507 | };
508 |
509 | /**
510 | * Alias for {@link vec4.subtract}
511 | * @function
512 | */
513 | export float *vec4(sub)(float *out, float *a, float *b) {
514 | return vec4(subtract)(out, a, b);
515 | };
516 |
517 | /**
518 | * Alias for {@link vec4.multiply}
519 | * @function
520 | */
521 | export float *vec4(mul)(float *out, float *a, float *b) {
522 | return vec4(multiply)(out, a, b);
523 | };
524 |
525 | /**
526 | * Alias for {@link vec4.divide}
527 | * @function
528 | */
529 | export float *vec4(div)(float *out, float *a, float *b) {
530 | return vec4(divide)(out, a, b);
531 | };
532 |
533 | /**
534 | * Alias for {@link vec4.distance}
535 | * @function
536 | */
537 | export float vec4(dist)(float *a, float *b) {
538 | return vec4(distance)(a, b);
539 | };
540 |
541 | /**
542 | * Alias for {@link vec4.squaredDistance}
543 | * @function
544 | */
545 | export float vec4(sqrDist)(float *a, float *b) {
546 | return vec4(squaredDistance)(a, b);
547 | };
548 |
549 | /**
550 | * Alias for {@link vec4.length}
551 | * @function
552 | */
553 | export float vec4(len)(float *a) {
554 | return vec4(length)(a);
555 | };
556 |
557 | /**
558 | * Alias for {@link vec4.squaredLength}
559 | * @function
560 | */
561 | export float vec4(sqrLen)(float *a) {
562 | return vec4(squaredLength)(a);
563 | };
564 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import {
2 | load,
3 | imports
4 | } from "./utils";
5 |
6 | import module from "./module.js";
7 |
8 | import vec3_bridge from "./gl-matrix/bridges/vec3.js";
9 | import vec4_bridge from "./gl-matrix/bridges/vec4.js";
10 | import mat4_bridge from "./gl-matrix/bridges/mat4.js";
11 |
12 | let vec3 = {};
13 | let vec4 = {};
14 | let mat4 = {};
15 |
16 | function validateEnvironment() {
17 | if (typeof WebAssembly === "undefined") {
18 | throw new Error(`WebAssembly is not available or unsupported!`);
19 | }
20 | };
21 |
22 | function init() {
23 | return new Promise(resolve => {
24 | validateEnvironment();
25 | load(module, imports).then(instance => {
26 | createLinks(vec3, "vec3", instance);
27 | createLinks(vec4, "vec4", instance);
28 | createLinks(mat4, "mat4", instance);
29 | resolve(true);
30 | });
31 | });
32 | };
33 |
34 | function getMethodsFromExportsByName(exports, name) {
35 | let module = {};
36 | for (let key in exports) {
37 | if (key.substr(0, name.length) === name) {
38 | module[key.substr(name.length + 1, key.length)] = exports[key];
39 | }
40 | };
41 | return module;
42 | };
43 |
44 | function createLinks(module, name, instance) {
45 | let memory = instance.memory;
46 | let exports = instance.exports;
47 | // link
48 | let methods = getMethodsFromExportsByName(exports, name);
49 | Object.assign(module, methods);
50 | // bridge
51 | switch (name) {
52 | case "vec3": vec3_bridge(module, memory); break;
53 | case "vec4": vec4_bridge(module, memory); break;
54 | case "mat4": mat4_bridge(module, memory); break;
55 | };
56 | };
57 |
58 | export {
59 | init,
60 | vec3,
61 | vec4,
62 | mat4
63 | };
64 |
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | export let imports = {
2 | initialMemory: 0,
3 | imports: {
4 | randf: () => Math.random(),
5 | printi: console.log.bind(console),
6 | printch: (cc) => console.log(String.fromCharCode(cc))
7 | }
8 | };
9 |
10 | export function load(buffer, options = {}) {
11 |
12 | let imports = options.imports || {};
13 |
14 | let memory = imports.memory;
15 | if (!memory) {
16 | let opts = { initial: options.initialMemory || 1 };
17 | memory = new WebAssembly.Memory(opts);
18 | memory.initial = options.initialMemory || 1;
19 | }
20 |
21 | let table = imports.table;
22 | if (!table) table = new WebAssembly.Table({ initial: 0, element: "anyfunc" });
23 |
24 | function grow() {
25 | let buffer = memory.buffer;
26 | memory.F32 = new Float32Array(buffer);
27 | memory.F64 = new Float64Array(buffer);
28 | };
29 |
30 | grow();
31 |
32 | let env = {};
33 | env.memoryBase = imports.memoryBase || 0;
34 | env.memory = memory;
35 | env.tableBase = imports.tableBase || 0;
36 | env.table = table;
37 |
38 | Object.keys(imports).forEach(key => env[key] = imports[key]);
39 |
40 | env._abort = errno => { throw Error("abnormal abort in " + file + ": " + errno); };
41 | env._exit = code => { if (code) throw Error("abnormal exit in " + file + ": " + code); }
42 |
43 | env._grow = grow;
44 |
45 | return WebAssembly.instantiate(buffer, { env: env })
46 | .then(module => {
47 | var instance = module.instance;
48 | instance.imports = imports;
49 | instance.memory = memory;
50 | instance.env = env;
51 | return instance;
52 | });
53 |
54 | };
55 |
--------------------------------------------------------------------------------