From ded48e9969f94ae2e111588afeb7833e22915841 Mon Sep 17 00:00:00 2001 From: archmoj Date: Sat, 6 Oct 2018 22:56:48 -0400 Subject: [PATCH 1/9] align long axis lables --- axes.js | 13 +- lib/shaders/textVert.glsl | 46 +- lib/text.js | 6 +- package-lock.json | 1692 +++++++++++++++++++++++++++++++++++++ 4 files changed, 1746 insertions(+), 11 deletions(-) create mode 100644 package-lock.json diff --git a/axes.js b/axes.js index 60ff5c9..41984a2 100644 --- a/axes.js +++ b/axes.js @@ -457,6 +457,8 @@ proto.draw = function(params) { projection, this.pixelRatio) + var allDirections = [[1,0,0],[0,1,0],[0,0,1]]; + for(var i=0; i<3; ++i) { var minor = lineOffset[i].primalMinor @@ -482,7 +484,8 @@ proto.draw = function(params) { this.tickSize[i], this.tickAngle[i], offset, - this.tickColor[i]) + this.tickColor[i], + [0,0,0]) } //Draw labels @@ -494,13 +497,19 @@ proto.draw = function(params) { } offset[i] += 0.5 * (bounds[0][i] + bounds[1][i]) + var direction = [0,0,0]; + if(this.labels[i].length > 4) { // for large label axis enable alignment to axis + direction = allDirections[i]; + } + //Draw axis this._text.drawLabel( i, this.labelSize[i], this.labelAngle[i], offset, - this.labelColor[i]) + this.labelColor[i], + direction) } } diff --git a/lib/shaders/textVert.glsl b/lib/shaders/textVert.glsl index d0e2f68..df5c308 100644 --- a/lib/shaders/textVert.glsl +++ b/lib/shaders/textVert.glsl @@ -4,24 +4,56 @@ uniform mat4 model, view, projection; uniform vec3 offset, axis; uniform float scale, angle, pixelScale; uniform vec2 resolution; +uniform vec3 direction; -void main() { - //Compute plane offset - vec2 planeCoord = position.xy * pixelScale; - mat2 planeXform = scale * mat2(cos(angle), sin(angle), - -sin(angle), cos(angle)); - vec2 viewOffset = 2.0 * planeXform * planeCoord / resolution; +float PI = 3.141592; + +void main() { //Compute world offset float axisDistance = position.z; vec3 dataPosition = axisDistance * axis + offset; vec4 worldPosition = model * vec4(dataPosition, 1); - + //Compute clip position vec4 viewPosition = view * worldPosition; vec4 clipPosition = projection * viewPosition; clipPosition /= clipPosition.w; + float axisAngle = 0.0; + + if ((direction.x != 0.0) || + (direction.y != 0.0) || + (direction.z != 0.0)) { + + vec4 endPoint = projection * view * model * vec4( direction, 1.0); + vec4 startPoint = projection * view * model * vec4(-direction, 1.0); + + axisAngle = atan( + (endPoint.y - startPoint.y), + (endPoint.x - startPoint.x) + ); + + // force positive angles + if (axisAngle < 0.0) axisAngle += 2.0 * PI; + + // logic for horizontal or vertical align + if (axisAngle < 0.35 * PI) axisAngle = 0.0; + else if (axisAngle < 0.65 * PI) axisAngle = 0.5 * PI; + else if (axisAngle < 1.35 * PI) axisAngle = 0.0; + else if (axisAngle < 1.65 * PI) axisAngle = 0.5 * PI; + else axisAngle = 0.0; + } + + //Compute plane offset + vec2 planeCoord = position.xy * pixelScale; + + float totalAngle = angle + axisAngle; + + mat2 planeXform = scale * mat2(cos(totalAngle), sin(totalAngle), + -sin(totalAngle), cos(totalAngle)); + vec2 viewOffset = 2.0 * planeXform * planeCoord / resolution; + //Apply text offset in clip coordinates clipPosition += vec4(viewOffset, 0, 0); diff --git a/lib/text.js b/lib/text.js index 460f622..190d07d 100644 --- a/lib/text.js +++ b/lib/text.js @@ -123,7 +123,7 @@ proto.update = function(bounds, labels, labelFont, ticks, tickFont) { //Draws the tick marks for an axis var AXIS = [0,0,0] -proto.drawTicks = function(d, scale, angle, offset, color) { +proto.drawTicks = function(d, scale, angle, offset, color, direction) { if(!this.tickCount[d]) { return } @@ -136,12 +136,13 @@ proto.drawTicks = function(d, scale, angle, offset, color) { this.shader.uniforms.angle = angle this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset + this.shader.uniforms.direction = direction this.vao.draw(this.gl.TRIANGLES, this.tickCount[d], this.tickOffset[d]) } //Draws the text label for an axis var ZERO = [0,0,0] -proto.drawLabel = function(d, scale, angle, offset, color) { +proto.drawLabel = function(d, scale, angle, offset, color, direction) { if(!this.labelCount[d]) { return } @@ -150,6 +151,7 @@ proto.drawLabel = function(d, scale, angle, offset, color) { this.shader.uniforms.angle = angle this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset + this.shader.uniforms.direction = direction this.vao.draw(this.gl.TRIANGLES, this.labelCount[d], this.labelOffset[d]) } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..48ce6b3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1692 @@ +{ + "name": "gl-axes3d", + "version": "1.2.7", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@choojs/findup": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@choojs/findup/-/findup-0.2.1.tgz", + "integrity": "sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw==", + "requires": { + "commander": "^2.15.1" + } + }, + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + }, + "add-line-numbers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/add-line-numbers/-/add-line-numbers-1.0.1.tgz", + "integrity": "sha1-SNu96kfb0jTer+rGyTzqb3C0t+M=", + "requires": { + "pad-left": "^1.0.2" + } + }, + "affine-hull": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/affine-hull/-/affine-hull-1.0.0.tgz", + "integrity": "sha1-dj/x040GPOt+Jy8X7k17vK+QXF0=", + "dev": true, + "requires": { + "robust-orientation": "^1.1.3" + } + }, + "atob-lite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-1.0.0.tgz", + "integrity": "sha1-uI3KYAaSK5YglPdVaCa6sxxKKWs=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "barycentric": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/barycentric/-/barycentric-1.0.1.tgz", + "integrity": "sha1-8VYruJGyb0/sRjqC7to2V4AOxog=", + "dev": true, + "requires": { + "robust-linear-solve": "^1.0.0" + } + }, + "big-rat": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/big-rat/-/big-rat-1.0.4.tgz", + "integrity": "sha1-do0JO7V5MN0Y7Vdcf8on3FORreo=", + "requires": { + "bit-twiddle": "^1.0.2", + "bn.js": "^4.11.6", + "double-bits": "^1.1.1" + } + }, + "binary-search-bounds": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-2.0.4.tgz", + "integrity": "sha512-2hg5kgdKql5ClF2ErBcSx0U5bnl5hgS4v7wMnLFodyR47yMtj2w+UAZB+0CiqyHct2q543i7Bi4/aMIegorCCg==" + }, + "bit-twiddle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", + "integrity": "sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4=" + }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "box-intersect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/box-intersect/-/box-intersect-1.0.1.tgz", + "integrity": "sha1-tyilnj8aPHPCJJM8JmC5J6oTeQI=", + "requires": { + "bit-twiddle": "^1.0.2", + "typedarray-pool": "^1.1.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "cdt2d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cdt2d/-/cdt2d-1.0.0.tgz", + "integrity": "sha1-TyEkNLzWe9s9aLj+9KzcLFRBUUE=", + "requires": { + "binary-search-bounds": "^2.0.3", + "robust-in-sphere": "^1.1.3", + "robust-orientation": "^1.1.3" + } + }, + "clean-pslg": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/clean-pslg/-/clean-pslg-1.1.2.tgz", + "integrity": "sha1-vTXHRgt+irWp92Gl7VF5aqPIbBE=", + "requires": { + "big-rat": "^1.0.3", + "box-intersect": "^1.0.1", + "nextafter": "^1.0.0", + "rat-vec": "^1.1.1", + "robust-segment-intersect": "^1.0.1", + "union-find": "^1.0.2", + "uniq": "^1.0.1" + } + }, + "colormap": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/colormap/-/colormap-2.3.0.tgz", + "integrity": "sha512-Mkk6mQUMbCleXEeStFm2xLwv5zbRakZMUFB1T1+iNEv58VKBByfPwYIjMQDwSRmXNM1gvo5y3WTYAhmdMn/rbg==", + "dev": true, + "requires": { + "lerp": "^1.0.3" + } + }, + "commander": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", + "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==" + }, + "compare-angle": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/compare-angle/-/compare-angle-1.0.1.tgz", + "integrity": "sha1-pOtjQW6jx0f8a9bItjZotN5PoSk=", + "requires": { + "robust-orientation": "^1.0.2", + "robust-product": "^1.0.0", + "robust-sum": "^1.0.0", + "signum": "^0.0.0", + "two-sum": "^1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "convex-hull": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/convex-hull/-/convex-hull-1.0.3.tgz", + "integrity": "sha1-IKOqbOh/St6i/30XlxyfwcZ+H/8=", + "dev": true, + "requires": { + "affine-hull": "^1.0.0", + "incremental-convex-hull": "^1.0.1", + "monotone-convex-hull-2d": "^1.0.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cwise-compiler": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cwise-compiler/-/cwise-compiler-1.1.3.tgz", + "integrity": "sha1-9NZnQQ6FDToxOn0tt7HlBbsDTMU=", + "requires": { + "uniq": "^1.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "domready": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/domready/-/domready-1.0.8.tgz", + "integrity": "sha1-kfJS5Ze2Wvd+dFriTdAYXV4m1Yw=", + "dev": true + }, + "double-bits": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/double-bits/-/double-bits-1.1.1.tgz", + "integrity": "sha1-WKu6RUlNpND6Nrc60RoobJGEscY=" + }, + "dup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dup/-/dup-1.0.0.tgz", + "integrity": "sha1-UfxaxoX4GWRp3wuQXpNLIK9bQCk=" + }, + "duplexify": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "edges-to-adjacency-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/edges-to-adjacency-list/-/edges-to-adjacency-list-1.0.0.tgz", + "integrity": "sha1-wUbS4ISt37p0pRKTxuAZmkn3V/E=", + "requires": { + "uniq": "^1.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escodegen": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", + "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "events": { + "version": "1.1.1", + "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, + "extract-frustum-planes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/extract-frustum-planes/-/extract-frustum-planes-1.0.0.tgz", + "integrity": "sha1-l9VwP/BWTIw8aDjKxF+ee8UsnvU=" + }, + "falafel": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.1.0.tgz", + "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=", + "requires": { + "acorn": "^5.0.0", + "foreach": "^2.0.5", + "isarray": "0.0.1", + "object-keys": "^1.0.6" + } + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "game-shell": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/game-shell/-/game-shell-1.3.2.tgz", + "integrity": "sha1-YruZ+pfVIbThxZ2IdQAZvgqmqCI=", + "dev": true, + "requires": { + "binary-search-bounds": "^1.0.0", + "domready": "^1.0.5", + "invert-hash": "~0.0.0", + "iota-array": "^1.0.0", + "uniq": "^1.0.0", + "vkey": "~0.0.2" + }, + "dependencies": { + "binary-search-bounds": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-1.0.0.tgz", + "integrity": "sha1-MjyjF+PypA9CRMclX1OEpbIHu2k=", + "dev": true + } + } + }, + "game-shell-orbit-camera": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/game-shell-orbit-camera/-/game-shell-orbit-camera-1.0.0.tgz", + "integrity": "sha1-I7R0+IxC90KhE3AAgPY3Od4J15I=", + "dev": true, + "requires": { + "orbit-camera": "^1.0.0" + } + }, + "gamma": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/gamma/-/gamma-0.1.0.tgz", + "integrity": "sha1-MxVkNAO/J5BsqAqzfDbs6UQO8zA=" + }, + "gl-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/gl-buffer/-/gl-buffer-2.1.2.tgz", + "integrity": "sha1-LbjZwaVSf7oM25EonCBuiCuInNs=", + "requires": { + "ndarray": "^1.0.15", + "ndarray-ops": "^1.1.0", + "typedarray-pool": "^1.0.0" + } + }, + "gl-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gl-constants/-/gl-constants-1.0.0.tgz", + "integrity": "sha1-WXpQTjZHUP9QJTqjX43qevSl0jM=" + }, + "gl-format-compiler-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gl-format-compiler-error/-/gl-format-compiler-error-1.0.3.tgz", + "integrity": "sha1-DHmxdRiZzpcy6GJA8JCqQemEcag=", + "requires": { + "add-line-numbers": "^1.0.1", + "gl-constants": "^1.0.0", + "glsl-shader-name": "^1.0.0", + "sprintf-js": "^1.0.3" + } + }, + "gl-mat4": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gl-mat4/-/gl-mat4-1.2.0.tgz", + "integrity": "sha512-sT5C0pwB1/e9G9AvAoLsoaJtbMGjfd/jfxo8jMCKqYYEnjZuFvqV5rehqar0538EmssjdDeiEWnKyBSTw7quoA==" + }, + "gl-matrix": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-2.8.1.tgz", + "integrity": "sha512-0YCjVpE3pS5XWlN3J4X7AiAx65+nqAI54LndtVFnQZB6G/FVLkZH8y8V6R3cIoOQR4pUdfwQGd1iwyoXHJ4Qfw==", + "dev": true + }, + "gl-mesh3d": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/gl-mesh3d/-/gl-mesh3d-1.3.2.tgz", + "integrity": "sha512-sxqKOQA8T2V1CaNefC7X2FTbTPRXWlmzyPd+UOmeUoUYypanFufnDoNLjMEmD5Njq8M5DBg4G7POzf4Jd8272w==", + "dev": true, + "requires": { + "barycentric": "^1.0.1", + "colormap": "^2.1.0", + "gl-buffer": "^2.0.8", + "gl-mat4": "^1.0.0", + "gl-shader": "^4.2.1", + "gl-texture2d": "^2.0.8", + "gl-vao": "^1.1.3", + "glsl-specular-cook-torrance": "^2.0.1", + "glslify": "^6.1.0", + "ndarray": "^1.0.15", + "normals": "^1.0.1", + "polytope-closest-point": "^1.0.0", + "simplicial-complex-contour": "^1.0.0", + "typedarray-pool": "^1.1.0" + } + }, + "gl-now": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gl-now/-/gl-now-1.4.0.tgz", + "integrity": "sha1-KKw1ahmLuqEUeKGjueA25V5P0IA=", + "dev": true, + "requires": { + "game-shell": "^1.0.0", + "webglew": "^1.0.0" + } + }, + "gl-shader": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/gl-shader/-/gl-shader-4.2.1.tgz", + "integrity": "sha1-vJuAjpKTxRtmjojeYVsMETcI3C8=", + "requires": { + "gl-format-compiler-error": "^1.0.2", + "weakmap-shim": "^1.1.0" + } + }, + "gl-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gl-state/-/gl-state-1.0.0.tgz", + "integrity": "sha1-Ji+qdYNbC5xTLBLzitxCXR0wzRc=", + "requires": { + "uniq": "^1.0.0" + } + }, + "gl-texture2d": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/gl-texture2d/-/gl-texture2d-2.1.0.tgz", + "integrity": "sha1-/2gk5+fDGoum/c2+nlxpXX4hh8c=", + "dev": true, + "requires": { + "ndarray": "^1.0.15", + "ndarray-ops": "^1.2.2", + "typedarray-pool": "^1.1.0" + } + }, + "gl-vao": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/gl-vao/-/gl-vao-1.3.0.tgz", + "integrity": "sha1-6ekqqVWIyrnVwvBLaTRAw99pGSM=" + }, + "gl-vec4": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gl-vec4/-/gl-vec4-1.0.1.tgz", + "integrity": "sha1-l9loeCgbFLUyy84QF4Xf0cs0CWQ=" + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glsl-inject-defines": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/glsl-inject-defines/-/glsl-inject-defines-1.0.3.tgz", + "integrity": "sha1-3RqswsF/yyvT/DJBHGYz0Ne2D9Q=", + "requires": { + "glsl-token-inject-block": "^1.0.0", + "glsl-token-string": "^1.0.1", + "glsl-tokenizer": "^2.0.2" + } + }, + "glsl-resolve": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/glsl-resolve/-/glsl-resolve-0.0.1.tgz", + "integrity": "sha1-iUvvc5ENeSyBtRQxgANdCnivdtM=", + "requires": { + "resolve": "^0.6.1", + "xtend": "^2.1.2" + }, + "dependencies": { + "resolve": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", + "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=" + }, + "xtend": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.2.0.tgz", + "integrity": "sha1-7vax8ZjByN6vrYsXZaBNrUoBxak=" + } + } + }, + "glsl-shader-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glsl-shader-name/-/glsl-shader-name-1.0.0.tgz", + "integrity": "sha1-osMLO6c0mb77DMcYTXx3M91LSH0=", + "requires": { + "atob-lite": "^1.0.0", + "glsl-tokenizer": "^2.0.2" + } + }, + "glsl-specular-beckmann": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/glsl-specular-beckmann/-/glsl-specular-beckmann-1.1.2.tgz", + "integrity": "sha1-/OkFaTPs3yRWJ4N2pU0IKJPndfE=", + "dev": true + }, + "glsl-specular-cook-torrance": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/glsl-specular-cook-torrance/-/glsl-specular-cook-torrance-2.0.1.tgz", + "integrity": "sha1-qJHMBsjHtPRyhwK0gk/ay7ln148=", + "dev": true, + "requires": { + "glsl-specular-beckmann": "^1.1.1" + } + }, + "glsl-token-assignments": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/glsl-token-assignments/-/glsl-token-assignments-2.0.2.tgz", + "integrity": "sha1-pdgqt4SZwuimuDy2lJXm5mXOAZ8=" + }, + "glsl-token-defines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glsl-token-defines/-/glsl-token-defines-1.0.0.tgz", + "integrity": "sha1-y4kqqVmTYjFyhHDU90AySJaX+p0=", + "requires": { + "glsl-tokenizer": "^2.0.0" + } + }, + "glsl-token-depth": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/glsl-token-depth/-/glsl-token-depth-1.1.2.tgz", + "integrity": "sha1-I8XjDuK9JViEtKKLyFC495HpXYQ=" + }, + "glsl-token-descope": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glsl-token-descope/-/glsl-token-descope-1.0.2.tgz", + "integrity": "sha1-D8kKsyYYa4L1l7LnfcniHvzTIHY=", + "requires": { + "glsl-token-assignments": "^2.0.0", + "glsl-token-depth": "^1.1.0", + "glsl-token-properties": "^1.0.0", + "glsl-token-scope": "^1.1.0" + } + }, + "glsl-token-inject-block": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/glsl-token-inject-block/-/glsl-token-inject-block-1.1.0.tgz", + "integrity": "sha1-4QFfWYDBCRgkraomJfHf3ovQADQ=" + }, + "glsl-token-properties": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glsl-token-properties/-/glsl-token-properties-1.0.1.tgz", + "integrity": "sha1-SD3D2Dnw1LXGFx0VkfJJvlPCip4=" + }, + "glsl-token-scope": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/glsl-token-scope/-/glsl-token-scope-1.1.2.tgz", + "integrity": "sha1-oXKOeN8kRE+cuT/RjvD3VQOmQ7E=" + }, + "glsl-token-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glsl-token-string/-/glsl-token-string-1.0.1.tgz", + "integrity": "sha1-WUQdL4V958NEnJRWZgIezjWOSOw=" + }, + "glsl-token-whitespace-trim": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glsl-token-whitespace-trim/-/glsl-token-whitespace-trim-1.0.0.tgz", + "integrity": "sha1-RtHf6Yx1vX1QTAXX0RsbPpzJOxA=" + }, + "glsl-tokenizer": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/glsl-tokenizer/-/glsl-tokenizer-2.1.4.tgz", + "integrity": "sha512-AkZgCYSRJVeVcg/n/D7q3WWyyf0CR+BXPxdM+kzE0ov8lf8BL6jWhL2+ZrCV5J6yHKTJUyW+pW8yltzGFb5wKw==", + "requires": { + "through2": "^0.6.3" + } + }, + "glslify": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/glslify/-/glslify-6.3.1.tgz", + "integrity": "sha512-3Hy85N8NmpDprwAxZaOC9k+DBXEwblVZ+yHIyt1QYg5dIrYaiGorz2WWBRxdUzapjDsxdhQ1ad9GSlIebxeBmA==", + "requires": { + "bl": "^1.0.0", + "concat-stream": "^1.5.2", + "duplexify": "^3.4.5", + "falafel": "^2.1.0", + "from2": "^2.3.0", + "glsl-resolve": "0.0.1", + "glsl-token-whitespace-trim": "^1.0.0", + "glslify-bundle": "^5.0.0", + "glslify-deps": "^1.2.5", + "minimist": "^1.2.0", + "resolve": "^1.1.5", + "stack-trace": "0.0.9", + "static-eval": "^2.0.0", + "tape": "^4.6.0", + "through2": "^2.0.1", + "xtend": "^4.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + } + } + }, + "glslify-bundle": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glslify-bundle/-/glslify-bundle-5.0.0.tgz", + "integrity": "sha1-AlKtoe+d8wtmAAbguyH9EwtIbkI=", + "requires": { + "glsl-inject-defines": "^1.0.1", + "glsl-token-defines": "^1.0.0", + "glsl-token-depth": "^1.1.1", + "glsl-token-descope": "^1.0.2", + "glsl-token-scope": "^1.1.1", + "glsl-token-string": "^1.0.1", + "glsl-token-whitespace-trim": "^1.0.0", + "glsl-tokenizer": "^2.0.2", + "murmurhash-js": "^1.0.0", + "shallow-copy": "0.0.1" + } + }, + "glslify-deps": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/glslify-deps/-/glslify-deps-1.3.1.tgz", + "integrity": "sha512-Ogm179MCazwIRyEqs3g3EOY4Y3XIAa0yl8J5RE9rJC6QH1w8weVOp2RZu0mvnYy/2xIas1w166YR2eZdDkWQxg==", + "requires": { + "@choojs/findup": "^0.2.0", + "events": "^1.0.2", + "glsl-resolve": "0.0.1", + "glsl-tokenizer": "^2.0.0", + "graceful-fs": "^4.1.2", + "inherits": "^2.0.1", + "map-limit": "0.0.1", + "resolve": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + }, + "incremental-convex-hull": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/incremental-convex-hull/-/incremental-convex-hull-1.0.1.tgz", + "integrity": "sha1-UUKMFMudmmFEv+abKFH7N3M0vh4=", + "dev": true, + "requires": { + "robust-orientation": "^1.1.2", + "simplicial-complex": "^1.0.0" + }, + "dependencies": { + "simplicial-complex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simplicial-complex/-/simplicial-complex-1.0.0.tgz", + "integrity": "sha1-bDOk7Wn81Nkbe8rdOzC2NoPq4kE=", + "dev": true, + "requires": { + "bit-twiddle": "^1.0.0", + "union-find": "^1.0.0" + } + } + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "interval-tree-1d": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/interval-tree-1d/-/interval-tree-1d-1.0.3.tgz", + "integrity": "sha1-j9veArayx9verWNry+2OCHENhcE=", + "requires": { + "binary-search-bounds": "^1.0.0" + }, + "dependencies": { + "binary-search-bounds": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-1.0.0.tgz", + "integrity": "sha1-MjyjF+PypA9CRMclX1OEpbIHu2k=" + } + } + }, + "invert-hash": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/invert-hash/-/invert-hash-0.0.0.tgz", + "integrity": "sha1-dUFZqov5/gi+Hx3KFBeHt6tk+nc=", + "dev": true + }, + "invert-permutation": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-permutation/-/invert-permutation-1.0.0.tgz", + "integrity": "sha1-oKeAQurbNrwXVR54fv0UOa3VSTM=" + }, + "iota-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz", + "integrity": "sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "requires": { + "has-symbols": "^1.0.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isosurface": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isosurface/-/isosurface-1.0.0.tgz", + "integrity": "sha1-fCTax7pv/21ktASNlsFAlYA1Hu0=", + "dev": true + }, + "lerp": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/lerp/-/lerp-1.0.3.tgz", + "integrity": "sha1-oYyJaPkXiW3hXM/MKNVaa3Med24=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "map-limit": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/map-limit/-/map-limit-0.0.1.tgz", + "integrity": "sha1-63lhAxwPDo0AG/LVb6toXViCLzg=", + "requires": { + "once": "~1.3.0" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "requires": { + "wrappy": "1" + } + } + } + }, + "marching-simplex-table": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/marching-simplex-table/-/marching-simplex-table-1.0.0.tgz", + "integrity": "sha1-vBYlbg+Pm1WKqbKHL4gy2UM/Uuo=", + "dev": true, + "requires": { + "convex-hull": "^1.0.3" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "monotone-convex-hull-2d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/monotone-convex-hull-2d/-/monotone-convex-hull-2d-1.0.1.tgz", + "integrity": "sha1-R/Xa6t88Sv03dkuqGqh4ekDu4Iw=", + "dev": true, + "requires": { + "robust-orientation": "^1.1.3" + } + }, + "murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E=" + }, + "ndarray": { + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.18.tgz", + "integrity": "sha1-tg06cyJOxVXQ+qeXEeUCRI/T95M=", + "requires": { + "iota-array": "^1.0.0", + "is-buffer": "^1.0.2" + } + }, + "ndarray-extract-contour": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ndarray-extract-contour/-/ndarray-extract-contour-1.0.1.tgz", + "integrity": "sha1-Cu4ROjozsia5DEiIz4d79HUTBeQ=", + "requires": { + "typedarray-pool": "^1.0.0" + } + }, + "ndarray-ops": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ndarray-ops/-/ndarray-ops-1.2.2.tgz", + "integrity": "sha1-WeiNLDKn7ryxvGkPrhQVeVV6YU4=", + "requires": { + "cwise-compiler": "^1.0.0" + } + }, + "ndarray-sort": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ndarray-sort/-/ndarray-sort-1.0.1.tgz", + "integrity": "sha1-/qBbTLg0x/TgIWo1TzynUTAN/Wo=", + "dev": true, + "requires": { + "typedarray-pool": "^1.0.0" + } + }, + "nextafter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nextafter/-/nextafter-1.0.0.tgz", + "integrity": "sha1-t9d7U1MQ4+CX5gJauwqQNHfsGjo=", + "requires": { + "double-bits": "^1.1.0" + } + }, + "normals": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/normals/-/normals-1.1.0.tgz", + "integrity": "sha1-MltZXtNK/kZ6bFWhT9kIV4f/WcA=", + "dev": true + }, + "numeric": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/numeric/-/numeric-1.2.6.tgz", + "integrity": "sha1-dlsCvvl5iPz4gNTrPza4D6MTNao=", + "dev": true + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "orbit-camera": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/orbit-camera/-/orbit-camera-1.0.0.tgz", + "integrity": "sha1-jaFhWrXB53eiv2W5XlzR9Rfx/DE=", + "dev": true, + "requires": { + "gl-matrix": "^2.2.0" + } + }, + "pad-left": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pad-left/-/pad-left-1.0.2.tgz", + "integrity": "sha1-GeVzXqmDlaJs7carkm6tEPMQDUw=", + "requires": { + "repeat-string": "^1.3.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "permutation-parity": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/permutation-parity/-/permutation-parity-1.0.0.tgz", + "integrity": "sha1-AXTVH8pwSxG5pLFSsj1Tf9xrXvQ=", + "requires": { + "typedarray-pool": "^1.0.0" + } + }, + "permutation-rank": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/permutation-rank/-/permutation-rank-1.0.0.tgz", + "integrity": "sha1-n9mLvOzwj79ZlLXq3JSmLmeUg7U=", + "requires": { + "invert-permutation": "^1.0.0", + "typedarray-pool": "^1.0.0" + } + }, + "planar-dual": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/planar-dual/-/planar-dual-1.0.2.tgz", + "integrity": "sha1-tqQjVSOxsMt55fkm+OozXdmC1WM=", + "requires": { + "compare-angle": "^1.0.0", + "dup": "^1.0.0" + } + }, + "planar-graph-to-polyline": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/planar-graph-to-polyline/-/planar-graph-to-polyline-1.0.5.tgz", + "integrity": "sha1-iCuGBRmbqIv9RkyVUzA1VsUrmIo=", + "requires": { + "edges-to-adjacency-list": "^1.0.0", + "planar-dual": "^1.0.0", + "point-in-big-polygon": "^2.0.0", + "robust-orientation": "^1.0.1", + "robust-sum": "^1.0.0", + "two-product": "^1.0.0", + "uniq": "^1.0.0" + } + }, + "point-in-big-polygon": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/point-in-big-polygon/-/point-in-big-polygon-2.0.0.tgz", + "integrity": "sha1-ObYT6mzxfWtD4Yj3fzTETGszulU=", + "requires": { + "binary-search-bounds": "^1.0.0", + "interval-tree-1d": "^1.0.1", + "robust-orientation": "^1.1.3", + "slab-decomposition": "^1.0.1" + }, + "dependencies": { + "binary-search-bounds": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-1.0.0.tgz", + "integrity": "sha1-MjyjF+PypA9CRMclX1OEpbIHu2k=" + } + } + }, + "polytope-closest-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/polytope-closest-point/-/polytope-closest-point-1.0.0.tgz", + "integrity": "sha1-5uV/QIGrXox3i4Ee8G4sSK4zjD8=", + "dev": true, + "requires": { + "numeric": "^1.2.6" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "rat-vec": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/rat-vec/-/rat-vec-1.1.1.tgz", + "integrity": "sha1-Dd4rZrezS7G80qI4BerIBth/0X8=", + "requires": { + "big-rat": "^1.0.3" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "requires": { + "path-parse": "^1.0.5" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "requires": { + "through": "~2.3.4" + } + }, + "robust-compress": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/robust-compress/-/robust-compress-1.0.0.tgz", + "integrity": "sha1-TPYsSzGNgwhRYBK7jBF1Lzkymxs=", + "dev": true + }, + "robust-determinant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/robust-determinant/-/robust-determinant-1.1.0.tgz", + "integrity": "sha1-jsrnm3nKqz509t6+IjflORon6cc=", + "dev": true, + "requires": { + "robust-compress": "^1.0.0", + "robust-scale": "^1.0.0", + "robust-sum": "^1.0.0", + "two-product": "^1.0.0" + } + }, + "robust-dot-product": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/robust-dot-product/-/robust-dot-product-1.0.0.tgz", + "integrity": "sha1-yboBeL0sMEv9cl9Y6Inx2UYARVM=", + "requires": { + "robust-sum": "^1.0.0", + "two-product": "^1.0.0" + } + }, + "robust-in-sphere": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/robust-in-sphere/-/robust-in-sphere-1.1.3.tgz", + "integrity": "sha1-HFiD0WpOkjkpR27zSBmFe/Kpz3U=", + "requires": { + "robust-scale": "^1.0.0", + "robust-subtract": "^1.0.0", + "robust-sum": "^1.0.0", + "two-product": "^1.0.0" + } + }, + "robust-linear-solve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/robust-linear-solve/-/robust-linear-solve-1.0.0.tgz", + "integrity": "sha1-DNasUEBpGm8qo81jEdcokFyjofE=", + "dev": true, + "requires": { + "robust-determinant": "^1.1.0" + } + }, + "robust-orientation": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/robust-orientation/-/robust-orientation-1.1.3.tgz", + "integrity": "sha1-2v9bANO+TmByLw6cAVbvln8cIEk=", + "requires": { + "robust-scale": "^1.0.2", + "robust-subtract": "^1.0.0", + "robust-sum": "^1.0.0", + "two-product": "^1.0.2" + } + }, + "robust-product": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/robust-product/-/robust-product-1.0.0.tgz", + "integrity": "sha1-aFJQAHzbunzx3nW/9tKScBEJir4=", + "requires": { + "robust-scale": "^1.0.0", + "robust-sum": "^1.0.0" + } + }, + "robust-scale": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/robust-scale/-/robust-scale-1.0.2.tgz", + "integrity": "sha1-d1Ey7QlULQKOWLLMecBikLz3jDI=", + "requires": { + "two-product": "^1.0.2", + "two-sum": "^1.0.0" + } + }, + "robust-segment-intersect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/robust-segment-intersect/-/robust-segment-intersect-1.0.1.tgz", + "integrity": "sha1-MlK2oPwboUreaRXMvgnLzpqrHBw=", + "requires": { + "robust-orientation": "^1.1.3" + } + }, + "robust-subtract": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/robust-subtract/-/robust-subtract-1.0.0.tgz", + "integrity": "sha1-4LFk4e2LpOOl3aRaEgODSNvtPpo=" + }, + "robust-sum": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/robust-sum/-/robust-sum-1.0.0.tgz", + "integrity": "sha1-FmRuUlKStNJdgnV6KGlV4Lv6U9k=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "shallow-copy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", + "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=" + }, + "signum": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/signum/-/signum-0.0.0.tgz", + "integrity": "sha1-q1UbEAM1EHCnBHg/GgnF52kfnPY=" + }, + "simplicial-complex": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/simplicial-complex/-/simplicial-complex-0.3.3.tgz", + "integrity": "sha1-TDDK1X+eRXKd2PMGyHU1efRr6Z4=", + "requires": { + "bit-twiddle": "~0.0.1", + "union-find": "~0.0.3" + }, + "dependencies": { + "bit-twiddle": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-0.0.2.tgz", + "integrity": "sha1-wurruVKjuUrMFASX4c3NLxoz9Y4=" + }, + "union-find": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/union-find/-/union-find-0.0.4.tgz", + "integrity": "sha1-uFSzMBYZva0USwAUx4+W6sDS8PY=" + } + } + }, + "simplicial-complex-contour": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/simplicial-complex-contour/-/simplicial-complex-contour-1.0.2.tgz", + "integrity": "sha1-iQqsrChDZTQBEFRc8mKaJuBL+dE=", + "dev": true, + "requires": { + "marching-simplex-table": "^1.0.0", + "ndarray": "^1.0.15", + "ndarray-sort": "^1.0.0", + "typedarray-pool": "^1.1.0" + } + }, + "simplify-planar-graph": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/simplify-planar-graph/-/simplify-planar-graph-2.0.1.tgz", + "integrity": "sha1-vIWJNyXzLo+oriVoE5hEbSy892Y=", + "requires": { + "robust-orientation": "^1.0.1", + "simplicial-complex": "^0.3.3" + } + }, + "slab-decomposition": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/slab-decomposition/-/slab-decomposition-1.0.2.tgz", + "integrity": "sha1-He1WdU1AixBznxRRA9/GGAf2UTQ=", + "requires": { + "binary-search-bounds": "^1.0.0", + "functional-red-black-tree": "^1.0.0", + "robust-orientation": "^1.1.3" + }, + "dependencies": { + "binary-search-bounds": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-1.0.0.tgz", + "integrity": "sha1-MjyjF+PypA9CRMclX1OEpbIHu2k=" + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + }, + "split-polygon": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split-polygon/-/split-polygon-1.0.0.tgz", + "integrity": "sha1-DqzIoTanaxKj2VJW6n2kXbDC0kc=", + "requires": { + "robust-dot-product": "^1.0.0", + "robust-sum": "^1.0.0" + } + }, + "sprintf-js": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz", + "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=" + }, + "stack-trace": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", + "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=" + }, + "static-eval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.0.tgz", + "integrity": "sha512-6flshd3F1Gwm+Ksxq463LtFd1liC77N/PX1FVVc3OzL3hAmo2fwHFbuArkcfi7s9rTNsLEhcRmXGFZhlgy40uw==", + "requires": { + "escodegen": "^1.8.1" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + }, + "string.prototype.trim": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", + "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.0", + "function-bind": "^1.0.2" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "surface-nets": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/surface-nets/-/surface-nets-1.0.2.tgz", + "integrity": "sha1-5DPIy7qUpydMb0yZVStGG/H8eks=", + "requires": { + "ndarray-extract-contour": "^1.0.0", + "triangulate-hypercube": "^1.0.0", + "zero-crossings": "^1.0.0" + } + }, + "tape": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "requires": { + "deep-equal": "~1.0.1", + "defined": "~1.0.0", + "for-each": "~0.3.3", + "function-bind": "~1.1.1", + "glob": "~7.1.2", + "has": "~1.0.3", + "inherits": "~2.0.3", + "minimist": "~1.2.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", + "resumer": "~0.0.0", + "string.prototype.trim": "~1.1.2", + "through": "~2.3.8" + }, + "dependencies": { + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "requires": { + "path-parse": "^1.0.5" + } + } + } + }, + "through": { + "version": "2.3.8", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "triangulate-hypercube": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/triangulate-hypercube/-/triangulate-hypercube-1.0.1.tgz", + "integrity": "sha1-2Acdsuv8/VHzCNC88qXEils20Tc=", + "requires": { + "gamma": "^0.1.0", + "permutation-parity": "^1.0.0", + "permutation-rank": "^1.0.0" + } + }, + "triangulate-polyline": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/triangulate-polyline/-/triangulate-polyline-1.0.3.tgz", + "integrity": "sha1-v4uod6hQVBA/65+lphtOjXAXgU0=", + "requires": { + "cdt2d": "^1.0.0" + } + }, + "two-product": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/two-product/-/two-product-1.0.2.tgz", + "integrity": "sha1-Z9ldSyV6kh4stL16+VEfkIhSLqo=" + }, + "two-sum": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/two-sum/-/two-sum-1.0.0.tgz", + "integrity": "sha1-MdPzIjnk9zHsqd+RVeKyl/AIq2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "typedarray-pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/typedarray-pool/-/typedarray-pool-1.1.0.tgz", + "integrity": "sha1-0RT0hIAUifU+yrXoCIqiMET0mNk=", + "requires": { + "bit-twiddle": "^1.0.0", + "dup": "^1.0.0" + } + }, + "union-find": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/union-find/-/union-find-1.0.2.tgz", + "integrity": "sha1-KSusQV5q06iVNdI3AQ20pTYoTlg=" + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "vectorize-text": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vectorize-text/-/vectorize-text-3.0.2.tgz", + "integrity": "sha1-BasWMOQJ83eWTiuSBbLVWakvYNg=", + "requires": { + "cdt2d": "^1.0.0", + "clean-pslg": "^1.1.0", + "ndarray": "^1.0.11", + "planar-graph-to-polyline": "^1.0.0", + "simplify-planar-graph": "^2.0.1", + "surface-nets": "^1.0.0", + "triangulate-polyline": "^1.0.0" + } + }, + "vkey": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/vkey/-/vkey-0.0.3.tgz", + "integrity": "sha1-Y03XlS6ywRUxvxhZ8ObUGUeAM98=", + "dev": true + }, + "weak-map": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.5.tgz", + "integrity": "sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes=", + "dev": true + }, + "weakmap-shim": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/weakmap-shim/-/weakmap-shim-1.1.1.tgz", + "integrity": "sha1-1lr9eEEJshZuAP9XHDMVDsKkC0k=" + }, + "webglew": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/webglew/-/webglew-1.0.5.tgz", + "integrity": "sha1-Jv/u95cyFLsxucIMWbAxjRbGvbM=", + "dev": true, + "requires": { + "weak-map": "^1.0.5" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "zero-crossings": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/zero-crossings/-/zero-crossings-1.0.1.tgz", + "integrity": "sha1-xWK9MRNkPzRDokXRJAa4i2m5qf8=", + "requires": { + "cwise-compiler": "^1.0.0" + } + } + } +} From 561ea6b2d815c6425dcb5c66079b779467977ea1 Mon Sep 17 00:00:00 2001 From: archmoj Date: Sun, 7 Oct 2018 16:20:30 -0400 Subject: [PATCH 2/9] improved alignments --- axes.js | 12 ++++++------ lib/shaders/textVert.glsl | 40 ++++++++++++++++++++------------------- lib/text.js | 16 +++++----------- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/axes.js b/axes.js index 41984a2..1d6b079 100644 --- a/axes.js +++ b/axes.js @@ -457,8 +457,6 @@ proto.draw = function(params) { projection, this.pixelRatio) - var allDirections = [[1,0,0],[0,1,0],[0,0,1]]; - for(var i=0; i<3; ++i) { var minor = lineOffset[i].primalMinor @@ -473,9 +471,11 @@ proto.draw = function(params) { //Draw tick text if(this.tickEnable[i]) { + var axis = [0,0,0] //Add tick padding for(var j=0; j<3; ++j) { offset[j] += pixelScaleF * minor[j] * this.tickPad[j] / model[5*j] + axis[i] = 1 } //Draw axis @@ -485,7 +485,7 @@ proto.draw = function(params) { this.tickAngle[i], offset, this.tickColor[i], - [0,0,0]) + axis) } //Draw labels @@ -497,9 +497,9 @@ proto.draw = function(params) { } offset[i] += 0.5 * (bounds[0][i] + bounds[1][i]) - var direction = [0,0,0]; + var axis = [0,0,0] if(this.labels[i].length > 4) { // for large label axis enable alignment to axis - direction = allDirections[i]; + axis[i] = 1 } //Draw axis @@ -509,7 +509,7 @@ proto.draw = function(params) { this.labelAngle[i], offset, this.labelColor[i], - direction) + axis) } } diff --git a/lib/shaders/textVert.glsl b/lib/shaders/textVert.glsl index df5c308..64ea182 100644 --- a/lib/shaders/textVert.glsl +++ b/lib/shaders/textVert.glsl @@ -4,7 +4,11 @@ uniform mat4 model, view, projection; uniform vec3 offset, axis; uniform float scale, angle, pixelScale; uniform vec2 resolution; -uniform vec3 direction; + +vec3 project(vec3 p) { + vec4 pp = projection * view * model * vec4(p, 1.0); + return pp.xyz / max(pp.w, 0.0001); +} float PI = 3.141592; @@ -13,21 +17,15 @@ void main() { //Compute world offset float axisDistance = position.z; vec3 dataPosition = axisDistance * axis + offset; - vec4 worldPosition = model * vec4(dataPosition, 1); - - //Compute clip position - vec4 viewPosition = view * worldPosition; - vec4 clipPosition = projection * viewPosition; - clipPosition /= clipPosition.w; float axisAngle = 0.0; - - if ((direction.x != 0.0) || - (direction.y != 0.0) || - (direction.z != 0.0)) { - vec4 endPoint = projection * view * model * vec4( direction, 1.0); - vec4 startPoint = projection * view * model * vec4(-direction, 1.0); + if ((axis.x != 0.0) || + (axis.y != 0.0) || + (axis.z != 0.0)) { + + vec3 endPoint = project(-axis); + vec3 startPoint = project( axis); axisAngle = atan( (endPoint.y - startPoint.y), @@ -38,11 +36,12 @@ void main() { if (axisAngle < 0.0) axisAngle += 2.0 * PI; // logic for horizontal or vertical align - if (axisAngle < 0.35 * PI) axisAngle = 0.0; - else if (axisAngle < 0.65 * PI) axisAngle = 0.5 * PI; - else if (axisAngle < 1.35 * PI) axisAngle = 0.0; - else if (axisAngle < 1.65 * PI) axisAngle = 0.5 * PI; + if (axisAngle < 0.75 * PI) axisAngle = 0.0; + else if (axisAngle < 0.75 * PI) axisAngle = 0.5 * PI; + else if (axisAngle < 1.25 * PI) axisAngle = 0.0; + else if (axisAngle < 1.75 * PI) axisAngle = 0.5 * PI; else axisAngle = 0.0; + } //Compute plane offset @@ -54,9 +53,12 @@ void main() { -sin(totalAngle), cos(totalAngle)); vec2 viewOffset = 2.0 * planeXform * planeCoord / resolution; + //Compute clip position + vec3 clipPosition = project(dataPosition); + //Apply text offset in clip coordinates - clipPosition += vec4(viewOffset, 0, 0); + clipPosition += vec3(viewOffset, 0.0); //Done - gl_Position = clipPosition; + gl_Position = vec4(clipPosition, 1.0); } \ No newline at end of file diff --git a/lib/text.js b/lib/text.js index 190d07d..5d579a6 100644 --- a/lib/text.js +++ b/lib/text.js @@ -122,36 +122,30 @@ proto.update = function(bounds, labels, labelFont, ticks, tickFont) { } //Draws the tick marks for an axis -var AXIS = [0,0,0] -proto.drawTicks = function(d, scale, angle, offset, color, direction) { +proto.drawTicks = function(d, scale, angle, offset, color, axis) { if(!this.tickCount[d]) { return } - var v = AXIS - v[0] = v[1] = v[2] = 0 - v[d] = 1 - this.shader.uniforms.axis = v + this.shader.uniforms.axis = axis this.shader.uniforms.color = color this.shader.uniforms.angle = angle this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset - this.shader.uniforms.direction = direction this.vao.draw(this.gl.TRIANGLES, this.tickCount[d], this.tickOffset[d]) } //Draws the text label for an axis -var ZERO = [0,0,0] -proto.drawLabel = function(d, scale, angle, offset, color, direction) { +proto.drawLabel = function(d, scale, angle, offset, color, axis) { if(!this.labelCount[d]) { return } - this.shader.uniforms.axis = ZERO + + this.shader.uniforms.axis = axis this.shader.uniforms.color = color this.shader.uniforms.angle = angle this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset - this.shader.uniforms.direction = direction this.vao.draw(this.gl.TRIANGLES, this.labelCount[d], this.labelOffset[d]) } From f262c7278b458fffe914f83a0085a63bcb63402a Mon Sep 17 00:00:00 2001 From: archmoj Date: Sun, 7 Oct 2018 23:19:09 -0400 Subject: [PATCH 3/9] apply alignment only for labels, not ticks --- axes.js | 10 ++++++++-- lib/shaders/textVert.glsl | 21 ++++++++++----------- lib/text.js | 6 ++++-- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/axes.js b/axes.js index 1d6b079..7f50f96 100644 --- a/axes.js +++ b/axes.js @@ -477,6 +477,8 @@ proto.draw = function(params) { offset[j] += pixelScaleF * minor[j] * this.tickPad[j] / model[5*j] axis[i] = 1 } + + var alignment = [0,0,0] // i.e. no alignmnet for ticks //Draw axis this._text.drawTicks( @@ -485,7 +487,8 @@ proto.draw = function(params) { this.tickAngle[i], offset, this.tickColor[i], - axis) + axis, + alignment) } //Draw labels @@ -501,6 +504,8 @@ proto.draw = function(params) { if(this.labels[i].length > 4) { // for large label axis enable alignment to axis axis[i] = 1 } + + var alignment = [axis[0], axis[1], axis[2]] // align with axis //Draw axis this._text.drawLabel( @@ -509,7 +514,8 @@ proto.draw = function(params) { this.labelAngle[i], offset, this.labelColor[i], - axis) + axis, + alignment) } } diff --git a/lib/shaders/textVert.glsl b/lib/shaders/textVert.glsl index 64ea182..5568f98 100644 --- a/lib/shaders/textVert.glsl +++ b/lib/shaders/textVert.glsl @@ -1,7 +1,7 @@ attribute vec3 position; uniform mat4 model, view, projection; -uniform vec3 offset, axis; +uniform vec3 offset, axis, alignment; uniform float scale, angle, pixelScale; uniform vec2 resolution; @@ -20,12 +20,12 @@ void main() { float axisAngle = 0.0; - if ((axis.x != 0.0) || - (axis.y != 0.0) || - (axis.z != 0.0)) { + if ((alignment.x != 0.0) || + (alignment.y != 0.0) || + (alignment.z != 0.0)) { - vec3 endPoint = project(-axis); - vec3 startPoint = project( axis); + vec3 endPoint = project(-alignment); + vec3 startPoint = project( alignment); axisAngle = atan( (endPoint.y - startPoint.y), @@ -36,12 +36,11 @@ void main() { if (axisAngle < 0.0) axisAngle += 2.0 * PI; // logic for horizontal or vertical align - if (axisAngle < 0.75 * PI) axisAngle = 0.0; - else if (axisAngle < 0.75 * PI) axisAngle = 0.5 * PI; - else if (axisAngle < 1.25 * PI) axisAngle = 0.0; - else if (axisAngle < 1.75 * PI) axisAngle = 0.5 * PI; + if (axisAngle < 0.33 * PI) axisAngle = 0.0; + else if (axisAngle < 0.66 * PI) axisAngle = 0.5 * PI; + else if (axisAngle < 1.33 * PI) axisAngle = 0.0; + else if (axisAngle < 1.66 * PI) axisAngle = 0.5 * PI; else axisAngle = 0.0; - } //Compute plane offset diff --git a/lib/text.js b/lib/text.js index 5d579a6..4261588 100644 --- a/lib/text.js +++ b/lib/text.js @@ -122,7 +122,7 @@ proto.update = function(bounds, labels, labelFont, ticks, tickFont) { } //Draws the tick marks for an axis -proto.drawTicks = function(d, scale, angle, offset, color, axis) { +proto.drawTicks = function(d, scale, angle, offset, color, axis, alignment) { if(!this.tickCount[d]) { return } @@ -132,11 +132,12 @@ proto.drawTicks = function(d, scale, angle, offset, color, axis) { this.shader.uniforms.angle = angle this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset + this.shader.uniforms.alignment = alignment this.vao.draw(this.gl.TRIANGLES, this.tickCount[d], this.tickOffset[d]) } //Draws the text label for an axis -proto.drawLabel = function(d, scale, angle, offset, color, axis) { +proto.drawLabel = function(d, scale, angle, offset, color, axis, alignment) { if(!this.labelCount[d]) { return } @@ -146,6 +147,7 @@ proto.drawLabel = function(d, scale, angle, offset, color, axis) { this.shader.uniforms.angle = angle this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset + this.shader.uniforms.alignment = alignment this.vao.draw(this.gl.TRIANGLES, this.labelCount[d], this.labelOffset[d]) } From 7cbaf36c3566044b311fd95e8aaa1022769218fc Mon Sep 17 00:00:00 2001 From: archmoj Date: Mon, 8 Oct 2018 00:02:26 -0400 Subject: [PATCH 4/9] center labels --- axes.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/axes.js b/axes.js index 7f50f96..2412afd 100644 --- a/axes.js +++ b/axes.js @@ -471,14 +471,13 @@ proto.draw = function(params) { //Draw tick text if(this.tickEnable[i]) { - var axis = [0,0,0] //Add tick padding for(var j=0; j<3; ++j) { offset[j] += pixelScaleF * minor[j] * this.tickPad[j] / model[5*j] - axis[i] = 1 } - - var alignment = [0,0,0] // i.e. no alignmnet for ticks + + var axis = [0,0,0] + axis[i] = 1 //Draw axis this._text.drawTicks( @@ -487,8 +486,8 @@ proto.draw = function(params) { this.tickAngle[i], offset, this.tickColor[i], - axis, - alignment) + axis, + [0,0,0]) } //Draw labels @@ -500,12 +499,10 @@ proto.draw = function(params) { } offset[i] += 0.5 * (bounds[0][i] + bounds[1][i]) - var axis = [0,0,0] + var alignment = [0,0,0] if(this.labels[i].length > 4) { // for large label axis enable alignment to axis - axis[i] = 1 + alignment[i] = 1 } - - var alignment = [axis[0], axis[1], axis[2]] // align with axis //Draw axis this._text.drawLabel( @@ -514,7 +511,7 @@ proto.draw = function(params) { this.labelAngle[i], offset, this.labelColor[i], - axis, + [0,0,0], alignment) } } From 19ed93f99a4cfff537f03e2aceb46fbfb13569df Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 9 Oct 2018 16:17:43 -0400 Subject: [PATCH 5/9] more and better options for label adjustments --- axes.js | 5 ++- lib/shaders/textVert.glsl | 73 ++++++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/axes.js b/axes.js index 2412afd..e426eb0 100644 --- a/axes.js +++ b/axes.js @@ -503,6 +503,9 @@ proto.draw = function(params) { if(this.labels[i].length > 4) { // for large label axis enable alignment to axis alignment[i] = 1 } + + var axis = [0,0,0] + axis[i] = 1 //Draw axis this._text.drawLabel( @@ -511,7 +514,7 @@ proto.draw = function(params) { this.labelAngle[i], offset, this.labelColor[i], - [0,0,0], + axis, alignment) } } diff --git a/lib/shaders/textVert.glsl b/lib/shaders/textVert.glsl index 5568f98..0400ace 100644 --- a/lib/shaders/textVert.glsl +++ b/lib/shaders/textVert.glsl @@ -10,7 +10,46 @@ vec3 project(vec3 p) { return pp.xyz / max(pp.w, 0.0001); } -float PI = 3.141592; +const float PI = 3.141592; +const float TWO_PI = 2.0 * PI; +const float HALF_PI = 0.5 * PI; +const float ONE_AND_HALF_PI = 1.5 * PI; + +float positive_angle(float a) { + if (a < 0.0) return a + TWO_PI; + return a; +} + +float look_upwards(float a) { + float b = positive_angle(a); + if ((b > HALF_PI) && (b < ONE_AND_HALF_PI)) return b - PI; + return b; +} + +float look_horizontal_or_vertical(float a, float ratio) { + // ratio controls the ratio between being horizontal to (vertical + horizontal) + // if ratio is set to 0.5 then it is 50%, 50%. + // when using a higher ratio e.g. 0.75 the result would + // likely be more horizontal than vertical. + + float b = positive_angle(a); + if (b < ( ratio) * HALF_PI) return 0.0; + else if (b < (2.0 - ratio) * HALF_PI) return -HALF_PI; + else if (b < (2.0 + ratio) * HALF_PI) return 0.0; + else if (b < (4.0 - ratio) * HALF_PI) return HALF_PI; //HALF_PI; + return 0.0; +} + +float roundTo(float a, float b) { + return float(b * floor((a + 0.5 * b) / b)); +} + +float look_round_n_directions(float a, int n) { + float b = positive_angle(a); + float div = TWO_PI / float(n); + float c = roundTo(b, div); + return look_upwards(c); +} void main() { @@ -18,38 +57,40 @@ void main() { float axisDistance = position.z; vec3 dataPosition = axisDistance * axis + offset; - float axisAngle = 0.0; + float clipAngle = 0.0; if ((alignment.x != 0.0) || (alignment.y != 0.0) || (alignment.z != 0.0)) { - vec3 endPoint = project(-alignment); - vec3 startPoint = project( alignment); + vec3 startPoint = project(dataPosition); + vec3 endPoint = project(dataPosition + alignment); - axisAngle = atan( + clipAngle = atan( (endPoint.y - startPoint.y), (endPoint.x - startPoint.x) ); - // force positive angles - if (axisAngle < 0.0) axisAngle += 2.0 * PI; + // option 1: use free angle, but flip when reversed + //clipAngle = look_upwards(clipAngle); - // logic for horizontal or vertical align - if (axisAngle < 0.33 * PI) axisAngle = 0.0; - else if (axisAngle < 0.66 * PI) axisAngle = 0.5 * PI; - else if (axisAngle < 1.33 * PI) axisAngle = 0.0; - else if (axisAngle < 1.66 * PI) axisAngle = 0.5 * PI; - else axisAngle = 0.0; + // option 2: horizontal or vertical + clipAngle = look_horizontal_or_vertical(clipAngle, 0.8); // 0.8 here means: increase the chance of horizontals + + // option 3: round to n directions + //clipAngle = look_round_n_directions(clipAngle, 12); // 12 here means use 8 direction steps } //Compute plane offset vec2 planeCoord = position.xy * pixelScale; - float totalAngle = angle + axisAngle; + float totalAngle = angle + clipAngle; + + mat2 planeXform = scale * mat2( + cos(totalAngle), sin(totalAngle), + -sin(totalAngle), cos(totalAngle) + ); - mat2 planeXform = scale * mat2(cos(totalAngle), sin(totalAngle), - -sin(totalAngle), cos(totalAngle)); vec2 viewOffset = 2.0 * planeXform * planeCoord / resolution; //Compute clip position From d5d195f55489122d32b576e5e8ed118ff6475c10 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 9 Oct 2018 17:41:22 -0400 Subject: [PATCH 6/9] options prototype --- axes.js | 18 +++++++------ lib/shaders/textVert.glsl | 56 ++++++++++++++++++++++++++------------- lib/text.js | 10 ++++--- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/axes.js b/axes.js index e426eb0..affa315 100644 --- a/axes.js +++ b/axes.js @@ -487,6 +487,7 @@ proto.draw = function(params) { offset, this.tickColor[i], axis, + [0,0,0], [0,0,0]) } @@ -499,13 +500,13 @@ proto.draw = function(params) { } offset[i] += 0.5 * (bounds[0][i] + bounds[1][i]) - var alignment = [0,0,0] - if(this.labels[i].length > 4) { // for large label axis enable alignment to axis - alignment[i] = 1 + var alignDir = [0,0,0] + if(this.labels[i].length > 4) { // for large label axis enable alignDir to axis + alignDir[i] = 1 } - - var axis = [0,0,0] - axis[i] = 1 + + var alignPos = [0,0,0] + alignPos[i] = 1 //Draw axis this._text.drawLabel( @@ -514,8 +515,9 @@ proto.draw = function(params) { this.labelAngle[i], offset, this.labelColor[i], - axis, - alignment) + [0,0,0], + alignDir, + alignPos) } } diff --git a/lib/shaders/textVert.glsl b/lib/shaders/textVert.glsl index 0400ace..9ed9587 100644 --- a/lib/shaders/textVert.glsl +++ b/lib/shaders/textVert.glsl @@ -1,7 +1,7 @@ attribute vec3 position; uniform mat4 model, view, projection; -uniform vec3 offset, axis, alignment; +uniform vec3 offset, axis, alignDir, alignPos; uniform float scale, angle, pixelScale; uniform vec2 resolution; @@ -36,7 +36,7 @@ float look_horizontal_or_vertical(float a, float ratio) { if (b < ( ratio) * HALF_PI) return 0.0; else if (b < (2.0 - ratio) * HALF_PI) return -HALF_PI; else if (b < (2.0 + ratio) * HALF_PI) return 0.0; - else if (b < (4.0 - ratio) * HALF_PI) return HALF_PI; //HALF_PI; + else if (b < (4.0 - ratio) * HALF_PI) return HALF_PI; return 0.0; } @@ -51,6 +51,28 @@ float look_round_n_directions(float a, int n) { return look_upwards(c); } +int alignOpt = 2; // from {-1, 0, 1, 2, 3, ..., n} + +float applyAlignOption(float rawAngle) { + + if (alignOpt == -1) { + // useful for backward compatibility, all texts remains horizontal + return 0.0; + } else if (alignOpt == 0) { + // use the raw angle as calculated by atan + return rawAngle; + } else if (alignOpt == 1) { + // option 1: use free angle, but flip when reversed + return look_upwards(rawAngle); + } else if (alignOpt == 2) { + // option 2: horizontal or vertical + return look_horizontal_or_vertical(rawAngle, 0.8); // 0.8 here means: increase the chance of getting horizontal labels + } + + // option 3-n: round to n directions + return look_round_n_directions(rawAngle, alignOpt); +} + void main() { //Compute world offset @@ -59,28 +81,24 @@ void main() { float clipAngle = 0.0; - if ((alignment.x != 0.0) || - (alignment.y != 0.0) || - (alignment.z != 0.0)) { + if ((alignDir.x != 0.0) || + (alignDir.y != 0.0) || + (alignDir.z != 0.0)) { - vec3 startPoint = project(dataPosition); - vec3 endPoint = project(dataPosition + alignment); + vec3 REF = alignPos + offset; - clipAngle = atan( - (endPoint.y - startPoint.y), - (endPoint.x - startPoint.x) - ); - - // option 1: use free angle, but flip when reversed - //clipAngle = look_upwards(clipAngle); + vec3 startPoint = project(REF); + vec3 endPoint = project(REF + alignDir); - // option 2: horizontal or vertical - clipAngle = look_horizontal_or_vertical(clipAngle, 0.8); // 0.8 here means: increase the chance of horizontals - - // option 3: round to n directions - //clipAngle = look_round_n_directions(clipAngle, 12); // 12 here means use 8 direction steps + clipAngle = applyAlignOption( + atan( + (endPoint.y - startPoint.y), + (endPoint.x - startPoint.x) + ) + ); } + //Compute plane offset vec2 planeCoord = position.xy * pixelScale; diff --git a/lib/text.js b/lib/text.js index 4261588..375bfc0 100644 --- a/lib/text.js +++ b/lib/text.js @@ -122,7 +122,7 @@ proto.update = function(bounds, labels, labelFont, ticks, tickFont) { } //Draws the tick marks for an axis -proto.drawTicks = function(d, scale, angle, offset, color, axis, alignment) { +proto.drawTicks = function(d, scale, angle, offset, color, axis, alignDir, alignPos) { if(!this.tickCount[d]) { return } @@ -132,12 +132,13 @@ proto.drawTicks = function(d, scale, angle, offset, color, axis, alignment) { this.shader.uniforms.angle = angle this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset - this.shader.uniforms.alignment = alignment + this.shader.uniforms.alignDir = alignDir + this.shader.uniforms.alignPos = alignPos this.vao.draw(this.gl.TRIANGLES, this.tickCount[d], this.tickOffset[d]) } //Draws the text label for an axis -proto.drawLabel = function(d, scale, angle, offset, color, axis, alignment) { +proto.drawLabel = function(d, scale, angle, offset, color, axis, alignDir, alignPos) { if(!this.labelCount[d]) { return } @@ -147,7 +148,8 @@ proto.drawLabel = function(d, scale, angle, offset, color, axis, alignment) { this.shader.uniforms.angle = angle this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset - this.shader.uniforms.alignment = alignment + this.shader.uniforms.alignDir = alignDir + this.shader.uniforms.alignPos = alignPos this.vao.draw(this.gl.TRIANGLES, this.labelCount[d], this.labelOffset[d]) } From af91f665906562a8034f5ee3a543b07b87d2e60d Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 9 Oct 2018 18:58:15 -0400 Subject: [PATCH 7/9] free rotation --- lib/shaders/textVert.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/shaders/textVert.glsl b/lib/shaders/textVert.glsl index 9ed9587..0e1c917 100644 --- a/lib/shaders/textVert.glsl +++ b/lib/shaders/textVert.glsl @@ -51,7 +51,7 @@ float look_round_n_directions(float a, int n) { return look_upwards(c); } -int alignOpt = 2; // from {-1, 0, 1, 2, 3, ..., n} +int alignOpt = 1; // from {-1, 0, 1, 2, 3, ..., n} float applyAlignOption(float rawAngle) { From 8c696e5c5d51a17030662266f4d236326f5d67ed Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 9 Oct 2018 22:45:40 -0400 Subject: [PATCH 8/9] apply text options --- axes.js | 21 +++++++++++++++------ lib/shaders/textVert.glsl | 22 ++++++++++------------ lib/text.js | 6 ++++-- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/axes.js b/axes.js index affa315..1db2eea 100644 --- a/axes.js +++ b/axes.js @@ -457,6 +457,10 @@ proto.draw = function(params) { projection, this.pixelRatio) + var alignOpt = [0,0,1] + // Note: the 3rd member is the integer option + // from {-1, 0, 1, 2, 3, ..., n} + for(var i=0; i<3; ++i) { var minor = lineOffset[i].primalMinor @@ -468,6 +472,12 @@ proto.draw = function(params) { } } + var axis = [0,0,0] + axis[i] = 1 + + var alignDir = [0,0,0] + alignDir[i] = 1 + //Draw tick text if(this.tickEnable[i]) { @@ -476,19 +486,17 @@ proto.draw = function(params) { offset[j] += pixelScaleF * minor[j] * this.tickPad[j] / model[5*j] } - var axis = [0,0,0] - axis[i] = 1 - //Draw axis this._text.drawTicks( i, this.tickSize[i], - this.tickAngle[i], + this.tickAngle[i] + 0.5 * Math.PI, offset, this.tickColor[i], axis, + alignDir, [0,0,0], - [0,0,0]) + alignOpt) } //Draw labels @@ -517,7 +525,8 @@ proto.draw = function(params) { this.labelColor[i], [0,0,0], alignDir, - alignPos) + alignPos, + alignOpt) } } diff --git a/lib/shaders/textVert.glsl b/lib/shaders/textVert.glsl index 0e1c917..0e7814d 100644 --- a/lib/shaders/textVert.glsl +++ b/lib/shaders/textVert.glsl @@ -1,7 +1,7 @@ attribute vec3 position; uniform mat4 model, view, projection; -uniform vec3 offset, axis, alignDir, alignPos; +uniform vec3 offset, axis, alignDir, alignPos, alignOpt; uniform float scale, angle, pixelScale; uniform vec2 resolution; @@ -51,26 +51,26 @@ float look_round_n_directions(float a, int n) { return look_upwards(c); } -int alignOpt = 1; // from {-1, 0, 1, 2, 3, ..., n} +int option = int(floor(alignOpt.z + 0.001)); float applyAlignOption(float rawAngle) { - if (alignOpt == -1) { + if (option == -1) { // useful for backward compatibility, all texts remains horizontal return 0.0; - } else if (alignOpt == 0) { + } else if (option == 0) { // use the raw angle as calculated by atan return rawAngle; - } else if (alignOpt == 1) { + } else if (option == 1) { // option 1: use free angle, but flip when reversed return look_upwards(rawAngle); - } else if (alignOpt == 2) { + } else if (option == 2) { // option 2: horizontal or vertical return look_horizontal_or_vertical(rawAngle, 0.8); // 0.8 here means: increase the chance of getting horizontal labels } // option 3-n: round to n directions - return look_round_n_directions(rawAngle, alignOpt); + return look_round_n_directions(rawAngle, option); } void main() { @@ -91,6 +91,7 @@ void main() { vec3 endPoint = project(REF + alignDir); clipAngle = applyAlignOption( + angle + // user defined attribute atan( (endPoint.y - startPoint.y), (endPoint.x - startPoint.x) @@ -98,15 +99,12 @@ void main() { ); } - //Compute plane offset vec2 planeCoord = position.xy * pixelScale; - float totalAngle = angle + clipAngle; - mat2 planeXform = scale * mat2( - cos(totalAngle), sin(totalAngle), - -sin(totalAngle), cos(totalAngle) + cos(clipAngle), sin(clipAngle), + -sin(clipAngle), cos(clipAngle) ); vec2 viewOffset = 2.0 * planeXform * planeCoord / resolution; diff --git a/lib/text.js b/lib/text.js index 375bfc0..965e2ed 100644 --- a/lib/text.js +++ b/lib/text.js @@ -122,7 +122,7 @@ proto.update = function(bounds, labels, labelFont, ticks, tickFont) { } //Draws the tick marks for an axis -proto.drawTicks = function(d, scale, angle, offset, color, axis, alignDir, alignPos) { +proto.drawTicks = function(d, scale, angle, offset, color, axis, alignDir, alignPos, alignOpt) { if(!this.tickCount[d]) { return } @@ -134,11 +134,12 @@ proto.drawTicks = function(d, scale, angle, offset, color, axis, alignDir, align this.shader.uniforms.offset = offset this.shader.uniforms.alignDir = alignDir this.shader.uniforms.alignPos = alignPos + this.shader.uniforms.alignOpt = alignOpt this.vao.draw(this.gl.TRIANGLES, this.tickCount[d], this.tickOffset[d]) } //Draws the text label for an axis -proto.drawLabel = function(d, scale, angle, offset, color, axis, alignDir, alignPos) { +proto.drawLabel = function(d, scale, angle, offset, color, axis, alignDir, alignPos, alignOpt) { if(!this.labelCount[d]) { return } @@ -150,6 +151,7 @@ proto.drawLabel = function(d, scale, angle, offset, color, axis, alignDir, align this.shader.uniforms.offset = offset this.shader.uniforms.alignDir = alignDir this.shader.uniforms.alignPos = alignPos + this.shader.uniforms.alignOpt = alignOpt this.vao.draw(this.gl.TRIANGLES, this.labelCount[d], this.labelOffset[d]) } From 16330881d570aa93c3b1e648a41fa94c8ce620ff Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 10 Oct 2018 13:33:37 -0400 Subject: [PATCH 9/9] fixed rotation angles --- axes.js | 5 ----- lib/shaders/textVert.glsl | 10 +++++----- lib/text.js | 6 ++---- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/axes.js b/axes.js index 1db2eea..fa5914f 100644 --- a/axes.js +++ b/axes.js @@ -495,7 +495,6 @@ proto.draw = function(params) { this.tickColor[i], axis, alignDir, - [0,0,0], alignOpt) } @@ -513,9 +512,6 @@ proto.draw = function(params) { alignDir[i] = 1 } - var alignPos = [0,0,0] - alignPos[i] = 1 - //Draw axis this._text.drawLabel( i, @@ -525,7 +521,6 @@ proto.draw = function(params) { this.labelColor[i], [0,0,0], alignDir, - alignPos, alignOpt) } } diff --git a/lib/shaders/textVert.glsl b/lib/shaders/textVert.glsl index 0e7814d..5bf1be7 100644 --- a/lib/shaders/textVert.glsl +++ b/lib/shaders/textVert.glsl @@ -1,7 +1,7 @@ attribute vec3 position; uniform mat4 model, view, projection; -uniform vec3 offset, axis, alignDir, alignPos, alignOpt; +uniform vec3 offset, axis, alignDir, alignOpt; uniform float scale, angle, pixelScale; uniform vec2 resolution; @@ -85,16 +85,16 @@ void main() { (alignDir.y != 0.0) || (alignDir.z != 0.0)) { - vec3 REF = alignPos + offset; + vec3 REF = dataPosition; vec3 startPoint = project(REF); vec3 endPoint = project(REF + alignDir); clipAngle = applyAlignOption( - angle + // user defined attribute + angle + // i.e. user defined attributes for each tick atan( - (endPoint.y - startPoint.y), - (endPoint.x - startPoint.x) + (endPoint.y - startPoint.y) * resolution.y, + (endPoint.x - startPoint.x) * resolution.x ) ); } diff --git a/lib/text.js b/lib/text.js index 965e2ed..e0059eb 100644 --- a/lib/text.js +++ b/lib/text.js @@ -122,7 +122,7 @@ proto.update = function(bounds, labels, labelFont, ticks, tickFont) { } //Draws the tick marks for an axis -proto.drawTicks = function(d, scale, angle, offset, color, axis, alignDir, alignPos, alignOpt) { +proto.drawTicks = function(d, scale, angle, offset, color, axis, alignDir, alignOpt) { if(!this.tickCount[d]) { return } @@ -133,13 +133,12 @@ proto.drawTicks = function(d, scale, angle, offset, color, axis, alignDir, align this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset this.shader.uniforms.alignDir = alignDir - this.shader.uniforms.alignPos = alignPos this.shader.uniforms.alignOpt = alignOpt this.vao.draw(this.gl.TRIANGLES, this.tickCount[d], this.tickOffset[d]) } //Draws the text label for an axis -proto.drawLabel = function(d, scale, angle, offset, color, axis, alignDir, alignPos, alignOpt) { +proto.drawLabel = function(d, scale, angle, offset, color, axis, alignDir, alignOpt) { if(!this.labelCount[d]) { return } @@ -150,7 +149,6 @@ proto.drawLabel = function(d, scale, angle, offset, color, axis, alignDir, align this.shader.uniforms.scale = scale this.shader.uniforms.offset = offset this.shader.uniforms.alignDir = alignDir - this.shader.uniforms.alignPos = alignPos this.shader.uniforms.alignOpt = alignOpt this.vao.draw(this.gl.TRIANGLES, this.labelCount[d], this.labelOffset[d]) }