├── test ├── .gitignore ├── test.interp.hxml ├── profile.each.hxml ├── test.cs.hxml ├── test.java.hxml ├── test.cpp.hxml ├── profile.cpp.hxml ├── profile.java.hxml ├── test.python.hxml ├── test.each.hxml ├── test.node.hxml ├── profile.node.hxml ├── TestMain.hx ├── glm │ ├── TestMat2.hx │ ├── TestMat3.hx │ ├── TestVec4.hx │ ├── TestVec2.hx │ ├── TestVec3.hx │ ├── TestMat4.hx │ ├── TestGLM.hx │ └── TestQuat.hx └── ProfileMain.hx ├── .haxerc ├── sample ├── build.hxml └── Sample.hx ├── docs ├── favicon.ico ├── triangle-closed.png ├── triangle-opened.png ├── bootstrap │ ├── img │ │ ├── glyphicons-halflings.png │ │ └── glyphicons-halflings-white.png │ └── css │ │ └── bootstrap-select.min.css ├── highlighter.css ├── nav.js ├── highlighter.js ├── glm │ ├── Mat2Base.html │ ├── Mat3Base.html │ ├── Mat4Base.html │ ├── QuatBase.html │ ├── Vec2Base.html │ ├── Vec3Base.html │ ├── Vec4Base.html │ └── index.html ├── Class.html ├── EnumValue.html ├── Void.html ├── Enum.html ├── haxe │ ├── index.html │ ├── EnumValueTools.html │ └── EnumTools.html ├── index.html ├── ArrayAccess.html ├── Dynamic.html ├── Bool.html ├── Null.html ├── Iterable.html ├── Float.html ├── Int.html ├── haxe-nav.css ├── Iterator.html ├── index.js ├── styles.css └── Std.html ├── completion.hxml ├── haxe_libraries ├── promhx.hxml ├── asynctools.hxml └── buddy.hxml ├── haxelib.json ├── dox.hxml ├── manual ├── static_extensions.md └── destination_arguments.md ├── .travis.yml ├── .gitignore ├── src └── glm │ ├── Mat2.hx │ ├── GLM.hx │ └── Vec2.hx ├── README.md └── LICENSE /test/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ -------------------------------------------------------------------------------- /test/test.interp.hxml: -------------------------------------------------------------------------------- 1 | test.each.hxml 2 | --interp -------------------------------------------------------------------------------- /.haxerc: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.4.4", 3 | "resolveLibs": "scoped" 4 | } -------------------------------------------------------------------------------- /test/profile.each.hxml: -------------------------------------------------------------------------------- 1 | -cp . 2 | -cp ../src 3 | -dce full 4 | -main ProfileMain -------------------------------------------------------------------------------- /test/test.cs.hxml: -------------------------------------------------------------------------------- 1 | test.each.hxml 2 | -cs bin 3 | -cmd mono bin/bin/TestMain.exe -------------------------------------------------------------------------------- /sample/build.hxml: -------------------------------------------------------------------------------- 1 | -D glm 2 | -cp ../src 3 | -main Sample 4 | -dce full 5 | --interp -------------------------------------------------------------------------------- /test/test.java.hxml: -------------------------------------------------------------------------------- 1 | test.each.hxml 2 | -java bin 3 | -cmd java -jar bin/TestMain.jar -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/haxe-glm/master/docs/favicon.ico -------------------------------------------------------------------------------- /test/test.cpp.hxml: -------------------------------------------------------------------------------- 1 | test.each.hxml 2 | -cpp bin 3 | -cmd bin/TestMain 4 | -D HXCPP_M64 -------------------------------------------------------------------------------- /test/profile.cpp.hxml: -------------------------------------------------------------------------------- 1 | profile.each.hxml 2 | -cpp bin 3 | -cmd bin/ProfileMain 4 | -D HXCPP_M64 5 | -------------------------------------------------------------------------------- /test/profile.java.hxml: -------------------------------------------------------------------------------- 1 | profile.each.hxml 2 | -java bin 3 | -cmd java -jar bin/ProfileMain.jar 4 | -------------------------------------------------------------------------------- /test/test.python.hxml: -------------------------------------------------------------------------------- 1 | test.each.hxml 2 | -python bin/TestMain.py 3 | -cmd python3 bin/TestMain.py -------------------------------------------------------------------------------- /docs/triangle-closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/haxe-glm/master/docs/triangle-closed.png -------------------------------------------------------------------------------- /docs/triangle-opened.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/haxe-glm/master/docs/triangle-opened.png -------------------------------------------------------------------------------- /test/test.each.hxml: -------------------------------------------------------------------------------- 1 | -lib buddy 2 | -cp . 3 | -cp ../src 4 | -D testing 5 | #-D kha 6 | -main TestMain 7 | -------------------------------------------------------------------------------- /test/test.node.hxml: -------------------------------------------------------------------------------- 1 | test.each.hxml 2 | -D nodejs 3 | -js bin/TestMain.node.js 4 | -cmd node bin/TestMain.node.js -------------------------------------------------------------------------------- /test/profile.node.hxml: -------------------------------------------------------------------------------- 1 | profile.each.hxml 2 | -D nodejs 3 | -js bin/ProfileMain.node.js 4 | -cmd node bin/ProfileMain.node.js -------------------------------------------------------------------------------- /docs/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/haxe-glm/master/docs/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/haxe-glm/master/docs/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /completion.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | glm.GLM 4 | glm.Mat2 5 | glm.Mat3 6 | glm.Mat4 7 | glm.Quat 8 | glm.Vec2 9 | glm.Vec3 10 | glm.Vec4 11 | 12 | #-D kha 13 | 14 | --interp 15 | 16 | -------------------------------------------------------------------------------- /haxe_libraries/promhx.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "haxelib:promhx#1.1.0" into promhx/1.1.0/haxelib 2 | -D promhx=1.1.0 3 | -cp ${HAXESHIM_LIBCACHE}/promhx/1.1.0/haxelib/src/main 4 | -------------------------------------------------------------------------------- /haxe_libraries/asynctools.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "haxelib:asynctools#0.1.0" into asynctools/0.1.0/haxelib 2 | -D asynctools=0.1.0 3 | -cp ${HAXESHIM_LIBCACHE}/asynctools/0.1.0/haxelib/ 4 | -------------------------------------------------------------------------------- /haxe_libraries/buddy.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "haxelib:buddy#2.6.2" into buddy/2.6.2/haxelib 2 | -D buddy=2.6.2 3 | -cp ${HAXESHIM_LIBCACHE}/buddy/2.6.2/haxelib/ 4 | 5 | -lib promhx 6 | -lib asynctools -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glm", 3 | "url" : "https://github.com/FuzzyWuzzie/haxe-glm", 4 | "license": "Apache", 5 | "classPath": "src", 6 | "tags": ["cross", "utility"], 7 | "description": "Native Haxe version of the fantastic GLM library.", 8 | "version": "2.1.0", 9 | "releasenote": "Added Mat2, fleshed out Mat3, changed underlying types", 10 | "contributors": ["FuzzyWuzzie"], 11 | "dependencies": {} 12 | } -------------------------------------------------------------------------------- /dox.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | glm.GLM 4 | glm.Mat2 5 | glm.Mat3 6 | glm.Mat4 7 | glm.Quat 8 | glm.Vec2 9 | glm.Vec3 10 | glm.Vec4 11 | 12 | -xml dox.xml 13 | 14 | --next 15 | -cmd haxelib run dox -i . -o docs --title "GLM" --toplevel-package "glm" -D version "2.1.0" -D source-path "https://github.com/FuzzyWuzzie/haxe-glm/tree/master/src" -D description "Native Haxe version of the fantastic GLM library (https://github.com/g-truc/glm)." -------------------------------------------------------------------------------- /test/TestMain.hx: -------------------------------------------------------------------------------- 1 | package ; 2 | 3 | import glm.*; 4 | 5 | class TestMain { 6 | public static function main() { 7 | var reporter = new buddy.reporting.ConsoleFileReporter(true); 8 | var runner = new buddy.SuitesRunner([ 9 | new TestGLM(), 10 | new TestMat2(), 11 | new TestMat3(), 12 | new TestMat4(), 13 | new TestVec2(), 14 | new TestVec3(), 15 | new TestVec4(), 16 | new TestQuat() 17 | ], reporter); 18 | 19 | runner.run(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docs/highlighter.css: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | Code Highlighting 4 | **/ 5 | 6 | html pre, html pre code { 7 | font-family: consolas, monospace; 8 | white-space: pre; 9 | overflow-x: auto; 10 | } 11 | pre { 12 | color: #333; 13 | margin: 15px 0; 14 | padding: 0.5em; 15 | } 16 | pre .type { 17 | color: #0086b3; 18 | } 19 | pre .kwd { 20 | color: #00a; 21 | } 22 | pre .val { 23 | color: #44a; 24 | } 25 | pre .str, div.pre .str, pre .str .kwd, pre .str .val, pre .str .type { 26 | color: #a00; 27 | } 28 | pre .cmt { 29 | color: #008800; 30 | color: #998; 31 | font-style: italic; 32 | } 33 | /* Make sure keywords inside comments are not highlighted*/ 34 | pre .cmt .kwd, pre .cmt .str, pre .cmt .val, pre .cmt .type { 35 | color: #998; 36 | } 37 | 38 | .last-modified { 39 | color:#999; 40 | } -------------------------------------------------------------------------------- /manual/static_extensions.md: -------------------------------------------------------------------------------- 1 | # Static Extensions 2 | 3 | The bulk of the functions in the vector and matrix classes in this library are designed to be used either statically or as [static extensions](https://haxe.org/manual/lf-static-extension.html). 4 | 5 | Thus the following are equivalent: 6 | 7 | ```haxe 8 | var a:Mat4 = new Mat4(); 9 | var b:Mat4 = Mat4.copy(a, new Mat4()); 10 | ``` 11 | 12 | and: 13 | 14 | ```haxe 15 | using glm.Mat4; 16 | 17 | var a:Mat4 = new Mat4(); 18 | var b:Mat4 = a.copy(new Mat4()); 19 | ``` 20 | 21 | By including the `using ;` line at the top of the source file, you can omit the first argument (usually, the source parameter). Although this is slightly inconvenient, it adds some handy flexibility and is a small price to pay for that flexibility. 22 | -------------------------------------------------------------------------------- /manual/destination_arguments.md: -------------------------------------------------------------------------------- 1 | # Destination Arguments 2 | 3 | The bulk of the functions in the vector and matrix classes in this library include a `dest` parameter. This puts the onus on you to decide how instantiation will occur (or not). Instead of automatically creating a new object on every operation, each operation gives you the choice to set the values of a pre-instantiated object instead. 4 | 5 | For example, you can create a completely new identity matrix using: 6 | 7 | ```haxe 8 | var m:Mat4 = Mat4.identity(new Mat4()); 9 | ``` 10 | 11 | Alternatively, you can modify an existing matrix to make it an identity matrix using: 12 | 13 | ```haxe 14 | var somePreexistingUnusedMat:Mat4 = new Mat4(1, 2, 3, 4); 15 | 16 | // ... 17 | 18 | var m:Mat4 = Mat4.identity(somePreexistingUnusedMat); 19 | 20 | m == somePreexistingUnusedMat; // true! 21 | ``` 22 | -------------------------------------------------------------------------------- /sample/Sample.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import Sys; 4 | import glm.GLM; 5 | using glm.Mat4; 6 | using glm.Vec3; 7 | using glm.Vec4; 8 | using glm.Quat; 9 | 10 | class Sample { 11 | public static function main() { 12 | var P:Mat4 = GLM.perspective(45 * Math.PI / 180, 640 / 480, 0.1, 100, new Mat4()); 13 | Sys.println('P:'); 14 | Sys.println(P.toString()); 15 | 16 | var camM:Mat4 = GLM.translate(new Vec3(0, 0, 6) , new Mat4()); 17 | var V:Mat4 = camM.invert(new Mat4()); 18 | Sys.println('V:'); 19 | Sys.println(V.toString()); 20 | 21 | var PV:Mat4 = P.multMat(V, new Mat4()); 22 | Sys.println('PV:'); 23 | Sys.println(PV.toString()); 24 | 25 | var p3d:Vec4 = new Vec4(1, 1, 0, 1); 26 | var p2d:Vec4 = PV * p3d; 27 | Vec4.multiplyScalar(p2d, 1 / p2d.w, p2d); 28 | Sys.println(p3d.toString() + ' -> ' + p2d.toString()); 29 | 30 | var rot:Quat = new Quat().identity(); 31 | Sys.println('\nrot: ' + rot.toString()); 32 | } 33 | } -------------------------------------------------------------------------------- /test/glm/TestMat2.hx: -------------------------------------------------------------------------------- 1 | package glm; 2 | 3 | import buddy.*; 4 | using buddy.Should; 5 | 6 | using glm.Mat2; 7 | 8 | class TestMat2 extends BuddySuite { 9 | public function new() { 10 | describe('Using Mat2s', { 11 | var ma:Mat2, mb:Mat2, mono:Mat2; 12 | 13 | beforeEach({ 14 | }); 15 | 16 | it("should provide element access"); 17 | 18 | it("should access elements in column-major order"); 19 | 20 | it("should provide an identity"); 21 | 22 | it("should provide copy support"); 23 | 24 | it("should be able to transpose", { 25 | ma = new Mat2( 26 | 0, 1, 27 | 2, 3 28 | ); 29 | var mb = ma.transpose(new Mat2()); 30 | mb.r0c1.should.be(2); 31 | mb.r1c0.should.be(1); 32 | }); 33 | 34 | it("should calculate the determinant"); 35 | 36 | it("should invert"); 37 | 38 | it("should multiply other matrices"); 39 | 40 | it("should multiply vectors"); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /docs/nav.js: -------------------------------------------------------------------------------- 1 | var navContent=''; -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # adapted from https://github.com/andyli/HaxeCI/blob/master/.travis.yml 2 | language: haxe 3 | 4 | # keep everything in the test subdir 5 | before_script: cd test 6 | 7 | env: 8 | matrix: 9 | - TARGET=interp 10 | - TARGET=cpp 11 | - TARGET=cs 12 | - TARGET=java 13 | - TARGET=node 14 | - TARGET=python 15 | 16 | # Test with Current Haxe and Haxe development. 17 | haxe: 18 | - stable 19 | - development 20 | 21 | matrix: 22 | # Allow Haxe development to fail. 23 | allow_failures: 24 | - haxe: development 25 | 26 | install: 27 | # install haxelibs 28 | - haxelib install buddy 29 | 30 | # apt packages for each target 31 | - sudo apt-get update 32 | - sh -c "if [ '$TARGET' = 'cpp' ]; then sudo apt-get install gcc-multilib g++-multilib -y; fi" 33 | - sh -c "if [ '$TARGET' = 'cs' ]; then sudo apt-get install mono-devel -y; fi" 34 | - sh -c "if [ '$TARGET' = 'python' ]; then sudo apt-get install python3 -y; fi" 35 | 36 | # haxelib dependencies for each target 37 | - sh -c "if [ '$TARGET' = 'cpp' ]; then haxelib install hxcpp; fi" 38 | - sh -c "if [ '$TARGET' = 'java' ]; then haxelib install hxjava; fi" 39 | - sh -c "if [ '$TARGET' = 'cs' ]; then haxelib install hxcs; fi" 40 | 41 | script: 42 | - haxe test.${TARGET}.hxml 43 | 44 | branches: 45 | only: 46 | - master 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | .vscode/ 3 | dox.xml 4 | 5 | # Created by https://www.gitignore.io/api/windows,osx,linux,visualstudiocode 6 | 7 | ### Linux ### 8 | *~ 9 | 10 | # temporary files which can be created if a process still has a handle open of a deleted file 11 | .fuse_hidden* 12 | 13 | # KDE directory preferences 14 | .directory 15 | 16 | # Linux trash folder which might appear on any partition or disk 17 | .Trash-* 18 | 19 | # .nfs files are created when an open file is removed but is still being accessed 20 | .nfs* 21 | 22 | ### OSX ### 23 | *.DS_Store 24 | .AppleDouble 25 | .LSOverride 26 | 27 | # Icon must end with two \r 28 | Icon 29 | 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | .com.apple.timemachine.donotpresent 42 | 43 | # Directories potentially created on remote AFP share 44 | .AppleDB 45 | .AppleDesktop 46 | Network Trash Folder 47 | Temporary Items 48 | .apdisk 49 | 50 | ### VisualStudioCode ### 51 | .vscode/* 52 | !.vscode/settings.json 53 | !.vscode/tasks.json 54 | !.vscode/launch.json 55 | !.vscode/extensions.json 56 | 57 | ### Windows ### 58 | # Windows thumbnail cache files 59 | Thumbs.db 60 | ehthumbs.db 61 | ehthumbs_vista.db 62 | 63 | # Folder config file 64 | Desktop.ini 65 | 66 | # Recycle Bin used on file shares 67 | $RECYCLE.BIN/ 68 | 69 | # Windows Installer files 70 | *.cab 71 | *.msi 72 | *.msm 73 | *.msp 74 | 75 | # Windows shortcuts 76 | *.lnk 77 | 78 | # End of https://www.gitignore.io/api/windows,osx,linux,visualstudiocode 79 | -------------------------------------------------------------------------------- /test/glm/TestMat3.hx: -------------------------------------------------------------------------------- 1 | package glm; 2 | 3 | import buddy.*; 4 | using buddy.Should; 5 | 6 | using glm.Mat3; 7 | 8 | class TestMat3 extends BuddySuite { 9 | public function new() { 10 | describe('Using Mat3s', { 11 | var ma:Mat3, mb:Mat3, mono:Mat3; 12 | 13 | beforeEach({ 14 | ma = new Mat3( 15 | 1, 0, 1, 16 | 0, 1, 2, 17 | 0, 0, 1 18 | ); 19 | 20 | mb = new Mat3( 21 | 1, 0, 4, 22 | 0, 1, 5, 23 | 0, 0, 1 24 | ); 25 | 26 | mono = new Mat3( 27 | 1, 2, 3, 28 | 4, 5, 6, 29 | 7, 8, 9 30 | ); 31 | }); 32 | 33 | it("should provide element access", { 34 | ma.r0c2.should.be(1); 35 | ma.r1c2.should.be(2); 36 | ma.r2c2.should.be(1); 37 | 38 | ma.r0c1 = 42; 39 | ma.r0c1.should.be(42); 40 | }); 41 | 42 | it("should access elements in column-major order", { 43 | ma[3].should.be(ma.r0c1); 44 | ma[7].should.be(ma.r1c2); 45 | }); 46 | 47 | it("should provide an identity", { 48 | ma = Mat3.identity(new Mat3()); 49 | 50 | var identity:Mat3 = new Mat3( 51 | 1, 0, 0, 52 | 0, 1, 0, 53 | 0, 0, 1); 54 | ma.equals(identity).should.be(true); 55 | }); 56 | 57 | it("should provide copy support", { 58 | ma[0] = 5; 59 | ma[8] = 42; 60 | mb = ma.copy(new Mat3()); 61 | mb.equals(ma).should.be(true); 62 | }); 63 | 64 | it("should be able to transpose", { 65 | ma = new Mat3( 66 | 0, 1, 2, 67 | 3, 4, 5, 68 | 6, 7, 8 69 | ); 70 | var mb = ma.transpose(new Mat3()); 71 | mb.r1c0.should.be(1); 72 | mb.r0c2.should.be(6); 73 | }); 74 | 75 | it("should calculate the determinant"); 76 | 77 | it("should invert"); 78 | 79 | it("should multiply other matrices"); 80 | 81 | it("should multiply vectors"); 82 | }); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /docs/highlighter.js: -------------------------------------------------------------------------------- 1 | // highlighter adapted from code.haxe.org 2 | (function (console) { "use strict"; 3 | var EReg = function(r,opt) { 4 | opt = opt.split("u").join(""); 5 | this.r = new RegExp(r,opt); 6 | }; 7 | EReg.prototype = { 8 | replace: function(s,by) { 9 | return s.replace(this.r,by); 10 | } 11 | }; 12 | var Highlighter = function() { }; 13 | Highlighter.main = function() { 14 | js.JQuery("pre code").each(function() { 15 | var el = js.JQuery(this); 16 | if(!el.hasClass("highlighted")) { 17 | el.html(Highlighter.syntaxHighlight(el.html())); 18 | el.addClass("highlighted"); 19 | } 20 | }); 21 | }; 22 | Highlighter.syntaxHighlight = function(html) { 23 | var kwds = ["abstract","trace","break","case","cast","class","continue","default","do","dynamic","else","enum","extends","extern","for","function","if","implements","import","in","inline","interface","macro","new","override","package","private","public","return","static","switch","throw","try","typedef","untyped","using","var","while"]; 24 | var kwds1 = new EReg("\\b(" + kwds.join("|") + ")\\b","g"); 25 | var vals = ["null","true","false","this"]; 26 | var vals1 = new EReg("\\b(" + vals.join("|") + ")\\b","g"); 27 | var types = new EReg("\\b([A-Z][a-zA-Z0-9]*)\\b","g"); 28 | html = kwds1.replace(html,"$1"); 29 | html = vals1.replace(html,"$1"); 30 | html = types.replace(html,"$1"); 31 | html = new EReg("(\"[^\"]*\")","g").replace(html,"$1"); 32 | html = new EReg("(//.+\n)","g").replace(html,"$1"); 33 | html = new EReg("(/\\*\\*?[^*]*\\*?\\*/)","g").replace(html,"$1"); 34 | return html; 35 | }; 36 | var q = window.jQuery; 37 | var js = js || {} 38 | js.JQuery = q; 39 | Highlighter.main(); 40 | })(typeof console != "undefined" ? console : {log:function(){}}); -------------------------------------------------------------------------------- /test/glm/TestVec4.hx: -------------------------------------------------------------------------------- 1 | package glm; 2 | 3 | import buddy.*; 4 | using buddy.Should; 5 | 6 | using glm.Vec4; 7 | 8 | class TestVec4 extends BuddySuite { 9 | public function new() { 10 | describe('Using Vec4s', { 11 | var va:Vec4, vb:Vec4; 12 | 13 | beforeEach({ 14 | va = new Vec4(1, 2, 3, 1); 15 | vb = new Vec4(-1, -2, -3, -1); 16 | }); 17 | 18 | it("should provide element access", { 19 | va[2].should.be(3); 20 | va.y.should.be(2); 21 | va.x = 42; 22 | va[0].should.be(42); 23 | }); 24 | 25 | it("should calculate the magnitude", { 26 | va.lengthSquared().should.be(15); 27 | va.length().should.beCloseTo(3.872983346207417); 28 | }); 29 | 30 | it("should provide copy support", { 31 | va.copy(vb); 32 | va.equals(vb).should.be(true); 33 | }); 34 | 35 | it("should provide vector math", { 36 | va.addVec(new Vec4(1, 1, 1, 1), vb); 37 | vb.equals(new Vec4(2, 3, 4, 2)).should.be(true); 38 | 39 | vb.subtractVec(new Vec4(1, 1, 1, 1), vb); 40 | vb.equals(va).should.be(true); 41 | 42 | var vc:Vec4 = va + new Vec4(1, 1, 1, 1); 43 | vc.equals(new Vec4(2, 3, 4, 2)).should.be(true); 44 | 45 | vc = va - new Vec4(1, 2, 3, 1); 46 | vc.equals(new Vec4()).should.be(true); 47 | }); 48 | 49 | it("should provide scalar math", { 50 | va.addScalar(1, vb); 51 | vb.equals(new Vec4(2, 3, 4, 2)).should.be(true); 52 | va.multiplyScalar(0.5, vb); 53 | vb.equals(new Vec4(0.5, 1, 1.5, 0.5)).should.be(true); 54 | 55 | var vc:Vec4 = va * 3; 56 | vc.equals(new Vec4(3, 6, 9, 3)).should.be(true); 57 | 58 | vc = va + 3; 59 | vc.equals(new Vec4(4, 5, 6, 4)).should.be(true); 60 | 61 | vc = va - 1; 62 | vc.equals(new Vec4(0, 1, 2, 0)).should.be(true); 63 | }); 64 | 65 | it("should calculate distance between vectors", { 66 | va.distanceSquared(vb).should.beCloseTo(60); 67 | va.distance(vb).should.beCloseTo(7.745966692414834); 68 | }); 69 | 70 | it("should calculate the dot product", { 71 | va.dot(vb).should.beCloseTo(-15); 72 | }); 73 | 74 | it("should normalize", { 75 | var v:Vec4 = va.normalize(new Vec4()); 76 | v.x.should.beCloseTo(0.2581988897471611); 77 | v.y.should.beCloseTo(0.5163977794943222); 78 | v.z.should.beCloseTo(0.7745966692414834); 79 | v.w.should.beCloseTo(0.2581988897471611); 80 | }); 81 | 82 | it("should linearly interpolate", { 83 | var x:Vec4 = va.lerp(vb, 0.5, new Vec4()); 84 | x.equals(new Vec4()).should.be(true); 85 | }); 86 | }); 87 | } 88 | } -------------------------------------------------------------------------------- /test/glm/TestVec2.hx: -------------------------------------------------------------------------------- 1 | package glm; 2 | 3 | import buddy.*; 4 | using buddy.Should; 5 | 6 | using glm.Vec2; 7 | using glm.Vec3; 8 | 9 | class TestVec2 extends BuddySuite { 10 | public function new() { 11 | describe('Using Vec2s', { 12 | var va:Vec2, vb:Vec2; 13 | 14 | beforeEach({ 15 | va = new Vec2(1, 2); 16 | vb = new Vec2(-1, -2); 17 | }); 18 | 19 | it("should provide element access", { 20 | va[1].should.be(2); 21 | va.x.should.be(1); 22 | va.x = 42; 23 | va[0].should.be(42); 24 | }); 25 | 26 | it("should calculate the magnitude", { 27 | var m:Float = Math.sqrt(va.x*va.x + va.y*va.y); 28 | va.length().should.beCloseTo(m); 29 | }); 30 | 31 | it("should provide copy support", { 32 | var vc:Vec2 = va.copy(new Vec2()); 33 | vc.x.should.beCloseTo(va.x); 34 | vc.y.should.beCloseTo(va.y); 35 | }); 36 | 37 | it("should provide vector math", { 38 | va.addVec(new Vec2(1, 1), vb); 39 | vb.equals(new Vec2(2, 3)).should.be(true); 40 | 41 | vb.subtractVec(new Vec2(1, 1), vb); 42 | vb.equals(va).should.be(true); 43 | 44 | var vc:Vec2 = va + new Vec2(1, 1); 45 | vc.equals(new Vec2(2, 3)).should.be(true); 46 | 47 | vc = va - new Vec2(1, 2); 48 | vc.equals(new Vec2()).should.be(true); 49 | }); 50 | 51 | it("should provide scalar math", { 52 | va.addScalar(1, vb); 53 | vb.equals(new Vec2(2, 3)).should.be(true); 54 | va.multiplyScalar(0.5, vb); 55 | vb.equals(new Vec2(0.5, 1)).should.be(true); 56 | 57 | var vc:Vec2 = va * 3; 58 | vc.equals(new Vec2(3, 6)).should.be(true); 59 | 60 | vc = va + 3; 61 | vc.equals(new Vec2(4, 5)).should.be(true); 62 | 63 | vc = va - 1; 64 | vc.equals(new Vec2(0, 1)).should.be(true); 65 | }); 66 | 67 | it("should calculate distance between vectors", { 68 | va.distance(vb).should.beCloseTo(4.4721); 69 | }); 70 | 71 | it("should calculate the dot product", { 72 | va.dot(vb).should.beCloseTo(-5); 73 | }); 74 | 75 | it("should normalize", { 76 | var v:Vec2 = va.normalize(new Vec2()); 77 | v.x.should.beCloseTo(0.4472); 78 | v.y.should.beCloseTo(0.8944); 79 | }); 80 | 81 | it("should linearly interpolate", { 82 | var x:Vec2 = va.lerp(vb, 0.5, new Vec2()); 83 | x.equals(new Vec2()).should.be(true); 84 | }); 85 | 86 | it("provide the cross product", { 87 | va = new Vec2(1, 0); 88 | vb = new Vec2(0, 1); 89 | var vc:Vec3 = va.cross(vb, new Vec3()); 90 | 91 | vc.x.should.be(0); 92 | vc.y.should.be(0); 93 | vc.z.should.be(1); 94 | }); 95 | }); 96 | } 97 | } -------------------------------------------------------------------------------- /test/glm/TestVec3.hx: -------------------------------------------------------------------------------- 1 | package glm; 2 | 3 | import buddy.*; 4 | using buddy.Should; 5 | 6 | using glm.Vec3; 7 | 8 | class TestVec3 extends BuddySuite { 9 | public function new() { 10 | describe('Using Vec3s', { 11 | var va:Vec3, vb:Vec3; 12 | 13 | beforeEach({ 14 | va = new Vec3(1, 2, 3); 15 | vb = new Vec3(-1, -2, -3); 16 | }); 17 | 18 | it("should provide element access", { 19 | va[1].should.be(2); 20 | va.x.should.be(1); 21 | va.x = 42; 22 | va[0].should.be(42); 23 | }); 24 | 25 | it("should calculate the magnitude", { 26 | var m:Float = Math.sqrt(va.x*va.x + va.y*va.y + va.z*va.z); 27 | va.length().should.beCloseTo(m); 28 | }); 29 | 30 | it("should provide copy support", { 31 | var vc:Vec3 = va.copy(new Vec3()); 32 | vc.x.should.beCloseTo(va.x); 33 | vc.y.should.beCloseTo(va.y); 34 | vc.z.should.beCloseTo(va.z); 35 | }); 36 | 37 | it("should provide vector math", { 38 | va.addVec(new Vec3(1, 1, 1), vb); 39 | vb.equals(new Vec3(2, 3, 4)).should.be(true); 40 | 41 | vb.subtractVec(new Vec3(1, 1, 1), vb); 42 | vb.equals(va).should.be(true); 43 | 44 | var vc:Vec3 = va + new Vec3(1, 1, 1); 45 | vc.equals(new Vec3(2, 3, 4)).should.be(true); 46 | 47 | vc = va - new Vec3(1, 2, 3); 48 | vc.equals(new Vec3()).should.be(true); 49 | }); 50 | 51 | it("should provide scalar math", { 52 | va.addScalar(1, vb); 53 | vb.equals(new Vec3(2, 3, 4)).should.be(true); 54 | va.multiplyScalar(0.5, vb); 55 | vb.equals(new Vec3(0.5, 1, 1.5)).should.be(true); 56 | 57 | var vc:Vec3 = va * 3; 58 | vc.equals(new Vec3(3, 6, 9)).should.be(true); 59 | 60 | vc = va + 3; 61 | vc.equals(new Vec3(4, 5, 6)).should.be(true); 62 | 63 | vc = va - 1; 64 | vc.equals(new Vec3(0, 1, 2)).should.be(true); 65 | }); 66 | 67 | it("should calculate distance between vectors", { 68 | va.distance(vb).should.beCloseTo(7.4833); 69 | }); 70 | 71 | it("should calculate the dot product", { 72 | va.dot(vb).should.beCloseTo(-14); 73 | }); 74 | 75 | it("should normalize", { 76 | var v:Vec3 = va.normalize(new Vec3()); 77 | v.x.should.beCloseTo(0.2673); 78 | v.y.should.beCloseTo(0.5345); 79 | v.z.should.beCloseTo(0.8018); 80 | }); 81 | 82 | it("should linearly interpolate", { 83 | var x:Vec3 = va.lerp(vb, 0.5, new Vec3()); 84 | x.equals(new Vec3()).should.be(true); 85 | }); 86 | 87 | it("provide the cross product", { 88 | va = new Vec3(1, 0, 0); 89 | vb = new Vec3(0, 1, 0); 90 | var vc:Vec3 = va.cross(vb, new Vec3()); 91 | 92 | vc.x.should.be(0); 93 | vc.y.should.be(0); 94 | vc.z.should.be(1); 95 | }); 96 | }); 97 | } 98 | } -------------------------------------------------------------------------------- /docs/glm/Mat2Base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | glm.Mat2Base - GLM

