diff --git a/demo2/cover.fs.glsl b/demo2/cover.fs.glsl index 0deaafdc..e2c851bc 100644 --- a/demo2/cover.fs.glsl +++ b/demo2/cover.fs.glsl @@ -15,11 +15,12 @@ precision highp float; uniform sampler2D uStencilTexture; in vec2 vTexCoord; +in float vBackdrop; in vec4 vColor; out vec4 oFragColor; void main() { - float coverage = abs(texture(uStencilTexture, vTexCoord).r); + float coverage = abs(texture(uStencilTexture, vTexCoord).r + vBackdrop); oFragColor = vec4(vColor.rgb, vColor.a * coverage); } diff --git a/demo2/cover.vs.glsl b/demo2/cover.vs.glsl index 49722b0f..dafad025 100644 --- a/demo2/cover.vs.glsl +++ b/demo2/cover.vs.glsl @@ -18,10 +18,12 @@ uniform vec2 uStencilTextureSize; in vec2 aTessCoord; in vec2 aTileOrigin; +in float aBackdrop; in uint aTileIndex; in vec4 aColor; out vec2 vTexCoord; +out float vBackdrop; out vec4 vColor; vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { @@ -34,6 +36,7 @@ void main() { vec2 position = aTileOrigin + uTileSize * aTessCoord; vec2 texCoord = computeTileOffset(aTileIndex, uStencilTextureSize.x) + aTessCoord * uTileSize; vTexCoord = texCoord / uStencilTextureSize; + vBackdrop = aBackdrop; vColor = aColor; gl_Position = vec4((position / uFramebufferSize * 2.0 - 1.0) * vec2(1.0, -1.0), 0.0, 1.0); } diff --git a/demo2/index.html b/demo2/index.html index 5510ca0c..78fa63d6 100644 --- a/demo2/index.html +++ b/demo2/index.html @@ -5,10 +5,13 @@ Pathfinder Demo - + + diff --git a/demo2/package-lock.json b/demo2/package-lock.json index f3548852..641d2bf7 100644 --- a/demo2/package-lock.json +++ b/demo2/package-lock.json @@ -39,16 +39,234 @@ "resolved": "https://registry.npmjs.org/@types/webgl2/-/webgl2-0.0.4.tgz", "integrity": "sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw==" }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "bezier-js": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/bezier-js/-/bezier-js-2.3.1.tgz", "integrity": "sha512-nFpFL9tuayvlHfWh6xM7OHeTZvwr74+6KnzO3eNZMt0BC0cqb9lCTc9C8OVzrHBvbrNwriTw7XaF2SBsWQJLZA==" }, + "binary-extensions": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", + "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "dev": true + }, + "bootstrap": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.3.tgz", + "integrity": "sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w==" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, "color-convert": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", @@ -60,18 +278,801 @@ "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", "dev": true }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, "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=", "dev": true }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, "events": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", "dev": true }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "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" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "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" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true + } + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, "glsl-inject-defines": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/glsl-inject-defines/-/glsl-inject-defines-1.0.3.tgz", @@ -218,18 +1219,198 @@ "resolved": "https://registry.npmjs.org/graham_scan/-/graham_scan-1.0.4.tgz", "integrity": "sha1-OZZR3R+DU+GID1nqjl+Uud9Mkoo=" }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, "makerjs": { "version": "0.9.93", "resolved": "https://registry.npmjs.org/makerjs/-/makerjs-0.9.93.tgz", @@ -244,6 +1425,12 @@ "graham_scan": "^1.0.4" } }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, "map-limit": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/map-limit/-/map-limit-0.0.1.tgz", @@ -253,12 +1440,153 @@ "once": "~1.3.0" } }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, "murmurhash-js": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", "integrity": "sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E=", "dev": true }, + "nan": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.0.tgz", + "integrity": "sha512-zT5nC0JhbljmyEf+Z456nvm7iO7XgRV2hYxoBtPpnyp+0Q4aCoP6uWNn76v/I6k2kCYNLWqWbwBWQcjsNI/bjw==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, "once": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", @@ -276,12 +1604,42 @@ "color-convert": "~0.5.0" } }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, "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==", "dev": true }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "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==", + "dev": true + }, "readable-stream": { "version": "1.0.34", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", @@ -294,6 +1652,77 @@ "string_decoder": "~0.10.x" } }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "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==", + "dev": true, + "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": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -303,12 +1732,233 @@ "path-parse": "^1.0.5" } }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "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==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "sass": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.15.2.tgz", + "integrity": "sha512-YFncPpx3ewKEhMg9sWdCxKUpPN/jwVLa0Q9iO2tcV5Y5Z/YAlFV6k6JaQwq3tmbN6FXKjUYElXRHcG0g4D1zkQ==", + "dev": true, + "requires": { + "chokidar": "^2.0.0" + } + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "shallow-copy": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=", "dev": true }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -346,12 +1996,159 @@ } } }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, "typescript": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz", "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==", "dev": true }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/demo2/package.json b/demo2/package.json index 3147a42f..429ec9c8 100644 --- a/demo2/package.json +++ b/demo2/package.json @@ -2,10 +2,12 @@ "devDependencies": { "glslify-bundle": "^5.1.1", "glslify-deps": "^1.3.1", + "sass": "^1.15.2", "typescript": "^3.1.6" }, "dependencies": { "@types/webgl2": "0.0.4", + "bootstrap": "^4.1.3", "parse-color": "^1.0.0", "svg-path-outline": "^1.0.1", "svgpath": "^2.2.1" diff --git a/demo2/pathfinder.css b/demo2/pathfinder.css deleted file mode 100644 index dd246c89..00000000 --- a/demo2/pathfinder.css +++ /dev/null @@ -1,11 +0,0 @@ -html, body { - background: #e0e0e0; - margin: 0; - /*overflow: hidden;*/ -} - -.tile { - position: absolute; - top: 0; - left: 0; -} diff --git a/demo2/pathfinder.scss b/demo2/pathfinder.scss new file mode 100644 index 00000000..db8f3a61 --- /dev/null +++ b/demo2/pathfinder.scss @@ -0,0 +1,13 @@ +@import "./node_modules/bootstrap/scss/bootstrap.scss"; + +html, body { + height: 100%; + width: 100%; +} + +#open-wrapper { + display: block; + position: absolute; + right: 0; + bottom: 0; +} diff --git a/demo2/pathfinder.ts b/demo2/pathfinder.ts index 3ebde976..e616b338 100644 --- a/demo2/pathfinder.ts +++ b/demo2/pathfinder.ts @@ -14,17 +14,12 @@ import OPAQUE_VERTEX_SHADER_SOURCE from "./opaque.vs.glsl"; import OPAQUE_FRAGMENT_SHADER_SOURCE from "./opaque.fs.glsl"; import STENCIL_VERTEX_SHADER_SOURCE from "./stencil.vs.glsl"; import STENCIL_FRAGMENT_SHADER_SOURCE from "./stencil.fs.glsl"; -import SVG from "../resources/svg/Ghostscript_Tiger.svg"; import AREA_LUT from "../resources/textures/area-lut.png"; -import {Matrix2D, Point2D, Rect, Size2D, Vector3D, approxEq, cross, lerp} from "./geometry"; -import {flattenPath, Outline, makePathMonotonic} from "./path-utils"; -import {SVGPath, TILE_SIZE, TileDebugger, Tiler, testIntervals, TileStrip} from "./tiling"; +import {Matrix2D, Size2D} from "./geometry"; +import {SVGPath, TILE_SIZE} from "./tiling"; import {staticCast, unwrapNull} from "./util"; const SVGPath: (path: string) => SVGPath = require('svgpath'); -const parseColor: (color: string) => any = require('parse-color'); - -const SVG_NS: string = "http://www.w3.org/2000/svg"; const STENCIL_FRAMEBUFFER_SIZE: Size2D = { width: TILE_SIZE.width * 128, @@ -38,7 +33,8 @@ const QUAD_VERTEX_POSITIONS: Uint8Array = new Uint8Array([ 0, 1, ]); -const GLOBAL_TRANSFORM: Matrix2D = new Matrix2D(3.0, 0.0, 0.0, 3.0, 800.0, 550.0); +const FILL_INSTANCE_SIZE: number = 20; +const TILE_INSTANCE_SIZE: number = 16; interface Color { r: number; @@ -51,7 +47,7 @@ type Edge = 'left' | 'top' | 'right' | 'bottom'; class App { private canvas: HTMLCanvasElement; - private svg: XMLDocument; + private openButton: HTMLInputElement; private areaLUT: HTMLImageElement; private gl: WebGL2RenderingContext; @@ -59,33 +55,37 @@ class App { private areaLUTTexture: WebGLTexture; private stencilTexture: WebGLTexture; private stencilFramebuffer: WebGLFramebuffer; - private stencilProgram: Program<'FramebufferSize' | 'TileSize' | 'AreaLUT', - 'TessCoord' | 'From' | 'Ctrl' | 'To' | 'TileIndex'>; - private opaqueProgram: Program<'FramebufferSize' | 'TileSize', + private fillProgram: Program<'FramebufferSize' | 'TileSize' | 'AreaLUT', + 'TessCoord' | 'From' | 'To' | 'TileIndex'>; + private solidTileProgram: Program<'FramebufferSize' | 'TileSize', 'TessCoord' | 'TileOrigin' | 'Color'>; - private coverProgram: + private maskTileProgram: Program<'FramebufferSize' | 'TileSize' | 'StencilTexture' | 'StencilTextureSize', - 'TessCoord' | 'TileOrigin' | 'TileIndex' | 'Color'>; + 'TessCoord' | 'TileOrigin' | 'TileIndex' | 'Backdrop' | 'Color'>; private quadVertexBuffer: WebGLBuffer; - private stencilVertexPositionsBuffer: WebGLBuffer; - private stencilVertexTileIndicesBuffer: WebGLBuffer; - private stencilVertexArray: WebGLVertexArrayObject; - private opaqueVertexBuffer: WebGLBuffer; - private opaqueVertexArray: WebGLVertexArrayObject; - private coverVertexBuffer: WebGLBuffer; - private coverVertexArray: WebGLVertexArrayObject; + private fillVertexBuffer: WebGLBuffer; + private fillVertexArray: WebGLVertexArrayObject; + private tileVertexBuffer: WebGLBuffer; + private instanceIDVertexBuffer: WebGLBuffer; + private solidIndexBuffer: WebGLBuffer; + private solidVertexArray: WebGLVertexArrayObject; + private maskIndexBuffer: WebGLBuffer; + private maskVertexArray: WebGLVertexArrayObject; - private scene: Scene | null; - private primitiveCount: number; - private tileCount: number; - private opaqueTileCount: number; + private fillPrimitiveCount: number; + private totalTileCount: number; + private solidTileCount: number; + private maskTileCount: number; - constructor(svg: XMLDocument, areaLUT: HTMLImageElement) { + constructor(areaLUT: HTMLImageElement) { const canvas = staticCast(document.getElementById('canvas'), HTMLCanvasElement); + const openButton = staticCast(document.getElementById('open'), HTMLInputElement); this.canvas = canvas; - this.svg = svg; + this.openButton = openButton; this.areaLUT = areaLUT; + this.openButton.addEventListener('change', event => this.loadFile(), false); + const devicePixelRatio = window.devicePixelRatio; canvas.width = window.innerWidth * devicePixelRatio; canvas.height = window.innerHeight * devicePixelRatio; @@ -131,7 +131,7 @@ class App { if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) throw new Error("Stencil framebuffer incomplete!"); - const coverProgram = new Program(gl, + const maskTileProgram = new Program(gl, COVER_VERTEX_SHADER_SOURCE, COVER_FRAGMENT_SHADER_SOURCE, [ @@ -140,123 +140,162 @@ class App { 'StencilTexture', 'StencilTextureSize' ], - ['TessCoord', 'TileOrigin', 'TileIndex', 'Color']); - this.coverProgram = coverProgram; + [ + 'TessCoord', + 'TileOrigin', + 'TileIndex', + 'Backdrop', + 'Color', + ]); + this.maskTileProgram = maskTileProgram; - const opaqueProgram = new Program(gl, - OPAQUE_VERTEX_SHADER_SOURCE, - OPAQUE_FRAGMENT_SHADER_SOURCE, - ['FramebufferSize', 'TileSize'], - ['TessCoord', 'TileOrigin', 'Color']); - this.opaqueProgram = opaqueProgram; + const solidTileProgram = new Program(gl, + OPAQUE_VERTEX_SHADER_SOURCE, + OPAQUE_FRAGMENT_SHADER_SOURCE, + ['FramebufferSize', 'TileSize'], + ['TessCoord', 'TileOrigin', 'Color']); + this.solidTileProgram = solidTileProgram; - const stencilProgram = new Program(gl, + const fillProgram = new Program(gl, STENCIL_VERTEX_SHADER_SOURCE, STENCIL_FRAGMENT_SHADER_SOURCE, ['FramebufferSize', 'TileSize', 'AreaLUT'], - ['TessCoord', 'From', 'Ctrl', 'To', 'TileIndex']); - this.stencilProgram = stencilProgram; + ['TessCoord', 'From', 'To', 'TileIndex']); + this.fillProgram = fillProgram; // Initialize quad VBO. this.quadVertexBuffer = unwrapNull(gl.createBuffer()); gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, QUAD_VERTEX_POSITIONS, gl.STATIC_DRAW); - // Initialize stencil VBOs. - this.stencilVertexPositionsBuffer = unwrapNull(gl.createBuffer()); - this.stencilVertexTileIndicesBuffer = unwrapNull(gl.createBuffer()); + // Initialize fill VBOs. + this.fillVertexBuffer = unwrapNull(gl.createBuffer()); - // Initialize stencil VAO. - this.stencilVertexArray = unwrapNull(gl.createVertexArray()); - gl.bindVertexArray(this.stencilVertexArray); - gl.useProgram(this.stencilProgram.program); + // Initialize fill VAO. + this.fillVertexArray = unwrapNull(gl.createVertexArray()); + gl.bindVertexArray(this.fillVertexArray); + gl.useProgram(this.fillProgram.program); gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer); - gl.vertexAttribPointer(stencilProgram.attributes.TessCoord, + gl.vertexAttribPointer(fillProgram.attributes.TessCoord, 2, gl.UNSIGNED_BYTE, false, 0, 0); - gl.bindBuffer(gl.ARRAY_BUFFER, this.stencilVertexPositionsBuffer); - gl.vertexAttribPointer(stencilProgram.attributes.From, 2, gl.FLOAT, false, 24, 0); - gl.vertexAttribDivisor(stencilProgram.attributes.From, 1); - gl.vertexAttribPointer(stencilProgram.attributes.Ctrl, 2, gl.FLOAT, false, 24, 8); - gl.vertexAttribDivisor(stencilProgram.attributes.Ctrl, 1); - gl.vertexAttribPointer(stencilProgram.attributes.To, 2, gl.FLOAT, false, 24, 16); - gl.vertexAttribDivisor(stencilProgram.attributes.To, 1); - gl.bindBuffer(gl.ARRAY_BUFFER, this.stencilVertexTileIndicesBuffer); - gl.vertexAttribIPointer(stencilProgram.attributes.TileIndex, + gl.bindBuffer(gl.ARRAY_BUFFER, this.fillVertexBuffer); + gl.vertexAttribPointer(fillProgram.attributes.From, + 2, + gl.FLOAT, + false, + FILL_INSTANCE_SIZE, + 0); + gl.vertexAttribDivisor(fillProgram.attributes.From, 1); + gl.vertexAttribPointer(fillProgram.attributes.To, + 2, + gl.FLOAT, + false, + FILL_INSTANCE_SIZE, + 8); + gl.vertexAttribDivisor(fillProgram.attributes.To, 1); + gl.vertexAttribIPointer(fillProgram.attributes.TileIndex, 1, - gl.UNSIGNED_SHORT, - 0, - 0); - gl.vertexAttribDivisor(stencilProgram.attributes.TileIndex, 1); - gl.enableVertexAttribArray(stencilProgram.attributes.TessCoord); - gl.enableVertexAttribArray(stencilProgram.attributes.From); - gl.enableVertexAttribArray(stencilProgram.attributes.Ctrl); - gl.enableVertexAttribArray(stencilProgram.attributes.To); - gl.enableVertexAttribArray(stencilProgram.attributes.TileIndex); + gl.UNSIGNED_INT, + FILL_INSTANCE_SIZE, + 16); + gl.vertexAttribDivisor(fillProgram.attributes.TileIndex, 1); + gl.enableVertexAttribArray(fillProgram.attributes.TessCoord); + gl.enableVertexAttribArray(fillProgram.attributes.From); + gl.enableVertexAttribArray(fillProgram.attributes.To); + gl.enableVertexAttribArray(fillProgram.attributes.TileIndex); - // Initialize opaque VBO. - this.opaqueVertexBuffer = unwrapNull(gl.createBuffer()); + // Initialize tile VBOs and IBOs. + this.tileVertexBuffer = unwrapNull(gl.createBuffer()); + this.instanceIDVertexBuffer = unwrapNull(gl.createBuffer()); + this.solidIndexBuffer = unwrapNull(gl.createBuffer()); + this.maskIndexBuffer = unwrapNull(gl.createBuffer()); - // Initialize opaque VAO. - this.opaqueVertexArray = unwrapNull(gl.createVertexArray()); - gl.bindVertexArray(this.opaqueVertexArray); - gl.useProgram(this.opaqueProgram.program); + // Initialize solid tile VAO. + this.solidVertexArray = unwrapNull(gl.createVertexArray()); + gl.bindVertexArray(this.solidVertexArray); + gl.useProgram(this.solidTileProgram.program); gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer); - gl.vertexAttribPointer(opaqueProgram.attributes.TessCoord, + gl.vertexAttribPointer(solidTileProgram.attributes.TessCoord, 2, gl.UNSIGNED_BYTE, false, 0, 0); - gl.bindBuffer(gl.ARRAY_BUFFER, this.opaqueVertexBuffer); - gl.vertexAttribPointer(opaqueProgram.attributes.TileOrigin, 2, gl.SHORT, false, 10, 0); - gl.vertexAttribDivisor(opaqueProgram.attributes.TileOrigin, 1); - gl.vertexAttribPointer(opaqueProgram.attributes.Color, 4, gl.UNSIGNED_BYTE, true, 10, 6); - gl.vertexAttribDivisor(opaqueProgram.attributes.Color, 1); - gl.enableVertexAttribArray(opaqueProgram.attributes.TessCoord); - gl.enableVertexAttribArray(opaqueProgram.attributes.TileOrigin); - gl.enableVertexAttribArray(opaqueProgram.attributes.Color); + gl.bindBuffer(gl.ARRAY_BUFFER, this.tileVertexBuffer); + gl.vertexAttribPointer(solidTileProgram.attributes.TileOrigin, + 2, + gl.FLOAT, + false, + TILE_INSTANCE_SIZE, + 0); + gl.vertexAttribDivisor(solidTileProgram.attributes.TileOrigin, 1); + gl.vertexAttribPointer(solidTileProgram.attributes.Color, + 4, + gl.UNSIGNED_BYTE, + true, + TILE_INSTANCE_SIZE, + 12); + gl.vertexAttribDivisor(solidTileProgram.attributes.Color, 1); + gl.enableVertexAttribArray(solidTileProgram.attributes.TessCoord); + gl.enableVertexAttribArray(solidTileProgram.attributes.TileOrigin); + gl.enableVertexAttribArray(solidTileProgram.attributes.Color); - // Initialize cover VBO. - this.coverVertexBuffer = unwrapNull(gl.createBuffer()); - - // Initialize cover VAO. - this.coverVertexArray = unwrapNull(gl.createVertexArray()); - gl.bindVertexArray(this.coverVertexArray); - gl.useProgram(this.coverProgram.program); + // Initialize mask tile VAO. + this.maskVertexArray = unwrapNull(gl.createVertexArray()); + gl.bindVertexArray(this.maskVertexArray); + gl.useProgram(this.maskTileProgram.program); gl.bindBuffer(gl.ARRAY_BUFFER, this.quadVertexBuffer); - gl.vertexAttribPointer(coverProgram.attributes.TessCoord, + gl.vertexAttribPointer(maskTileProgram.attributes.TessCoord, 2, gl.UNSIGNED_BYTE, false, 0, 0); - gl.bindBuffer(gl.ARRAY_BUFFER, this.coverVertexBuffer); - gl.vertexAttribPointer(coverProgram.attributes.TileOrigin, 2, gl.SHORT, false, 10, 0); - gl.vertexAttribDivisor(coverProgram.attributes.TileOrigin, 1); - gl.vertexAttribIPointer(coverProgram.attributes.TileIndex, 1, gl.UNSIGNED_SHORT, 10, 4); - gl.vertexAttribDivisor(coverProgram.attributes.TileIndex, 1); - gl.vertexAttribPointer(coverProgram.attributes.Color, 4, gl.UNSIGNED_BYTE, true, 10, 6); - gl.vertexAttribDivisor(coverProgram.attributes.Color, 1); - gl.enableVertexAttribArray(coverProgram.attributes.TessCoord); - gl.enableVertexAttribArray(coverProgram.attributes.TileOrigin); - gl.enableVertexAttribArray(coverProgram.attributes.TileIndex); - gl.enableVertexAttribArray(coverProgram.attributes.Color); + gl.bindBuffer(gl.ARRAY_BUFFER, this.tileVertexBuffer); + gl.vertexAttribPointer(maskTileProgram.attributes.TileOrigin, + 2, + gl.FLOAT, + false, + TILE_INSTANCE_SIZE, + 0); + gl.vertexAttribDivisor(maskTileProgram.attributes.TileOrigin, 1); + gl.vertexAttribPointer(maskTileProgram.attributes.Backdrop, + 1, + gl.FLOAT, + false, + TILE_INSTANCE_SIZE, + 8); + gl.vertexAttribDivisor(maskTileProgram.attributes.Backdrop, 1); + gl.vertexAttribPointer(maskTileProgram.attributes.Color, + 4, + gl.UNSIGNED_BYTE, + true, + TILE_INSTANCE_SIZE, + 12); + gl.vertexAttribDivisor(maskTileProgram.attributes.Color, 1); + gl.bindBuffer(gl.ARRAY_BUFFER, this.tileVertexBuffer); + gl.vertexAttribIPointer(maskTileProgram.attributes.TileIndex, 1, gl.UNSIGNED_SHORT, 10, 4); + gl.vertexAttribDivisor(maskTileProgram.attributes.TileIndex, 1); + gl.enableVertexAttribArray(maskTileProgram.attributes.TessCoord); + gl.enableVertexAttribArray(maskTileProgram.attributes.TileOrigin); + gl.enableVertexAttribArray(maskTileProgram.attributes.TileIndex); + gl.enableVertexAttribArray(maskTileProgram.attributes.Color); // Set up event handlers. this.canvas.addEventListener('click', event => this.onClick(event), false); - this.scene = null; - this.primitiveCount = 0; - this.tileCount = 0; - this.opaqueTileCount = 0; + this.fillPrimitiveCount = 0; + this.totalTileCount = 0; + this.solidTileCount = 0; + this.maskTileCount = 0; } redraw(): void { - const gl = this.gl, canvas = this.canvas, scene = unwrapNull(this.scene); + const gl = this.gl, canvas = this.canvas; // Start timer. let timerQuery = null; @@ -265,28 +304,75 @@ class App { gl.beginQuery(this.disjointTimerQueryExt.TIME_ELAPSED_EXT, timerQuery); } - // Stencil. + // Fill. gl.bindFramebuffer(gl.FRAMEBUFFER, this.stencilFramebuffer); gl.viewport(0, 0, STENCIL_FRAMEBUFFER_SIZE.width, STENCIL_FRAMEBUFFER_SIZE.height); gl.clearColor(0.0, 0.0, 0.0, 0.0); gl.clear(gl.COLOR_BUFFER_BIT); - gl.bindVertexArray(this.stencilVertexArray); - gl.useProgram(this.stencilProgram.program); - gl.uniform2f(this.stencilProgram.uniforms.FramebufferSize, + gl.bindVertexArray(this.fillVertexArray); + gl.useProgram(this.fillProgram.program); + gl.uniform2f(this.fillProgram.uniforms.FramebufferSize, STENCIL_FRAMEBUFFER_SIZE.width, STENCIL_FRAMEBUFFER_SIZE.height); - gl.uniform2f(this.stencilProgram.uniforms.TileSize, TILE_SIZE.width, TILE_SIZE.height); + gl.uniform2f(this.fillProgram.uniforms.TileSize, TILE_SIZE.width, TILE_SIZE.height); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, this.areaLUTTexture); - gl.uniform1i(this.stencilProgram.uniforms.AreaLUT, 0); + gl.uniform1i(this.fillProgram.uniforms.AreaLUT, 0); gl.blendEquation(gl.FUNC_ADD); gl.blendFunc(gl.ONE, gl.ONE); gl.enable(gl.BLEND); - gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, unwrapNull(this.primitiveCount)); + gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, unwrapNull(this.fillPrimitiveCount)); gl.disable(gl.BLEND); // Read back stencil and dump it. + //this.dumpStencil(); + + // Draw solid tiles. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + const framebufferSize = {width: canvas.width, height: canvas.height}; + gl.viewport(0, 0, framebufferSize.width, framebufferSize.height); + gl.clearColor(0.85, 0.85, 0.85, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + + gl.bindVertexArray(this.solidVertexArray); + gl.useProgram(this.solidTileProgram.program); + gl.uniform2f(this.solidTileProgram.uniforms.FramebufferSize, + framebufferSize.width, + framebufferSize.height); + gl.uniform2f(this.solidTileProgram.uniforms.TileSize, TILE_SIZE.width, TILE_SIZE.height); + gl.disable(gl.BLEND); + gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, this.solidTileCount); + + // Draw masked tiles. + gl.bindVertexArray(this.maskVertexArray); + gl.useProgram(this.maskTileProgram.program); + gl.uniform2f(this.maskTileProgram.uniforms.FramebufferSize, + framebufferSize.width, + framebufferSize.height); + gl.uniform2f(this.maskTileProgram.uniforms.TileSize, TILE_SIZE.width, TILE_SIZE.height); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this.stencilTexture); + gl.uniform1i(this.maskTileProgram.uniforms.StencilTexture, 0); + gl.uniform2f(this.maskTileProgram.uniforms.StencilTextureSize, + STENCIL_FRAMEBUFFER_SIZE.width, + STENCIL_FRAMEBUFFER_SIZE.height); + gl.blendEquation(gl.FUNC_ADD); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + gl.enable(gl.BLEND); + gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, this.maskTileCount); + gl.disable(gl.BLEND); + + // End timer. + if (timerQuery != null) { + gl.endQuery(this.disjointTimerQueryExt.TIME_ELAPSED_EXT); + waitForQuery(gl, this.disjointTimerQueryExt, timerQuery); + } + } + + private dumpStencil(): void { + const gl = this.gl; + const totalStencilFramebufferSize = STENCIL_FRAMEBUFFER_SIZE.width * STENCIL_FRAMEBUFFER_SIZE.height * 4; const stencilData = new Float32Array(totalStencilFramebufferSize); @@ -312,145 +398,71 @@ class App { stencilDumpCanvasContext.putImageData(stencilDumpImageData, 0, 0); document.body.appendChild(stencilDumpCanvas); //console.log(stencilData); - - // Draw opaque tiles. - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - const framebufferSize = {width: canvas.width, height: canvas.height}; - gl.viewport(0, 0, framebufferSize.width, framebufferSize.height); - gl.clearColor(0.85, 0.85, 0.85, 1.0); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.bindVertexArray(this.opaqueVertexArray); - gl.useProgram(this.opaqueProgram.program); - gl.uniform2f(this.opaqueProgram.uniforms.FramebufferSize, - framebufferSize.width, - framebufferSize.height); - gl.uniform2f(this.opaqueProgram.uniforms.TileSize, TILE_SIZE.width, TILE_SIZE.height); - gl.disable(gl.BLEND); - gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, this.opaqueTileCount); - - // Cover. - gl.bindVertexArray(this.coverVertexArray); - gl.useProgram(this.coverProgram.program); - gl.uniform2f(this.coverProgram.uniforms.FramebufferSize, - framebufferSize.width, - framebufferSize.height); - gl.uniform2f(this.coverProgram.uniforms.TileSize, TILE_SIZE.width, TILE_SIZE.height); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.stencilTexture); - gl.uniform1i(this.coverProgram.uniforms.StencilTexture, 0); - gl.uniform2f(this.coverProgram.uniforms.StencilTextureSize, - STENCIL_FRAMEBUFFER_SIZE.width, - STENCIL_FRAMEBUFFER_SIZE.height); - gl.blendEquation(gl.FUNC_ADD); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); - gl.enable(gl.BLEND); - gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, this.tileCount); - gl.disable(gl.BLEND); - - // End timer. - if (timerQuery != null) { - gl.endQuery(this.disjointTimerQueryExt.TIME_ELAPSED_EXT); - waitForQuery(gl, this.disjointTimerQueryExt, timerQuery); - } } - buildScene(): void { - this.scene = new Scene(this.svg); + private loadFile(): void { + console.log("loadFile"); + // TODO(pcwalton) + const file = unwrapNull(unwrapNull(this.openButton.files)[0]); + const reader = new FileReader; + reader.addEventListener('loadend', () => { + const gl = this.gl; + const arrayBuffer = staticCast(reader.result, ArrayBuffer); + const root = new RIFFChunk(new DataView(arrayBuffer)); + for (const subchunk of root.subchunks()) { + let bindPoint, buffer; + let countFieldName: 'fillPrimitiveCount' | 'totalTileCount' | 'solidTileCount' | + 'maskTileCount'; + let instanceSize; + const id = subchunk.stringID(); + switch (id) { + case 'fill': + bindPoint = gl.ARRAY_BUFFER; + buffer = this.fillVertexBuffer; + countFieldName = 'fillPrimitiveCount'; + instanceSize = FILL_INSTANCE_SIZE; + break; + case 'tile': + bindPoint = gl.ARRAY_BUFFER; + buffer = this.tileVertexBuffer; + countFieldName = 'totalTileCount'; + instanceSize = TILE_INSTANCE_SIZE; + break; + case 'soli': + bindPoint = gl.ELEMENT_ARRAY_BUFFER; + buffer = this.solidIndexBuffer; + countFieldName = 'solidTileCount'; + instanceSize = 4; + break; + case 'mask': + bindPoint = gl.ELEMENT_ARRAY_BUFFER; + buffer = this.maskIndexBuffer; + countFieldName = 'maskTileCount'; + instanceSize = 4; + break; + default: + throw new Error("Unexpected subchunk ID: " + id); + } + + gl.bindBuffer(bindPoint, buffer); + gl.bufferData(bindPoint, subchunk.contents(), gl.DYNAMIC_DRAW); + this[countFieldName] = subchunk.length() / instanceSize; + } + + this.regenerateInstanceIDBuffer(); + this.redraw(); + }, false); + reader.readAsArrayBuffer(file); } - prepare(): void { - const gl = this.gl, scene = unwrapNull(this.scene); + private regenerateInstanceIDBuffer(): void { + const instanceIDs = new Uint32Array(this.totalTileCount); + for (let instanceID = 0; instanceID < this.totalTileCount; instanceID++) + instanceIDs[instanceID] = instanceID; - // Construct opaque tile VBOs. - this.opaqueTileCount = 0; - const opaqueVertexData: number[] = []; - const opaqueTiles: number[][] = []; - for (let pathIndex = scene.pathTileStrips.length - 1; pathIndex >= 0; pathIndex--) { - const pathTileStrips = scene.pathTileStrips[pathIndex]; - for (const tileStrip of pathTileStrips) { - for (const tile of tileStrip.tiles) { - // TODO(pcwalton) - const color = scene.pathColors[pathIndex]; - if (!tile.isFilled()) - continue; - - if (opaqueTiles[tile.tileLeft] == null) - opaqueTiles[tile.tileLeft] = []; - if (opaqueTiles[tile.tileLeft][tileStrip.tileTop] != null) - continue; - opaqueTiles[tile.tileLeft][tileStrip.tileTop] = pathIndex; - - opaqueVertexData.push(Math.floor(tile.tileLeft), - Math.floor(tileStrip.tileTop), - 0, - color.r | (color.g << 8), - color.b | (color.a << 8)); - this.opaqueTileCount++; - } - } - } - - // Construct stencil and cover VBOs. - this.tileCount = 0; - let primitiveCount = 0; - const stencilVertexPositions: number[] = [], stencilVertexTileIndices: number[] = []; - const coverVertexData: number[] = []; - for (let pathIndex = 0; pathIndex < scene.pathTileStrips.length; pathIndex++) { - const pathTileStrips = scene.pathTileStrips[pathIndex]; - for (const tileStrip of pathTileStrips) { - for (const tile of tileStrip.tiles) { - const color = scene.pathColors[pathIndex]; - if (tile.isFilled()) - continue; - - if (opaqueTiles[tile.tileLeft] != null && - opaqueTiles[tile.tileLeft][tileStrip.tileTop] != null && - pathIndex <= opaqueTiles[tile.tileLeft][tileStrip.tileTop]) { - continue; - } - - for (const edge of tile.edges) { - let ctrl; - if (edge.ctrl == null) - ctrl = edge.from.lerp(edge.to, 0.5); - else - ctrl = edge.ctrl; - stencilVertexPositions.push(edge.from.x, edge.from.y, - ctrl.x, ctrl.y, - edge.to.x, edge.to.y); - stencilVertexTileIndices.push(this.tileCount); - primitiveCount++; - } - - coverVertexData.push(Math.floor(tile.tileLeft), - Math.floor(tileStrip.tileTop), - this.tileCount, - color.r | (color.g << 8), - color.b | (color.a << 8)); - - this.tileCount++; - } - } - } - - // Populate the stencil VBOs. - gl.bindBuffer(gl.ARRAY_BUFFER, this.stencilVertexPositionsBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(stencilVertexPositions), gl.STATIC_DRAW); - gl.bindBuffer(gl.ARRAY_BUFFER, this.stencilVertexTileIndicesBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Uint16Array(stencilVertexTileIndices), gl.STATIC_DRAW); - - // Populate the opaque VBO. - gl.bindBuffer(gl.ARRAY_BUFFER, this.opaqueVertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Int16Array(opaqueVertexData), gl.DYNAMIC_DRAW); - - // Populate the cover VBO. - gl.bindBuffer(gl.ARRAY_BUFFER, this.coverVertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Int16Array(coverVertexData), gl.DYNAMIC_DRAW); - //console.log(coverVertexData); - - this.primitiveCount = primitiveCount; - console.log(primitiveCount + " primitives"); + const gl = this.gl; + gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceIDVertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, instanceIDs, gl.DYNAMIC_DRAW); } private onClick(event: MouseEvent): void { @@ -458,148 +470,6 @@ class App { } } -class Scene { - pathTileStrips: TileStrip[][]; - pathColors: Color[]; - - constructor(svg: XMLDocument) { - const svgElement = unwrapNull(svg.documentElement).cloneNode(true); - document.body.appendChild(svgElement); - - const pathElements = Array.from(document.getElementsByTagName('path')); - const pathColors: any[] = []; - - this.pathTileStrips = []; - - //const tileDebugger = new TileDebugger(document); - - let fillCount = 0, strokeCount = 0; - const paths: SVGPath[] = []; - for (let pathElementIndex = 0; - pathElementIndex < pathElements.length; - pathElementIndex++) { - const pathElement = pathElements[pathElementIndex]; - const pathString = unwrapNull(pathElement.getAttribute('d')); - - const style = window.getComputedStyle(pathElement); - if (style.fill != null && style.fill !== 'none') { - fillCount++; - this.addPath(paths, pathColors, style.fill, pathString, null); - } - if (style.stroke != null && style.stroke !== 'none') { - strokeCount++; - const strokeWidth = - style.strokeWidth == null ? 1.0 : parseFloat(style.strokeWidth); - this.addPath(paths, pathColors, style.stroke, pathString, strokeWidth); - } - } - console.log("", fillCount, "fills,", strokeCount, "strokes"); - - const startTime = window.performance.now(); - - for (const path of paths) { - const tiler = new Tiler(path); - tiler.tile(); - //tileDebugger.addTiler(tiler, paint, "" + realPathIndex); - //console.log("path", pathElementIndex, "tiles", tiler.getStrips()); - - const pathTileStrips = tiler.getTileStrips(); - this.pathTileStrips.push(pathTileStrips); - } - - const endTime = window.performance.now(); - console.log("elapsed time for tiling: " + (endTime - startTime) + "ms"); - - /* - for (const tile of tiles) { - const newSVG = staticCast(document.createElementNS(SVG_NS, 'svg'), SVGElement); - newSVG.setAttribute('class', "tile"); - newSVG.style.left = (GLOBAL_OFFSET.x + tile.origin.x) + "px"; - newSVG.style.top = (GLOBAL_OFFSET.y + tile.origin.y) + "px"; - newSVG.style.width = TILE_SIZE + "px"; - newSVG.style.height = TILE_SIZE + "px"; - - const newPath = document.createElementNS(SVG_NS, 'path'); - newPath.setAttribute('d', - tile.path - .translate(-tile.origin.x, -tile.origin.y) - .toString()); - - const color = pathColors[tile.pathIndex]; - newPath.setAttribute('fill', - "rgba(" + color.r + "," + color.g + "," + color.b + "," + - (color.a / 255.0)); - - newSVG.appendChild(newPath); - document.body.appendChild(newSVG); - }*/ - - document.body.removeChild(svgElement); - - const svgContainer = document.createElement('div'); - svgContainer.style.position = 'relative'; - svgContainer.style.width = "2000px"; - svgContainer.style.height = "2000px"; - //svgContainer.appendChild(tileDebugger.svg); - document.body.appendChild(svgContainer); - - this.pathColors = pathColors; - } - - private addPath(paths: SVGPath[], - pathColors: any[], - paint: string, - pathString: string, - strokeWidth: number | null): - void { - const color = parseColor(paint).rgba; - pathColors.push({ - r: color[0], - g: color[1], - b: color[2], - a: Math.round(color[3] * 255.), - }); - - let path: SVGPath = SVGPath(pathString); - path = path.matrix([ - GLOBAL_TRANSFORM.a, GLOBAL_TRANSFORM.b, - GLOBAL_TRANSFORM.c, GLOBAL_TRANSFORM.d, - GLOBAL_TRANSFORM.tx, GLOBAL_TRANSFORM.ty, - ]); - - path = flattenPath(path); - - if (strokeWidth != null) { - const outline = new Outline(path); - outline.calculateNormals(); - outline.stroke(strokeWidth * GLOBAL_TRANSFORM.a); - const strokedPathString = outline.toSVGPathString(); - - /* - const newSVG = staticCast(document.createElementNS(SVG_NS, 'svg'), SVGElement); - newSVG.style.position = 'absolute'; - newSVG.style.left = "0"; - newSVG.style.top = "0"; - newSVG.style.width = "2000px"; - newSVG.style.height = "2000px"; - - const newPath = document.createElementNS(SVG_NS, 'path'); - newPath.setAttribute('d', strokedPathString); - newPath.setAttribute('fill', - "rgba(" + color[0] + "," + color[1] + "," + color[2] + "," + - color[3] + ")"); - newSVG.appendChild(newPath); - document.body.appendChild(newSVG); - */ - - path = SVGPath(strokedPathString); - path = makePathMonotonic(path); - } - - paths.push(path); - } -} - class Program { program: WebGLProgram; uniforms: {[key in U]: WebGLUniformLocation | null}; @@ -652,6 +522,43 @@ class Program { } } +class RIFFChunk { + private data: DataView; + + constructor(data: DataView) { + this.data = data; + } + + stringID(): string { + return String.fromCharCode(this.data.getUint8(0), + this.data.getUint8(1), + this.data.getUint8(2), + this.data.getUint8(3)); + } + + length(): number { + return this.data.getUint32(4, true); + } + + contents(): DataView { + return new DataView(this.data.buffer, this.data.byteOffset + 8, this.length()); + } + + subchunks(): RIFFChunk[] { + const subchunks = []; + const contents = this.contents(), length = this.length(); + let offset = 4; + while (offset < length) { + const subchunk = new RIFFChunk(new DataView(contents.buffer, + contents.byteOffset + offset, + length - offset)); + subchunks.push(subchunk); + offset += subchunk.length() + 8; + } + return subchunks; + } +} + function waitForQuery(gl: WebGL2RenderingContext, disjointTimerQueryExt: any, query: WebGLQuery): void { const queryResultAvailable = disjointTimerQueryExt.QUERY_RESULT_AVAILABLE_EXT; @@ -664,27 +571,16 @@ function waitForQuery(gl: WebGL2RenderingContext, disjointTimerQueryExt: any, qu console.log(elapsed + "ms elapsed"); } -function main(): void { - window.fetch(SVG).then(svg => { - svg.text().then(svgText => { - //testIntervals(); - - const svg = staticCast((new DOMParser).parseFromString(svgText, 'image/svg+xml'), - XMLDocument); - const image = new Image; - image.src = AREA_LUT; - image.addEventListener('load', event => { - try { - const app = new App(svg, image); - app.buildScene(); - app.prepare(); - app.redraw(); - } catch (e) { - console.error("error", e, e.stack); - } - }, false); - }); +function loadAreaLUT(): Promise { + return new Promise((resolve, reject) => {; + const image = new Image; + image.src = AREA_LUT; + image.addEventListener('load', event => resolve(image), false); }); } +function main(): void { + loadAreaLUT().then(image => new App(image)); +} + document.addEventListener('DOMContentLoaded', () => main(), false); diff --git a/demo2/stencil.vs.glsl b/demo2/stencil.vs.glsl index b557dcdf..8803a6cc 100644 --- a/demo2/stencil.vs.glsl +++ b/demo2/stencil.vs.glsl @@ -17,7 +17,6 @@ uniform vec2 uTileSize; in vec2 aTessCoord; in vec2 aFrom; -in vec2 aCtrl; in vec2 aTo; in uint aTileIndex; @@ -34,23 +33,24 @@ vec2 computeTileOffset(uint tileIndex, float stencilTextureWidth) { void main() { vec2 tileOrigin = computeTileOffset(aTileIndex, uFramebufferSize.x); - vec2 from = aFrom, ctrl = aCtrl, to = aTo; + vec2 from = aFrom, to = aTo; vec2 position; bool zeroArea = !(abs(from.x - to.x) > 0.1) || !(abs(uTileSize.y - min(from.y, to.y)) > 0.1); if (aTessCoord.x < 0.5) - position.x = floor(min(min(from.x, to.x), ctrl.x)); + position.x = floor(min(from.x, to.x)); else - position.x = ceil(max(max(from.x, to.x), ctrl.x)); + position.x = ceil(max(from.x, to.x)); if (aTessCoord.y < 0.5) - position.y = floor(min(min(from.y, to.y), ctrl.y)); + position.y = floor(min(from.y, to.y)); else position.y = uTileSize.y; vFrom = from - position; - vCtrl = ctrl - position; vTo = to - position; + vCtrl = mix(vFrom, vTo, 0.5); + if (zeroArea) gl_Position = vec4(0.0); else diff --git a/utils/tile-svg/src/main.rs b/utils/tile-svg/src/main.rs index 203eaee6..123b4752 100644 --- a/utils/tile-svg/src/main.rs +++ b/utils/tile-svg/src/main.rs @@ -1049,6 +1049,7 @@ impl BuiltScene { for tile_primitive in &self.tiles { let color = tile_primitive.color; write_point(writer, &tile_primitive.position)?; + writer.write_f32::(tile_primitive.backdrop)?; writer.write_all(&[color.r, color.g, color.b, color.a]).unwrap(); }