-------------------------------------------------------------------------------- /docs/glm/Mat3Base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | glm.Mat3Base - GLM

-------------------------------------------------------------------------------- /docs/glm/Mat4Base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | glm.Mat4Base - GLM

-------------------------------------------------------------------------------- /docs/glm/QuatBase.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | glm.QuatBase - GLM

-------------------------------------------------------------------------------- /docs/glm/Vec2Base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | glm.Vec2Base - GLM

-------------------------------------------------------------------------------- /docs/glm/Vec3Base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | glm.Vec3Base - GLM

-------------------------------------------------------------------------------- /docs/glm/Vec4Base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | glm.Vec4Base - GLM

-------------------------------------------------------------------------------- /docs/Class.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Class - GLM

An abstract type that represents a Class.

10 |

See Type for the Haxe Reflection API.

See:

-------------------------------------------------------------------------------- /docs/EnumValue.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | EnumValue - GLM

An abstract type that represents any enum value. 11 | See Type for the Haxe Reflection API.

See:

-------------------------------------------------------------------------------- /docs/Void.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Void - GLM

The standard Void type. Only null values can be of the type Void.

See:

-------------------------------------------------------------------------------- /docs/Enum.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Enum - GLM

An abstract type that represents an Enum type.

10 |

The corresponding enum instance type is EnumValue.

11 |

See Type for the Haxe Reflection API.

See:

-------------------------------------------------------------------------------- /docs/haxe/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | haxe - GLM

haxe

..
EnumTools

This class provides advanced methods on enums. It is ideally used with 10 | using EnumTools and then acts as an 11 | extension to the 12 | enum types.

EnumValueTools

This class provides advanced methods on enum values. It is ideally used with 13 | using EnumValueTools and then acts as an 14 | extension to the 15 | EnumValue types.

-------------------------------------------------------------------------------- /docs/glm/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | glm - GLM

glm

..
Mat2

A 4x4 matrix

Mat3

A 4x4 matrix

Mat4

A 4x4 matrix

Quat

A quaternion

Vec2

A two-element vector

Vec3

A three-element vector

Vec4

A four-element vector

-------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | top level - GLM

top level version 2.1.0

Native Haxe version of the fantastic GLM library (https://github.com/g-truc/glm).

GLM

Utility functions for 3D math

Mat2

A 4x4 matrix

Mat3

A 4x4 matrix

Mat4

A 4x4 matrix

Quat

A quaternion

Vec2

A two-element vector

Vec3

A three-element vector

Vec4

A four-element vector

-------------------------------------------------------------------------------- /docs/ArrayAccess.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ArrayAccess - GLM

ArrayAccess is used to indicate a class that can be accessed using brackets. 11 | The type parameter represents the type of the elements stored.

12 |

This interface should be used for externs only. Haxe does not support custom 13 | array access on classes. However, array access can be implemented for 14 | abstract types.

See:

-------------------------------------------------------------------------------- /docs/Dynamic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dynamic - GLM

Dynamic is a special type which is compatible with all other types.

10 |

Use of Dynamic should be minimized as it prevents several compiler 11 | checks and optimizations. See Any type for a safer alternative for 12 | representing values of any type.

See:

-------------------------------------------------------------------------------- /docs/Bool.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bool - GLM

The standard Boolean type, which can either be true or false.

10 |

On static targets, null cannot be assigned to Bool. If this is necessary, 11 | Null<Bool> can be used instead.

See:

-------------------------------------------------------------------------------- /docs/Null.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Null - GLM

Null can be useful in two cases. In order to document some methods 13 | that accept or can return a null value, or for the Flash compiler and AS3 14 | generator to distinguish between base values that can be null and others that 15 | can't.

See:

-------------------------------------------------------------------------------- /docs/Iterable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Iterable - GLM

An Iterable is a data structure which has an iterator() method. 11 | See Lambda for generic functions on iterable structures.

See:

Properties

-------------------------------------------------------------------------------- /docs/Float.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Float - GLM

The standard Float type, this is a double-precision IEEE 64bit float.

10 |

On static targets, null cannot be assigned to Float. If this is necessary, 11 | Null<Float> can be used instead.

12 |

Std.int converts a Float to an Int, rounded towards 0. 13 | Std.parseFloat converts a String to a Float.

See:

-------------------------------------------------------------------------------- /test/ProfileMain.hx: -------------------------------------------------------------------------------- 1 | package ; 2 | 3 | import glm.*; 4 | import haxe.Timer; 5 | 6 | using StringTools; 7 | 8 | typedef ProfileResult = { 9 | var name:String; 10 | var times:String; 11 | var totalTime:String; 12 | var unitTime:String; 13 | } 14 | 15 | class ProfileMain { 16 | private static var results:Array = new Array(); 17 | 18 | private inline static function log10(x:Float):Float { 19 | return Math.log(x) / Math.log(10); 20 | } 21 | 22 | private static function toSI(x:Float):String { 23 | var incPrefixes:Array = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; 24 | var decPrefixes:Array = ['m', 'u', 'n', 'p', 'f', 'a', 'z', 'y']; 25 | 26 | var degree:Int = Math.floor(log10(Math.abs(x)) / 3); 27 | 28 | var prefix:String = ''; 29 | if(degree != 0) { 30 | var ds:Float = degree / Math.abs(degree); 31 | if(ds == 1) { 32 | if(degree - 1 < incPrefixes.length) { 33 | prefix = incPrefixes[degree - 1]; 34 | } 35 | else { 36 | prefix = incPrefixes[incPrefixes.length - 1]; 37 | degree = incPrefixes.length; 38 | } 39 | } 40 | else if(ds == -1) { 41 | if(-degree - 1 < decPrefixes.length) { 42 | prefix = decPrefixes[-degree - 1]; 43 | } 44 | else { 45 | prefix = decPrefixes[decPrefixes.length - 1]; 46 | degree = -decPrefixes.length; 47 | } 48 | } 49 | 50 | var scaled:Float = x * Math.pow(1000, -degree); 51 | scaled = Math.fround(scaled * 10) / 10; 52 | return '${scaled}${prefix}'; 53 | } 54 | 55 | return '${x}'; 56 | } 57 | 58 | private static function measure(name:String, times:Int = 100000, fn:Void->Void):Void { 59 | var start:Float = Timer.stamp(); 60 | for(i in 0...times) fn(); 61 | var end:Float = Timer.stamp(); 62 | results.push({ 63 | name: name, 64 | times: '${times}', 65 | totalTime: '${end - start}s', 66 | unitTime: toSI((end - start) / times) + 's' 67 | }); 68 | } 69 | 70 | private static function printResults() { 71 | results.insert(0, { 72 | name: 'Test', 73 | times: 'Times', 74 | totalTime: 'Total Time', 75 | unitTime: 'Unit Time' 76 | }); 77 | results.insert(1, { 78 | name: '----', 79 | times: '-----', 80 | totalTime: '----------', 81 | unitTime: '---------' 82 | }); 83 | 84 | var nameWidth:Int = 0, timesWidth:Int = 0, totalTimeWidth:Int = 0, unitTimeWidth:Int = 0; 85 | for(result in results) { 86 | if(result.name.length > nameWidth) nameWidth = result.name.length; 87 | if(result.times.length > timesWidth) timesWidth = result.times.length; 88 | if(result.totalTime.length > totalTimeWidth) totalTimeWidth = result.totalTime.length; 89 | if(result.unitTime.length > unitTimeWidth) unitTimeWidth = result.unitTime.length; 90 | } 91 | 92 | for(result in results) { 93 | var line:String = '| '; 94 | line += result.name.rpad(' ', nameWidth) + ' | '; 95 | line += result.times.lpad(' ', timesWidth) + ' | '; 96 | line += result.totalTime.lpad(' ', totalTimeWidth) + ' | '; 97 | line += result.unitTime.lpad(' ', unitTimeWidth) + ' |'; 98 | 99 | #if sys 100 | Sys.println(line); 101 | #elseif js 102 | untyped __js__("console.log(line)"); 103 | #else 104 | trace(line); 105 | #end 106 | } 107 | } 108 | 109 | public static function main() { 110 | measure("mat4 instantiation", function() { 111 | var ma:Mat4 = new Mat4( 112 | 1, 0, 0, 0, 113 | 0, 1, 0, 0, 114 | 0, 0, 1, 0, 115 | 1, 2, 3, 1 116 | ); 117 | ma = null; 118 | }); 119 | 120 | var a:Mat4 = new Mat4( 121 | 1, 0, 0, 0, 122 | 0, 1, 0, 0, 123 | 0, 0, 1, 0, 124 | 1, 2, 3, 1 125 | ); 126 | var b:Mat4 = new Mat4(); 127 | var va:Vec4 = new Vec4(1, 2, 3, 1); 128 | var vb:Vec4 = new Vec4(); 129 | 130 | measure("mat4 transpose", function() { 131 | Mat4.transpose(a, b); 132 | }); 133 | 134 | measure("mat4 determinant", function() { 135 | Mat4.determinant(a); 136 | }); 137 | 138 | measure("mat4 invert", function() { 139 | Mat4.invert(a, b); 140 | }); 141 | 142 | measure("mat4 mat multiply", function() { 143 | Mat4.multMat(a, b, b); 144 | }); 145 | 146 | measure("mat4 vec multiply", function() { 147 | Mat4.multVec(a, va, vb); 148 | }); 149 | 150 | printResults(); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /docs/Int.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Int - GLM

The standard Int type. Its precision depends on the platform.

10 |

On static targets, null cannot be assigned to Int. If this is necessary, 11 | Null<Int> can be used instead.

12 |

Std.int converts a Float to an Int, rounded towards 0. 13 | Std.parseInt converts a String to an Int.

See:

-------------------------------------------------------------------------------- /test/glm/TestMat4.hx: -------------------------------------------------------------------------------- 1 | package glm; 2 | 3 | import buddy.*; 4 | using buddy.Should; 5 | 6 | using glm.Mat4; 7 | 8 | class TestMat4 extends BuddySuite { 9 | public function new() { 10 | describe('Using Mat4s', { 11 | var ma:Mat4, mb:Mat4, mono:Mat4; 12 | 13 | beforeEach({ 14 | ma = new Mat4( 15 | 1, 0, 0, 1, 16 | 0, 1, 0, 2, 17 | 0, 0, 1, 3, 18 | 0, 0, 0, 1 19 | ); 20 | 21 | mb = new Mat4( 22 | 1, 0, 0, 4, 23 | 0, 1, 0, 5, 24 | 0, 0, 1, 6, 25 | 0, 0, 0, 1 26 | ); 27 | 28 | mono = new Mat4( 29 | 1, 2, 3, 4, 30 | 5, 6, 7, 8, 31 | 9, 10, 11, 12, 32 | 13, 14, 15, 16 33 | ); 34 | }); 35 | 36 | it("should provide element access", { 37 | ma.r0c3.should.be(1); 38 | ma.r1c3.should.be(2); 39 | ma.r2c3.should.be(3); 40 | ma.r3c0.should.be(0); 41 | 42 | ma.r0c1 = 42; 43 | ma.r0c1.should.be(42); 44 | }); 45 | 46 | it("should access elements in column-major order", { 47 | ma[3].should.be(ma.r3c0); 48 | ma[7].should.be(ma.r3c1); 49 | ma[11].should.be(ma.r3c2); 50 | ma[15].should.be(ma.r3c3); 51 | }); 52 | 53 | it("should provide an identity", { 54 | ma = Mat4.identity(new Mat4()); 55 | 56 | var identity:Mat4 = new Mat4( 57 | 1, 0, 0, 0, 58 | 0, 1, 0, 0, 59 | 0, 0, 1, 0, 60 | 0, 0, 0, 1); 61 | ma.equals(identity).should.be(true); 62 | }); 63 | 64 | it("should provide copy support", { 65 | ma[0] = 5; 66 | ma[9] = 42; 67 | mb = ma.copy(new Mat4()); 68 | mb.equals(ma).should.be(true); 69 | }); 70 | 71 | it("should be able to transpose", { 72 | mb = ma.transpose(new Mat4()); 73 | mb.r3c0.should.beCloseTo(1); 74 | mb.r3c1.should.beCloseTo(2); 75 | mb.r3c2.should.beCloseTo(3); 76 | var mc:Mat4 = new Mat4(); 77 | ma.transpose(mc); 78 | mc.equals(mb).should.be(true); 79 | }); 80 | 81 | it("should calculate the determinant", { 82 | ma.determinant().should.beCloseTo(1); 83 | }); 84 | 85 | it("should invert", { 86 | var target:Mat4 = new Mat4( 87 | 1, 0, 0, -1, 88 | 0, 1, 0, -2, 89 | 0, 0, 1, -3, 90 | 0, 0, 0, 1 91 | ); 92 | 93 | mb = ma.invert(new Mat4()); 94 | target.equals(mb).should.be(true); 95 | 96 | // now try a "real-world" matrix 97 | ma = new Mat4( 98 | 1.3910845518112183, -0.3573116362094879, 1.3918377161026, 7.8977532386779785, 99 | 1.4369703531265259, 0.3458636403083801, -1.347402811050415, -7.944790840148926, 100 | 2.8320780984358862e-05, 1.9371904134750366, 0.4972859025001526, 2.9501945972442627, 101 | 0.0, 0.0, 0.0, 1.0); 102 | 103 | // invert it twice, it should go back to itself! 104 | mb = ma.invert(mb); 105 | mb.invert(mb); 106 | for(i in 0...16) { 107 | ma[i].should.beCloseTo(mb[i]); 108 | } 109 | 110 | // and it should roughly equal this: 111 | target = new Mat4( 112 | 0.34777113795280457, 0.35924261808395386, 7.078052021824988e-06, 0.10747592151165009, 113 | -0.08932791650295258, 0.08646592497825623, 0.48429763317108154, -0.03632880374789238, 114 | 0.3479594588279724, -0.33685073256492615, 0.12432148307561874, -5.791079521179199, 115 | -0.0, 0.0, -0.0, 1.0); 116 | mb.invert(mb); 117 | for(i in 0...16) { 118 | mb[i].should.beCloseTo(target[i]); 119 | } 120 | }); 121 | 122 | it("should multiply other matrices", { 123 | var mc:Mat4 = ma.multMat(mb, new Mat4()); 124 | var target:Mat4 = new Mat4( 125 | 1, 0, 0, 5, 126 | 0, 1, 0, 7, 127 | 0, 0, 1, 9, 128 | 0, 0, 0, 1 129 | ); 130 | target.equals(mc).should.be(true); 131 | 132 | target = new Mat4( 133 | 14, 16, 18, 20, 134 | 31, 34, 37, 40, 135 | 48, 52, 56, 60, 136 | 13, 14, 15, 16 137 | ); 138 | ma.multMat(mono, mc); 139 | target.equals(mc).should.be(true); 140 | 141 | mc = ma * mono; 142 | mc.equals(target).should.be(true); 143 | }); 144 | 145 | it("should multiply vectors", { 146 | var p:Vec4 = new Vec4(0, 0, 0, 1); 147 | var t:Vec4 = ma.multVec(p, new Vec4()); 148 | t.equals(new Vec4(1, 2, 3, 1)).should.be(true); 149 | 150 | t = ma * p; 151 | t.equals(new Vec4(1, 2, 3, 1)).should.be(true); 152 | }); 153 | }); 154 | } 155 | } -------------------------------------------------------------------------------- /docs/haxe-nav.css: -------------------------------------------------------------------------------- 1 | nav.nav { 2 | font-family: "Open Sans", sans-serif; 3 | font-size: 16px; 4 | margin:0; 5 | } 6 | 7 | nav .fa { 8 | color:#777; 9 | margin-right:5px; 10 | } 11 | 12 | body nav * {line-height:20px;} 13 | 14 | nav .navbar-inverse .navbar-inner { 15 | background:#13110f; 16 | border:0; 17 | } 18 | 19 | nav .navbar .nav { 20 | margin:0; 21 | } 22 | 23 | nav .dropdown-menu { 24 | background:#2c2722; 25 | font-size: 14px; 26 | border-radius:0px 0px 2px 2px; 27 | padding:10px 0px; 28 | border:1px solid #2c2722; 29 | margin-top:-1px; 30 | } 31 | 32 | nav .navbar .nav>li>a { 33 | padding: 14px 12px 15px 12px; 34 | color:#ccc; 35 | } 36 | 37 | nav .dropdown-menu li a { 38 | color: #b8b5b5; 39 | padding:3px 15px; 40 | } 41 | nav .divider { 42 | background-color:transparent; 43 | border-right:1px solid #39332d; 44 | margin:5px 20px 5px 10px; 45 | height:39px; 46 | } 47 | 48 | nav .dropdown-menu .divider { 49 | background-color:transparent; 50 | border:0; 51 | border-bottom:1px solid #39332d; 52 | margin:5px 0; 53 | } 54 | 55 | nav .navbar-inverse .nav .active>a, nav .navbar-inverse .nav .active>a:hover, nav .navbar-inverse .nav .active>a:focus, nav .navbar-inverse .nav li.dropdown.open>.dropdown-toggle, nav .navbar-inverse .nav li.dropdown.active>.dropdown-toggle, nav .navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle { 56 | color: #fff; 57 | background-color:transparent; 58 | background-image:none; 59 | } 60 | 61 | nav .navbar-inverse .nav .active>a:hover { 62 | background:#39332d; 63 | } 64 | 65 | nav .dropdown-menu>.active>a, nav .dropdown-menu>.active>a:hover, nav .dropdown-menu>.active>a:focus { 66 | font-weight:bold; 67 | color: #fff; 68 | background-image:none; 69 | background:#39332d; 70 | } 71 | 72 | nav .dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus, nav .dropdown-submenu:hover>a, nav .dropdown-submenu:focus>a { 73 | background:#39332d; 74 | } 75 | 76 | nav .navbar .nav>li>.dropdown-menu:after { 77 | border-bottom-color:#2c2722; 78 | } 79 | 80 | /** MEDIA Q **/ 81 | 82 | @media (max-width: 979px) 83 | { 84 | nav .navbar-fixed-top .navbar-inner, nav .navbar-fixed-bottom .navbar-inner { 85 | padding: 0px; 86 | } 87 | nav .navbar-fixed-top { 88 | margin-bottom: 0; 89 | } 90 | } 91 | 92 | /** SUB BRAND LOGOS **/ 93 | 94 | .navbar .brand.haxe-logo { padding-right:0; margin: 3px 0 0 0px; } 95 | .navbar .brand.haxe-logo:hover { opacity:.9; } 96 | 97 | .navbar .brand.haxe-logo:after { 98 | content:" "; 99 | position:absolute; 100 | /* create arrow */ 101 | width: 0; 102 | height: 0; 103 | border-top: 22px solid transparent; 104 | border-bottom: 22px solid transparent; 105 | border-left: 7px solid #13110f; /* same color as nav bar */ 106 | top:0; 107 | } 108 | .navbar .brand.sub { 109 | background: #39332d; /* Old browsers */ 110 | background: -moz-linear-gradient(top, #39332d 50%, #2c2722 51%); /* FF3.6+ */ 111 | background: -webkit-gradient(linear, left top, left bottom, color-stop(50%,#39332d), color-stop(51%,#2c2722)); /* Chrome,Safari4+ */ 112 | background: -webkit-linear-gradient(top, #39332d 50%,#2c2722 51%); /* Chrome10+,Safari5.1+ */ 113 | background: -o-linear-gradient(top, #39332d 50%,#2c2722 51%); /* Opera 11.10+ */ 114 | background: -ms-linear-gradient(top, #39332d 50%,#2c2722 51%); /* IE10+ */ 115 | background: linear-gradient(to bottom, #39332d 50%,#2c2722 51%); /* W3C */ 116 | padding:14px 20px 13px 20px; 117 | margin:0 10px 0 0; 118 | font:bold 18px "arial black", "open sans"; 119 | line-height:22px; 120 | color:rgb(255,255,255); 121 | } 122 | .navbar .brand.sub:hover { 123 | color:rgb(230,230,230); 124 | background: #2c2722; /* Old browsers */ 125 | } 126 | 127 | .navbar .brand.sub:before { 128 | content:".."; /* two dots */ 129 | position:absolute; 130 | margin-left:-33px; 131 | margin-top:-28px; 132 | line-height:0px; 133 | font:bold 40px "Open Sans", sans-serif; 134 | letter-spacing:0px; 135 | color:#fff200; 136 | } 137 | 138 | /** SUB BRAND COLORS **/ 139 | 140 | .navbar .brand.sub.try:before { 141 | color:#f89c0e; 142 | } 143 | 144 | .navbar .brand.sub.api:before { 145 | color:#eedc16; 146 | } 147 | 148 | .navbar .brand.sub.lib:before { 149 | color:#f1471d; 150 | } 151 | .navbar .brand.sub.ide:before { 152 | color:#f89c0e; 153 | } 154 | -------------------------------------------------------------------------------- /docs/Iterator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Iterator - GLM

An Iterator is a structure that permits iteration over elements of type T.

10 |

Any class with matching hasNext() and next() fields is considered an Iterator 11 | and can then be used e.g. in for-loops. This makes it easy to implement 12 | custom iterators.

See:

Properties

hasNext ():Bool

Returns false if the iteration is complete, true otherwise.

13 |

Usually iteration is considered to be complete if all elements of the 14 | underlying data structure were handled through calls to next(). However, 15 | in custom iterators any logic may be used to determine the completion 16 | state.

next ():T

Returns the current item of the Iterator and advances to the next one.

17 |

This method is not required to check hasNext() first. A call to this 18 | method while hasNext() is false yields unspecified behavior.

19 |

On the other hand, iterators should not require a call to hasNext() 20 | before the first call to next() if an element is available.

-------------------------------------------------------------------------------- /test/glm/TestGLM.hx: -------------------------------------------------------------------------------- 1 | package glm; 2 | 3 | import glm.GLM; 4 | import buddy.*; 5 | using buddy.Should; 6 | 7 | import glm.Vec3; 8 | import glm.Quat; 9 | import glm.Mat4; 10 | 11 | class TestGLM extends BuddySuite { 12 | public function new() { 13 | describe('Using GLM', { 14 | it("should provide a linear interpolation function", { 15 | GLM.lerp(0, 4, 0.75).should.beCloseTo(3); 16 | }); 17 | 18 | it("should create translation matrices", { 19 | var t:Mat4 = GLM.translate(new Vec3(2, 4, 5), new Mat4()); 20 | t.r0c3.should.be(2); 21 | t.r1c3.should.be(4); 22 | t.r2c3.should.be(5); 23 | }); 24 | 25 | it("should create rotation matrices from quaternions", { 26 | var r:Quat = Quat.axisAngle(new Vec3(0, 1, 0), -Math.PI / 2, new Quat()); 27 | var r_m:Mat4 = GLM.rotate(r, new Mat4()); 28 | 29 | var x:Vec4 = new Vec4(1, 0, 0, 1); 30 | var z:Vec4 = Mat4.multVec(r_m, x, new Vec4()); 31 | z.x.should.beCloseTo(0); 32 | z.y.should.beCloseTo(0); 33 | z.z.should.beCloseTo(1); 34 | z.w.should.beCloseTo(1); 35 | }); 36 | 37 | it("should create scale matrices", { 38 | var s:Mat4 = GLM.scale(new Vec3(-1, 2, 3), new Mat4()); 39 | s.r0c0.should.be(-1); 40 | s.r1c1.should.be(2); 41 | s.r2c2.should.be(3); 42 | }); 43 | 44 | it("should construct complete transformation matrices", { 45 | var t:Vec3 = new Vec3(-1, 2, 3); 46 | var r:Quat = Quat.axisAngle(new Vec3(1, 0, 0), Math.PI / 2, new Quat()); 47 | var s:Vec3 = new Vec3(2, 3, 4); 48 | 49 | var transform:Mat4 = GLM.transform(t, r, s, new Mat4()); 50 | 51 | var m_t:Mat4 = GLM.translate(t, new Mat4()); 52 | var m_r:Mat4 = GLM.rotate(r, new Mat4()); 53 | var m_s:Mat4 = GLM.scale(s, new Mat4()); 54 | 55 | var result:Mat4 = Mat4.multMat(m_r, m_s, new Mat4()); 56 | result = Mat4.multMat(m_t, result, result); 57 | 58 | transform.r0c0.should.beCloseTo(result.r0c0); 59 | transform.r1c0.should.beCloseTo(result.r1c0); 60 | transform.r1c0.should.beCloseTo(result.r1c0); 61 | transform.r1c0.should.beCloseTo(result.r1c0); 62 | 63 | transform.r0c1.should.beCloseTo(result.r0c1); 64 | transform.r1c1.should.beCloseTo(result.r1c1); 65 | transform.r1c1.should.beCloseTo(result.r1c1); 66 | transform.r1c1.should.beCloseTo(result.r1c1); 67 | 68 | transform.r0c2.should.beCloseTo(result.r0c2); 69 | transform.r1c2.should.beCloseTo(result.r1c2); 70 | transform.r1c2.should.beCloseTo(result.r1c2); 71 | transform.r1c2.should.beCloseTo(result.r1c2); 72 | 73 | transform.r0c3.should.beCloseTo(result.r0c3); 74 | transform.r1c3.should.beCloseTo(result.r1c3); 75 | transform.r1c3.should.beCloseTo(result.r1c3); 76 | transform.r1c3.should.beCloseTo(result.r1c3); 77 | }); 78 | 79 | it("should create perspective matrices", { 80 | var persp:Mat4 = GLM.perspective(45 * Math.PI / 180, 640 / 480, 0.1, 200, new Mat4()); 81 | persp.r0c0.should.beCloseTo(1.81066); 82 | persp.r1c1.should.beCloseTo(2.414213); 83 | persp.r2c2.should.beCloseTo(-1.001); 84 | persp.r2c3.should.beCloseTo(-0.2001); 85 | persp.r3c2.should.beCloseTo(-1); 86 | persp.r3c3.should.beCloseTo(0); 87 | }); 88 | 89 | it("should create orthogonal matrices", { 90 | var r:Float = 3; 91 | var b:Float = 3 * 9 / 16; 92 | var l:Float = -r; 93 | var t:Float = -b; 94 | var n:Float = -1; 95 | var f:Float = 1; 96 | 97 | var persp:Mat4 = GLM.orthographic(l, r, b, t, n, f, new Mat4()); 98 | var target:Mat4 = new Mat4( 99 | 1/r, 0, 0, 0, 100 | 0, 1/t, 0, 0, 101 | 0, 0, -2/(f-n), -1*(f+n)/(f-n), 102 | 0, 0, 0, 1 103 | ); 104 | 105 | persp.r0c0.should.beCloseTo(target.r0c0); 106 | persp.r1c0.should.beCloseTo(target.r1c0); 107 | persp.r2c0.should.beCloseTo(target.r2c0); 108 | persp.r3c0.should.beCloseTo(target.r3c0); 109 | 110 | persp.r0c1.should.beCloseTo(target.r0c1); 111 | persp.r1c1.should.beCloseTo(target.r1c1); 112 | persp.r2c1.should.beCloseTo(target.r2c1); 113 | persp.r3c1.should.beCloseTo(target.r3c1); 114 | 115 | persp.r0c2.should.beCloseTo(target.r0c2); 116 | persp.r1c2.should.beCloseTo(target.r1c2); 117 | persp.r2c2.should.beCloseTo(target.r2c2); 118 | persp.r3c2.should.beCloseTo(target.r3c2); 119 | 120 | persp.r0c3.should.beCloseTo(target.r0c3); 121 | persp.r1c3.should.beCloseTo(target.r1c3); 122 | persp.r2c3.should.beCloseTo(target.r2c3); 123 | persp.r3c3.should.beCloseTo(target.r3c3); 124 | }); 125 | 126 | it("should create frustrum matrices", { 127 | var persp:Mat4 = GLM.frustum(-1, 1, -1, 1, -1, 1, new Mat4()); 128 | persp.equals(new Mat4( 129 | -1, 0, 0, 0, 130 | 0, -1, 0, 0, 131 | 0, 0, 0, 1, 132 | 0, 0, -1, 0 133 | )).should.be(true); 134 | }); 135 | 136 | it("should create lookat matrices"); 137 | }); 138 | } 139 | } -------------------------------------------------------------------------------- /test/glm/TestQuat.hx: -------------------------------------------------------------------------------- 1 | package glm; 2 | 3 | import buddy.*; 4 | using buddy.Should; 5 | 6 | using glm.Quat; 7 | 8 | class TestQuat extends BuddySuite { 9 | public function new() { 10 | describe('Using Quats', { 11 | var qi:Quat, qx90:Quat, qa:Quat, qb:Quat; 12 | 13 | beforeEach({ 14 | qi = new Quat(0, 0, 0, 1); 15 | qx90 = new Quat(0.70710678118, 0, 0, 0.70710678118); 16 | qa = new Quat(1, 2, 3, 4); 17 | qb = new Quat(5, 6, 7, 8); 18 | }); 19 | 20 | it("should provide element access", { 21 | qx90.x.should.beCloseTo(0.70710678118); 22 | qi.y.should.be(0); 23 | qi.z.should.be(0); 24 | qi.w.should.be(1); 25 | }); 26 | 27 | it("should calculate the length of the quat", { 28 | qi.length().should.beCloseTo(1); 29 | qa.lengthSquared().should.beCloseTo(30); 30 | qa.length().should.beCloseTo(5.47722557505); 31 | }); 32 | 33 | it("should normalize", { 34 | qa.normalize(qa); 35 | qa.x.should.beCloseTo(0.18257418583505536); 36 | qa.y.should.beCloseTo(0.3651483716701107); 37 | qa.z.should.beCloseTo(0.5477225575051661); 38 | qa.w.should.beCloseTo(0.7302967433402214); 39 | }); 40 | 41 | it("should calculate dot products", { 42 | qi.dot(qx90).should.beCloseTo(0.70710678118); 43 | }); 44 | 45 | it("should create identity quaternions", { 46 | qx90.identity(); 47 | qx90.x.should.be(0); 48 | qx90.y.should.be(0); 49 | qx90.z.should.be(0); 50 | qx90.w.should.be(1); 51 | }); 52 | 53 | it("should provide a copy interface", { 54 | qa.copy(qi).equals(qa).should.be(true); 55 | }); 56 | 57 | it("should construct a quaternion from an axis and an angle", { 58 | qa = Quat.axisAngle(new Vec3(1, 0, 0), Math.PI / 2, qa); 59 | qa.equals(qx90).should.be(true); 60 | }); 61 | 62 | it("should multiply two quaternions together", { 63 | var qc:Quat = qa.multiplyQuats(qb, new Quat()); 64 | qc.equals(new Quat(24, 48, 48, -6)).should.be(true); 65 | qc = qa * qi; 66 | qc.equals(qa).should.be(true); 67 | }); 68 | 69 | it("should scale", { 70 | var qc:Quat = qa.multiplyScalar(2, new Quat()); 71 | qc.equals(new Quat(2, 4, 6, 8)).should.be(true); 72 | qc = qc * 0.5; 73 | qc.equals(qa).should.be(true); 74 | }); 75 | 76 | it("should lerp between two quaternions", { 77 | var qc:Quat = qa.lerp(qb, 0.5, new Quat()); 78 | qc.equals(new Quat(3, 4, 5, 6)).should.be(true); 79 | }); 80 | 81 | it("should slerp between two quaternions", { 82 | qa = new Quat(0.6753410084407496, 0.4087830051091744, 0.32856700410659473, 0.5185120064806223); 83 | qb = new Quat(0.6602792107657797, 0.43647413932562285, 0.35119011210236006, 0.5001871596632682); 84 | var qr:Quat = new Quat(); 85 | 86 | qa.slerp(qb, 0, qr).equals(qa).should.be(true); 87 | qa.slerp(qb, 1, qr).equals(qb).should.be(true); 88 | 89 | qa.slerp(qb, 0.5, qr); 90 | Math.abs(qr.dot(qa) - qr.dot(qb)).should.beCloseTo(0); 91 | qr.length().should.beCloseTo(1); 92 | 93 | qa.slerp(qb, 0.25, qr); 94 | (qr.dot(qa) > qr.dot(qb)).should.be(true); 95 | qr.length().should.beCloseTo(1); 96 | 97 | qa.slerp(qb, 0.75, qr); 98 | (qr.dot(qa) < qr.dot(qb)).should.be(true); 99 | qr.length().should.beCloseTo(1); 100 | 101 | qa = new Quat(1, 0, 0, 0); 102 | qb = new Quat(0, 0, 1, 0); 103 | qr = qa.slerp(qb, 0.5, qr); 104 | qr.x.should.beCloseTo(Math.sqrt(0.5)); 105 | qr.y.should.beCloseTo(Math.sqrt(0)); 106 | qr.z.should.beCloseTo(Math.sqrt(0.5)); 107 | qr.w.should.beCloseTo(Math.sqrt(0)); 108 | qr.length().should.beCloseTo(1); 109 | 110 | qa = new Quat(0, Math.sqrt(0.5), 0, Math.sqrt(0.5)); 111 | qb = new Quat(0, -Math.sqrt(0.5), 0, Math.sqrt(0.5)); 112 | qr = qa.slerp(qb, 0.5, qr); 113 | qr.equals(qi).should.be(true); 114 | qr.length().should.beCloseTo(1); 115 | }); 116 | 117 | it("should be able to invert", { 118 | var qr:Quat = qa.invert(new Quat()); 119 | qr.x.should.beCloseTo(-0.03333333); 120 | qr.y.should.beCloseTo(-0.06666666); 121 | qr.z.should.beCloseTo(-0.1); 122 | qr.w.should.beCloseTo( 0.13333333); 123 | }); 124 | 125 | it("should calculate the conjugate", { 126 | var qr:Quat = qa.conjugate(new Quat()); 127 | qr.x.should.be(-1); 128 | qr.y.should.be(-2); 129 | qr.z.should.be(-3); 130 | qr.w.should.be(4); 131 | }); 132 | 133 | it("should convert euler angles", { 134 | var qx:Quat = Quat.fromEuler(Math.PI / 2, 0, 0, new Quat()); 135 | var qy:Quat = Quat.fromEuler(0, Math.PI / 2, 0, new Quat()); 136 | var qz:Quat = Quat.fromEuler(0, 0, Math.PI / 2, new Quat()); 137 | 138 | var x:Vec4 = new Vec4(1, 0, 0, 1); 139 | var y:Vec4 = new Vec4(0, 1, 0, 1); 140 | var z:Vec4 = new Vec4(0, 0, 1, 1); 141 | 142 | var m:Mat4 = new Mat4(); 143 | var r:Vec4 = new Vec4(); 144 | 145 | GLM.rotate(qx, m); 146 | Mat4.multVec(m, y, r); 147 | r.x.should.beCloseTo(0); 148 | r.y.should.beCloseTo(0); 149 | r.z.should.beCloseTo(1); 150 | r.w.should.beCloseTo(1); 151 | 152 | GLM.rotate(qy, m); 153 | Mat4.multVec(m, x, r); 154 | r.x.should.beCloseTo(0); 155 | r.y.should.beCloseTo(0); 156 | r.z.should.beCloseTo(-1); 157 | r.w.should.beCloseTo(1); 158 | 159 | GLM.rotate(qz, m); 160 | Mat4.multVec(m, x, r); 161 | r.x.should.beCloseTo(0); 162 | r.y.should.beCloseTo(1); 163 | r.z.should.beCloseTo(0); 164 | r.w.should.beCloseTo(1); 165 | }); 166 | }); 167 | } 168 | } -------------------------------------------------------------------------------- /docs/bootstrap/css/bootstrap-select.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/) 3 | * 4 | * Copyright 2013-2014 bootstrap-select 5 | * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE) 6 | */.bootstrap-select{width:220px \0}.bootstrap-select>.btn{width:100%;padding-right:25px}.error .bootstrap-select .btn{border:1px solid #b94a48}.control-group.error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select.fit-width{width:auto!important}.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn){width:220px}.bootstrap-select .btn:focus{outline:thin dotted #333!important;outline:5px auto -webkit-focus-ring-color!important;outline-offset:-2px}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:none}.bootstrap-select.form-control:not([class*=col-]){width:100%}.bootstrap-select.btn-group:not(.input-group-btn),.bootstrap-select.btn-group[class*=col-]{float:none;display:inline-block;margin-left:0}.bootstrap-select.btn-group.dropdown-menu-right,.bootstrap-select.btn-group[class*=col-].dropdown-menu-right,.row-fluid .bootstrap-select.btn-group[class*=col-].dropdown-menu-right{float:right}.form-search .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group,.form-group .bootstrap-select.btn-group{margin-bottom:0}.form-group-lg .bootstrap-select.btn-group.form-control,.form-group-sm .bootstrap-select.btn-group.form-control{padding:0}.form-inline .bootstrap-select.btn-group .form-control{width:100%}.input-append .bootstrap-select.btn-group{margin-left:-1px}.input-prepend .bootstrap-select.btn-group{margin-right:-1px}.bootstrap-select.btn-group>.disabled{cursor:not-allowed}.bootstrap-select.btn-group>.disabled:focus{outline:0!important}.bootstrap-select.btn-group .btn .filter-option{display:inline-block;overflow:hidden;width:100%;text-align:left}.bootstrap-select.btn-group .btn .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group[class*=col-] .btn{width:100%}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;z-index:1035;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;border:0;padding:0;margin:0;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:hover small,.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:focus small,.bootstrap-select.btn-group .dropdown-menu li.active:not(.disabled) a small{color:#64b1d8;color:rgba(100,177,216,.4)}.bootstrap-select.btn-group .dropdown-menu li.disabled a{cursor:not-allowed}.bootstrap-select.btn-group .dropdown-menu li a{cursor:pointer}.bootstrap-select.btn-group .dropdown-menu li a.opt{position:relative;padding-left:2.25em}.bootstrap-select.btn-group .dropdown-menu li a span.check-mark{display:none}.bootstrap-select.btn-group .dropdown-menu li a span.text{display:inline-block}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .no-results{padding:3px;background:#f5f5f5;margin:0 5px}.bootstrap-select.btn-group.fit-width .btn .filter-option{position:static}.bootstrap-select.btn-group.fit-width .btn .caret{position:static;top:auto;margin-top:-1px}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark{position:absolute;display:inline-block;right:15px;margin-top:5px}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.show-menu-arrow.open>.btn{z-index:1035+1}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';border-left:7px solid transparent;border-right:7px solid transparent;border-bottom-width:7px;border-bottom-style:solid;border-bottom-color:#ccc;border-bottom-color:rgba(204,204,204,.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-bottom:0;border-top-width:7px;border-top-style:solid;border-top-color:#ccc;border-top-color:rgba(204,204,204,.2)}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after{display:block}.bs-searchbox,.bs-actionsbox{padding:4px 8px}.bs-actionsbox{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-actionsbox .btn-group button{width:50%}.bs-searchbox+.bs-actionsbox{padding:0 8px 4px}.bs-searchbox input.form-control{margin-bottom:0;width:100%}.mobile-device{position:absolute;top:0;left:0;display:block!important;width:100%;height:100%!important;opacity:0} -------------------------------------------------------------------------------- /docs/index.js: -------------------------------------------------------------------------------- 1 | function createCookie(name, value, days) { 2 | localStorage.setItem(name, value); 3 | } 4 | 5 | function readCookie(name) { 6 | return localStorage.getItem(name); 7 | } 8 | 9 | function toggleInherited(el) { 10 | var toggle = $(el).closest(".toggle"); 11 | toggle.toggleClass("toggle-on"); 12 | if (toggle.hasClass("toggle-on")) { 13 | $("i", toggle).removeClass("fa-arrow-circle-right").addClass("fa-arrow-circle-down"); 14 | } else { 15 | $("i", toggle).addClass("fa-arrow-circle-right").removeClass("fa-arrow-circle-down"); 16 | } 17 | return false; 18 | } 19 | 20 | function toggleCollapsed(el) { 21 | var toggle = $(el).closest(".expando"); 22 | toggle.toggleClass("expanded"); 23 | 24 | if (toggle.hasClass("expanded")) { 25 | $(toggle).find("i").first().removeClass("fa-arrow-circle-right").addClass("fa-arrow-circle-down"); 26 | } else { 27 | $(toggle).find("i").first().addClass("fa-arrow-circle-right").removeClass("fa-arrow-circle-down"); 28 | } 29 | updateTreeState(); 30 | return false; 31 | } 32 | 33 | function updateTreeState(){ 34 | var states = []; 35 | $("#nav .expando").each(function(i, e){ 36 | states.push($(e).hasClass("expanded") ? 1 : 0); 37 | }); 38 | var treeState = JSON.stringify(states); 39 | createCookie("treeState", treeState); 40 | } 41 | 42 | var filters = {}; 43 | 44 | function selectVersion(e) { 45 | setVersion($(e.target).parent().attr("data")); 46 | } 47 | 48 | function setPlatform(platform) { 49 | createCookie("platform", platform); 50 | $("#select-platform").val(platform); 51 | 52 | var styles = ".platform { display:none }"; 53 | var platforms = dox.platforms; 54 | if (platform == "flash" || platform == "js") { 55 | styles += ".package-sys { display:none; } "; 56 | } 57 | for (var i = 0; i < platforms.length; i++) { 58 | var p = platforms[i]; 59 | if (platform == "sys") { 60 | if (p != "flash" && p != "js") { 61 | styles += ".platform-" + p + " { display:inherit } "; 62 | } 63 | } 64 | else 65 | { 66 | if (platform == "all" || p == platform) { 67 | styles += ".platform-" + p + " { display:inherit } "; 68 | } 69 | } 70 | } 71 | 72 | if (platform != "flash" && platform != "js") { 73 | styles += ".platform-sys { display:inherit } "; 74 | } 75 | 76 | $("#dynamicStylesheet").text(styles); 77 | } 78 | /* 79 | function setVersion(version) { 80 | createCookie("version", version); 81 | } 82 | */ 83 | 84 | $(document).ready(function(){ 85 | $("#nav").html(navContent); 86 | var treeState = readCookie("treeState"); 87 | 88 | $("#nav .expando").each(function(i, e){ 89 | $("i", e).first().addClass("fa-arrow-circle-right").removeClass("fa-arrow-circle-down"); 90 | }); 91 | 92 | $(".treeLink").each(function() { 93 | this.href = this.href.replace("::rootPath::", dox.rootPath); 94 | }); 95 | 96 | if (treeState != null) 97 | { 98 | var states = JSON.parse(treeState); 99 | $("#nav .expando").each(function(i, e){ 100 | if (states[i]) { 101 | $(e).addClass("expanded"); 102 | $("i", e).first().removeClass("fa-arrow-circle-right").addClass("fa-arrow-circle-down"); 103 | } 104 | }); 105 | } 106 | $("head").append(""); 107 | 108 | setPlatform(readCookie("platform") == null ? "all" : readCookie("platform")); 109 | //setVersion(readCookie("version") == null ? "3_0" : readCookie("version")); 110 | 111 | $("#search").focus(); 112 | $("#search").on("input", function(e){ 113 | searchQuery(e.target.value); 114 | }); 115 | $(window).keypress(function(e){ 116 | $("#search").focus(); 117 | }) 118 | 119 | $("#select-platform").selectpicker().on("change", function(e){ 120 | var value = $(":selected", this).val(); 121 | setPlatform(value); 122 | }); 123 | 124 | $("#nav a").each(function () { 125 | if (this.href == location.href) { 126 | $(this.parentElement).addClass("active"); 127 | } 128 | }); 129 | 130 | $("a.expand-button").click(function (e) { 131 | var container = $(this).parent().next(); 132 | container.toggle(); 133 | $("i", this).removeClass("fa-arrow-circle-down") 134 | .removeClass("fa-arrow-circle-right") 135 | .addClass(container.is(":visible") ? "fa-arrow-circle-down" : "fa-arrow-circle-right"); 136 | return false; 137 | }); 138 | 139 | // Because there is no CSS parent selector 140 | $("code.prettyprint").parents("pre").addClass("example"); 141 | }); 142 | 143 | function searchQuery(query) { 144 | $("#searchForm").removeAttr("action"); 145 | query = query.replace(/[&<>"']/g, ""); 146 | if (!query || query.length<2) { 147 | $("#nav").removeClass("searching"); 148 | $("#nav li").each(function(index, element){ 149 | var e = $(element); 150 | e.css("display", ""); 151 | }); 152 | $("#nav ul:first-child").css("display", "block"); 153 | $("#search-results-list").css("display", "none"); 154 | return; 155 | } 156 | var queryParts = query.toLowerCase().split(" "); 157 | var listItems = []; 158 | var bestMatch = 200; 159 | $("#nav").addClass("searching"); 160 | $("#nav ul:first-child").css("display","none"); 161 | $("#nav li").each(function(index, element) { 162 | var e = $(element); 163 | if (!e.hasClass("expando")) { 164 | var content = e.attr("data_path"); 165 | var score = searchMatch(content, queryParts); 166 | if (score >= 0) { 167 | if (score < bestMatch) { 168 | var url = dox.rootPath + e.attr("data_path").split(".").join("/") + ".html"; 169 | $("#searchForm").attr("action", url); 170 | // best match will be form action 171 | bestMatch = score; 172 | } 173 | 174 | var elLink = $("a", element); 175 | // highlight matched parts 176 | var elLinkContent = elLink.text().replace(new RegExp("(" + queryParts.join("|").split(".").join("|") + ")", "ig"), "$1"); 177 | var liStyle = (score == 0) ? ("font-weight:bold") : ""; 178 | listItems.push({score: score, item: "
  • " + elLinkContent + "
  • "}); 179 | } 180 | } 181 | }); 182 | if ($("#search-results-list").length == 0) { 183 | // append to nav 184 | $("#nav").parent().append(""); 185 | } 186 | listItems.sort(function(x, y) { return x.score - y.score; }); // put in order 187 | $("#search-results-list").css("display","block").html(listItems.map(function(x) { return x.item; }).join("")); 188 | } 189 | 190 | function match(textParts, query) { 191 | var queryParts = query.split("."); 192 | if (queryParts.length == 1) { 193 | var queryPart = queryParts[0]; 194 | for (var i = 0; i < textParts.length; ++i) { 195 | var textPart = textParts[i]; 196 | if (textPart.indexOf(queryPart) > -1) { 197 | // We don't want to match the same part twice, so let's remove it 198 | textParts[i] = textParts[i].split(queryPart).join(""); 199 | return textPart.length - queryPart.length; 200 | } 201 | } 202 | } else { 203 | var offset = -1; 204 | outer: 205 | while (true) { 206 | ++offset; 207 | if (queryParts.length + offset > textParts.length) { 208 | return -1; 209 | } 210 | var scoreSum = 0; 211 | for (var i = 0; i < queryParts.length; ++i) { 212 | var queryPart = queryParts[i]; 213 | var textPart = textParts[i + offset]; 214 | var index = textPart.indexOf(queryPart); 215 | if (index != 0) { 216 | continue outer; 217 | } 218 | scoreSum += textPart.length - queryPart.length; 219 | } 220 | return scoreSum; 221 | } 222 | } 223 | } 224 | 225 | function searchMatch(text, queryParts) { 226 | text = text.toLowerCase(); 227 | var textParts = text.split("."); 228 | var scoreSum = 0; 229 | for (var i = 0; i < queryParts.length; ++i) { 230 | var score = match(textParts, queryParts[i]); 231 | if (score == -1) { 232 | return -1; 233 | } 234 | scoreSum += score + text.length; 235 | } 236 | return scoreSum; 237 | } 238 | -------------------------------------------------------------------------------- /docs/haxe/EnumValueTools.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | haxe.EnumValueTools - GLM

    This class provides advanced methods on enum values. It is ideally used with 13 | using EnumValueTools and then acts as an 14 | extension to the 15 | EnumValue types.

    16 |

    If the first argument to any of the methods is null, the result is 17 | unspecified.

    Static methods

    staticinline equals<T> (a:T, b:T):Bool

    Recursively compares two enum instances a and b by value.

    18 |

    Unlike a == b, this function performs a deep equality check on the 19 | arguments of the constructors (if there are any).

    20 |

    If a or b are null, the result is unspecified.

    staticinline getIndex (e:EnumValue):Int

    Returns the index of enum instance e.

    21 |

    This corresponds to the original syntactic position of e. The index of 22 | the first declared constructor is 0, the next one is 1 etc.

    23 |

    If e is null, the result is unspecified.

    staticinline getName (e:EnumValue):String

    Returns the constructor name of enum instance e.

    24 |

    The result String does not contain any constructor arguments.

    25 |

    If e is null, the result is unspecified.

    staticinline getParameters (e:EnumValue):Array<Dynamic>

    Returns a list of the constructor arguments of enum instance e.

    26 |

    If e has no arguments, the result is [].

    27 |

    Otherwise the result are the values that were used as arguments to e, 28 | in the order of their declaration.

    29 |

    If e is null, the result is unspecified.

    staticmatch (e:EnumValue, pattern:Dynamic):Bool

    Matches enum instance e against pattern pattern, returning true if 30 | matching succeeded and false otherwise.

    31 |

    Example usage:

    32 |
    if (e.match(pattern)) {
    33 | 	// codeIfTrue
    34 | } else {
    35 | 	// codeIfFalse
    36 | }
    37 |

    This is equivalent to the following code:

    38 |
    switch (e) {
    39 | 	case pattern:
    40 | 		// codeIfTrue
    41 | 	case _:
    42 | 		// codeIfFalse
    43 | }
    44 |

    This method is implemented in the compiler. This definition exists only 45 | for documentation.

    -------------------------------------------------------------------------------- /docs/styles.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top:15px; 3 | } 4 | 5 | .dark { 6 | background: rgb(20,20,25); 7 | color: white; 8 | } 9 | .dark a { 10 | color: white; 11 | } 12 | .dark a:hover { 13 | color: rgb(200,200,200); 14 | } 15 | .dark blockquote { 16 | border-left: 3px solid rgb(126,126,129); 17 | } 18 | .dark blockquote small { 19 | color: white; 20 | font-weight: bold; 21 | } 22 | .dark blockquote small:before { 23 | display: none; 24 | } 25 | 26 | /* #nav { */ 27 | /* float: left; */ 28 | /* width: 250px; */ 29 | /* background: green; */ 30 | /* } */ 31 | /*#content .header { position:absolute; background:rgba(255,255,255,0.9); left:250px; right:15px; padding:0px 12px; border-bottom:1px solid #EEE;}*/ 32 | /*#content .body { padding-top:80px;}*/ 33 | .nav-list {padding-right: 0; } 34 | .nav-list>li>a, .nav-list .nav-header {margin-right:0;} 35 | .nav-list>li>a.treeLink {padding-left:20px;} 36 | .nav-list a { word-wrap: break-word; font-size:14px; text-shadow: none!important;} 37 | .nav-list>.active>a.treeLink, .nav-list>.active>a.treeLink:hover, .nav-list>.active>a.treeLink:focus { 38 | background:#999; 39 | color:#fff; 40 | } 41 | 42 | .nav-list li i.fa { 43 | height: 16px; 44 | width: 16px; 45 | color: rgb(200,200,200); 46 | font-weight:normal; 47 | font-size:16px; 48 | } 49 | 50 | .viewsource {float:right} 51 | 52 | /** Footer sitemap **/ 53 | footer{ 54 | margin-top:40px; 55 | font-size:14px; 56 | } 57 | .copyright { 58 | padding: 6px; 59 | overflow: hidden; 60 | text-align:center; 61 | margin: 40px 0; 62 | } 63 | .dark .copyright a { color:#F48821; } 64 | 65 | /* .doc { margin-top:16px; } */ 66 | .toggle-hide { display:block; } 67 | .toggle-show { display:none; } 68 | .toggle-on .toggle-hide { display:none !important; } 69 | .toggle-on .toggle-show { display:block !important; } 70 | .related-types .toggle-hide { padding-top:4px; } 71 | /* .availability { margin-left:14px; color:#93a1a1; } */ 72 | /* .doc { margin-left:14px; } */ 73 | 74 | 75 | 76 | /* #nav li { list-style-type: none; } */ 77 | #nav .expando > ul { display:none; } 78 | #nav .expando.expanded > ul { display:inherit; } 79 | /* #nav ul, #nav li li { margin-left: 10px; } */ 80 | #nav img { padding-right:4px; } 81 | #nav .pack { display:none; } 82 | 83 | /* .nav .nav li { margin-left: 14px; } */ 84 | 85 | .dropdown { padding: 0 9px; } 86 | 87 | #nav.searching .expando > ul { display:inherit; } 88 | #nav.searching .expando > a { display:none; } 89 | #nav.searching ul { margin-left:0px; } 90 | #nav.searching .pack { display:inline; } 91 | #nav.searching .nav-list .nav-list { padding-left: 0; padding-right: 0; } 92 | 93 | .nav-header { 94 | text-transform: none; 95 | font-size:14px; 96 | color:#555; 97 | text-shadow: none; 98 | } 99 | 100 | .availability { 101 | color: #AB611A; 102 | font-size: 90%; 103 | } 104 | 105 | h3 code { 106 | background:none; 107 | box-shadow: 0 0 15px rgb(240, 240, 240); 108 | padding: 4px 8px; 109 | white-space: inherit; 110 | display: inline-block; 111 | line-height: 1.5em; 112 | margin-left: -10px; 113 | } 114 | 115 | h3 span.label { 116 | margin-right: 5px; 117 | } 118 | 119 | code { 120 | font-family: Monaco,Menlo,Consolas,"Courier New",monospace; 121 | font-weight: normal; 122 | color: #666; 123 | background-color: #f7f7f9; 124 | border: 1px solid #e1e1e8; 125 | white-space: nowrap; 126 | border-radius: 3px; 127 | padding: 2px 4px; 128 | font-size: 13px; 129 | } 130 | 131 | code .identifier { 132 | font-family:bold 14px "Helvetica Neue",Helvetica,Arial,sans-serif; 133 | color:#002b36; 134 | padding: 0 0 0 5px; 135 | } 136 | 137 | code .identifier, code.type { 138 | font-weight: bold; 139 | } 140 | 141 | /* code { background:#FDF6E3; color:#002b36; tab-size:4; } [> light <] */ 142 | code a { text-decoration:none; } 143 | code a:hover { text-decoration:underline; } 144 | 145 | /*code.dark { background:#272822; color:#F8F8F2; border:none; } */ 146 | code .type { color:#268bd2; } 147 | /* code .keyword { color:#dc322f; } */ 148 | /* code .directive { color:#2aa198; } */ 149 | /* code .constant { color:#AE81FF; } */ 150 | /* code .comment { color:#75715E; } */ 151 | /* code .string { color:#E6DB74; } */ 152 | /* code .macro { color:#A6E22A; } */ 153 | /* code .inactive { color:#75715E; } */ 154 | 155 | /* .navbar-fixed-top { position: fixed; } */ 156 | /* .navbar-fixed-top .navbar-inner, */ 157 | /* .navbar-fixed-bottom .navbar-inner { padding: 0; } */ 158 | 159 | body { 160 | padding: 0px; 161 | font-size:16px; 162 | font-family:"Open Sans", sans-serif; 163 | color: #1e1e1e; 164 | line-height: 1.5; 165 | } 166 | 167 | h1, h2, h3, h4, h5, h6 { 168 | font-family: "Source Sans Pro", sans-serif; 169 | font-weight: 600; 170 | word-wrap: break-word; 171 | } 172 | h1 { 173 | font-size: 36px; 174 | color: #171717; 175 | } 176 | h1 small { 177 | font-size: 14px; 178 | color: #999; 179 | font-weight: normal; 180 | } 181 | h2 { 182 | font-size: 30px; 183 | } 184 | h3 { 185 | font-size: 24px; 186 | } 187 | h4 { 188 | font-size: 20px; 189 | } 190 | h5, h5 code { 191 | font-size: 18px; 192 | } 193 | h6 { 194 | font-size: 16px; 195 | } 196 | 197 | .sidebar-nav { 198 | padding: 9px 0; 199 | } 200 | 201 | #searchForm { 202 | padding: 0 9px; 203 | margin-bottom:10px; 204 | } 205 | 206 | #searchForm .control-group { 207 | margin: 0; 208 | } 209 | 210 | .indent { 211 | margin-left: 20px; 212 | border-left: 5px solid #eeeeee; 213 | padding-left:20px; 214 | } 215 | 216 | table.params { 217 | border-left: 5px solid #eeeeee; 218 | margin-left: 20px; 219 | } 220 | table.params th { 221 | background:#fcfcfc; 222 | } 223 | 224 | .doc-main { 225 | margin-bottom: 40px; 226 | } 227 | 228 | .doc-main p { font-style: italic; } 229 | 230 | .section { 231 | border-bottom: 1px solid #eee; 232 | } 233 | 234 | .table p { 235 | margin: 3px 0; 236 | } 237 | 238 | .table th, .table td { 239 | border-top: 0; 240 | border-bottom: 1px solid #ccc; 241 | } 242 | 243 | .table a small { 244 | color: #666; 245 | } 246 | 247 | .table .fa { 248 | color: rgb(200,200,200); 249 | margin-right:5px; 250 | } 251 | 252 | .javadoc { 253 | /* font-weight: normal; */ 254 | /* font-size: small; */ 255 | margin-top: 20px; 256 | font-style: italic; 257 | } 258 | .inline-content * { 259 | display: inline; 260 | } 261 | /** 262 | * Stuff for input-block-level: 263 | * http://stackoverflow.com/questions/13306670/bootstrap-prepended-and-appended-input-how-to-max-input-field-width 264 | */ 265 | .input-append.input-block-level, 266 | .input-prepend.input-block-level { 267 | display: table; 268 | } 269 | .input-append.input-block-level .add-on, 270 | .input-prepend.input-block-level .add-on { 271 | display: table-cell; 272 | } 273 | .input-append.input-block-level > input, 274 | .input-prepend.input-block-level > input { 275 | box-sizing: border-box; /* use bootstrap mixin or include vendor variants */ 276 | -moz-box-sizing: border-box; /* for Firefox */ 277 | -webkit-box-sizing: border-box; /* for Firefox */ 278 | -ms-box-sizing: border-box; /* for Firefox */ 279 | -o-box-sizing: border-box; /* for Firefox */ 280 | display: table; /* table-cell is not working well in Chrome for small widths */ 281 | min-height: inherit; 282 | width: 100%; 283 | } 284 | .input-append.input-block-level > input { 285 | border-right: 0; 286 | } 287 | .input-prepend.input-block-level > input { 288 | border-left: 0; 289 | } 290 | 291 | .field { 292 | padding-bottom: 10px; 293 | } 294 | .field + .field { 295 | border-top: 1px solid #eee; 296 | margin-top: 10px; 297 | } 298 | .fields { 299 | margin-left: 40px; 300 | } 301 | .field-source { 302 | margin-top: 15px; 303 | visibility: hidden; 304 | } 305 | .field:hover .field-source { 306 | visibility: inherit; 307 | } 308 | 309 | pre.example { 310 | position: relative; 311 | padding-top: 34.5px; 312 | } 313 | pre.example:before { 314 | position: absolute; 315 | top: -1px; 316 | left: -1px; 317 | 318 | content: "Example"; 319 | color: #999; 320 | padding: 2px 6px; 321 | background: #fff; 322 | font-weight: bold; 323 | font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 324 | 325 | -moz-border-radius: 4px 0; 326 | -ms-border-radius: 4px 0; 327 | -webkit-border-radius: 4px 0; 328 | border-radius: 4px 0; 329 | border: 1px solid rgba(0,0,0,0.15); 330 | } 331 | 332 | .inherited-fields { 333 | padding: 5px 20px; 334 | margin-top:1em; 335 | background:#fcfcfc; 336 | } 337 | 338 | @media (max-width: 767px) { 339 | .navbar-fixed-top, .navbar-fixed-bottom, .navbar-static-top { 340 | margin-right: 0; 341 | margin-left: 0; 342 | } 343 | .navbar .divider { 344 | display: none; 345 | } 346 | 347 | .main-content { 348 | margin-top:0px; 349 | } 350 | } 351 | @media (max-width: 979px) { 352 | .main-content { 353 | margin-top:15px; 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /docs/haxe/EnumTools.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | haxe.EnumTools - GLM

    This class provides advanced methods on enums. It is ideally used with 13 | using EnumTools and then acts as an 14 | extension to the 15 | enum types.

    16 |

    If the first argument to any of the methods is null, the result is 17 | unspecified.

    Static methods

    staticinline createAll<T> (e:Enum<T>):Array<T>

    Returns a list of all constructors of enum e that require no 18 | arguments.

    19 |

    This may return the empty Array [] if all constructors of e require 20 | arguments.

    21 |

    Otherwise an instance of e constructed through each of its non- 22 | argument constructors is returned, in the order of the constructor 23 | declaration.

    24 |

    If e is null, the result is unspecified.

    staticinline createByIndex<T> (e:Enum<T>, index:Int, ?params:Array<Dynamic>):T

    Creates an instance of enum e by calling its constructor number 25 | index with arguments params.

    26 |

    The constructor indices are preserved from Haxe syntax, so the first 27 | declared is index 0, the next index 1 etc.

    28 |

    If e or index is null, or if enum e has no constructor 29 | corresponding to index index, or if the number of elements in params 30 | does not match the expected number of constructor arguments, or if any 31 | argument has an invalid type, the result is unspecified.

    staticinline createByName<T> (e:Enum<T>, constr:String, ?params:Array<Dynamic>):T

    Creates an instance of enum e by calling its constructor constr with 32 | arguments params.

    33 |

    If e or constr is null, or if enum e has no constructor named 34 | constr, or if the number of elements in params does not match the 35 | expected number of constructor arguments, or if any argument has an 36 | invalid type, the result is unspecified.

    staticinline getConstructors<T> (e:Enum<T>):Array<String>

    Returns a list of the names of all constructors of enum e.

    37 |

    The order of the constructor names in the returned Array is preserved 38 | from the original syntax.

    39 |

    If c is null, the result is unspecified.

    staticinline getName<T> (e:Enum<T>):String

    Returns the name of enum e, including its path.

    40 |

    If e is inside a package, the package structure is returned dot- 41 | separated, with another dot separating the enum name:

    42 |
    pack1.pack2.(...).packN.EnumName
    43 | 
    44 |

    If e is a sub-type of a Haxe module, that module is not part of the 45 | package structure.

    46 |

    If e has no package, the enum name is returned.

    47 |

    If e is null, the result is unspecified.

    48 |

    The enum name does not include any type parameters.

    -------------------------------------------------------------------------------- /docs/Std.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Std - GLM

    The Std class provides standard methods for manipulating basic types.

    Static methods

    staticinstance<T, S> (value:T, c:Class<S>):S

    Checks if object value is an instance of class c.

    10 |

    Compiles only if the class specified by c can be assigned to the type 11 | of value.

    12 |

    This method checks if a downcast is possible. That is, if the runtime 13 | type of value is assignable to the class specified by c, value is 14 | returned. Otherwise null is returned.

    15 |

    This method is not guaranteed to work with interfaces or core types such 16 | as String, Array and Date.

    17 |

    If value is null, the result is null. If c is null, the result is 18 | unspecified.

    staticint (x:Float):Int

    Converts a Float to an Int, rounded towards 0.

    19 |

    If x is outside of the signed Int32 range, or is NaN, NEGATIVE_INFINITY or POSITIVE_INFINITY, the result is unspecified.

    staticis (v:Dynamic, t:Dynamic):Bool

    Tells if a value v is of the type t. Returns false if v or t are null.

    staticparseFloat (x:String):Float

    Converts a String to a Float.

    20 |

    The parsing rules for parseInt apply here as well, with the exception of invalid input 21 | resulting in a NaN value instead of null.

    22 |

    Additionally, decimal notation may contain a single . to denote the start of the fractions.

    staticparseInt (x:String):Null<Int>

    Converts a String to an Int.

    23 |

    Leading whitespaces are ignored.

    24 |

    If x starts with 0x or 0X, hexadecimal notation is recognized where the following digits may 25 | contain 0-9 and A-F.

    26 |

    Otherwise x is read as decimal number with 0-9 being allowed characters. x may also start with 27 | a - to denote a negative value.

    28 |

    In decimal mode, parsing continues until an invalid character is detected, in which case the 29 | result up to that point is returned. For hexadecimal notation, the effect of invalid characters 30 | is unspecified.

    31 |

    Leading 0s that are not part of the 0x/0X hexadecimal notation are ignored, which means octal 32 | notation is not supported.

    33 |

    If the input cannot be recognized, the result is null.

    staticrandom (x:Int):Int

    Return a random integer between 0 included and x excluded.

    34 |

    If x <= 1, the result is always 0.

    staticstring (s:Dynamic):String

    Converts any value to a String.

    35 |

    If s is of String, Int, Float or Bool, its value is returned.

    36 |

    If s is an instance of a class and that class or one of its parent classes has 37 | a toString method, that method is called. If no such method is present, the result 38 | is unspecified.

    39 |

    If s is an enum constructor without argument, the constructor's name is returned. If 40 | arguments exists, the constructor's name followed by the String representations of 41 | the arguments is returned.

    42 |

    If s is a structure, the field names along with their values are returned. The field order 43 | and the operator separating field names and values are unspecified.

    44 |

    If s is null, "null" is returned.

    -------------------------------------------------------------------------------- /src/glm/Mat2.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Kenton Hamaluik 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | package glm; 15 | 16 | #if kha 17 | import kha.math.FastMatrix2; 18 | #else 19 | @:dox(hide) 20 | @:allow(glm.Mat2) 21 | class Mat2Base { 22 | function new() {} 23 | 24 | var _00: Float; var _10: Float; 25 | var _01: Float; var _11: Float; 26 | } 27 | #end 28 | 29 | /** 30 | A 4x4 matrix 31 | */ 32 | #if kha 33 | abstract Mat2(FastMatrix2) from FastMatrix2 to FastMatrix2 { 34 | #else 35 | abstract Mat2(Mat2Base) { 36 | #end 37 | public inline function new( 38 | _r0c0:Float = 0, _r0c1:Float = 0, 39 | _r1c0:Float = 0, _r1c1:Float = 0 40 | ) { 41 | #if kha 42 | this = new FastMatrix2( 43 | _r0c0, _r0c1, 44 | _r1c0, _r1c1 45 | ); 46 | #else 47 | this = new Mat2Base(); 48 | r0c0 = _r0c0; 49 | r1c0 = _r1c0; 50 | 51 | r0c1 = _r0c1; 52 | r1c1 = _r1c1; 53 | #end 54 | } 55 | 56 | /** 57 | Accessor for the element in row 0 and column 0 58 | */ 59 | public var r0c0(get, set):Float; 60 | private inline function get_r0c0():Float return this._00; 61 | private inline function set_r0c0(v:Float):Float return this._00 = v; 62 | 63 | /** 64 | Accessor for the element in row 1 and column 0 65 | */ 66 | public var r1c0(get, set):Float; 67 | private inline function get_r1c0():Float return this._01; 68 | private inline function set_r1c0(v:Float):Float return this._01 = v; 69 | 70 | /** 71 | Accessor for the element in row 0 and column 1 72 | */ 73 | public var r0c1(get, set):Float; 74 | private inline function get_r0c1():Float return this._10; 75 | private inline function set_r0c1(v:Float):Float return this._10 = v; 76 | 77 | /** 78 | Accessor for the element in row 1 and column 1 79 | */ 80 | public var r1c1(get, set):Float; 81 | private inline function get_r1c1():Float return this._11; 82 | private inline function set_r1c1(v:Float):Float return this._11 = v; 83 | 84 | /** 85 | Read an element using a column-major index 86 | @param key the index to use 87 | @return Float 88 | */ 89 | @:arrayAccess 90 | public inline function get(key:Int):Float { 91 | return switch(key) { 92 | case 0: r0c0; 93 | case 1: r1c0; 94 | case 2: r0c1; 95 | case 3: r1c1; 96 | case _: throw 'Index ${key} out of bounds (0-3)!'; 97 | }; 98 | } 99 | 100 | /** 101 | Write to an element using a column-major index 102 | @param key the index to use 103 | @param value the value to set 104 | @return Float 105 | */ 106 | @:arrayAccess 107 | public inline function set(key:Int, value:Float):Float { 108 | return switch(key) { 109 | case 0: r0c0 = value; 110 | case 1: r1c0 = value; 111 | case 2: r0c1 = value; 112 | case 3: r1c1 = value; 113 | case _: throw 'Index ${key} out of bounds (0-3)!'; 114 | }; 115 | } 116 | 117 | /** 118 | Tests if two matrices are equal on an element-by-element basis 119 | @param m the other matrix to check 120 | @return Bool 121 | */ 122 | public inline function equals(b:Mat2):Bool { 123 | return !( 124 | Math.abs(r0c0 - b.r0c0) >= glm.GLM.EPSILON 125 | || Math.abs(r0c1 - b.r0c1) >= glm.GLM.EPSILON 126 | || Math.abs(r1c0 - b.r1c0) >= glm.GLM.EPSILON 127 | || Math.abs(r1c1 - b.r1c1) >= glm.GLM.EPSILON 128 | ); 129 | } 130 | 131 | /** 132 | Gets a string representation of the matrix 133 | @return String 134 | */ 135 | public inline function toString():String { 136 | return 137 | '[${r0c0}, ${r0c1}]\n' + 138 | '[${r1c0}, ${r1c1}]\n'; 139 | } 140 | 141 | /** 142 | Fill `dest` with an identity matrix 143 | @param dest the matrix to fill out 144 | @return Mat2 145 | */ 146 | public inline static function identity(dest:Mat2):Mat2 { 147 | dest.r0c0 = 1; 148 | dest.r0c1 = 0; 149 | 150 | dest.r1c0 = 0; 151 | dest.r1c1 = 1; 152 | 153 | return dest; 154 | } 155 | 156 | /** 157 | Copies one matrix into another 158 | @param src The matrix to copy from 159 | @param dest The matrix to copy into 160 | @return Mat2 161 | */ 162 | public inline static function copy(src:Mat2, dest:Mat2):Mat2 { 163 | dest.r0c0 = src.r0c0; 164 | dest.r0c1 = src.r0c1; 165 | 166 | dest.r1c0 = src.r1c0; 167 | dest.r1c1 = src.r1c1; 168 | 169 | return dest; 170 | } 171 | 172 | /** 173 | Transposes a matrix 174 | @param src The matrix to transpose 175 | @param dest The destination matrix. Call with `src == dest` to modify `src` in place 176 | @return Mat2 177 | */ 178 | public inline static function transpose(src:Mat2, dest:Mat2):Mat2 { 179 | var src_r1c0 = src.r1c0; 180 | 181 | dest.r0c0 = src.r0c0; 182 | dest.r1c0 = src.r0c1; 183 | 184 | dest.r0c1 = src_r1c0; 185 | dest.r1c1 = src.r1c1; 186 | 187 | return dest; 188 | } 189 | 190 | /** 191 | Calculates the determinant of the matrix 192 | @param src The matrix to calculate the determinant of 193 | @return Float 194 | */ 195 | public inline static function determinant(src:Mat2):Float { 196 | return src.r0c0 * src.r1c1 - src.r0c1 * src.r1c0; 197 | } 198 | 199 | /** 200 | Inverts the `src` matrix, storing the result in `dest`. If `src == dest`, modifies `src` in place. 201 | @param src The source matrix 202 | @param dest The matrix to store the result in 203 | @return Mat2 204 | */ 205 | public inline static function invert(src:Mat2, dest:Mat2):Mat2 { 206 | var det:Float = Mat2.determinant(src); 207 | if (Math.abs(det) < glm.GLM.EPSILON) { 208 | throw "determinant is too small"; 209 | } 210 | 211 | var invdet:Float = 1.0 / det; 212 | 213 | var _s:Mat2 = src; 214 | if(src == dest) _s = Mat2.copy(src, new Mat2()); 215 | 216 | dest.r0c0 = _s.r1c1 * invdet; 217 | dest.r0c1 = -_s.r0c1 * invdet; 218 | dest.r1c0 = -_s.r1c0 * invdet; 219 | dest.r1c1 = _s.r0c0 * invdet; 220 | return dest; 221 | } 222 | 223 | /** 224 | Multiplies two matrices together, storing the result in `dest`. Caches `a` and `b` so `a == dest` and `b == dest` are valid. 225 | @param a The left-hand matrix 226 | @param b The right-hand matrix 227 | @param dest The matrix to store the result in 228 | @return Mat2 229 | */ 230 | public inline static function multMat(a:Mat2, b:Mat2, dest:Mat2):Mat2 { 231 | // cache what we need to do the calculations 232 | var _a:Mat2; 233 | var _b:Mat2; 234 | if(dest == a) { 235 | _a = Mat2.copy(a, new Mat2()); 236 | _b = b; 237 | } 238 | else if(dest == b) { 239 | _a = a; 240 | _b = Mat2.copy(b, new Mat2()); 241 | } 242 | else { 243 | _a = a; 244 | _b = b; 245 | } 246 | 247 | dest.r0c0 = _a.r0c0*_b.r0c0 + _a.r0c1*_b.r1c0; 248 | dest.r0c1 = _a.r0c0*_b.r0c1 + _a.r0c1*_b.r1c1; 249 | 250 | dest.r1c0 = _a.r1c0*_b.r0c0 + _a.r1c1*_b.r1c0; 251 | dest.r1c1 = _a.r1c0*_b.r0c1 + _a.r1c1*_b.r1c1; 252 | 253 | return dest; 254 | } 255 | 256 | /** 257 | Shortcut operator for `multMat(a, b, new Mat2())` 258 | @param a 259 | @param b 260 | @return Mat2 261 | */ 262 | @:op(A * B) 263 | inline static function multMatOp(a:Mat2, b:Mat2):Mat2 { 264 | return multMat(a, b, new Mat2()); 265 | } 266 | 267 | /** 268 | Multiplies a vector `v` by a matrix `m`, storing the result in `dest`. Caches so `v == dest` is valid. 269 | @param m The transforming matrix 270 | @param v The vector to multiply with 271 | @param dest The resulting vector 272 | @return Vec4 273 | */ 274 | public inline static function multVec(m:Mat2, v:Vec2, dest:Vec2):Vec2 { 275 | var x:Float = v.x, y:Float = v.y; 276 | dest.x = m.r0c0*x + m.r0c1*y; 277 | dest.y = m.r1c0*x + m.r1c1*y; 278 | return dest; 279 | } 280 | 281 | /** 282 | Shortcut for `multVec(m, v, new Vec4())` 283 | @param m 284 | @param v 285 | @return Vec4 286 | */ 287 | @:op(A * B) 288 | inline static function multVecOp(m:Mat2, v:Vec2):Vec2 { 289 | return multVec(m, v, new Vec2()); 290 | } 291 | 292 | /** 293 | Construct a Mat2 from an array of floats in column-major order 294 | @param arr an array with 16 elements 295 | @return Mat2 296 | */ 297 | @:from 298 | public inline static function fromFloatArray(arr:Array):Mat2 { 299 | return new Mat2( 300 | arr[0], arr[2], 301 | arr[1], arr[3] 302 | ); 303 | } 304 | 305 | /** 306 | Cast the matrix in an array of floats, in column-major order 307 | @return Array 308 | */ 309 | @:to 310 | public inline function toFloatArray():Array { 311 | return [ 312 | r0c0, r1c0, 313 | r0c1, r1c1 314 | ]; 315 | } 316 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # haxe-glm 2 | [![GitHub license](https://img.shields.io/badge/license-Apache%202-blue.svg?style=flat-square)](https://raw.githubusercontent.com/FuzzyWuzzie/haxe-glm/master/LICENSE) [![Build Status](https://img.shields.io/travis/FuzzyWuzzie/haxe-glm.svg?style=flat-square)](https://travis-ci.org/FuzzyWuzzie/haxe-glm) 3 | 4 | Native Haxe version of the fantastic GLM library (https://github.com/g-truc/glm). For those unaware of the GLM library, it is basically a toolset for using 2, 3, and 4 dimensional vectors and matrices, as well as quaternions. This tends to be rather useful when working with OpenGL, which is largely all about rasterizing primitives using vectors and matrices. 5 | 6 | ## Contributing 7 | 8 | Issues, forks, and pull requests are gladly welcomed! 9 | 10 | ## Documentation 11 | 12 | ### Manual 13 | 14 | This library provides several classes (actually, abstracts over floating point arrays) which enable vector, matrix, and quaternion mathematical operations (`Vec2`, `Vec3`, `Vec4`, `Mat2`, `Mat3`, `Mat4`, and `Quat`). The library also includes static utilities for generating transformation and projection matrices (`GLM`). 15 | 16 | The library includes [static extensions](manual/static_extensions.md) and gives you the flexibility to instantiate or reuse objects as desired using [destination arguments](manual/destination_arguments.md). 17 | 18 | #### Motivation 19 | 20 | I decided to create this library for Haxe after seeing project after project write their own code for dealing with vectors, matrices, and quaternions. This has resulted in a lot of duplicated effort by developers who all seem to write their own classes to deal with this. 21 | 22 | Hopefully the creation of this [fully cross-target and cross-platform] library, some of this duplicated effort can be minimized in the future. 23 | 24 | ### API 25 | 26 | API documentation is available here: http://fuzzywuzzie.github.io/haxe-glm/ 27 | 28 | ### Samples 29 | 30 | ```haxe 31 | // create a new perspective projection matrix 32 | var P:Mat4 = GLM.perspective( 33 | 45 * Math.PI / 180, // field of view (radians) 34 | 640 / 480, // aspect ratio 35 | 0.1, 100, // near, far 36 | new Mat4() // where to store the result 37 | ); 38 | ``` 39 | 40 | ```haxe 41 | using glm.Quat; 42 | 43 | // transform components 44 | var pos:Vec3 = new Vec3(0, 0, 1.5); 45 | var rot:Quat = new Quat().identity(); 46 | var sca:Vec3 = new Vec3(1, 1, 1); 47 | var modelMatrix:Mat4 = new Mat4(); 48 | 49 | // ... 50 | 51 | // update the model matrix 52 | GLM.transform(pos, rot, sca, modelMatrix); 53 | ``` 54 | 55 | ### Underlying Types 56 | 57 | This library is written using [abstract types](https://haxe.org/manual/types-abstract.html) over simple base object. When used on its own, the library uses basic classes containing each type's data. For example, Vec4s are implemented as: 58 | 59 | ```haxe 60 | class Vec4Base { 61 | function new(){} 62 | var x:Float; 63 | var y:Float; 64 | var z:Float; 65 | var w:Float; 66 | } 67 | 68 | abstract Vec4(Vec4Base) { 69 | // ... 70 | } 71 | ``` 72 | 73 | Since there are a plethora of libraries out there that each have their own internal format, when the library detects a supported library, it changes to become an abstract over that library's type. For example, if [Kha](https://github.com/Kode/Kha) is detected, `Vec4` becomes an abstract over Kha's `FastVector4` type with implicit casts to and from `FastVector4`s. This enables you to use the functionality in this library without taking performance hits converting to and from the types your library expects. 74 | 75 | Implemented underlying types: 76 | 77 | - [x] Standalone 78 | - [x] Kha ('Fast' versions—(32-bit floats on cpp, 64-bit doubles everywhere else)) 79 | - [ ] Heaps 80 | - [ ] lime 81 | - [ ] OpenFL 82 | - [ ] HaxeFlixel 83 | - [ ] luxe 84 | 85 | ### Calculations / Features 86 | 87 | * :heavy_check_mark:—The calculation is currently available 88 | * :x:—The calculation is planned but not yet available 89 | 90 | #### GLM 91 | 92 | | Calculation | GLM | API | 93 | |:------------|:---:|:----| 94 | | Lerp scalars | :heavy_check_mark: | `GLM.lerp(a:Float, b:Float, t:Float):Float` | 95 | | Translation matrix | :heavy_check_mark: | `GLM.translate(translation:Vec3, dest:Mat4):Mat4` | 96 | | Rotation matrix | :heavy_check_mark: | `GLM.rotate(rotation:Quat, dest:Mat4):Mat4` | 97 | | Scale matrix | :heavy_check_mark: | `GLM.scale(scale:Quat, dest:Mat4):Mat4` | 98 | | Transformation / model matrix | :heavy_check_mark: | `GLM.transform(translation:Vec3, rotation:Quat, scale:Vec3, dest:Mat4):Mat4` | 99 | | Look-at matrix | :heavy_check_mark: | `GLM.lookAt(eye:Vec3, centre:Vec3, up:Vec3, dest:Mat4):Mat4` | 100 | | Perspective projection matrix | :heavy_check_mark: | `GLM.perspective(fovy:Float, aspectRatio:Float, near:Float, far:Float, dest:Mat4):Mat4` | 101 | | Orthographic projection matrix | :heavy_check_mark: | `GLM.orthographic(left:Float, right:Float, bottom:Float, top:Float, near:Float=-1, far:Float=1, dest:Mat4):Mat4` | 102 | | Frustum projection matrix | :heavy_check_mark: | `GLM.frustum(left:Float, right:Float, bottom:Float, top:Float, near:Float=-1, far:Float=1, dest:Mat4):Mat4` | 103 | 104 | #### Vectors 105 | 106 | | Calculation | Vec2 | Vec3 | Vec4 | API | 107 | |:------------|:----:|:----:|:----:|:----| 108 | | Add vectors | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `VecX.addVec(a, b, dest)` | 109 | | Add scalars | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `VecX.addScalar(a, s, dest)` | 110 | | Array access | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `vec[index]` | 111 | | Copy | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `VecX.copy(src, dest)` | 112 | | Cross product | :heavy_check_mark: | :heavy_check_mark: | | `VecX.cross(a, b, dest)` | 113 | | Distance | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `VecX.distance (a, b)` | 114 | | Distance squared | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `VecX.distanceSquared (a, b)` | 115 | | VecX × scalar op | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `v * c` | 116 | | VecX ÷ scalar op | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `v / c` | 117 | | VecX + scalar op | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `v + c` | 118 | | VecX - scalar op | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `v - c` | 119 | | Dot product | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `VecX.dot(a, b)` | 120 | | Equals | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `VecX.equals(a, b)` | 121 | | Length (magnitude) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `vec.length()` | 122 | | Length squared | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `vec.lengthSquared()` | 123 | | Lerp | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `VecX.lerp(a, b, t, dest)` | 124 | | Normalize | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `VecX.normalize(v, dest)` | 125 | | String representation | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `vec.toString()` | 126 | | To/from float array | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `vec.toFloatArray()`, `VecX.fromFloatArray(arr)` | 127 | 128 | #### Quaternions 129 | 130 | | Calculation | Quat | API | 131 | |:------------|:----:|:----| 132 | | Axis-angle | :heavy_check_mark: | `Quat.axisAngle(axis, angle, dest)` | 133 | | Copy | :heavy_check_mark: | `Quat.copy(src, dest)` | 134 | | Conjugate | :heavy_check_mark: | `Quat.conjugate(q, dest)` | 135 | | Dot product | :heavy_check_mark: | `Quat.dot(a, b)` | 136 | | From Euler | :heavy_check_mark: | `Quat.fromEuler(x, y, z, dest)` | 137 | | Get axis-angle | :x: | | 138 | | Dot product | :heavy_check_mark: | `Quat.identity(dest)` | 139 | | Invert | :heavy_check_mark: | `Quat.invert(q, dest)` | 140 | | Length (magnitude) | :heavy_check_mark: | `quat.length()` | 141 | | Length squared | :heavy_check_mark: | `quat.lengthSquared()` | 142 | | Lerp | :heavy_check_mark: | `Quat.lerp(a, b, t, dest)` | 143 | | SLerp | :heavy_check_mark: | `Quat.slerp(a, b, t, dest)` | 144 | | Multiply w/ quats | :heavy_check_mark: | `Quat.multiplyQuats(a, b, dest)` | 145 | | Multiply w/ scalar | :heavy_check_mark: | `Quat.multiplyScalar(a, s, dest)` | 146 | | Quat × quat | :heavy_check_mark: | `a * b` | 147 | | Quat × scalar | :heavy_check_mark: | `a * s` | 148 | | Normalize | :heavy_check_mark: | `Quat.normalize(q, dest)` | 149 | | String representation | :heavy_check_mark: | `quat.toString()` | 150 | | To/from float array | :heavy_check_mark: | `quat.toFloatArray()`, `Quat.fromFloatArray(arr)` | 151 | 152 | #### Matrices 153 | 154 | | Calculation | Mat2 | Mat3 | Mat4 | API | 155 | |:------------|:----:|:----:|:----:|:----| 156 | | Add matrices | :x: | :x: | :x: | | 157 | | Add scalars | :x: | :x: | :x: | | 158 | | Adjugate | :x: | :x: | :x: | | 159 | | Array access | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `mat[index]` | 160 | | Copy | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `MatX.copy(src, dest)` | 161 | | Determinant | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `MatX.determinant(src)` | 162 | | Equals | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `MatX.equals(a, b)` | 163 | | Identity | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `MatX.identity(dest)` | 164 | | Invert | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `MatX.invert(src, dest)` | 165 | | Multiply w/ matrices | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `MatX.multMat(a, b, dest)` | 166 | | Multiply w/ vectors | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `MatX.multVec(m, v, dest)` | 167 | | Multiply w/ scalars | :x: | :x: | :x: | | 168 | | String representation | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `mat.toString()` | 169 | | To/from float array | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `mat.toFloatArray()`, `MatX.fromFloatArray(arr)` | 170 | | Transpose | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | `MatX.transpose(src, dest)` | 171 | -------------------------------------------------------------------------------- /src/glm/GLM.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Kenton Hamaluik 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | package glm; 15 | 16 | using glm.Mat4; 17 | using glm.Vec3; 18 | 19 | /** 20 | Utility functions for 3D math 21 | */ 22 | class GLM { 23 | /** 24 | Minimum absolute value difference of floats before they are considered equal 25 | */ 26 | public static var EPSILON:Float = 0.0000001; 27 | 28 | /** 29 | Utility for linearly interpolating between two values 30 | @param a The value when `t == 0` 31 | @param b The value when `t == 1` 32 | @param t A value between `0` and `1`, not clamped by the function 33 | @return Float 34 | */ 35 | public inline static function lerp(a:Float, b:Float, t:Float):Float { 36 | return a + t * (b - a); 37 | } 38 | 39 | /** 40 | Constructs a 3D translation matrix 41 | @param translation How far to move in each of the directions 42 | @param dest Where the result will be stored 43 | @return Mat4 44 | */ 45 | public inline static function translate(translation:Vec3, dest:Mat4):Mat4 { 46 | dest.identity(); 47 | dest.r0c3 = translation.x; 48 | dest.r1c3 = translation.y; 49 | dest.r2c3 = translation.z; 50 | return dest; 51 | } 52 | 53 | /** 54 | Constructs a 3D rotation matrix 55 | @param rotation The quaternion to use as rotation 56 | @param dest Where the result will be stored 57 | @return Mat4 58 | */ 59 | public inline static function rotate(rotation:Quat, dest:Mat4):Mat4 { 60 | var x2:Float = rotation.x+rotation.x, y2:Float = rotation.y+rotation.y, z2:Float = rotation.z+rotation.z; 61 | var xx:Float = rotation.x * x2, xy:Float = rotation.x * y2, xz:Float = rotation.x * z2; 62 | var yy:Float = rotation.y * y2, yz:Float = rotation.y * z2, zz:Float = rotation.z * z2; 63 | var wx:Float = rotation.w * x2, wy:Float = rotation.w * y2, wz:Float = rotation.w * z2; 64 | 65 | dest.r0c0 = 1 - (yy + zz); 66 | dest.r0c1 = xy - wz; 67 | dest.r0c2 = xz + wy; 68 | dest.r0c3 = 0; 69 | 70 | dest.r1c0 = xy + wz; 71 | dest.r1c1 = 1 - (xx + zz); 72 | dest.r1c2 = yz - wx; 73 | dest.r1c3 = 0; 74 | 75 | dest.r2c0 = xz - wy; 76 | dest.r2c1 = yz + wx; 77 | dest.r2c2 = 1 - (xx + yy); 78 | dest.r2c3 = 0; 79 | 80 | dest.r3c0 = 0; 81 | dest.r3c1 = 0; 82 | dest.r3c2 = 0; 83 | dest.r3c3 = 1; 84 | return dest; 85 | } 86 | 87 | /** 88 | Constructs a 3D scale matrix 89 | @param amount How much to scale by in each of the three directions 90 | @param dest Where the result will be stored 91 | @return Mat4 92 | */ 93 | public inline static function scale(amount:Vec3, dest:Mat4):Mat4 { 94 | dest.identity(); 95 | dest.r0c0 = amount.x; 96 | dest.r1c1 = amount.y; 97 | dest.r2c2 = amount.z; 98 | return dest; 99 | } 100 | 101 | /** 102 | Constructs a complete transformation matrix from translation, rotation, and scale components. 103 | It should be a fair bit faster than constructing each on their own and multiplying together. 104 | @param translation The translation vector 105 | @param rotation The rotation quaternion 106 | @param scale The scale vector 107 | @param dest Where to store the result 108 | @return Mat4 109 | */ 110 | public inline static function transform(translation:Vec3, rotation:Quat, scale:Vec3, dest:Mat4):Mat4 { 111 | var x2:Float = rotation.x + rotation.x; 112 | var y2:Float = rotation.y + rotation.y; 113 | var z2:Float = rotation.z + rotation.z; 114 | 115 | var xx:Float = rotation.x * x2; 116 | var xy:Float = rotation.x * y2; 117 | var xz:Float = rotation.x * z2; 118 | var yy:Float = rotation.y * y2; 119 | var yz:Float = rotation.y * z2; 120 | var zz:Float = rotation.z * z2; 121 | var wx:Float = rotation.w * x2; 122 | var wy:Float = rotation.w * y2; 123 | var wz:Float = rotation.w * z2; 124 | 125 | dest.r0c0 = (1 - (yy + zz)) * scale.x; 126 | dest.r1c0 = (xy + wz) * scale.x; 127 | dest.r2c0 = (xz - wy) * scale.x; 128 | dest.r3c0 = 0; 129 | dest.r0c1 = (xy - wz) * scale.y; 130 | dest.r1c1 = (1 - (xx + zz)) * scale.y; 131 | dest.r2c1 = (yz + wx) * scale.y; 132 | dest.r3c1 = 0; 133 | dest.r0c2 = (xz + wy) * scale.z; 134 | dest.r1c2 = (yz - wx) * scale.z; 135 | dest.r2c2 = (1 - (xx + yy)) * scale.z; 136 | dest.r3c2 = 0; 137 | dest.r0c3 = translation.x; 138 | dest.r1c3 = translation.y; 139 | dest.r2c3 = translation.z; 140 | dest.r3c3 = 1; 141 | return dest; 142 | } 143 | 144 | /** 145 | Constructs a lookat matrix to position a view matrix at `eye`, looking at `centre`, with `up` orienting the view 146 | @param eye Where the viewer is located 147 | @param centre Where the viewer is looking at 148 | @param up A vector pointing `up` for the view 149 | @param dest Where to store the result 150 | @return Mat4 151 | */ 152 | public static function lookAt(eye:Vec3, centre:Vec3, up:Vec3, dest:Mat4):Mat4 { 153 | var f:Vec3 = centre - eye; 154 | f.normalize(f); 155 | var s:Vec3 = Vec3.cross(f, up, new Vec3()); 156 | s.normalize(s); 157 | var u:Vec3 = Vec3.cross(s, f, new Vec3()); 158 | 159 | dest.identity(); 160 | dest.r0c0 = s.x; 161 | dest.r0c1 = s.y; 162 | dest.r0c2 = s.z; 163 | dest.r1c0 = u.x; 164 | dest.r1c1 = u.y; 165 | dest.r1c2 = u.z; 166 | dest.r2c0 =-f.x; 167 | dest.r2c1 =-f.y; 168 | dest.r2c2 =-f.z; 169 | dest.r0c3 = -Vec3.dot(s, eye); 170 | dest.r1c3 = -Vec3.dot(u, eye); 171 | dest.r2c3 = Vec3.dot(f, eye); 172 | 173 | return dest; 174 | } 175 | 176 | /** 177 | Constructs a perspective projection matrix 178 | @see https://github.com/toji/gl-matrix/blob/7fc31d5d292fb65b10aa98186b218a0bdef3a207/src/gl-matrix/mat4.js#L1241-L1271 179 | @param fovy The vertical field of view in radians 180 | @param aspectRatio The aspect ratio of the view 181 | @param near The near clipping plane 182 | @param far The far clipping plane 183 | @param dest Where to store the result 184 | @return Mat4 185 | */ 186 | public inline static function perspective(fovy:Float, aspectRatio:Float, near:Float, far:Float, dest:Mat4):Mat4 { 187 | var f:Float = 1 / Math.tan(fovy / 2); 188 | var nf:Float = 1 / (near - far); 189 | 190 | dest.r0c0 = f / aspectRatio; 191 | dest.r1c0 = 0; 192 | dest.r2c0 = 0; 193 | dest.r3c0 = 0; 194 | 195 | dest.r0c1 = 0; 196 | dest.r1c1 = f; 197 | dest.r2c1 = 0; 198 | dest.r3c1 = 0; 199 | 200 | dest.r0c2 = 0; 201 | dest.r1c2 = 0; 202 | dest.r2c2 = (far + near) * nf; 203 | dest.r3c2 = -1; 204 | 205 | dest.r0c3 = 0; 206 | dest.r1c3 = 0; 207 | dest.r2c3 = (2 * far * near) * nf; 208 | dest.r3c3 = 0; 209 | return dest; 210 | } 211 | 212 | /** 213 | Constructs an orthographic projection matrix 214 | @param left 215 | @param right 216 | @param bottom 217 | @param top 218 | @param near 219 | @param far 220 | @param dest Where to store the result 221 | @return Mat4 222 | */ 223 | public inline static function orthographic(left:Float, right:Float, bottom:Float, top:Float, near:Float=-1, far:Float=1, dest:Mat4):Mat4 { 224 | var rl:Float = 1 / (right - left); 225 | var tb:Float = 1 / (top - bottom); 226 | var fn:Float = 1 / (far - near); 227 | 228 | dest.r0c0 = 2 * rl; 229 | dest.r0c1 = 0; 230 | dest.r0c2 = 0; 231 | dest.r0c3 = -1 * (left + right) * rl; 232 | 233 | dest.r1c0 = 0; 234 | dest.r1c1 = 2 * tb; 235 | dest.r1c2 = 0; 236 | dest.r1c3 = -1 * (top + bottom) * tb; 237 | 238 | dest.r2c0 = 0; 239 | dest.r2c1 = 0; 240 | dest.r2c2 = -2 * fn; 241 | dest.r2c3 = -1 * (far + near) * fn; 242 | 243 | dest.r3c0 = 0; 244 | dest.r3c1 = 0; 245 | dest.r3c2 = 0; 246 | dest.r3c3 = 1; 247 | return dest; 248 | } 249 | 250 | /** 251 | Constructs an orthographic projection matrix 252 | @see https://github.com/toji/gl-matrix/blob/7fc31d5d292fb65b10aa98186b218a0bdef3a207/src/gl-matrix/mat4.js#L1206-L1239 253 | @param left 254 | @param right 255 | @param bottom 256 | @param top 257 | @param near 258 | @param far 259 | @param dest Where to store the result 260 | @return Mat4 261 | */ 262 | public inline static function frustum(left:Float, right:Float, bottom:Float, top:Float, near:Float=-1, far:Float=1, dest:Mat4):Mat4 { 263 | var rl:Float = 1 / (right - left); 264 | var tb:Float = 1 / (top - bottom); 265 | var nf:Float = 1 / (near - far); 266 | 267 | dest.r0c0 = (near * 2) * rl; 268 | dest.r1c0 = 0; 269 | dest.r2c0 = 0; 270 | dest.r3c0 = 0; 271 | 272 | dest.r0c1 = 0; 273 | dest.r1c1 = (near * 2) * tb; 274 | dest.r2c1 = 0; 275 | dest.r3c1 = 0; 276 | 277 | dest.r0c2 = (right + left) * tb; 278 | dest.r1c2 = (top + bottom) * tb; 279 | dest.r2c2 = (far + near) * nf; 280 | dest.r3c2 = -1; 281 | 282 | dest.r0c3 = 0; 283 | dest.r1c3 = 0; 284 | dest.r2c3 = (far * near * 2) * nf; 285 | dest.r3c3 = 0; 286 | return dest; 287 | } 288 | } -------------------------------------------------------------------------------- /src/glm/Vec2.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 Kenton Hamaluik 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at: 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | package glm; 15 | 16 | #if kha 17 | import kha.math.FastVector2; 18 | #else 19 | @:dox(hide) 20 | @:allow(glm.Vec2) 21 | class Vec2Base { 22 | function new() {} 23 | 24 | var x:Float; 25 | var y:Float; 26 | } 27 | #end 28 | 29 | /** 30 | A two-element vector 31 | */ 32 | #if kha 33 | abstract Vec2(FastVector2) from FastVector2 to FastVector2 { 34 | #else 35 | abstract Vec2(Vec2Base) { 36 | #end 37 | /** 38 | Accessor for the first element of the vector 39 | */ 40 | public var x(get, set):Float; 41 | private inline function get_x():Float return this.x; 42 | private inline function set_x(v:Float):Float return this.x = v; 43 | 44 | /** 45 | Accessor for the second element of the vector 46 | */ 47 | public var y(get, set):Float; 48 | private inline function get_y():Float return this.y; 49 | private inline function set_y(v:Float):Float return this.y = v; 50 | 51 | /** 52 | Accessor for the first element of the vector 53 | */ 54 | public var i(get, set):Float; 55 | private inline function get_i():Float return this.x; 56 | private inline function set_i(v:Float):Float return this.x = v; 57 | 58 | /** 59 | Accessor for the second element of the vector 60 | */ 61 | public var j(get, set):Float; 62 | private inline function get_j():Float return this.y; 63 | private inline function set_j(v:Float):Float return this.y = v; 64 | 65 | /** 66 | Read an element using an index 67 | @param key the index to use 68 | @return Float 69 | */ 70 | @:arrayAccess 71 | public inline function get(key:Int):Float { 72 | return switch(key) { 73 | case 0: x; 74 | case 1: y; 75 | case _: throw 'Index ${key} out of bounds (0-1)!'; 76 | }; 77 | } 78 | 79 | /** 80 | Write to an element using an index 81 | @param key the index to use 82 | @param value the value to set 83 | @return Float 84 | */ 85 | @:arrayAccess 86 | public inline function set(key:Int, value:Float):Float { 87 | return switch(key) { 88 | case 0: x = value; 89 | case 1: y = value; 90 | case _: throw 'Index ${key} out of bounds (0-1)!'; 91 | }; 92 | } 93 | 94 | public inline function new(x:Float = 0, y:Float = 0) { 95 | #if kha 96 | this = new FastVector2(); 97 | #else 98 | this = new Vec2Base(); 99 | #end 100 | this.x = x; 101 | this.y = y; 102 | } 103 | 104 | /** 105 | Checks if `this == v` on an element-by-element basis 106 | @param v - The vector to check against 107 | @return Bool 108 | */ 109 | public inline function equals(b:Vec2):Bool { 110 | return !( 111 | Math.abs(x - b.x) >= glm.GLM.EPSILON 112 | || Math.abs(y - b.y) >= glm.GLM.EPSILON 113 | ); 114 | } 115 | 116 | /** 117 | Creates a string reprentation of `this` 118 | @return String 119 | */ 120 | public inline function toString():String { 121 | return 122 | '<${x}, ${y}>'; 123 | } 124 | 125 | /** 126 | Calculates the square of the magnitude of the vector, to save calculation time if the actual magnitude isn't needed 127 | @return Float 128 | */ 129 | public inline function lengthSquared():Float { 130 | return x*x + y*y; 131 | } 132 | 133 | /** 134 | Calculates the magnitude of the vector 135 | @return Float 136 | */ 137 | public inline function length():Float { 138 | return Math.sqrt(lengthSquared()); 139 | } 140 | 141 | /** 142 | Copies one vector into another 143 | @param src The vector to copy from 144 | @param dest The vector to copy into 145 | @return Vec2 146 | */ 147 | public inline static function copy(src:Vec2, dest:Vec2):Vec2 { 148 | dest.x = src.x; 149 | dest.y = src.y; 150 | return dest; 151 | } 152 | 153 | /** 154 | Utility for setting an entire vector at once 155 | @param dest The vector to set values into 156 | @param x 157 | @param y 158 | @return Vec2 159 | */ 160 | public inline static function setComponents(dest:Vec2, x:Float = 0, y:Float = 0):Vec2 { 161 | dest.x = x; 162 | dest.y = y; 163 | return dest; 164 | } 165 | 166 | /** 167 | Adds two vectors on an element-by-element basis 168 | @param a 169 | @param b 170 | @param dest The vector to store the result in 171 | @return Vec2 172 | */ 173 | public inline static function addVec(a:Vec2, b:Vec2, dest:Vec2):Vec2 { 174 | dest.x = a.x + b.x; 175 | dest.y = a.y + b.y; 176 | return dest; 177 | } 178 | 179 | /** 180 | Subtracts `b` from `a` on an element-by-element basis 181 | @param a 182 | @param b 183 | @param dest The vector to store the result in 184 | @return Vec2 185 | */ 186 | public inline static function subtractVec(a:Vec2, b:Vec2, dest:Vec2):Vec2 { 187 | dest.x = a.x - b.x; 188 | dest.y = a.y - b.y; 189 | return dest; 190 | } 191 | 192 | /** 193 | Shortcut operator for `addVec(a, b, new Vec2())` 194 | @param a 195 | @param b 196 | @return Vec2 197 | */ 198 | @:op(A + B) 199 | inline static function addVecOp(a:Vec2, b:Vec2):Vec2 { 200 | return addVec(a, b, new Vec2()); 201 | } 202 | 203 | /** 204 | Shortcut operator for `subtractVec(a, b, new Vec2())` 205 | @param a 206 | @param b 207 | @return Vec2 208 | */ 209 | @:op(A - B) 210 | inline static function subtractVecOp(a:Vec2, b:Vec2):Vec2 { 211 | return subtractVec(a, b, new Vec2()); 212 | } 213 | 214 | /** 215 | Adds a scalar to a vector 216 | @param a The vector to add a scalar to 217 | @param s A scalar to add 218 | @param dest The vector to store the result in 219 | @return Vec2 220 | */ 221 | public inline static function addScalar(a:Vec2, s:Float, dest:Vec2):Vec2 { 222 | dest.x = a.x + s; 223 | dest.y = a.y + s; 224 | return dest; 225 | } 226 | 227 | /** 228 | Multiplies the elements of `a` by `s`, storing the result in `dest` 229 | @param a 230 | @param s 231 | @param dest 232 | @return Vec2 233 | */ 234 | public inline static function multiplyScalar(a:Vec2, s:Float, dest:Vec2):Vec2 { 235 | dest.x = a.x * s; 236 | dest.y = a.y * s; 237 | return dest; 238 | } 239 | 240 | /** 241 | Shortcut operator for `addScalar(a, s, new Vec2())` 242 | @param a 243 | @param s 244 | @return Vec2 245 | */ 246 | @:op(A + B) 247 | inline static function addScalarOp(a:Vec2, s:Float):Vec2 { 248 | return addScalar(a, s, new Vec2()); 249 | } 250 | 251 | /** 252 | Shortcut operator for `addScalar(a, -s, new Vec2())` 253 | @param a 254 | @param s 255 | @return Vec2 256 | */ 257 | @:op(A - B) 258 | inline static function subtractScalarOp(a:Vec2, s:Float):Vec2 { 259 | return addScalar(a, -s, new Vec2()); 260 | } 261 | 262 | /** 263 | Shortcut operator for `multiplyScalar(a, s, new Vec2())` 264 | @param a 265 | @param s 266 | @return Vec2 267 | */ 268 | @:op(A * B) 269 | inline static function multiplyScalarOp(a:Vec2, s:Float):Vec2 { 270 | return multiplyScalar(a, s, new Vec2()); 271 | } 272 | 273 | /** 274 | Shortcut operator for `multiplyScalar(a, 1/s, new Vec2())` 275 | @param a 276 | @param s 277 | @return Vec2 278 | */ 279 | @:op(A / B) 280 | inline static function divideScalarOp(a:Vec2, s:Float):Vec2 { 281 | return multiplyScalar(a, 1/s, new Vec2()); 282 | } 283 | 284 | /** 285 | Calculates the square of the distance between two vectors 286 | @param a 287 | @param b 288 | @return Float 289 | */ 290 | public inline static function distanceSquared(a:Vec2, b:Vec2):Float { 291 | return (a.x - b.x) * (a.x - b.x) + 292 | (a.y - b.y) * (a.y - b.y); 293 | } 294 | 295 | /** 296 | Calculates the distance (magnitude) between two vectors 297 | @param a 298 | @param b 299 | @return Float 300 | */ 301 | public inline static function distance(a:Vec2, b:Vec2):Float { 302 | return Math.sqrt(distanceSquared(a, b)); 303 | } 304 | 305 | /** 306 | Calculates the dot product of two vectors 307 | @param a 308 | @param b 309 | @return Float 310 | */ 311 | public inline static function dot(a:Vec2, b:Vec2):Float { 312 | return a.x * b.x + 313 | a.y * b.y; 314 | } 315 | 316 | /** 317 | Calculates the cross product of `a` and `b` 318 | @param a The left-hand side vector to cross 319 | @param b The right-hand side vector to cross 320 | @param dest Where to store the result 321 | @return Vec3 `dest` 322 | */ 323 | public inline static function cross(a:Vec2, b:Vec2, dest:Vec3):Vec3 { 324 | dest = new Vec3( 325 | 0, 326 | 0, 327 | a.x * b.y - a.y * b.x); 328 | return dest; 329 | } 330 | 331 | /** 332 | Normalizes `v` such that `v.length() == 1`, and stores the result in `dest` 333 | @param v 334 | @param dest 335 | @return Vec2 336 | */ 337 | public inline static function normalize(v:Vec2, dest:Vec2):Vec2 { 338 | var length:Float = v.length(); 339 | var mult:Float = 0; 340 | if(length >= glm.GLM.EPSILON) { 341 | mult = 1 / length; 342 | } 343 | return Vec2.multiplyScalar(v, mult, dest); 344 | } 345 | 346 | /** 347 | Linearly interpolates between `a` and `b`. 348 | @param a The value when `t == 0` 349 | @param b The value when `t == 1` 350 | @param t A value between `0` and `1`, not clamped by the function 351 | @param dest The vector to store the result in 352 | @return Vec2 353 | */ 354 | public inline static function lerp(a:Vec2, b:Vec2, t:Float, dest:Vec2):Vec2 { 355 | dest.x = glm.GLM.lerp(a.x, b.x, t); 356 | dest.y = glm.GLM.lerp(a.y, b.y, t); 357 | return dest; 358 | } 359 | 360 | /** 361 | Construct a Vec2 from an array of floats 362 | @param arr an array with 2 elements, corresponding to x, y 363 | @return Vec2 364 | */ 365 | @:from 366 | public inline static function fromFloatArray(arr:Array):Vec2 { 367 | return new Vec2(arr[0], arr[1]); 368 | } 369 | 370 | /** 371 | Converts this into a 2-element array of floats 372 | @return Array 373 | */ 374 | @:to 375 | public inline function toFloatArray():Array { 376 | return [x, y]; 377 | } 378 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2017 Kenton Hamaluik 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. --------------------------------------------------------------------------------