diff --git a/README.md b/README.md index 4fb95a3711..83a2500598 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,22 @@ ## About -Mono-repository for almost 100 thi.ng TypeScript/ES6 projects, a wide +Mono-repository for 100+ thi.ng TypeScript/ES6 projects, a wide collection of largely data transformation oriented packages and building blocks for: - Functional programming (composition, memoization, transducers, multi-methods) - Stream based, reactive programming, dataflow graphs / pipelines -- Data structures & data transformations for wide range of use cases +- WebWorker workflow abstractions +- Data structures & data transformations for wide range of use cases (list, sets, maps) +- Value-based equivalence - Data driven UI components, event & side effect handling -- Immutable data handling +- Immediate mode GUI components +- Immutable data handling, state containers, Undo-Redo history - Geometry generation, processing & visualization - Vector & matrix implementations with optional support for strided layouts +- Color space conversions, cosine gradients +- Multi-format pixel buffers, conversions, Porter-Duff alpha-blending operators - Declarative WebGL 1/2 abstraction layer - DSL for shader functions defined in TypeScript and cross-compilation to GLSL, JS, VEX etc. - Low-level tooling for binary data, shared memory / WASM / WebGL interop @@ -78,8 +83,8 @@ contribute, please first read [this document](./CONTRIBUTING.md). (These packages are only available on their respective feature branches) -- @thi.ng/scenegraph (not yet pushed) - 2D/3D scenegraph -- [@thi.ng/webgl-shadertoy](https://github.com/thi-ng/umbrella/tree/feature/shadertoy/packages/webgl-shadertoy) - WebGL shadertoy-like setup +- [@thi.ng/grid-iterators](https://github.com/thi-ng/umbrella/tree/master/packages/grid-iterators) - 2D grid coordinate iterators +- [@thi.ng/scenegraph](https://github.com/thi-ng/umbrella/tree/feature/scenegraph/packages/scenegraph) - 2D/3D scenegraph ### Fundamentals @@ -106,6 +111,7 @@ contribute, please first read [this document](./CONTRIBUTING.md). |---------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|----------------------------------| | [`@thi.ng/csp`](./packages/csp) | [![version](https://img.shields.io/npm/v/@thi.ng/csp.svg)](https://www.npmjs.com/package/@thi.ng/csp) | [changelog](./packages/csp/CHANGELOG.md) | Channel based async ops | | [`@thi.ng/fsm`](./packages/fsm) | [![version](https://img.shields.io/npm/v/@thi.ng/fsm.svg)](https://www.npmjs.com/package/@thi.ng/fsm) | [changelog](./packages/fsm/CHANGELOG.md) | FSM / parser primitives | +| [`@thi.ng/grid-iterators`](./packages/grid-iterators) | [![version](https://img.shields.io/npm/v/@thi.ng/grid-iterators.svg)](https://www.npmjs.com/package/@thi.ng/grid-iterators) | [changelog](./packages/grid-iterators/CHANGELOG.md) | 2D grid iterator strategies | | [`@thi.ng/iterators`](./packages/iterators) | [![version](https://img.shields.io/npm/v/@thi.ng/iterators.svg)](https://www.npmjs.com/package/@thi.ng/iterators) | [changelog](./packages/iterators/CHANGELOG.md) | ES6 generators / iterators | | [`@thi.ng/sax`](./packages/sax) | [![version](https://img.shields.io/npm/v/@thi.ng/sax.svg)](https://www.npmjs.com/package/@thi.ng/sax) | [changelog](./packages/sax/CHANGELOG.md) | SAX-like XML parser / transducer | | [`@thi.ng/transducers`](./packages/transducers) | [![version](https://img.shields.io/npm/v/@thi.ng/transducers.svg)](https://www.npmjs.com/package/@thi.ng/transducers) | [changelog](./packages/transducers/CHANGELOG.md) | Composable data transformations | @@ -202,6 +208,7 @@ contribute, please first read [this document](./CONTRIBUTING.md). | [`@thi.ng/shader-ast-stdlib`](./packages/shader-ast-stdlib) | [![version](https://img.shields.io/npm/v/@thi.ng/shader-ast-stdlib.svg)](https://www.npmjs.com/package/@thi.ng/shader-ast-stdlib) | [changelog](./packages/shader-ast-stdlib/CHANGELOG.md) | 100+ useful AST shader functions | | [`@thi.ng/webgl`](./packages/webgl) | [![version](https://img.shields.io/npm/v/@thi.ng/webgl.svg)](https://www.npmjs.com/package/@thi.ng/webgl) | [changelog](./packages/webgl/CHANGELOG.md) | WebGL 1/2 / GPGPU facilities | | [`@thi.ng/webgl-msdf`](./packages/webgl-msdf) | [![version](https://img.shields.io/npm/v/@thi.ng/webgl-msdf.svg)](https://www.npmjs.com/package/@thi.ng/webgl-msdf) | [changelog](./packages/webgl-msdf/CHANGELOG.md) | MSDF font rendering | +| [`@thi.ng/webgl-shadertoy`](./packages/webgl-shadertoy) | [![version](https://img.shields.io/npm/v/@thi.ng/webgl-shadertoy.svg)](https://www.npmjs.com/package/@thi.ng/webgl-shadertoy) | [changelog](./packages/webgl-shadertoy/CHANGELOG.md) | Shadertoy-like WebGL setup | ### Low-level, binary, memory management @@ -225,6 +232,7 @@ contribute, please first read [this document](./CONTRIBUTING.md). |-------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------| | [`@thi.ng/pointfree`](./packages/pointfree) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree.svg)](https://www.npmjs.com/package/@thi.ng/pointfree) | [changelog](./packages/pointfree/CHANGELOG.md) | Stack-based DSL & functional composition | | [`@thi.ng/pointfree-lang`](./packages/pointfree-lang) | [![version](https://img.shields.io/npm/v/@thi.ng/pointfree-lang.svg)](https://www.npmjs.com/package/@thi.ng/pointfree-lang) | [changelog](./packages/pointfree-lang/CHANGELOG.md) | Forth-like syntax layer for @thi.ng/pointfree | +| [`@thi.ng/sexpr`](./packages/sexpr) | [![version](https://img.shields.io/npm/v/@thi.ng/sexpr.svg)](https://www.npmjs.com/package/@thi.ng/sexpr) | [changelog](./packages/sexpr/CHANGELOG.md) | S-Expression parser & runtime infrastructure | ## Building diff --git a/assets/dot/crypto-dflow.dot b/assets/diagrams/crypto-dflow.dot similarity index 100% rename from assets/dot/crypto-dflow.dot rename to assets/diagrams/crypto-dflow.dot diff --git a/assets/dot/dot-example.dot b/assets/diagrams/dot-example.dot similarity index 100% rename from assets/dot/dot-example.dot rename to assets/diagrams/dot-example.dot diff --git a/assets/dot/hdom-canvas-shapes.dot b/assets/diagrams/hdom-canvas-shapes.dot similarity index 100% rename from assets/dot/hdom-canvas-shapes.dot rename to assets/diagrams/hdom-canvas-shapes.dot diff --git a/assets/dot/hdom-v5.xml b/assets/diagrams/hdom-v5.xml similarity index 100% rename from assets/dot/hdom-v5.xml rename to assets/diagrams/hdom-v5.xml diff --git a/assets/dot/hdom.xml b/assets/diagrams/hdom.xml similarity index 100% rename from assets/dot/hdom.xml rename to assets/diagrams/hdom.xml diff --git a/assets/dot/iceps-dataflow.xml b/assets/diagrams/iceps-dataflow.xml similarity index 100% rename from assets/dot/iceps-dataflow.xml rename to assets/diagrams/iceps-dataflow.xml diff --git a/assets/dot/q1.dot b/assets/diagrams/q1.dot similarity index 100% rename from assets/dot/q1.dot rename to assets/diagrams/q1.dot diff --git a/assets/dot/q2.dot b/assets/diagrams/q2.dot similarity index 100% rename from assets/dot/q2.dot rename to assets/diagrams/q2.dot diff --git a/assets/dot/rle-layout.dot b/assets/diagrams/rle-layout.dot similarity index 100% rename from assets/dot/rle-layout.dot rename to assets/diagrams/rle-layout.dot diff --git a/assets/dot/rs-dflow.dot b/assets/diagrams/rs-dflow.dot similarity index 100% rename from assets/dot/rs-dflow.dot rename to assets/diagrams/rs-dflow.dot diff --git a/assets/dot/rs-dot-example.dot b/assets/diagrams/rs-dot-example.dot similarity index 100% rename from assets/dot/rs-dot-example.dot rename to assets/diagrams/rs-dot-example.dot diff --git a/assets/dot/rs-query1.dot b/assets/diagrams/rs-query1.dot similarity index 100% rename from assets/dot/rs-query1.dot rename to assets/diagrams/rs-query1.dot diff --git a/assets/dot/rstream-constructs.xml b/assets/diagrams/rstream-constructs.xml similarity index 100% rename from assets/dot/rstream-constructs.xml rename to assets/diagrams/rstream-constructs.xml diff --git a/assets/dot/transducers-hdom-dflow.dot b/assets/diagrams/transducers-hdom-dflow.dot similarity index 100% rename from assets/dot/transducers-hdom-dflow.dot rename to assets/diagrams/transducers-hdom-dflow.dot diff --git a/assets/diagrams/wolfram-dflow.dot b/assets/diagrams/wolfram-dflow.dot new file mode 100644 index 0000000000..a82eb21c41 --- /dev/null +++ b/assets/diagrams/wolfram-dflow.dot @@ -0,0 +1,54 @@ +digraph g { +rankdir=LR; +node[fontname=Inconsolata,fontsize=11,style=filled,fontcolor=white]; +edge[fontname=Inconsolata,fontsize=11]; +s0[label="rule\n(Stream)", color="blue"]; +s1[label="xform-2", color="black"]; +s2[label="in-rule", color="black"]; +s3[label="", color="gray"]; +s4[label="wolfram\n(StreamSync)", color="red"]; +s5[label="xform-7", color="black"]; +s6[label="in-sim", color="black"]; +s7[label="", color="gray"]; +s8[label="main\n(StreamSync)", color="red"]; +s9[label="hdom", color="black"]; +s10[label="xform-10", color="black"]; +s11[label="sidetoggle-11", color="black"]; +s12[label="obj export", color="black"]; +s13[label="in-id", color="black"]; +s14[label="", color="gray"]; +s15[label="kernel\n(Stream)", color="blue"]; +s16[label="xform-3", color="black"]; +s17[label="in-kernel", color="black"]; +s18[label="", color="gray"]; +s19[label="in-ksize", color="black"]; +s20[label="", color="gray"]; +s21[label="export trigger", color="blue"]; +s22[label="sub-12", color="black"]; +s23[label="", color="gray"]; +s23 -> s11[label="sidechain"]; +s8 -> s9[label="xform"]; +s7 -> s8[label="xform"]; +s6 -> s7; +s5 -> s6[label="xform"]; +s11 -> s12[label="xform"]; +s10 -> s11; +s4 -> s5[label="xform"]; +s4 -> s10[label="xform"]; +s3 -> s4[label="xform"]; +s2 -> s3; +s1 -> s2[label="xform"]; +s14 -> s8[label="xform"]; +s13 -> s14; +s0 -> s1[label="xform"]; +s0 -> s13[label="xform"]; +s18 -> s4[label="xform"]; +s17 -> s18; +s16 -> s17[label="xform"]; +s20 -> s8[label="xform"]; +s19 -> s20; +s15 -> s16[label="xform"]; +s15 -> s19[label="xform"]; +s22 -> s23; +s21 -> s22; +} \ No newline at end of file diff --git a/assets/dot/xml-converter.dot b/assets/diagrams/xml-converter.dot similarity index 100% rename from assets/dot/xml-converter.dot rename to assets/diagrams/xml-converter.dot diff --git a/assets/dot-example.png b/assets/dot/dot-example.png similarity index 100% rename from assets/dot-example.png rename to assets/dot/dot-example.png diff --git a/assets/screenshots/estuary.jpg b/assets/estuary/estuary.jpg similarity index 100% rename from assets/screenshots/estuary.jpg rename to assets/estuary/estuary.jpg diff --git a/assets/screenshots/canvas-dial.png b/assets/examples/canvas-dial.png similarity index 100% rename from assets/screenshots/canvas-dial.png rename to assets/examples/canvas-dial.png diff --git a/assets/examples/cellular-automata.png b/assets/examples/cellular-automata.png new file mode 100644 index 0000000000..3eea408f63 Binary files /dev/null and b/assets/examples/cellular-automata.png differ diff --git a/assets/screenshots/commit-table-ssr.png b/assets/examples/commit-table-ssr.png similarity index 100% rename from assets/screenshots/commit-table-ssr.png rename to assets/examples/commit-table-ssr.png diff --git a/assets/screenshots/crypto-chart.png b/assets/examples/crypto-chart.png similarity index 100% rename from assets/screenshots/crypto-chart.png rename to assets/examples/crypto-chart.png diff --git a/assets/crypto-dflow.png b/assets/examples/crypto-dflow.png similarity index 100% rename from assets/crypto-dflow.png rename to assets/examples/crypto-dflow.png diff --git a/assets/screenshots/gesture-analysis.png b/assets/examples/gesture-analysis.png similarity index 100% rename from assets/screenshots/gesture-analysis.png rename to assets/examples/gesture-analysis.png diff --git a/assets/screenshots/mandelbrot.jpg b/assets/examples/mandelbrot.jpg similarity index 100% rename from assets/screenshots/mandelbrot.jpg rename to assets/examples/mandelbrot.jpg diff --git a/assets/rs-dflow.png b/assets/examples/rs-dflow.png similarity index 100% rename from assets/rs-dflow.png rename to assets/examples/rs-dflow.png diff --git a/assets/rs-dot-example.svg b/assets/examples/rs-dot-example.svg similarity index 100% rename from assets/rs-dot-example.svg rename to assets/examples/rs-dot-example.svg diff --git a/assets/examples/rs-query1.png b/assets/examples/rs-query1.png new file mode 100644 index 0000000000..d9861ae32b Binary files /dev/null and b/assets/examples/rs-query1.png differ diff --git a/assets/rs-query1.svg b/assets/examples/rs-query1.svg similarity index 100% rename from assets/rs-query1.svg rename to assets/examples/rs-query1.svg diff --git a/assets/screenshots/rstream-grid.png b/assets/examples/rstream-grid.png similarity index 100% rename from assets/screenshots/rstream-grid.png rename to assets/examples/rstream-grid.png diff --git a/assets/screenshots/svg-barchart.png b/assets/examples/svg-barchart.png similarity index 100% rename from assets/screenshots/svg-barchart.png rename to assets/examples/svg-barchart.png diff --git a/assets/screenshots/svg-waveform.png b/assets/examples/svg-waveform.png similarity index 100% rename from assets/screenshots/svg-waveform.png rename to assets/examples/svg-waveform.png diff --git a/assets/xml-converter.png b/assets/examples/xml-converter-dflow.png similarity index 100% rename from assets/xml-converter.png rename to assets/examples/xml-converter-dflow.png diff --git a/assets/screenshots/xml-converter.png b/assets/examples/xml-converter.png similarity index 100% rename from assets/screenshots/xml-converter.png rename to assets/examples/xml-converter.png diff --git a/assets/geom-isoline.png b/assets/geom/geom-isoline.png similarity index 100% rename from assets/geom-isoline.png rename to assets/geom/geom-isoline.png diff --git a/assets/geom/geom-isoline.svg b/assets/geom/geom-isoline.svg new file mode 100644 index 0000000000..072fcc566c --- /dev/null +++ b/assets/geom/geom-isoline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/geom-voronoi.jpg b/assets/geom/geom-voronoi.jpg similarity index 100% rename from assets/geom-voronoi.jpg rename to assets/geom/geom-voronoi.jpg diff --git a/assets/geom/tessel.png b/assets/geom/tessel.png new file mode 100644 index 0000000000..55c7dcd95c Binary files /dev/null and b/assets/geom/tessel.png differ diff --git a/assets/grid-iterators/grid-diagonal.gif b/assets/grid-iterators/grid-diagonal.gif new file mode 100644 index 0000000000..91213a7c0c Binary files /dev/null and b/assets/grid-iterators/grid-diagonal.gif differ diff --git a/assets/grid-iterators/grid-hilbert.gif b/assets/grid-iterators/grid-hilbert.gif new file mode 100644 index 0000000000..498645830d Binary files /dev/null and b/assets/grid-iterators/grid-hilbert.gif differ diff --git a/assets/grid-iterators/grid-spiral.gif b/assets/grid-iterators/grid-spiral.gif new file mode 100644 index 0000000000..8e4d2669cd Binary files /dev/null and b/assets/grid-iterators/grid-spiral.gif differ diff --git a/assets/grid-iterators/grid-zigzag-cols.gif b/assets/grid-iterators/grid-zigzag-cols.gif new file mode 100644 index 0000000000..f38ffd8b07 Binary files /dev/null and b/assets/grid-iterators/grid-zigzag-cols.gif differ diff --git a/assets/grid-iterators/grid-zigzag-rows.gif b/assets/grid-iterators/grid-zigzag-rows.gif new file mode 100644 index 0000000000..b079fb77c5 Binary files /dev/null and b/assets/grid-iterators/grid-zigzag-rows.gif differ diff --git a/assets/hdom-canvas/hdom-canvas-shapes-results.png b/assets/hdom-canvas/hdom-canvas-shapes-results.png new file mode 100644 index 0000000000..951545536c Binary files /dev/null and b/assets/hdom-canvas/hdom-canvas-shapes-results.png differ diff --git a/assets/hdom-canvas-shapes.png b/assets/hdom-canvas/hdom-canvas-shapes.png similarity index 100% rename from assets/hdom-canvas-shapes.png rename to assets/hdom-canvas/hdom-canvas-shapes.png diff --git a/assets/hdom-dataflow.png b/assets/hdom/hdom-dataflow.png similarity index 100% rename from assets/hdom-dataflow.png rename to assets/hdom/hdom-dataflow.png diff --git a/assets/screenshots/iges.png b/assets/iges/iges-houdini.png similarity index 100% rename from assets/screenshots/iges.png rename to assets/iges/iges-houdini.png diff --git a/assets/screenshots/imgui-all.png b/assets/imgui/imgui-all.png similarity index 100% rename from assets/screenshots/imgui-all.png rename to assets/imgui/imgui-all.png diff --git a/assets/screenshots/imgui-demo.png b/assets/imgui/imgui-demo.png similarity index 100% rename from assets/screenshots/imgui-demo.png rename to assets/imgui/imgui-demo.png diff --git a/assets/imgui/imgui-layout.drawio b/assets/imgui/imgui-layout.drawio new file mode 100644 index 0000000000..74788cc390 --- /dev/null +++ b/assets/imgui/imgui-layout.drawio @@ -0,0 +1 @@ +7VhNj5swFPw1SO0hK74Tjht2afcQaatIba9OcMCqwdQ4C+mvr41NCAHaVBvotkoOwR4/P5uZ4WGhWX5SfqAgi1ckhFgz9bDUrAfNNB1L5/8COEjAXtgSiCgKJWQ0wBr9gApU86I9CmHeCmSEYIayNrglaQq3rIUBSknRDtsR3F41AxHsAOstwF30CwpZLNGFozf4R4iiuF7Z0NVIAupgBeQxCElxAlmPmuVTQphsJaUPseCu5kXOCwZGjxujMGWXTPiMX7aB++l5/vX+m+tlIXvaoZnK8gLwXt0wBgeyZ3cpLNm792rn7FDTQck+DaHIqGvWsogRg+sMbMVowfXnWMwSzHsGb+5IygKQICy0f1queKpnDEt+WZGUiACEsU8woVVyK+A/3+e42hSkDJaDd2scOeTegySBjB54iJqwUKwf2t2i0dCulYpP9LMVBpRtomPihlneUOT+AdFmh2jNdDFfdZlnIG2R7H7fC09U9M12ir97TcjrgiSr+LEsm1/RJhGkSE4Twel5hJhV/VdSzXKplUiWEpoA3KzGW5G4nukv98hvWW5TxrzSFpOpblh/W3ZrUHahrihIkqVGh+5z0pGIFYTzl3c1kjlH0Mj3g+DRHUejnkfT8OwJNbJvGp1rZNZv6V+K5E4o0rxPJFnr0k2eqVJ3CfQaytUpA2yq2fp1yDbseYtss6dquT1Fy/DGInvx/5JtGs5vyXa8Kck2/pmjwWBNG+1sMGZN61O+t6aNp/zw6WBQ+YvFusI7DPHnj0q1NWfJ2fVtzXkYfpmN4AdKGGCIpLw78/SuQVxXHB+vVYfb/vCcHn/01GF3NH8Mn0xu/pjeHwvzrfnDufnjDfnDsL07ZzKL8G7z7agaO/kAZz3+BA== \ No newline at end of file diff --git a/assets/imgui-layout.png b/assets/imgui/imgui-layout.png similarity index 100% rename from assets/imgui-layout.png rename to assets/imgui/imgui-layout.png diff --git a/assets/lsys-0.png b/assets/lsys/lsys-0.png similarity index 100% rename from assets/lsys-0.png rename to assets/lsys/lsys-0.png diff --git a/assets/lsys-1.png b/assets/lsys/lsys-1.png similarity index 100% rename from assets/lsys-1.png rename to assets/lsys/lsys-1.png diff --git a/assets/lsys-2.png b/assets/lsys/lsys-2.png similarity index 100% rename from assets/lsys-2.png rename to assets/lsys/lsys-2.png diff --git a/assets/lsys-3.png b/assets/lsys/lsys-3.png similarity index 100% rename from assets/lsys-3.png rename to assets/lsys/lsys-3.png diff --git a/assets/lsys-tree.png b/assets/lsys/lsys-tree.png similarity index 100% rename from assets/lsys-tree.png rename to assets/lsys/lsys-tree.png diff --git a/assets/screenshots/pixel-basics.png b/assets/pixel/pixel-basics.png similarity index 100% rename from assets/screenshots/pixel-basics.png rename to assets/pixel/pixel-basics.png diff --git a/assets/screenshots/poisson.jpg b/assets/poisson/poisson.jpg similarity index 100% rename from assets/screenshots/poisson.jpg rename to assets/poisson/poisson.jpg diff --git a/assets/poisson/poisson.png b/assets/poisson/poisson.png new file mode 100644 index 0000000000..a576d311a5 Binary files /dev/null and b/assets/poisson/poisson.png differ diff --git a/assets/porter-duff-custom.png b/assets/porter-duff/porter-duff-custom.png similarity index 100% rename from assets/porter-duff-custom.png rename to assets/porter-duff/porter-duff-custom.png diff --git a/assets/porter-duff2.png b/assets/porter-duff/porter-duff2.png similarity index 100% rename from assets/porter-duff2.png rename to assets/porter-duff/porter-duff2.png diff --git a/assets/rle-layout.png b/assets/rle/rle-layout.png similarity index 100% rename from assets/rle-layout.png rename to assets/rle/rle-layout.png diff --git a/assets/rstream-merge.png b/assets/rstream/rstream-merge.png similarity index 100% rename from assets/rstream-merge.png rename to assets/rstream/rstream-merge.png diff --git a/assets/rstream-pubsub.png b/assets/rstream/rstream-pubsub.png similarity index 100% rename from assets/rstream-pubsub.png rename to assets/rstream/rstream-pubsub.png diff --git a/assets/rstream-sidechain-partition.png b/assets/rstream/rstream-sidechain-partition.png similarity index 100% rename from assets/rstream-sidechain-partition.png rename to assets/rstream/rstream-sidechain-partition.png diff --git a/assets/rstream-sidechain-toggle.png b/assets/rstream/rstream-sidechain-toggle.png similarity index 100% rename from assets/rstream-sidechain-toggle.png rename to assets/rstream/rstream-sidechain-toggle.png diff --git a/assets/rstream-sync.png b/assets/rstream/rstream-sync.png similarity index 100% rename from assets/rstream-sync.png rename to assets/rstream/rstream-sync.png diff --git a/assets/screenshots/shader-ast-01.jpg b/assets/shader-ast/shader-ast-01.jpg similarity index 100% rename from assets/screenshots/shader-ast-01.jpg rename to assets/shader-ast/shader-ast-01.jpg diff --git a/assets/screenshots/shader-ast-raymarch-compare.jpg b/assets/shader-ast/shader-ast-raymarch-compare.jpg similarity index 100% rename from assets/screenshots/shader-ast-raymarch-compare.jpg rename to assets/shader-ast/shader-ast-raymarch-compare.jpg diff --git a/assets/screenshots/shader-ast-raymarch-vex-sm.gif b/assets/shader-ast/shader-ast-raymarch-vex-sm.gif similarity index 100% rename from assets/screenshots/shader-ast-raymarch-vex-sm.gif rename to assets/shader-ast/shader-ast-raymarch-vex-sm.gif diff --git a/examples/README.md b/examples/README.md index b4db56b387..1797321eb6 100644 --- a/examples/README.md +++ b/examples/README.md @@ -56,23 +56,26 @@ in touch via PR, issue tracker, email or twitter! | 46 | [rstream-dataflow](./rstream-dataflow) | Dataflow graph | atom, hdom, rstream, rstream-gestures, rstream-graph, transducers | intermediate | | 47 | [rstream-grid](./rstream-grid) | Dataflow graph SVG grid | atom, hdom, hiccup-svg, interceptors, rstream-graph, transducers | advanced | | 48 | [rstream-hdom](./rstream-hdom) | rstream based UI updates & state handling | hdom, rstream, transducers | intermediate | -| 49 | [scenegraph](./scenegraph) | 2D scenegraph & shape picking | geom, hdom, hdom-canvas | intermediate | -| 50 | [scenegraph-image](./scenegraph-image) | 2D scenegraph & image map based geometry manipulation | geom, hdom, hdom-canvas, pixel | intermediate | -| 51 | [shader-ast-canvas2d](shader-ast-canvas2d) | 2D canvas shader emulation | shader-ast | basic | -| 52 | [shader-ast-noise](shader-ast-noise) | HOF shader function composition | shader-ast, webgl | basic | -| 53 | [shader-ast-raymarch](shader-ast-raymarch) | WebGL & Canvas2D raymarch shader | shader-ast, webgl | intermediate | -| 54 | [shader-ast-sdf2d](shader-ast-sdf2d) | WebGL & Canvas2D SDF | shader-ast, webgl | basic | -| 55 | [shader-ast-tunnel](shader-ast-tunnel) | WebGL & Canvas2D textured tunnel shader | shader-ast, webgl | basic | -| 56 | [svg-barchart](./svg-barchart) | hdom SVG barchart component | hdom, transducers | basic | -| 57 | [svg-particles](./svg-particles) | hdom SVG generation / animation | hdom, transducers | basic | -| 58 | [svg-waveform](./svg-waveform) | hdom SVG generation / undo history | atom, hdom, hiccup-svg, interceptors, iterators | intermediate | -| 59 | [talk-slides](./talk-slides) | Presentation slides from ClojureX 2018 | hdom, rstream, transducers-hdom | intermediate | -| 60 | [todo-list](./todo-list) | Canonical Todo list with undo/redo | atom, hdom, transducers | intermediate | -| 61 | [transducers-hdom](./transducers-hdom) | Transducer & rstream based hdom UI updates | hdom, rstream, transducers-hdom | basic | -| 62 | [triple-query](./triple-query) | Triple store query results & sortable table | atom, hdom, hdom-components, rstream-query, transducers | intermediate | -| 63 | [webgl-cubemap](./webgl-cubemap) | WebGL cubemap, async texture loading | hdom, webgl, shader-ast | intermediate | -| 64 | [webgl-gpgpu-basics](./webgl-gpgpu-basics) | Minimal GPGPU example | webgl, shader-ast | basic | +| 49 | [rstream-spreadsheet](./rstream-spreadsheet) | Spreadsheet w/ S-expr formula DSL | hdom, rstream-graph, sexpr, transducers | advanced | +| 50 | [scenegraph](./scenegraph) | 2D scenegraph & shape picking | geom, hdom, hdom-canvas | intermediate | +| 51 | [scenegraph-image](./scenegraph-image) | 2D scenegraph & image map based geometry manipulation | geom, hdom, hdom-canvas, pixel | intermediate | +| 52 | [shader-ast-canvas2d](shader-ast-canvas2d) | 2D canvas shader emulation | shader-ast | basic | +| 53 | [shader-ast-noise](shader-ast-noise) | HOF shader function composition | shader-ast, webgl | basic | +| 54 | [shader-ast-raymarch](shader-ast-raymarch) | WebGL & Canvas2D raymarch shader | shader-ast, webgl | intermediate | +| 55 | [shader-ast-sdf2d](shader-ast-sdf2d) | WebGL & Canvas2D SDF | shader-ast, webgl | basic | +| 56 | [shader-ast-tunnel](shader-ast-tunnel) | WebGL & Canvas2D textured tunnel shader | shader-ast, webgl | basic | +| 57 | [svg-barchart](./svg-barchart) | hdom SVG barchart component | hdom, transducers | basic | +| 58 | [svg-particles](./svg-particles) | hdom SVG generation / animation | hdom, transducers | basic | +| 59 | [svg-waveform](./svg-waveform) | hdom SVG generation / undo history | atom, hdom, hiccup-svg, interceptors, iterators | intermediate | +| 60 | [talk-slides](./talk-slides) | Presentation slides from ClojureX 2018 | hdom, rstream, transducers-hdom | intermediate | +| 61 | [todo-list](./todo-list) | Canonical Todo list with undo/redo | atom, hdom, transducers | intermediate | +| 62 | [transducers-hdom](./transducers-hdom) | Transducer & rstream based hdom UI updates | hdom, rstream, transducers-hdom | basic | +| 63 | [triple-query](./triple-query) | Triple store query results & sortable table | atom, hdom, hdom-components, rstream-query, transducers | intermediate | +| 64 | [webgl-cubemap](./webgl-cubemap) | WebGL cubemap, async texture loading | hdom, webgl, shader-ast | intermediate | | 65 | [webgl-grid](./webgl-grid) | WebGL instancing | webgl, hdom | intermediate | | 66 | [webgl-msdf](./webgl-msdf) | WebGL MSDF font rendering & particle system | webgl, webgl-msdf, shader-ast, hdom | intermediate | -| 67 | [webgl-ssao](./webgl-ssao) | WebGL screenspace ambient occlusion | webgl, shader-ast, rstream, hdom | advanced | -| 68 | [xml-converter](./xml-converter) | XML/HTML/SVG to hiccup conversion as you type | rstream, sax, transducers, transducers-hdom | advanced | +| 67 | [webgl-multipass](./webgl-multipass) | Minimal multi-pass / GPGPU example | webgl, shader-ast, shader-ast-stdlib | intermediate | +| 68 | [webgl-shadertoy](./webgl-shadertoy) | Shadertoy-like example | webgl, shader-ast, shader-ast-stdlib | basic | +| 69 | [webgl-ssao](./webgl-ssao) | WebGL screenspace ambient occlusion | webgl, shader-ast, rstream, hdom | advanced | +| 70 | [wolfram](./wolfram) | 1D Wolfram automata | rstream, transducers, transducers-hdom | intermediate | +| 71 | [xml-converter](./xml-converter) | XML/HTML/SVG to hiccup conversion as you type | rstream, sax, transducers, transducers-hdom | advanced | diff --git a/examples/crypto-chart/README.md b/examples/crypto-chart/README.md index 5a4dc6df14..89eb716674 100644 --- a/examples/crypto-chart/README.md +++ b/examples/crypto-chart/README.md @@ -2,7 +2,7 @@ [Live demo](https://s3.amazonaws.com/demo.thi.ng/umbrella/crypto-chart/index.html) -![chart](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/crypto-chart.png) +![chart](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/crypto-chart.png) Price data provided by [cryptocompare.com](https://min-api.cryptocompare.com/). @@ -20,7 +20,7 @@ updates / diffs when there were any relevant upstream value changes. The diagram below shows a schematic of the dataflow graph used: -![dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/crypto-dflow.png) +![dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/crypto-dflow.png) ## Building diff --git a/examples/webgl-gpgpu-basics/.gitignore b/examples/grid-iterators/.gitignore similarity index 100% rename from examples/webgl-gpgpu-basics/.gitignore rename to examples/grid-iterators/.gitignore diff --git a/examples/grid-iterators/README.md b/examples/grid-iterators/README.md new file mode 100644 index 0000000000..0d69adb255 --- /dev/null +++ b/examples/grid-iterators/README.md @@ -0,0 +1,13 @@ +# grid-iterators + +[Live demo](http://demo.thi.ng/umbrella/grid-iterators/) + +Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2019 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/webgl-gpgpu-basics/index.html b/examples/grid-iterators/index.html similarity index 66% rename from examples/webgl-gpgpu-basics/index.html rename to examples/grid-iterators/index.html index 92708882b3..f32d747f32 100644 --- a/examples/webgl-gpgpu-basics/index.html +++ b/examples/grid-iterators/index.html @@ -4,7 +4,7 @@ - webgl-gpgpu-basics + grid-iterators -

webgl-gpgpu-basics

-
Open console to view results...
+
+ diff --git a/examples/grid-iterators/package.json b/examples/grid-iterators/package.json new file mode 100644 index 0000000000..e0ef44584e --- /dev/null +++ b/examples/grid-iterators/package.json @@ -0,0 +1,29 @@ +{ + "name": "grid-iterators", + "version": "0.0.1", + "repository": "https://github.com/thi-ng/umbrella", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "clean": "rm -rf .cache build out", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report --experimental-scope-hoisting", + "build:webpack": "../../node_modules/.bin/webpack --mode production", + "start": "parcel index.html -p 8080 --open" + }, + "devDependencies": { + "parcel-bundler": "^1.12.3", + "terser": "^3.17.0", + "typescript": "^3.4.1" + }, + "dependencies": { + "@thi.ng/api": "latest", + "@thi.ng/rstream": "latest", + "@thi.ng/transducers-hdom": "latest" + }, + "browserslist": [ + "last 3 Chrome versions" + ], + "browser": { + "process": false + } +} diff --git a/examples/grid-iterators/src/index.ts b/examples/grid-iterators/src/index.ts new file mode 100644 index 0000000000..01fad2082a --- /dev/null +++ b/examples/grid-iterators/src/index.ts @@ -0,0 +1,49 @@ +import { hueRgba, rgbaCss } from "@thi.ng/color"; +import { + diagonal2d, + hilbert2d, + spiral2d, + zigzagColumns2d, + zigzagRows2d +} from "@thi.ng/grid-iterators"; +import { createElement } from "@thi.ng/hdom"; +import { concat, cycle } from "@thi.ng/transducers"; + +const W = 256; +const H = 256; +const canvas = ( + createElement(document.getElementById("app")!, "canvas", { + width: W, + height: H + }) +); +const ctx = canvas.getContext("2d")!; + +const NB: any = 16; +const BW = Math.ceil(W / NB); +const BH = Math.ceil(H / NB); +// create infinite sequence of all grid iterators +const buckets = cycle( + concat( + diagonal2d(NB, NB), + zigzagRows2d(NB, NB), + hilbert2d(NB, NB), + zigzagColumns2d(NB, NB), + spiral2d(NB, NB) + ) +); + +let frame = 0; +setInterval(() => { + const b = buckets.next(); + let [x, y] = b.value; + x *= BW; + y *= BH; + ctx.fillStyle = rgbaCss(hueRgba([], frame++ / (NB * NB))); + ctx.fillRect(x, y, BW, BH); +}, 16); + +// if (process.env.NODE_ENV !== "production") { +// const hot = (module).hot; +// hot && hot.dispose(() => {}); +// } diff --git a/examples/webgl-gpgpu-basics/tsconfig.json b/examples/grid-iterators/tsconfig.json similarity index 100% rename from examples/webgl-gpgpu-basics/tsconfig.json rename to examples/grid-iterators/tsconfig.json diff --git a/examples/webgl-gpgpu-basics/webpack.config.js b/examples/grid-iterators/webpack.config.js similarity index 100% rename from examples/webgl-gpgpu-basics/webpack.config.js rename to examples/grid-iterators/webpack.config.js diff --git a/examples/hdom-canvas-shapes/README.md b/examples/hdom-canvas-shapes/README.md index 7b0b4bcf4a..e929b40319 100644 --- a/examples/hdom-canvas-shapes/README.md +++ b/examples/hdom-canvas-shapes/README.md @@ -1,5 +1,7 @@ # hdom-canvas-shapes +![screenshots](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/hdom-canvas/hdom-canvas-shapes-results.png) + [Live demo](http://demo.thi.ng/umbrella/hdom-canvas-shapes/) This example demonstrates different features of the upcoming @@ -30,7 +32,7 @@ Related examples: Dataflow diagram: -![dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/hdom-canvas-shapes.png) +![dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/hdom-canvas/hdom-canvas-shapes.png) ## Building diff --git a/examples/imgui/README.md b/examples/imgui/README.md index 9a287dd366..4b49395d64 100644 --- a/examples/imgui/README.md +++ b/examples/imgui/README.md @@ -1,6 +1,6 @@ # imgui -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/imgui-demo.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/imgui/imgui-all.png) [Live demo](http://demo.thi.ng/umbrella/imgui/) @@ -9,7 +9,7 @@ WIP prototyping example for and realisation via [@thi.ng/hdom-canvas](https://github.com/thi-ng/umbrella/tree/master/packages/hdom-canvas). -Please consult package readmes for details. Also, please refer to the +Please consult package readme for details. Also, please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. diff --git a/examples/imgui/webpack.config.js b/examples/imgui/webpack.config.js new file mode 100644 index 0000000000..08baf21e9f --- /dev/null +++ b/examples/imgui/webpack.config.js @@ -0,0 +1,21 @@ +module.exports = { + entry: "./src/index.ts", + output: { + filename: "bundle.[hash].js", + path: __dirname + "/out" + }, + resolve: { + extensions: [".ts", ".js"] + }, + module: { + rules: [ + { + test: /\.(png|jpg|gif)$/, + loader: "file-loader", + options: { name: "[path][hash].[ext]" } + }, + { test: /\.ts$/, use: "ts-loader" } + ] + }, + node: false +}; diff --git a/examples/pixel-basics/README.md b/examples/pixel-basics/README.md index c3ef04c9ff..ad53594cb2 100644 --- a/examples/pixel-basics/README.md +++ b/examples/pixel-basics/README.md @@ -2,7 +2,7 @@ [Live demo](http://demo.thi.ng/umbrella/pixel-basics/) -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/pixel-basics.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/pixel/pixel-basics.png) Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. diff --git a/examples/rstream-dataflow/README.md b/examples/rstream-dataflow/README.md index 4b28b9a965..12d127ece9 100644 --- a/examples/rstream-dataflow/README.md +++ b/examples/rstream-dataflow/README.md @@ -8,7 +8,7 @@ on the wiki. ## About -![dataflow graph](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/rs-dflow.png) +![dataflow graph](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rs-dflow.png) This example combines the following packages to create & execute the above dataflow graph in a declarative manner. The diagram generation diff --git a/examples/rstream-spreadsheet/.gitignore b/examples/rstream-spreadsheet/.gitignore new file mode 100644 index 0000000000..0c5abcab62 --- /dev/null +++ b/examples/rstream-spreadsheet/.gitignore @@ -0,0 +1,5 @@ +.cache +out +node_modules +yarn.lock +*.js diff --git a/examples/rstream-spreadsheet/README.md b/examples/rstream-spreadsheet/README.md new file mode 100644 index 0000000000..b92d10b37a --- /dev/null +++ b/examples/rstream-spreadsheet/README.md @@ -0,0 +1,19 @@ +# rstream-spreadsheet + +[Live demo](http://demo.thi.ng/umbrella/rstream-spreadsheet/) + +Spreadsheet demo built w/ +[@thi.ng/rstream-graph](https://github.com/thi-ng/umbrella/tree/master/packages/rstream-graph) +primitives and [S-expression based formula +DSL](https://github.com/thi-ng/umbrella/tree/develop/packages/sexpr) to +dynamically define & edit the dataflow graph. + +Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2019 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/rstream-spreadsheet/index.html b/examples/rstream-spreadsheet/index.html new file mode 100644 index 0000000000..eb65c41002 --- /dev/null +++ b/examples/rstream-spreadsheet/index.html @@ -0,0 +1,61 @@ + + + + + + + rstream-spreadsheet + + + + +
+ +

S-expression formula syntax

+
    +
  • + a1 / + a1:c3 - cell ID / cell range + (case insensitive) +
  • +
  • + (* 10 (+ a1 a2:e2)) - 10 + times (cell A1 + entire row 2) +
  • +
  • + (min a1:c10) - min value of + columns A-C +
  • +
  • + (max a1:c10) - max value of + columns A-C +
  • +
  • + (avg a1:e5) - average value + of first 5 rows +
  • +
  • + (mag a1:e1) - vector + magnitude of row 1 +
  • +
  • + (abs a1) - absolute value of + cell A1 +
  • +
  • + (fit a1 a2 a3 a4 a5) - fit + cell value A1 from interval A2-A3 to A4-A5 +
  • +
+ + + diff --git a/examples/rstream-spreadsheet/package.json b/examples/rstream-spreadsheet/package.json new file mode 100644 index 0000000000..198afb4af8 --- /dev/null +++ b/examples/rstream-spreadsheet/package.json @@ -0,0 +1,29 @@ +{ + "name": "rstream-spreadsheet", + "version": "0.0.1", + "repository": "https://github.com/thi-ng/umbrella", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "clean": "rm -rf .cache build out", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report --experimental-scope-hoisting", + "build:webpack": "../../node_modules/.bin/webpack --mode production", + "start": "parcel index.html -p 8080 --open" + }, + "devDependencies": { + "parcel-bundler": "^1.12.3", + "terser": "^3.17.0", + "typescript": "^3.4.1" + }, + "dependencies": { + "@thi.ng/api": "latest", + "@thi.ng/rstream": "latest", + "@thi.ng/transducers-hdom": "latest" + }, + "browserslist": [ + "last 3 Chrome versions" + ], + "browser": { + "process": false + } +} \ No newline at end of file diff --git a/examples/rstream-spreadsheet/src/api.ts b/examples/rstream-spreadsheet/src/api.ts new file mode 100644 index 0000000000..17ee5c8f6c --- /dev/null +++ b/examples/rstream-spreadsheet/src/api.ts @@ -0,0 +1,24 @@ +import { ILifecycle } from "@thi.ng/hdom"; + +export const NUM_COLS = 5; +export const NUM_ROWS = 10; + +export const MAX_COL = "A".charCodeAt(0) + NUM_COLS - 1; + +export const CELL_STYLE = "div.dib.h2.pa2.ma0.br.bb.f7"; + +export const RE_CELL_ID = /^([A-Z])(\d+)$/i; +export const RE_CELL_RANGE = /^([A-Z])(\d+):([A-Z])(\d+)$/i; + +export interface Cell { + formula: string; + value: string | number; + error: string | null; + backup: string; + focus: boolean; +} + +export interface UICell extends ILifecycle { + element?: HTMLDivElement; + focus?: boolean; +} diff --git a/examples/rstream-spreadsheet/src/dsl.ts b/examples/rstream-spreadsheet/src/dsl.ts new file mode 100644 index 0000000000..d5470d6714 --- /dev/null +++ b/examples/rstream-spreadsheet/src/dsl.ts @@ -0,0 +1,258 @@ +import { Fn, IObjectOf } from "@thi.ng/api"; +import { defmulti } from "@thi.ng/defmulti"; +import { illegalArgs } from "@thi.ng/errors"; +import { fit } from "@thi.ng/math"; +import { memoize1 } from "@thi.ng/memoize"; +import { fromView } from "@thi.ng/rstream"; +import { + addNode, + node, + NodeInputSpec, + NodeSpec +} from "@thi.ng/rstream-graph"; +import { + ASTNode, + Implementations, + parse, + runtime, + Str, + Sym, + tokenize +} from "@thi.ng/sexpr"; +import { maybeParseFloat, Z2 } from "@thi.ng/strings"; +import { charRange } from "@thi.ng/strings"; +import { + add, + assocObj, + comp, + div, + filter, + map, + mapcat, + mapIndexed, + max, + mean, + min, + mul, + permutations, + range, + Reducer, + sub, + transduce +} from "@thi.ng/transducers"; +import { RE_CELL_ID, RE_CELL_RANGE } from "./api"; +import { DB, graph, removeCell } from "./state"; + +/** + * Runtime env, stores ID of result cell and tree/nesting depth of + * currently interpreted S-expression. + */ +interface Env { + id: string; + depth: number; +} + +// dynamic-dispatch function to delegate to actual DSL formula operators +const builtins = defmulti((x) => x.value); + +// init S-expression interpreter. this results in another +// dynamic-dispatch function which delegates based on AST node type +const rt = runtime, Env, any>({ + // As per Lisp convention, S-expressions are treated as function + // calls with 1st child item used as function name and rest as + // arguments. E.g. `(+ a1 b1 c1)` is a function call to the `+` + // function, with `a1`, `b1`, `c1` being arguments. + expr: (x, env) => + builtins(x.children[0], x.children, { + ...env, + depth: env.depth + 1 + }), + // other symbols are interpreted as cell IDs + sym: (x) => + RE_CELL_ID.test(x.value) + ? cellInput(x.value) + : illegalArgs("invalid cell ID"), + // strings & number used verbatim + str: (x) => ({ const: x.value }), + num: (x) => ({ const: x.value }) +}); + +/** + * S-expression evaluator. Parses and executes given s-expr and by doing + * so creates/updates the spreadsheet's dataflow graph. The `cellID` is + * used to store the result in the DB state atom. + * + * @param src + * @param cellID + */ +export const $eval = (src: string, cellID: string) => + rt(parse(tokenize(src)).children[0], { id: cellID, depth: 0 }); + +/** + * Takes a rstream-graph `NodeSpec` and array of AST nodes and an + * environment. For if the graph node corresponds to the top-level + * expression, the NodeSpec is configured to write the result of the + * computation back into the DB state atom. For inner/nested + * S-expressions we create an unique node ID to store the graph node in + * the graph. + * + * Any previously existing node for the resulting ID is first removed + * before the new one is created/added. + * + * @param spec + * @param vals + * @param env + */ +const defNode = (spec: NodeSpec, vals: ASTNode[], env: Env) => { + let id: string; + if (env.depth === 1) { + id = env.id; + spec.outs = { + "*": [id, "value"] + }; + } else { + id = JSON.stringify(vals); + if (graph[id]) { + return { stream: () => graph[id].node }; + } + } + removeCell(id); + const node = addNode(graph, DB, id, spec); + return { stream: () => node.node }; +}; + +/** + * Higher order function to define a DSL operator graph node with given + * transformation `fn`. Once added to the graph, that function is later + * called with a single arg, an object of numbered inputs like: `{ "00": + * 23, "01": 42 ... }` These inputs represent the resolved reactive + * argument values given in the original S-exression. For example, `(+ + * a1:c1 10)` will cause an object like: + * + * ``` + * { + * "00": curr value of a1, + * "01": curr value of b1, + * "02": curr value of c1, + * "03": 10, + * } + * ``` + * + * @param fn + */ +const defBuiltin = (fn: Fn, any>) => ( + _: ASTNode, + vals: ASTNode[], + env: Env +) => + defNode( + { + // wrapped transformation fn + fn: node(map(fn)), + // compile all s-expr arguments into a single object of input stream defs. + // - cell ranges yield multiple inputs + // - single cell IDs yield stream of cell's value + // - numeric args yield a single-item stream def of the given number + ins: transduce( + comp( + mapcat((i) => { + try { + return cellRangeInputs(i); + } catch (e) { + return [rt(i, env)]; + } + }), + mapIndexed((i, input) => [Z2(i), input]) + ), + assocObj(), + vals.slice(1) + ) + }, + vals, + env + ); + +/** + * Similar to `defBuiltin()`, but for reducer-based computations. Takes + * a no-arg function returning a reducer and an optional + * pre-transformer. The resulting transformation function filters out + * all empty cells. + * + * @param rfn + * @param xf + */ +const defReducer = ( + rfn: () => Reducer, + xf: Fn = (x) => x +) => + defBuiltin((ports: IObjectOf) => { + const keys = Object.keys(ports).sort(); + return transduce( + comp(map((k) => ports[k]), filter((x) => x != null), map(xf)), + rfn(), + xf(ports[keys.shift()!]), + keys + ); + }); + +/** + * Returns a rstream-graph NodeInputSpec linked to the cell value given + * by `id`, stored in the central DB state atom. The stream is + * configured to attempt string-to-number conversion of its values. + */ +const cellInput = memoize1( + (id: string): NodeInputSpec => ({ + stream: () => + fromView(DB, [id.toUpperCase(), "value"], (x) => + maybeParseFloat(x, null) + ) + }) +); + +/** + * Returns iterator of NodeInputSpecs for given cell range string. + * + * @param x + */ +const cellRangeInputs = (x: ASTNode) => { + const [acol, arow, bcol, brow] = parseCellIDRange(x); + return map<[string, number], NodeInputSpec>( + ([c, r]) => cellInput(`${c}${r}`), + permutations( + charRange(acol.toUpperCase(), bcol.toUpperCase()), + range(parseInt(arow), parseInt(brow) + 1) + ) + ); +}; + +/** + * Parses cell range string, e.g. `a5:c10` => ["a",5,"c",10] + * + * @param x + */ +const parseCellIDRange = (x: ASTNode) => { + const match = RE_CELL_RANGE.exec((x).value); + if (!match) illegalArgs("invalid cell range"); + return match!.slice(1, 5); +}; + +/** + * Register built-ins. + */ +builtins.addAll({ + "+": defReducer(add), + "*": defReducer(mul), + "-": defReducer(sub), + "/": defReducer(() => div(1)), + min: defReducer(min), + max: defReducer(max), + avg: defReducer(() => mean()), + mag: defReducer( + () => [() => 0, (acc) => Math.sqrt(acc), (acc, x) => acc + x], + (x) => x * x + ), + abs: defBuiltin(({ "00": x }) => Math.abs(x)), + fit: defBuiltin(({ "00": x, "01": a, "02": b, "03": c, "04": d }) => + fit(x, a, b, c, d) + ) +}); diff --git a/examples/rstream-spreadsheet/src/index.ts b/examples/rstream-spreadsheet/src/index.ts new file mode 100644 index 0000000000..2abbf7d731 --- /dev/null +++ b/examples/rstream-spreadsheet/src/index.ts @@ -0,0 +1,157 @@ +import { isNumber } from "@thi.ng/checks"; +import { fromAtom } from "@thi.ng/rstream"; +import { charRange } from "@thi.ng/strings"; +import { + comp, + map, + mapIndexed, + partition, + permutations, + push, + range, + transduce +} from "@thi.ng/transducers"; +import { updateDOM } from "@thi.ng/transducers-hdom"; +import { + CELL_STYLE, + MAX_COL, + NUM_COLS, + NUM_ROWS, + UICell +} from "./api"; +import { + blurCell, + cancelCell, + DB, + focusCell, + graph, + updateCell +} from "./state"; + +const formatCell = (x: string | number) => (isNumber(x) ? x.toFixed(2) : x); + +/** + * Choose background color based on cell state. + * + * @param cell + */ +const cellBackground = (cell: any) => + cell.focus + ? "bg-yellow" + : cell.formula + ? cell.error + ? "bg-red white" + : "bg-light-green" + : ""; + +/** + * thi.ng/hdom cell component with lifecycle methods. (The current + * markup used (editable div's) is far from perfect...) + * + * @param cellid tuple + */ +const cell = ([row, col]: [number, string]) => + { + init(el: HTMLDivElement) { + this.element = el; + this.focus = false; + }, + render(_: any, cells: any) { + const id = `${col}${row}`; + const cell = cells[id]; + return [ + `${CELL_STYLE}.w4.overflow-y-hidden.overflow-x-scroll`, + { + class: cellBackground(cell), + contentEditable: true, + onfocus: () => { + this.focus = true; + focusCell(id); + }, + onblur: () => { + if (this.focus) { + updateCell(id, this.element!.textContent!.trim()); + this.focus = false; + } + blurCell(id); + }, + onkeydown: (e: KeyboardEvent) => { + switch (e.key) { + case "Enter": + case "Tab": + updateCell( + id, + this.element!.textContent!.trim() + ); + this.element!.blur(); + break; + case "Escape": + this.focus = false; + cancelCell(id); + this.element!.blur(); + } + } + }, + String( + cell.focus && cell.formula + ? cell.formula + : cell.error || formatCell(cell.value) + ) + ]; + } + }; + +/** + * Main UI component HOF. Attached to to `main` rstream (defined below) + * and called with the DB state atom's current state when it changes. + * The function returns a thi.ng/hdom component tree representing the + * entire spreadsheet. + */ +const app = () => { + const CELLS: UICell[][] = transduce( + comp(map(cell), partition(NUM_COLS)), + push(), + permutations(range(1, NUM_ROWS + 1), charRange("A", MAX_COL)) + ); + return (state: any) => [ + "div", + {}, + [`${CELL_STYLE}.w2.b.bg-moon-gray`, "\u00a0"], + map( + (col) => [`${CELL_STYLE}.w4.b.bg-moon-gray`, {}, col], + charRange("A", MAX_COL) + ), + mapIndexed( + (i, rowid) => [ + "div", + {}, + [ + `${CELL_STYLE}.w2.b.bg-moon-gray.overflow-y-hidden.overflow-x-scroll`, + {}, + rowid + ], + ...CELLS[i].map((cell) => [cell, state]) + ], + range(1, NUM_ROWS + 1) + ) + ]; +}; + +// setLogger(new ConsoleLogger("rstream")); + +// main state value subscription +const main = fromAtom(DB); + +// transform state value into UI components and then apply to DOM. +// due to the use of `contentEditable` div's for spreadsheet cells, we +// need to disable the use of automatic span wrappers for text content +// in hdom +main.transform(map(app()), updateDOM({ span: false })); + +(window)["DB"] = DB; +(window)["graph"] = graph; + +if (process.env.NODE_ENV !== "production") { + const hot = (module).hot; + hot && hot.dispose(() => main.done()); +} diff --git a/examples/rstream-spreadsheet/src/state.ts b/examples/rstream-spreadsheet/src/state.ts new file mode 100644 index 0000000000..a5cd373cd9 --- /dev/null +++ b/examples/rstream-spreadsheet/src/state.ts @@ -0,0 +1,94 @@ +import { IObjectOf } from "@thi.ng/api"; +import { Atom } from "@thi.ng/atom"; +import { setIn, setInMany } from "@thi.ng/paths"; +import { Node, removeNode } from "@thi.ng/rstream-graph"; +import { charRange } from "@thi.ng/strings"; +import { + assocObj, + map, + permutations, + range, + transduce +} from "@thi.ng/transducers"; +import { Cell, MAX_COL, NUM_ROWS } from "./api"; +import { $eval } from "./dsl"; + +/** + * Initializes state atom with default cell values. Later on, the + * dataflow graph operators defined by various formula expressions will + * then attach subscriptions manipulate individual cell values. + */ +export const DB = new Atom>( + transduce( + map(([col, row]) => [ + `${col}${row}`, + { formula: "", value: "", backup: "", focus: false, error: "" } + ]), + assocObj(), + permutations(charRange("A", MAX_COL), range(1, NUM_ROWS + 1)) + ) +); + +/** + * Container object for storing dataflow graph. + */ +export const graph: IObjectOf = {}; + +export const removeCell = (id: string) => removeNode(graph, id); + +/** + * Enables focus flag for given cell + * + * @param id + */ +export const focusCell = (id: string) => { + DB.swapIn(id, (cell: Cell) => + setInMany(cell, "focus", true, "backup", cell.formula) + ); +}; + +/** + * Disables focus flag for given cell + * + * @param id + */ +export const blurCell = (id: string) => { + DB.swapIn(id, (cell: Cell) => setIn(cell, "focus", false)); +}; + +/** + * Restores cell value to `backup` string and clears focus. + * + * @param id + */ +export const cancelCell = (id: string) => { + DB.swapIn(id, (cell: Cell) => + setInMany(cell, "focus", false, "formula", cell.backup) + ); +}; + +/** + * Cell on-change handler. Checks if `val` is potentially an + * S-expression and if so attempts to parse and execute it. Sets cell + * error if failed. If not an s-expr, updates cell value and clears + * error. + * + * @param id + * @param val + */ +export const updateCell = (id: string, val: string) => { + if (val.startsWith("(")) { + DB.resetIn([id, "formula"], val); + try { + $eval(val, id); + DB.resetIn([id, "error"], null); + } catch (e) { + DB.resetIn([id, "error"], e.message); + } + } else { + removeCell(id); + DB.swapIn(id, (cell) => + setInMany(cell, "value", val, "formula", "", "error", null) + ); + } +}; diff --git a/examples/rstream-spreadsheet/tsconfig.json b/examples/rstream-spreadsheet/tsconfig.json new file mode 100644 index 0000000000..bbf112cc18 --- /dev/null +++ b/examples/rstream-spreadsheet/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "target": "es6", + "sourceMap": true + }, + "include": [ + "./src/**/*.ts" + ] +} diff --git a/examples/rstream-spreadsheet/webpack.config.js b/examples/rstream-spreadsheet/webpack.config.js new file mode 100644 index 0000000000..bf16021356 --- /dev/null +++ b/examples/rstream-spreadsheet/webpack.config.js @@ -0,0 +1,23 @@ +module.exports = { + entry: "./src/index.ts", + output: { + filename: "bundle.[hash].js", + path: __dirname + "/out" + }, + resolve: { + extensions: [".ts", ".js"] + }, + module: { + rules: [ + { + test: /\.(png|jpg|gif)$/, + loader: "file-loader", + options: { name: "[path][hash].[ext]" } + }, + { test: /\.ts$/, use: "ts-loader" } + ] + }, + node: { + process: false + } +}; diff --git a/examples/shader-ast-canvas2d/src/index.ts b/examples/shader-ast-canvas2d/src/index.ts index 3ecb1933bf..815317eebd 100644 --- a/examples/shader-ast-canvas2d/src/index.ts +++ b/examples/shader-ast-canvas2d/src/index.ts @@ -17,7 +17,7 @@ import { vec4 } from "@thi.ng/shader-ast"; import { targetGLSL } from "@thi.ng/shader-ast-glsl"; -import { initRuntime, targetJS } from "@thi.ng/shader-ast-js"; +import { canvasRenderer, targetJS } from "@thi.ng/shader-ast-js"; import { fit0111, fit1101 } from "@thi.ng/shader-ast-stdlib"; const js = targetJS(); @@ -80,10 +80,10 @@ canvas.width = W; canvas.height = H; document.body.appendChild(canvas); -const rt = initRuntime({ canvas }); +const rt = canvasRenderer(canvas); const t0 = Date.now(); setInterval(() => { const time = (Date.now() - t0) * 0.001; - rt.update((frag) => fn(frag, size, time)); + rt((frag) => fn(frag, size, time)); }, 16); diff --git a/examples/shader-ast-noise/src/index.ts b/examples/shader-ast-noise/src/index.ts index 0e93ea7370..aa83c7d7a1 100644 --- a/examples/shader-ast-noise/src/index.ts +++ b/examples/shader-ast-noise/src/index.ts @@ -15,7 +15,7 @@ import { vec4 } from "@thi.ng/shader-ast"; import { GLSLVersion, targetGLSL } from "@thi.ng/shader-ast-glsl"; -import { initRuntime, targetJS } from "@thi.ng/shader-ast-js"; +import { canvasRenderer, targetJS } from "@thi.ng/shader-ast-js"; import { additive, aspectCorrectedUV, @@ -82,12 +82,12 @@ if (JS_MODE) { // JS Canvas 2D shader emulation from here... // const fn = JS.compile(shaderProgram).mainImage; - const rt = initRuntime({ canvas }); + const rt = canvasRenderer(canvas); let time = 0; setInterval(() => { time += 0.01; - rt.update((frag) => fn(frag, size, time)); + rt((frag) => fn(frag, size, time)); }, 16); } else { // diff --git a/examples/shader-ast-raymarch/src/index.ts b/examples/shader-ast-raymarch/src/index.ts index 23e9bdcc73..01f896bdcf 100644 --- a/examples/shader-ast-raymarch/src/index.ts +++ b/examples/shader-ast-raymarch/src/index.ts @@ -21,7 +21,7 @@ import { vec4 } from "@thi.ng/shader-ast"; import { GLSLVersion, targetGLSL } from "@thi.ng/shader-ast-glsl"; -import { initRuntime, targetJS } from "@thi.ng/shader-ast-js"; +import { canvasRenderer, targetJS } from "@thi.ng/shader-ast-js"; import { clamp01, diffuseLighting, @@ -183,7 +183,7 @@ if (JS_MODE) { // JS Canvas 2D shader emulation from here... // const fn = JS.compile(shaderProgram).mainImage; - const rt = initRuntime({ canvas }); + const rt = canvasRenderer(canvas); let time = 0; setInterval(() => { @@ -193,7 +193,7 @@ if (JS_MODE) { Math.cos(time / 2) * 0.7, Math.sin(time) * 2.5 ]; - rt.update((frag) => fn(frag, size, eyePos, lightDir)); + rt((frag) => fn(frag, size, eyePos, lightDir)); }, 16); } else { // diff --git a/examples/shader-ast-sdf2d/src/index.ts b/examples/shader-ast-sdf2d/src/index.ts index 9e7c85bd00..b22191c7ed 100644 --- a/examples/shader-ast-sdf2d/src/index.ts +++ b/examples/shader-ast-sdf2d/src/index.ts @@ -17,7 +17,7 @@ import { vec4 } from "@thi.ng/shader-ast"; import { GLSLVersion, targetGLSL } from "@thi.ng/shader-ast-glsl"; -import { initRuntime, targetJS } from "@thi.ng/shader-ast-js"; +import { canvasRenderer, targetJS } from "@thi.ng/shader-ast-js"; import { aspectCorrectedUV, fit1101, @@ -114,10 +114,10 @@ if (JS_MODE) { // JS Canvas 2D shader emulation from here... // const fn = JS.compile(shaderProgram).mainImage; - const rt = initRuntime({ canvas }); + const rt = canvasRenderer(canvas); setInterval(() => { - rt.update((frag) => fn(frag, size)); + rt((frag) => fn(frag, size)); }, 16); } else { // diff --git a/examples/shader-ast-tunnel/src/index.ts b/examples/shader-ast-tunnel/src/index.ts index b9618d4510..e05597f4b1 100644 --- a/examples/shader-ast-tunnel/src/index.ts +++ b/examples/shader-ast-tunnel/src/index.ts @@ -25,7 +25,7 @@ import { vec4 } from "@thi.ng/shader-ast"; import { GLSLVersion, targetGLSL } from "@thi.ng/shader-ast-glsl"; -import { initRuntime, JS_DEFAULT_ENV, targetJS } from "@thi.ng/shader-ast-js"; +import { canvasRenderer, JS_DEFAULT_ENV, targetJS } from "@thi.ng/shader-ast-js"; import { compileModel, draw, @@ -129,12 +129,12 @@ if (JS_MODE) { // under the hood all vector & matrix operations delegate to // thi.ng/vectors and thi.ng/matrices packages by default const fn = JS.compile(shaderProgram).mainImage; - const rt = initRuntime({ canvas }); + const rt = canvasRenderer(canvas); let time = 0; setInterval(() => { time += 0.05; - rt.update((frag) => fn(frag, size, time)); + rt((frag) => fn(frag, size, time)); }, 16); }); } else { diff --git a/examples/svg-barchart/README.md b/examples/svg-barchart/README.md index 2c0026dddf..b6d066344d 100644 --- a/examples/svg-barchart/README.md +++ b/examples/svg-barchart/README.md @@ -4,7 +4,7 @@ SVG bar chart component & one-off rendering. -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/svg-barchart.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/svg-barchart.png) Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) diff --git a/examples/webgl-cubemap/src/index.ts b/examples/webgl-cubemap/src/index.ts index 0aee8401bc..3d17f2229d 100644 --- a/examples/webgl-cubemap/src/index.ts +++ b/examples/webgl-cubemap/src/index.ts @@ -17,6 +17,7 @@ import { vec4 } from "@thi.ng/shader-ast"; import { + BLEND_ADD, compileModel, cube, cubeMap, @@ -50,7 +51,9 @@ const CUBEMAP_SHADER: ShaderSpec = { tex: "samplerCube" }, state: { - depth: true + depth: false, + blend: true, + blendFn: BLEND_ADD } }; @@ -101,8 +104,8 @@ const app = () => { // prettier-ignore update: (el, gl, __, time) => { if (!model) return; - const bg = 0.1; - const p = perspective([], 45, gl.drawingBufferWidth/gl.drawingBufferHeight, 0.01, 5); + const bg = 0.01; + const p = perspective([], 45, gl.drawingBufferWidth/gl.drawingBufferHeight, 0.01, 10); const v = lookAt([],[0, 0, sin(time, 0.00008, 1.99, 2)],[0, 0, 0], [0, 1, 0]); const m = transform44([], [0, 0, 0], [sin(time, 0.0001, 0.7, 0.5), time * 0.0007,0], 1); model.uniforms!.mvp = concat([], p, v, m); diff --git a/examples/webgl-gpgpu-basics/README.md b/examples/webgl-gpgpu-basics/README.md deleted file mode 100644 index 24afc550c6..0000000000 --- a/examples/webgl-gpgpu-basics/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# webgl-gpgpu-basics - -[Live demo](http://demo.thi.ng/umbrella/webgl-gpgpu-basics/) - -Minimal example demonstrating usage of -[@thi.ng/webgl](https://github.com/thi-ng/umbrella/tree/master/packages/webgl)'s -GPGPU capability. Additionally, the actual GPU code is written directly -in TypeScript, using -[@thi.ng/shader-ast](https://github.com/thi-ng/umbrella/tree/master/packages/shader-ast). - -Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. - -## Authors - -- Karsten Schmidt - -## License - -© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/webgl-gpgpu-basics/src/index.ts b/examples/webgl-gpgpu-basics/src/index.ts deleted file mode 100644 index db9c24c869..0000000000 --- a/examples/webgl-gpgpu-basics/src/index.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - assign, - defMain, - index, - mul, - sym, - texture, - Vec4Sym -} from "@thi.ng/shader-ast"; -import { range } from "@thi.ng/transducers"; -import { gpgpu } from "@thi.ng/webgl"; - -const ctx = gpgpu({ - size: 64, // might be adjusted / rounded up to next power of 2 - inputs: 1, // max inputs - outputs: 3, // max outputs - version: 2 // webgl version -}); - -const job = ctx.newJob({ - inputs: 1, - outputs: 2, - src: (_, unis, ins, outs) => [ - defMain(() => { - let val: Vec4Sym; - return [ - (val = sym(texture(index(unis.inputs, 0), ins.v_uv))), - assign(outs.output0, mul(val, unis.factorA)), - assign(outs.output1, mul(val, unis.factorB)) - ]; - }) - ], - uniforms: { - // uniform params incl. default values - // an `inputs` uniform (sampler2D[]) will be injected automatically - factorA: ["float", 2], - factorB: ["float", 3] - } -}); - -const src = new Float32Array([...range(ctx.inputSize(0))]); -console.log("Original input data:"); -console.log(src); - -job.run({ inputs: [src] }); -console.log("Results of first iteration:"); -// obtain results as Float32Array -console.log(job.result(null, 0)); -console.log(job.result(null, 1)); - -job.run({ inputs: [ctx.outputs[0].tex], outputs: [1, 2] }); -console.log("Results of second iteration:"); -console.log(job.result(null, 1)); -console.log(job.result(null, 2)); - -job.run({ - inputs: [ctx.outputs[1].tex], - outputs: [0, 2], - uniforms: { factorA: 10, factorB: 100 } -}); -console.log("Final results:"); -console.log(job.result(null, 0)); -console.log(job.result(null, 2)); diff --git a/examples/webgl-multipass/.gitignore b/examples/webgl-multipass/.gitignore new file mode 100644 index 0000000000..0c5abcab62 --- /dev/null +++ b/examples/webgl-multipass/.gitignore @@ -0,0 +1,5 @@ +.cache +out +node_modules +yarn.lock +*.js diff --git a/examples/webgl-multipass/README.md b/examples/webgl-multipass/README.md new file mode 100644 index 0000000000..d9da83a2d2 --- /dev/null +++ b/examples/webgl-multipass/README.md @@ -0,0 +1,13 @@ +# webgl-multipass + +[Live demo](http://demo.thi.ng/umbrella/webgl-multipass/) + +Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/webgl-multipass/index.html b/examples/webgl-multipass/index.html new file mode 100644 index 0000000000..4746f103f8 --- /dev/null +++ b/examples/webgl-multipass/index.html @@ -0,0 +1,16 @@ + + + + + + + webgl-multipass + + + + +
+ + + diff --git a/examples/webgl-gpgpu-basics/package.json b/examples/webgl-multipass/package.json similarity index 80% rename from examples/webgl-gpgpu-basics/package.json rename to examples/webgl-multipass/package.json index 08bcab921e..bf54ca8619 100644 --- a/examples/webgl-gpgpu-basics/package.json +++ b/examples/webgl-multipass/package.json @@ -1,5 +1,5 @@ { - "name": "webgl-gpgpu-basics", + "name": "webgl-multipass", "version": "0.0.1", "repository": "https://github.com/thi-ng/umbrella", "author": "Karsten Schmidt ", @@ -12,13 +12,13 @@ }, "devDependencies": { "parcel-bundler": "^1.12.3", - "terser": "^4.0.0", + "terser": "^3.17.0", "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/shader-ast": "latest", - "@thi.ng/transducers": "latest", - "@thi.ng/webgl": "latest" + "@thi.ng/api": "latest", + "@thi.ng/rstream": "latest", + "@thi.ng/transducers-hdom": "latest" }, "browserslist": [ "last 3 Chrome versions" diff --git a/examples/webgl-multipass/src/index.ts b/examples/webgl-multipass/src/index.ts new file mode 100644 index 0000000000..82ab1a8c11 --- /dev/null +++ b/examples/webgl-multipass/src/index.ts @@ -0,0 +1,129 @@ +import { canvas2d, GRAY8, PackedBuffer } from "@thi.ng/pixel"; +import { + $x, + $xyz, + assign, + defMain, + fract, + index, + length, + mul, + pow, + sin, + sub, + sym, + texture, + Vec2Sym, + vec3, + vec4, + Vec4Sym +} from "@thi.ng/shader-ast"; +import { clamp01, fit1101, fragUV } from "@thi.ng/shader-ast-stdlib"; +import { + glCanvas, + multipass, + readTexture, + TextureFormat, + TextureType +} from "@thi.ng/webgl"; + +// create WebGL canvas +const canvas = glCanvas({ + // width: window.innerWidth, + // height: window.innerHeight, + width: 512, + height: 512, + parent: document.body, + version: 2 +}); + +// init multipass shader pipeline +const toy = multipass({ + gl: canvas.gl, + width: 32, + height: 32, + textures: { + foo: { format: TextureFormat.RGBA32F }, + bar: { format: TextureFormat.R32F } + }, + passes: [ + { + fs: (gl, unis, ins, outs) => [ + defMain(() => { + let uv: Vec2Sym; + return [ + (uv = sym(fragUV(gl.gl_FragCoord, unis.resolution))), + assign( + outs.output0, + vec4(vec3(uv, fract(unis.time)), 1) + ), + assign( + outs.output1, + vec4(clamp01(length(sub(uv, 0.5)))) + ) + ]; + }) + ], + inputs: [], + outputs: ["foo", "bar"], + uniforms: { + time: "float", + resolution: "vec2" + }, + uniformVals: { + // foo: () => Math.random() + } + }, + { + fs: (gl, unis, ins, outs) => [ + defMain(() => { + let uv: Vec2Sym; + return [ + (uv = sym(fragUV(gl.gl_FragCoord, unis.resolution))), + assign( + outs.fragColor, + vec4( + mul( + $xyz(texture(index(unis.inputs, 0), uv)), + pow( + $x(texture(index(unis.inputs, 1), uv)), + fit1101(sin(unis.time)) + ) + ), + 1 + ) + ) + ]; + }) + ], + inputs: ["foo", "bar"], + outputs: [], + uniforms: { + resolution: "vec2", + time: "float" + } + } + ] +}); + +toy.update(0); + +const canv = canvas2d(32, 32); +document.body.appendChild(canv.canvas); +new PackedBuffer( + 32, + 32, + GRAY8, + readTexture( + canvas.gl, + toy.textures.bar, + TextureFormat.RED, + TextureType.UNSIGNED_BYTE, + new Uint8Array(32 * 32) + ) +).blitCanvas(canv.canvas); + +if (process.env.NODE_ENV !== "production") { + const hot = (module).hot; + hot && hot.dispose(() => toy.stop()); +} diff --git a/examples/webgl-multipass/tsconfig.json b/examples/webgl-multipass/tsconfig.json new file mode 100644 index 0000000000..bbf112cc18 --- /dev/null +++ b/examples/webgl-multipass/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "target": "es6", + "sourceMap": true + }, + "include": [ + "./src/**/*.ts" + ] +} diff --git a/examples/webgl-multipass/webpack.config.js b/examples/webgl-multipass/webpack.config.js new file mode 100644 index 0000000000..bf16021356 --- /dev/null +++ b/examples/webgl-multipass/webpack.config.js @@ -0,0 +1,23 @@ +module.exports = { + entry: "./src/index.ts", + output: { + filename: "bundle.[hash].js", + path: __dirname + "/out" + }, + resolve: { + extensions: [".ts", ".js"] + }, + module: { + rules: [ + { + test: /\.(png|jpg|gif)$/, + loader: "file-loader", + options: { name: "[path][hash].[ext]" } + }, + { test: /\.ts$/, use: "ts-loader" } + ] + }, + node: { + process: false + } +}; diff --git a/examples/webgl-shadertoy/.gitignore b/examples/webgl-shadertoy/.gitignore new file mode 100644 index 0000000000..0c5abcab62 --- /dev/null +++ b/examples/webgl-shadertoy/.gitignore @@ -0,0 +1,5 @@ +.cache +out +node_modules +yarn.lock +*.js diff --git a/examples/webgl-shadertoy/README.md b/examples/webgl-shadertoy/README.md new file mode 100644 index 0000000000..014b01d782 --- /dev/null +++ b/examples/webgl-shadertoy/README.md @@ -0,0 +1,13 @@ +# webgl-shadertoy + +[Live demo](http://demo.thi.ng/umbrella/webgl-shadertoy/) + +Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki. + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/examples/webgl-shadertoy/index.html b/examples/webgl-shadertoy/index.html new file mode 100644 index 0000000000..6bc7487bee --- /dev/null +++ b/examples/webgl-shadertoy/index.html @@ -0,0 +1,24 @@ + + + + + + + webgl-shadertoy + + + + +
+ Hold down mouse button to change color theme +
+ + + diff --git a/examples/webgl-shadertoy/package.json b/examples/webgl-shadertoy/package.json new file mode 100644 index 0000000000..9c201e9ceb --- /dev/null +++ b/examples/webgl-shadertoy/package.json @@ -0,0 +1,29 @@ +{ + "name": "webgl-shadertoy", + "version": "0.0.1", + "repository": "https://github.com/thi-ng/umbrella", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "clean": "rm -rf .cache build out", + "build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report --experimental-scope-hoisting", + "build:webpack": "../../node_modules/.bin/webpack --mode production", + "start": "parcel index.html -p 8080 --open" + }, + "devDependencies": { + "parcel-bundler": "^1.12.3", + "terser": "^3.17.0", + "typescript": "^3.4.1" + }, + "dependencies": { + "@thi.ng/api": "latest", + "@thi.ng/rstream": "latest", + "@thi.ng/transducers-hdom": "latest" + }, + "browserslist": [ + "last 3 Chrome versions" + ], + "browser": { + "process": false + } +} diff --git a/examples/webgl-shadertoy/src/index.ts b/examples/webgl-shadertoy/src/index.ts new file mode 100644 index 0000000000..8b09b5a63a --- /dev/null +++ b/examples/webgl-shadertoy/src/index.ts @@ -0,0 +1,88 @@ +import { + $xy, + add, + distance, + eq, + float, + FloatSym, + fract, + int, + min, + mix, + mul, + neg, + ret, + sin, + sym, + Vec2Sym, + Vec2Term, + vec3, + Vec3Sym, + vec4 +} from "@thi.ng/shader-ast"; +import { aspectCorrectedUV, fit1101 } from "@thi.ng/shader-ast-stdlib"; +import { glCanvas } from "@thi.ng/webgl"; +import { MainImageFn, shaderToy } from "@thi.ng/webgl-shadertoy"; + +// main shader function, supplied to `shaderToy` below +// the 2 args given are objects containing GLSL builtin vars and uniforms +// +// see: +// https://github.com/thi-ng/umbrella/blob/master/packages/shader-ast-glsl/src/api.ts#L22 +// https://github.com/thi-ng/umbrella/blob/master/packages/webgl-shadertoy/src/api.ts#L13 +const mainImage: MainImageFn = (gl, unis) => { + // predeclare local vars / symbols + let uv: Vec2Sym; + let mp: Vec2Sym; + let d1: FloatSym; + let d2: FloatSym; + let col: Vec3Sym; + + // Inline function to create ring pattern with center at `p` + const rings = (p: Vec2Term, speed = 0.25, freq = 50) => + sin(mul(add(distance(uv, p), fract(mul(unis.time, speed))), freq)); + + return [ + // let's work in [-1..+1] range (based on vertical resolution) + (uv = sym(aspectCorrectedUV($xy(gl.gl_FragCoord), unis.resolution))), + (mp = sym(aspectCorrectedUV(unis.mouse, unis.resolution))), + // compute ring colors + (d1 = sym(rings(mp))), + (d2 = sym(rings(neg(mp)))), + // combine rings and multiply with target color based on + // mouse button state + (col = sym( + mul( + vec3(fit1101(min(d1, d2))), + mix( + vec3(1), + vec3(d1, 0, d2), + float(eq(unis.mouseButtons, int(1))) + ) + ) + )), + // return as vec4 (mandatory) + ret(vec4(col, 1)) + ]; +}; + +// create WebGL2 canvas +const canvas = glCanvas({ + width: window.innerWidth, + height: window.innerHeight, + parent: document.body, + version: 1 +}); + +// init shader toy with canvas & shader fn +const toy = shaderToy({ + canvas: canvas.canvas, + gl: canvas.gl, + main: mainImage +}); + +toy.start(); + +// toy.stop(); + +// toy.recompile(/* pass new mainImage fn */); diff --git a/examples/webgl-shadertoy/tsconfig.json b/examples/webgl-shadertoy/tsconfig.json new file mode 100644 index 0000000000..bbf112cc18 --- /dev/null +++ b/examples/webgl-shadertoy/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "target": "es6", + "sourceMap": true + }, + "include": [ + "./src/**/*.ts" + ] +} diff --git a/examples/webgl-shadertoy/webpack.config.js b/examples/webgl-shadertoy/webpack.config.js new file mode 100644 index 0000000000..bf16021356 --- /dev/null +++ b/examples/webgl-shadertoy/webpack.config.js @@ -0,0 +1,23 @@ +module.exports = { + entry: "./src/index.ts", + output: { + filename: "bundle.[hash].js", + path: __dirname + "/out" + }, + resolve: { + extensions: [".ts", ".js"] + }, + module: { + rules: [ + { + test: /\.(png|jpg|gif)$/, + loader: "file-loader", + options: { name: "[path][hash].[ext]" } + }, + { test: /\.ts$/, use: "ts-loader" } + ] + }, + node: { + process: false + } +}; diff --git a/examples/webgl-ssao/src/index.ts b/examples/webgl-ssao/src/index.ts index 70e6aa951e..fc77928e7d 100644 --- a/examples/webgl-ssao/src/index.ts +++ b/examples/webgl-ssao/src/index.ts @@ -72,13 +72,11 @@ const app = () => { } const [colorTex, posTex, normTex, noiseTex, ssaoTex] = [ {}, - { internalFormat: gl.RGBA16F, type: gl.FLOAT }, - { internalFormat: gl.RGBA16F, type: gl.FLOAT }, + { format: gl.RGBA16F }, + { format: gl.RGBA16F }, { image: NOISE, - internalFormat: gl.RG16F, - format: gl.RG, - type: gl.FLOAT + format: gl.RG16F }, {} ].map((opts: Partial) => @@ -206,5 +204,3 @@ if (process.env.NODE_ENV !== "production") { const hot = (module).hot; hot && hot.dispose(cancel); } - -//window["params"] = PARAMS; diff --git a/examples/webgl-ssao/src/shaders.ts b/examples/webgl-ssao/src/shaders.ts index bb52662115..28011494c0 100644 --- a/examples/webgl-ssao/src/shaders.ts +++ b/examples/webgl-ssao/src/shaders.ts @@ -10,7 +10,12 @@ import { vec4 } from "@thi.ng/shader-ast"; import { clamp01 } from "@thi.ng/shader-ast-stdlib"; -import { FX_SHADER_SPEC, ShaderFn, ShaderSpec } from "@thi.ng/webgl"; +import { + FX_SHADER_SPEC, + FX_SHADER_SPEC_UV, + ShaderFn, + ShaderSpec +} from "@thi.ng/webgl"; export const LIGHT_SHADER: ShaderSpec = { vs: `void main() { @@ -119,7 +124,7 @@ void main() { } }; -export const FINAL_SHADER: ShaderSpec = mergeDeepObj(FX_SHADER_SPEC, { +export const FINAL_SHADER: ShaderSpec = mergeDeepObj(FX_SHADER_SPEC_UV, { fs: ( ((_, unis, ins, outs) => [ defMain(() => [ diff --git a/examples/xml-converter/README.md b/examples/xml-converter/README.md index d60ae94e3e..afa73616fd 100644 --- a/examples/xml-converter/README.md +++ b/examples/xml-converter/README.md @@ -15,7 +15,7 @@ This diagram illustrates the [@thi.ng/rstream](https://github.com/thi-ng/umbrella/tree/master/packages/rstream) dataflow topology used by the browser app: -![dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/xml-converter.png) +![dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/xml-converter.png) ## Browser version diff --git a/packages/adjacency/CHANGELOG.md b/packages/adjacency/CHANGELOG.md index 47b979685e..fcbba3a2ad 100644 --- a/packages/adjacency/CHANGELOG.md +++ b/packages/adjacency/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.24](https://github.com/thi-ng/umbrella/compare/@thi.ng/adjacency@0.1.23...@thi.ng/adjacency@0.1.24) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/adjacency + + + + + ## [0.1.23](https://github.com/thi-ng/umbrella/compare/@thi.ng/adjacency@0.1.22...@thi.ng/adjacency@0.1.23) (2019-08-21) **Note:** Version bump only for package @thi.ng/adjacency diff --git a/packages/adjacency/package.json b/packages/adjacency/package.json index 8cb5f2c8ae..f1dd844b7e 100644 --- a/packages/adjacency/package.json +++ b/packages/adjacency/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/adjacency", - "version": "0.1.23", + "version": "0.1.24", "description": "Sparse & bitwise adjacency matrices for directed / undirected graphs", "module": "./index.js", "main": "./lib/index.js", @@ -25,7 +25,7 @@ "pub": "yarn build:release && yarn publish --access public" }, "devDependencies": { - "@thi.ng/vectors": "^3.3.0", + "@thi.ng/vectors": "^3.3.1", "@types/mocha": "^5.2.6", "@types/node": "^12.6.3", "mocha": "^6.1.4", @@ -34,12 +34,12 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/binary": "^1.1.0", - "@thi.ng/bitfield": "^0.1.12", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/dcons": "^2.1.4", - "@thi.ng/sparse": "^0.1.20" + "@thi.ng/bitfield": "^0.2.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/dcons": "^2.1.5", + "@thi.ng/sparse": "^0.1.21" }, "keywords": [ "adjacency", diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md index e11c49192c..c91d49fcca 100644 --- a/packages/api/CHANGELOG.md +++ b/packages/api/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [6.4.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/api@6.3.3...@thi.ng/api@6.4.0) (2019-09-21) + + +### Features + +* **api:** add Nullable ([8366223](https://github.com/thi-ng/umbrella/commit/8366223)) + + + + + ## [6.3.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/api@6.3.2...@thi.ng/api@6.3.3) (2019-08-21) **Note:** Version bump only for package @thi.ng/api diff --git a/packages/api/package.json b/packages/api/package.json index e589b0a116..1a806fd484 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/api", - "version": "6.3.3", + "version": "6.4.0", "description": "Common, generic types & interfaces for thi.ng projects", "module": "./index.js", "main": "./lib/index.js", diff --git a/packages/api/src/api.ts b/packages/api/src/api.ts index bc9c57630a..e5c2de4dca 100644 --- a/packages/api/src/api.ts +++ b/packages/api/src/api.ts @@ -275,6 +275,8 @@ export type Listener = Fn; export type NumericArray = number[] | TypedArray; +export type Nullable = T | null | undefined; + export type Primitive = number | string | boolean | symbol; /** diff --git a/packages/api/src/mixins/ienable.ts b/packages/api/src/mixins/ienable.ts index d9a86311c3..ab79c5caa4 100644 --- a/packages/api/src/mixins/ienable.ts +++ b/packages/api/src/mixins/ienable.ts @@ -20,28 +20,26 @@ interface _IEnable extends IEnable { export const IEnableMixin = mixin(>{ _enabled: true, - isEnabled() { - return (<_IEnable>this)._enabled; + isEnabled(this: _IEnable) { + return this._enabled; }, - enable() { - const $this = <_IEnable>this; - $this._enabled = true; - if ($this.notify) { - $this.notify({ id: EVENT_ENABLE, target: this }); + enable(this: _IEnable) { + this._enabled = true; + if (this.notify) { + this.notify({ id: EVENT_ENABLE, target: this }); } }, - disable() { - const $this = <_IEnable>this; - $this._enabled = false; - if ($this.notify) { - $this.notify({ id: EVENT_DISABLE, target: this }); + disable(this: _IEnable) { + this._enabled = false; + if (this.notify) { + this.notify({ id: EVENT_DISABLE, target: this }); } }, - toggle() { - (<_IEnable>this)._enabled ? this.disable() : this.enable(); - return (<_IEnable>this)._enabled; + toggle(this: _IEnable) { + this._enabled ? this.disable() : this.enable(); + return this._enabled; } }); diff --git a/packages/api/src/mixins/inotify.ts b/packages/api/src/mixins/inotify.ts index 6d9b4f33c1..592cf2f883 100644 --- a/packages/api/src/mixins/inotify.ts +++ b/packages/api/src/mixins/inotify.ts @@ -29,24 +29,24 @@ export const inotify_dispatch = (listeners: any[][], e: Event) => { * registered listeners. */ export const INotifyMixin = mixin({ - addListener(id: string, fn: Listener, scope?: any) { - let l = ((<_INotify>this)._listeners = - (<_INotify>this)._listeners || {})[id]; + addListener(this: _INotify, id: string, fn: Listener, scope?: any) { + let l = (this._listeners = + this._listeners || {})[id]; if (!l) { - l = (this)._listeners[id] = []; + l = this._listeners[id] = []; } - if ((<_INotify>this).__listener(l, fn, scope) === -1) { + if (this.__listener(l, fn, scope) === -1) { l.push([fn, scope]); return true; } return false; }, - removeListener(id: string, fn: Listener, scope?: any) { - if (!(<_INotify>this)._listeners) return false; - const l = (<_INotify>this)._listeners[id]; + removeListener(this: _INotify, id: string, fn: Listener, scope?: any) { + if (!this._listeners) return false; + const l = this._listeners[id]; if (l) { - const idx = (<_INotify>this).__listener(l, fn, scope); + const idx = this.__listener(l, fn, scope); if (idx !== -1) { l.splice(idx, 1); return true; @@ -55,11 +55,11 @@ export const INotifyMixin = mixin({ return false; }, - notify(e: Event) { - if (!(<_INotify>this)._listeners) return; + notify(this: _INotify, e: Event) { + if (!this._listeners) return; e.target === undefined && (e.target = this); - inotify_dispatch((<_INotify>this)._listeners[e.id], e); - inotify_dispatch((<_INotify>this)._listeners[EVENT_ALL], e); + inotify_dispatch(this._listeners[e.id], e); + inotify_dispatch(this._listeners[EVENT_ALL], e); }, __listener(listeners: [Listener, any][], f: Listener, scope: any) { diff --git a/packages/api/src/mixins/iwatch.ts b/packages/api/src/mixins/iwatch.ts index fcbe9400ac..403b092af8 100644 --- a/packages/api/src/mixins/iwatch.ts +++ b/packages/api/src/mixins/iwatch.ts @@ -11,27 +11,27 @@ interface _IWatch extends IWatch { } export const IWatchMixin = mixin(>{ - addWatch(id: string, fn: Fn3) { - (<_IWatch>this)._watches = (<_IWatch>this)._watches || {}; - if ((<_IWatch>this)._watches[id]) { + addWatch(this: _IWatch, id: string, fn: Fn3) { + this._watches = this._watches || {}; + if (this._watches[id]) { return false; } - (<_IWatch>this)._watches[id] = fn; + this._watches[id] = fn; return true; }, - removeWatch(id: string) { - if (!(<_IWatch>this)._watches) return; - if ((<_IWatch>this)._watches[id]) { - delete (<_IWatch>this)._watches[id]; + removeWatch(this: _IWatch, id: string) { + if (!this._watches) return; + if (this._watches[id]) { + delete this._watches[id]; return true; } return false; }, - notifyWatches(oldState: any, newState: any) { - if (!(<_IWatch>this)._watches) return; - const w = (<_IWatch>this)._watches; + notifyWatches(this: _IWatch, oldState: any, newState: any) { + if (!this._watches) return; + const w = this._watches; for (let id in w) { w[id](id, oldState, newState); } diff --git a/packages/arrays/CHANGELOG.md b/packages/arrays/CHANGELOG.md index 68115096f6..7806f7c9a6 100644 --- a/packages/arrays/CHANGELOG.md +++ b/packages/arrays/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/arrays@0.2.4...@thi.ng/arrays@0.2.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/arrays + + + + + ## [0.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/arrays@0.2.3...@thi.ng/arrays@0.2.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/arrays diff --git a/packages/arrays/package.json b/packages/arrays/package.json index b62160d6d2..046170560c 100644 --- a/packages/arrays/package.json +++ b/packages/arrays/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/arrays", - "version": "0.2.4", + "version": "0.2.5", "description": "Array / Arraylike utilities", "module": "./index.js", "main": "./lib/index.js", @@ -33,12 +33,12 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/compare": "^1.0.9", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/random": "^1.1.11" + "@thi.ng/random": "^1.1.12" }, "keywords": [ "arrays", diff --git a/packages/associative/CHANGELOG.md b/packages/associative/CHANGELOG.md index c4abc6a04c..8929d7ae69 100644 --- a/packages/associative/CHANGELOG.md +++ b/packages/associative/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.0.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@3.0.0...@thi.ng/associative@3.0.1) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/associative + + + + + # [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/associative@2.4.3...@thi.ng/associative@3.0.0) (2019-08-21) diff --git a/packages/associative/package.json b/packages/associative/package.json index d650cdc92b..53ab339902 100644 --- a/packages/associative/package.json +++ b/packages/associative/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/associative", - "version": "3.0.0", + "version": "3.0.1", "description": "Alternative Set & Map data type implementations with customizable equality semantics & supporting operations", "module": "./index.js", "main": "./lib/index.js", @@ -33,14 +33,14 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/binary": "^1.1.0", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/compare": "^1.0.9", - "@thi.ng/dcons": "^2.1.4", + "@thi.ng/dcons": "^2.1.5", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "data structures", diff --git a/packages/atom/CHANGELOG.md b/packages/atom/CHANGELOG.md index ae682b7639..331d13ac3d 100644 --- a/packages/atom/CHANGELOG.md +++ b/packages/atom/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.1.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@3.0.4...@thi.ng/atom@3.1.0) (2019-09-21) + + +### Features + +* **atom:** add Transacted wrapper & tests ([8aaf6e6](https://github.com/thi-ng/umbrella/commit/8aaf6e6)) +* **atom:** update Transacted watch ID handling, update tests, readme ([93d9e1d](https://github.com/thi-ng/umbrella/commit/93d9e1d)) + + + + + ## [3.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/atom@3.0.3...@thi.ng/atom@3.0.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/atom diff --git a/packages/atom/README.md b/packages/atom/README.md index 83687f3739..68ffa12f8f 100644 --- a/packages/atom/README.md +++ b/packages/atom/README.md @@ -7,6 +7,23 @@ This project is part of the [@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + +- [About](#about) + - [Status](#status) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) + - [Atom](#atom) + - [Transacted updates](#transacted-updates) + - [Cursor](#cursor) + - [Derived views](#derived-views) + - [Undo / Redo history](#undo--redo-history) +- [Authors](#authors) +- [License](#license) + + + ## About Clojure inspired mutable wrappers for (usually) immutable values, with @@ -15,44 +32,24 @@ infrastructure support for: - watches - derived view subscriptions - cursors (direct R/W access to nested values) +- transacted updates - undo/redo history Together these types act as building blocks for various application state handling patterns, specifically aimed (though not exclusively) at -the concept of using a nested, immutable, centralized atom as single -source of truth within an application. +the concept of using a centralized atom around a nested, immutable object +as single source of truth within an application. ### Status Stable, used in production and in active development. -**Note: On 2018-03-17 this package was split to remain more focused. -Path based getters/setters have been moved into the new -[@thi.ng/paths](https://github.com/thi-ng/umbrella/tree/master/packages/paths) -package. Likewise, all interceptor based event handling functionality -now lives in the -[@thi.ng/interceptors](https://github.com/thi-ng/umbrella/tree/master/packages/interceptors) -package.** - ## Installation ```bash yarn add @thi.ng/atom ``` -**New since 2018-03-15: You can now create a preconfigured app skeleton -using @thi.ng/atom, @thi.ng/hdom & @thi.ng/router using the -[create-hdom-app](https://github.com/thi-ng/create-hdom-app) project -generator:** - -```bash -yarn create hdom-app my-app - -cd my-app -yarn install -yarn start -``` - ## Dependencies - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) @@ -69,11 +66,11 @@ directory make heavy use of this library. ### Atom -An `Atom` is a mutable wrapper for immutable values. The wrapped value -can be obtained via `deref()`, replaced via `reset()` and updated using -`swap()`. An atom too supports the concept of watches, essentially -`onchange` event handlers which are called from `reset`/`swap` and -receive both the old and new atom values. +An `Atom` is a mutable wrapper for supposedly immutable values. The +wrapped value can be obtained via `deref()`, replaced via `reset()` and +updated using `swap()`. An atom too supports the concept of watches, +essentially `onchange` event handlers which are called from +`reset` / `swap` and receive both the old and new atom values. ```ts import * as atom from "@thi.ng/atom"; @@ -103,6 +100,75 @@ a.reset(42); // foo: 24 -> 42 ``` +When atoms are used to wrap nested object values, the `resetIn()` / +`swapIn()` methods can be used to directly update nested values. These +updates are handled via immutable setters provided by +[@thi.ng/paths](https://github.com/thi-ng/umbrella/tree/master/packages/paths). + +```ts +const db = new Atom({ a: { b: 1, c: 2 } }); + +db.resetIn("a.b", 100); +// { a: { b: 100, c: 2 } } + +db.swapIn("a.c", (x) => x + 1); +// { a: { b: 100, c: 3 } } + +// alternatively, the lookup path can be given as array +// see @thi.ng/paths for further reference +db.swapIn(["a", "c"], (x) => x + 1); +// { a: { b: 100, c: 4 } } +``` + +### Transacted updates + +Since v3.1.0, multiple sequential state updates can be grouped in +transactions and then applied in one go (or canceled altogether). This +can be useful to produce a clean(er) sequence of undo snapshots (see +further below) and avoids multiple / obsolete invocations of watches +caused by each interim state update. Using a transaction, the parent +state is only updated once and watches too are only notified once after +each commit. + +Transactions can also be canceled, thus not impacting the parent state +at all. Nested transactions are *not* supported and attempting to do so +will throw an error. + +The `Transacted` class can wrap any existing `IAtom` implementation, +e.g. `Atom`, `Cursor` or `History` instances and implements `IAtom` +itself... + +```ts +const db = new Atom({ a: 1, b: 2 }); +const tx = new Transacted(db); + +// start transaction +tx.begin(); + +// perform multiple updates +// (none of them are applied until `commit` is called) +// IMPORTANT: calling any of these update methods without +// a running transaction will throw an error! +tx.resetIn("a", 11); +tx.resetIn("c", 33); + +// tx.deref() will always return latest state +tx.deref() +// { a: 11, b: 2, c: 33 } + +// however, at this point db.deref() still yields pre-transaction state +db.deref() +// { a: 1, b: 2 } + +// apply all changes at once (or `cancel()` transaction) +tx.commit(); +// { a: 11, b: 2, c: 33 } + +// verify parent state +db.deref() +// { a: 11, b: 2, c: 33 } +``` + ### Cursor Cursors provide direct & immutable access to a nested value within a @@ -360,15 +426,16 @@ const app = () => start(document.body, app); ``` -### Undo history +### Undo / Redo history The `History` type can be used with & behaves like an Atom or Cursor, but creates snapshots of the current state before applying the new -state. By default history has length of 100 steps, but this is -configurable. +state. By default, the history has length of 100 steps, though this is +configurable via ctor args. ```ts -db = new atom.History(new atom.Atom({a: 1})) +// create history w/ max. 100 steps +db = new atom.History(new atom.Atom({a: 1}), 100) db.deref() // {a: 1} diff --git a/packages/atom/package.json b/packages/atom/package.json index 50c5869218..366e18be16 100644 --- a/packages/atom/package.json +++ b/packages/atom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/atom", - "version": "3.0.4", + "version": "3.1.0", "description": "Mutable wrappers for nested immutable values w/ optional undo/redo history", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/paths": "^2.1.4" + "@thi.ng/paths": "^2.1.5" }, "keywords": [ "derived views", @@ -47,8 +47,12 @@ "history", "immutable", "redo", + "state", + "transaction", "typescript", - "undo" + "undo", + "update", + "wrapper" ], "publishConfig": { "access": "public" diff --git a/packages/atom/src/index.ts b/packages/atom/src/index.ts index b5c592cc7e..f3abf70e32 100644 --- a/packages/atom/src/index.ts +++ b/packages/atom/src/index.ts @@ -2,4 +2,5 @@ export * from "./api"; export * from "./atom"; export * from "./cursor"; export * from "./history"; +export * from "./transacted"; export * from "./view"; diff --git a/packages/atom/src/transacted.ts b/packages/atom/src/transacted.ts new file mode 100644 index 0000000000..cf457e76ce --- /dev/null +++ b/packages/atom/src/transacted.ts @@ -0,0 +1,117 @@ +import { assert, Path, Watch } from "@thi.ng/api"; +import { setIn, updateIn } from "@thi.ng/paths"; +import { + IAtom, + IView, + SwapFn, + ViewTransform +} from "./api"; +import { nextID } from "./idgen"; +import { View } from "./view"; + +export class Transacted implements IAtom { + parent: IAtom; + current: T | undefined; + protected id: string; + protected isActive: boolean; + protected _watches: any; + + constructor(parent: IAtom) { + this.parent = parent; + this.current = undefined; + this.isActive = false; + this.id = `tx${nextID()}-`; + } + + get value() { + return this.deref(); + } + + set value(val: T) { + this.reset(val); + } + + get isTransaction() { + return this.isActive; + } + + deref() { + return this.isActive ? this.current! : this.parent.deref(); + } + + equiv(o: any) { + return this === o; + } + + reset(val: T) { + this.ensureTx(); + this.current = val; + return val; + } + + resetIn(path: Path, val: V) { + this.ensureTx(); + return this.reset(setIn(this.current, path, val)); + } + + swap(fn: SwapFn, ...args: any[]) { + this.ensureTx(); + return this.reset(fn.apply(null, [this.current!, ...args])); + } + + swapIn(path: Path, fn: SwapFn, ...args: any[]) { + this.ensureTx(); + return this.reset(updateIn(this.current, path, fn, ...args)); + } + + begin() { + assert(!this.isActive, "transaction already started"); + this.current = this.parent.deref(); + this.isActive = true; + } + + commit() { + this.ensureTx(); + const val = this.current!; + this.parent.reset(this.current!); + this.isActive = false; + this.current = undefined; + return val; + } + + cancel() { + this.ensureTx(); + this.isActive = false; + this.current = undefined; + } + + addWatch(id: string, watch: Watch) { + return this.parent.addWatch(this.id + id, (_, prev, curr) => + watch(id, prev, curr) + ); + } + + removeWatch(id: string) { + return this.parent.removeWatch(this.id + id); + } + + notifyWatches(old: T, curr: T) { + this.parent.notifyWatches(old, curr); + } + + addView(path: Path, tx?: ViewTransform, lazy = true): IView { + return new View(this, path, tx, lazy); + } + + release() { + delete this.parent; + delete this.current; + delete this.isActive; + delete this._watches; + return true; + } + + protected ensureTx() { + assert(this.isActive, "no active transaction"); + } +} diff --git a/packages/atom/test/index.ts b/packages/atom/test/index.ts deleted file mode 100644 index ff27842a95..0000000000 --- a/packages/atom/test/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./atom"; -export * from "./cursor"; -export * from "./history"; -export * from "./view"; diff --git a/packages/atom/test/transacted.ts b/packages/atom/test/transacted.ts new file mode 100644 index 0000000000..ab3c6bfbbb --- /dev/null +++ b/packages/atom/test/transacted.ts @@ -0,0 +1,87 @@ +import * as assert from "assert"; +import { Atom, Transacted } from "../src/index"; + +describe("transacted", () => { + let db: Atom; + let tx: Transacted; + + beforeEach(() => { + db = new Atom({ a: 1, b: 2 }); + tx = new Transacted(db); + }); + + it("initial", () => { + assert.deepEqual(db.deref(), { a: 1, b: 2 }); + assert.deepStrictEqual(tx.deref(), db.deref()); + }); + + it("transaction", () => { + tx.begin(); + assert.deepEqual(tx.deref(), { a: 1, b: 2 }); + assert.throws(() => tx.begin(), "no nested tx"); + tx.swapIn("a", (x: number) => x + 10); + tx.swapIn("b", (x: number) => x + 20); + assert.deepEqual(tx.deref(), { a: 11, b: 22 }); + assert.deepEqual(db.deref(), { a: 1, b: 2 }); + assert.deepEqual(tx.commit(), { a: 11, b: 22 }); + assert.deepEqual(tx.deref(), { a: 11, b: 22 }); + assert.deepStrictEqual(tx.deref(), db.deref()); + assert.throws(() => tx.commit(), "no double commit"); + }); + + it("cancel", () => { + tx.begin(); + tx.swapIn("a", (x: number) => x + 10); + assert.deepEqual(tx.deref(), { a: 11, b: 2 }); + tx.cancel(); + assert.deepEqual(tx.deref(), { a: 1, b: 2 }); + assert.deepStrictEqual(tx.deref(), db.deref()); + assert.throws(() => tx.cancel(), "no double cancel"); + }); + + it("no edits outside tx", () => { + assert.throws(() => tx.reset({}), "no reset"); + assert.throws(() => tx.swap(() => ({})), "no swap"); + assert.throws(() => tx.resetIn("a", {}), "no resetIn"); + assert.throws(() => tx.swapIn("a", () => ({})), "no swapIn"); + assert.throws(() => (tx.value = {}), "no .value"); + }); + + it("watches", () => { + let count = 0; + tx.addWatch("foo", (id, old, curr) => { + count++; + assert.equal(id, "foo"); + assert.deepEqual(old, { a: 1, b: 2 }); + assert.deepEqual(curr, { a: 22 }); + }); + tx.begin(); + tx.reset({ a: 11 }); + tx.reset({ a: 22 }); + tx.commit(); + assert.equal(count, 1); + }); + + it("view (lazy)", () => { + const acc: any[] = []; + const view = tx.addView("a", (x) => (acc.push(x), x), true); + assert.equal(view.deref(), 1); + tx.begin(); + tx.reset({ a: 11 }); + tx.reset({ a: 22 }); + tx.commit(); + assert.equal(view.deref(), 22); + assert.deepEqual(acc, [1, 22]); + }); + + it("view (eager)", () => { + const acc: any[] = []; + const view = tx.addView("a", (x) => (acc.push(x), x), false); + tx.begin(); + tx.reset({ a: 11 }); + tx.reset({ a: 22 }); + tx.commit(); + assert.deepEqual(acc, [1, 22]); + assert.equal(view.deref(), 22); + }); +}); diff --git a/packages/bencode/CHANGELOG.md b/packages/bencode/CHANGELOG.md index 2b7e9139f3..ac5d3e79b8 100644 --- a/packages/bencode/CHANGELOG.md +++ b/packages/bencode/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.3.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/bencode@0.3.4...@thi.ng/bencode@0.3.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/bencode + + + + + ## [0.3.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/bencode@0.3.3...@thi.ng/bencode@0.3.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/bencode diff --git a/packages/bencode/package.json b/packages/bencode/package.json index eccb9052cf..7da5560a46 100644 --- a/packages/bencode/package.json +++ b/packages/bencode/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/bencode", - "version": "0.3.4", + "version": "0.3.5", "description": "Bencode binary encoder / decoder with optional UTF8 encoding", "module": "./index.js", "main": "./lib/index.js", @@ -33,13 +33,13 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/arrays": "^0.2.4", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/defmulti": "^1.1.3", + "@thi.ng/api": "^6.4.0", + "@thi.ng/arrays": "^0.2.5", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/defmulti": "^1.1.4", "@thi.ng/errors": "^1.2.0", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/transducers-binary": "^0.4.4" + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/transducers-binary": "^0.4.5" }, "keywords": [ "bencode", diff --git a/packages/bitfield/CHANGELOG.md b/packages/bitfield/CHANGELOG.md index 14c85b771a..81965839de 100644 --- a/packages/bitfield/CHANGELOG.md +++ b/packages/bitfield/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.2.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/bitfield@0.1.12...@thi.ng/bitfield@0.2.0) (2019-09-21) + + +### Features + +* **bitfield:** update BitMatrix to support non-squared sizes, update docstrings ([0fd8620](https://github.com/thi-ng/umbrella/commit/0fd8620)) + + + + + ## [0.1.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/bitfield@0.1.11...@thi.ng/bitfield@0.1.12) (2019-08-21) **Note:** Version bump only for package @thi.ng/bitfield diff --git a/packages/bitfield/README.md b/packages/bitfield/README.md index 5b01602adc..d1ad9f809b 100644 --- a/packages/bitfield/README.md +++ b/packages/bitfield/README.md @@ -20,7 +20,8 @@ This project is part of the ## About -Typed array backed 1D / 2D bit field implementations. +Typed array backed 1D / 2D bit field / bit matrix implementations. Due +to `Uint32Array` backing, width is always a multiple of 32. ## Installation @@ -37,6 +38,45 @@ yarn add @thi.ng/bitfield ```ts import { BitField, BitMatrix } from "@thi.ng/bitfield"; + +// size always rounded up to a multiple of 32 +const field = new BitField(16); + +field.setAt(0); + +// if 2nd arg is false, the bit will be cleared +// setAt returns non-zero value if bit was previously set +field.setAt(31, true); +// 0 + +// returns non-zero value if bit is set +field.at(0) +// -2147483648 + +field.at(1) +// 0 + +field.toString(); +// 10000000000000000000000000000001 + +field.resize(64) +// 1000000000000000000000000000000100000000000000000000000000000000 + +const mat = new BitMatrix(8, 32); +for(let i = 0; i < 8; i++) mat.setAt(i, i); + +mat.at(7, 7); +// 16777216 + +mat.toString(); +// 10000000000000000000000000000000 +// 01000000000000000000000000000000 +// 00100000000000000000000000000000 +// 00010000000000000000000000000000 +// 00001000000000000000000000000000 +// 00000100000000000000000000000000 +// 00000010000000000000000000000000 +// 00000001000000000000000000000000 ``` ## Authors diff --git a/packages/bitfield/package.json b/packages/bitfield/package.json index 8db8bda3d0..661aeddc92 100644 --- a/packages/bitfield/package.json +++ b/packages/bitfield/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/bitfield", - "version": "0.1.12", + "version": "0.2.0", "description": "1D / 2D bit field implementations", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/binary": "^1.1.0", - "@thi.ng/strings": "^1.2.3" + "@thi.ng/strings": "^1.3.0" }, "keywords": [ "1D", diff --git a/packages/bitfield/src/bitfield.ts b/packages/bitfield/src/bitfield.ts index f6d7853c3b..676edeb0e0 100644 --- a/packages/bitfield/src/bitfield.ts +++ b/packages/bitfield/src/bitfield.ts @@ -1,8 +1,10 @@ import { align } from "@thi.ng/binary"; -import { radix } from "@thi.ng/strings"; - -const B32 = radix(2, 32); +import { B32 } from "@thi.ng/strings"; +/** + * 1D bit field, backed by a Uint32Array. Size is always a multiple of + * 32. + */ export class BitField { data: Uint32Array; n: number; @@ -13,7 +15,8 @@ export class BitField { } /** - * Resizes bitfield to new size given (aligned to multiples of 32). + * Resizes bitfield to new size given (rounded up to multiples of + * 32). * * @param n */ @@ -27,7 +30,8 @@ export class BitField { } /** - * Returns a non-zero value if bit `n` is enabled. + * Returns a non-zero value if bit `n` is enabled. No bounds + * checking. * * @param n */ @@ -37,7 +41,7 @@ export class BitField { /** * Enables or disables bit `n`. Returns a non-zero value if the bit - * was previously enabled. + * was previously enabled. No bounds checking. * . * @param n * @param v diff --git a/packages/bitfield/src/bitmatrix.ts b/packages/bitfield/src/bitmatrix.ts index 87a47be78b..6805f27110 100644 --- a/packages/bitfield/src/bitmatrix.ts +++ b/packages/bitfield/src/bitmatrix.ts @@ -1,38 +1,45 @@ import { align } from "@thi.ng/binary"; -import { radix } from "@thi.ng/strings"; - -const B32 = radix(2, 32); +import { B32 } from "@thi.ng/strings"; +/** + * MxN row-major 2D bit matrix, backed by a Uint32Array. Width is always + * a multiple of 32. + */ export class BitMatrix { data: Uint32Array; stride: number; + m: number; n: number; - constructor(n: number) { + constructor(m: number, n = m) { + this.m = m; this.n = n = align(n, 32); this.stride = n >>> 5; - this.data = new Uint32Array(n * this.stride); + this.data = new Uint32Array(m * this.stride); } /** - * Resizes matrix to new size given (aligned to multiples of 32). + * Resizes matrix to new size given (width always rounded up to + * multiples of 32). * - * @param n + * @param m new number of rows + * @param n new number of cols */ - resize(n: number) { + resize(m: number, n = m) { n = align(n, 32); const dstride = n >>> 5; const sstride = this.stride; const w = Math.min(dstride, sstride); const src = this.data; - const dest = new Uint32Array(n * dstride); + const dest = new Uint32Array(m * dstride); for ( - let i = this.n - 1, si = i * sstride, di = i * dstride; + let i = Math.min(m, this.m) - 1, si = i * sstride, di = i * dstride; i >= 0; i--, si -= sstride, di -= dstride ) { dest.set(src.slice(si, si + w), di); } + this.m = m; this.n = n; this.stride = dstride; this.data = dest; @@ -41,6 +48,7 @@ export class BitMatrix { /** * Returns a non-zero value if bit at `m,n` is enabled (row major). + * No bounds checking. * * @param m * @param n @@ -53,7 +61,7 @@ export class BitMatrix { /** * Enables or disables bit at `m,n` (row major). Returns a non-zero - * value if the bit was previously enabled. + * value if the bit was previously enabled. No bounds checking. * . * @param m * @param n @@ -73,7 +81,7 @@ export class BitMatrix { toString() { const res: string[] = []; - for (let i = 0, j = 0, s = this.stride; i < this.n; i++, j += s) { + for (let i = 0, j = 0, s = this.stride; i < this.m; i++, j += s) { res.push([...this.data.slice(j, j + s)].map(B32).join("")); } return res.join("\n"); diff --git a/packages/cache/CHANGELOG.md b/packages/cache/CHANGELOG.md index 2208727a9d..4cf3ecce68 100644 --- a/packages/cache/CHANGELOG.md +++ b/packages/cache/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.0.25](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@1.0.24...@thi.ng/cache@1.0.25) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/cache + + + + + ## [1.0.24](https://github.com/thi-ng/umbrella/compare/@thi.ng/cache@1.0.23...@thi.ng/cache@1.0.24) (2019-08-21) **Note:** Version bump only for package @thi.ng/cache diff --git a/packages/cache/package.json b/packages/cache/package.json index 8e3cb9368a..e7e9e9de98 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/cache", - "version": "1.0.24", + "version": "1.0.25", "description": "In-memory cache implementations with ES6 Map-like API and different eviction strategies", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/dcons": "^2.1.4", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/api": "^6.4.0", + "@thi.ng/dcons": "^2.1.5", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "cache", diff --git a/packages/checks/CHANGELOG.md b/packages/checks/CHANGELOG.md index 3ac94f9501..ab46067b6f 100644 --- a/packages/checks/CHANGELOG.md +++ b/packages/checks/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.4.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/checks@2.3.0...@thi.ng/checks@2.4.0) (2019-09-21) + + +### Features + +* **checks:** add generics to existsAndNotNull() ([bced8b9](https://github.com/thi-ng/umbrella/commit/bced8b9)) + + + + + # [2.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/checks@2.2.2...@thi.ng/checks@2.3.0) (2019-08-16) diff --git a/packages/checks/package.json b/packages/checks/package.json index 5dfe6f0896..a45990bce9 100644 --- a/packages/checks/package.json +++ b/packages/checks/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/checks", - "version": "2.3.0", + "version": "2.4.0", "description": "Single-function sub-modules for type, feature & value checks", "module": "./index.js", "main": "./lib/index.js", diff --git a/packages/checks/src/exists-not-null.ts b/packages/checks/src/exists-not-null.ts index c29fa61e82..d1a3264940 100644 --- a/packages/checks/src/exists-not-null.ts +++ b/packages/checks/src/exists-not-null.ts @@ -1 +1,2 @@ -export const existsAndNotNull = (x: any) => x != null; +export const existsAndNotNull = (x: T | null | undefined): x is T => + x != null; diff --git a/packages/checks/src/exists.ts b/packages/checks/src/exists.ts index 305311d128..bf3155129d 100644 --- a/packages/checks/src/exists.ts +++ b/packages/checks/src/exists.ts @@ -1 +1 @@ -export const exists = (x: any) => x !== undefined; +export const exists = (t: T | undefined): t is T => t !== undefined; diff --git a/packages/color/CHANGELOG.md b/packages/color/CHANGELOG.md index b3d95e02da..ad63c6c4d9 100644 --- a/packages/color/CHANGELOG.md +++ b/packages/color/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/color@1.1.0...@thi.ng/color@1.1.1) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/color + + + + + # [1.1.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/color@1.0.3...@thi.ng/color@1.1.0) (2019-08-21) diff --git a/packages/color/package.json b/packages/color/package.json index e6fdc3b553..adfc7f47d2 100644 --- a/packages/color/package.json +++ b/packages/color/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/color", - "version": "1.1.0", + "version": "1.1.1", "description": "Raw, array-based, color ops, conversions, opt. type wrappers, multi-color gradients", "module": "./index.js", "main": "./lib/index.js", @@ -33,15 +33,15 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/compose": "^1.3.3", - "@thi.ng/defmulti": "^1.1.3", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/compose": "^1.3.4", + "@thi.ng/defmulti": "^1.1.4", "@thi.ng/errors": "^1.2.0", "@thi.ng/math": "^1.4.2", - "@thi.ng/strings": "^1.2.3", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/strings": "^1.3.0", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "alpha", diff --git a/packages/compose/CHANGELOG.md b/packages/compose/CHANGELOG.md index d691cdb82b..dd46eb40bd 100644 --- a/packages/compose/CHANGELOG.md +++ b/packages/compose/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.3.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/compose@1.3.3...@thi.ng/compose@1.3.4) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/compose + + + + + ## [1.3.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/compose@1.3.2...@thi.ng/compose@1.3.3) (2019-08-21) **Note:** Version bump only for package @thi.ng/compose diff --git a/packages/compose/package.json b/packages/compose/package.json index b5d1258b5a..823ce8b148 100644 --- a/packages/compose/package.json +++ b/packages/compose/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/compose", - "version": "1.3.3", + "version": "1.3.4", "description": "Arity-optimized functional composition helpers", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/errors": "^1.2.0" }, "keywords": [ diff --git a/packages/csp/CHANGELOG.md b/packages/csp/CHANGELOG.md index e779c6bad1..94e3cbc8b7 100644 --- a/packages/csp/CHANGELOG.md +++ b/packages/csp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@1.1.4...@thi.ng/csp@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/csp + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/csp@1.1.3...@thi.ng/csp@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/csp diff --git a/packages/csp/package.json b/packages/csp/package.json index 1f639e8b6b..60f0bc2dee 100644 --- a/packages/csp/package.json +++ b/packages/csp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/csp", - "version": "1.1.4", + "version": "1.1.5", "description": "ES6 promise based CSP implementation", "module": "./index.js", "main": "./lib/index.js", @@ -37,12 +37,12 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/arrays": "^0.2.4", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/dcons": "^2.1.4", + "@thi.ng/api": "^6.4.0", + "@thi.ng/arrays": "^0.2.5", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/dcons": "^2.1.5", "@thi.ng/errors": "^1.2.0", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "async", diff --git a/packages/dcons/CHANGELOG.md b/packages/dcons/CHANGELOG.md index b54a90e2da..16874ee849 100644 --- a/packages/dcons/CHANGELOG.md +++ b/packages/dcons/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@2.1.4...@thi.ng/dcons@2.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/dcons + + + + + ## [2.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/dcons@2.1.3...@thi.ng/dcons@2.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/dcons diff --git a/packages/dcons/package.json b/packages/dcons/package.json index a57577c4f3..a0cc399ccc 100644 --- a/packages/dcons/package.json +++ b/packages/dcons/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dcons", - "version": "2.1.4", + "version": "2.1.5", "description": "Comprehensive doubly linked list structure w/ iterator support", "module": "./index.js", "main": "./lib/index.js", @@ -33,12 +33,12 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/compare": "^1.0.9", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "datastructure", diff --git a/packages/defmulti/CHANGELOG.md b/packages/defmulti/CHANGELOG.md index 071ea06608..cf8af97c9d 100644 --- a/packages/defmulti/CHANGELOG.md +++ b/packages/defmulti/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/defmulti@1.1.3...@thi.ng/defmulti@1.1.4) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/defmulti + + + + + ## [1.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/defmulti@1.1.2...@thi.ng/defmulti@1.1.3) (2019-08-21) **Note:** Version bump only for package @thi.ng/defmulti diff --git a/packages/defmulti/package.json b/packages/defmulti/package.json index d1444d8b92..3670f918e6 100644 --- a/packages/defmulti/package.json +++ b/packages/defmulti/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/defmulti", - "version": "1.1.3", + "version": "1.1.4", "description": "Dynamically extensible multiple dispatch via user supplied dispatch function.", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/errors": "^1.2.0" }, "keywords": [ diff --git a/packages/dgraph/CHANGELOG.md b/packages/dgraph/CHANGELOG.md index 1c33810374..f94c347f64 100644 --- a/packages/dgraph/CHANGELOG.md +++ b/packages/dgraph/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@1.1.14...@thi.ng/dgraph@1.1.15) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/dgraph + + + + + ## [1.1.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/dgraph@1.1.13...@thi.ng/dgraph@1.1.14) (2019-08-21) **Note:** Version bump only for package @thi.ng/dgraph diff --git a/packages/dgraph/package.json b/packages/dgraph/package.json index 3b8f8d27c3..64cbd77ded 100644 --- a/packages/dgraph/package.json +++ b/packages/dgraph/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dgraph", - "version": "1.1.14", + "version": "1.1.15", "description": "Type-agnostic directed acyclic graph (DAG) & graph operations", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/associative": "^3.0.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/associative": "^3.0.1", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "data structure", diff --git a/packages/diff/CHANGELOG.md b/packages/diff/CHANGELOG.md index 0261375bd5..42a9fe8c6a 100644 --- a/packages/diff/CHANGELOG.md +++ b/packages/diff/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@3.2.3...@thi.ng/diff@3.2.4) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/diff + + + + + ## [3.2.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/diff@3.2.2...@thi.ng/diff@3.2.3) (2019-08-21) **Note:** Version bump only for package @thi.ng/diff diff --git a/packages/diff/package.json b/packages/diff/package.json index 65e1f07fe2..89b45a38e5 100644 --- a/packages/diff/package.json +++ b/packages/diff/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/diff", - "version": "3.2.3", + "version": "3.2.4", "description": "Array & object Diff", "module": "./index.js", "main": "./lib/index.js", @@ -32,7 +32,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/equiv": "^1.0.9" }, "keywords": [ diff --git a/packages/dot/CHANGELOG.md b/packages/dot/CHANGELOG.md index 025eb54155..5ba69f5f33 100644 --- a/packages/dot/CHANGELOG.md +++ b/packages/dot/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/dot@1.1.4...@thi.ng/dot@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/dot + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/dot@1.1.3...@thi.ng/dot@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/dot diff --git a/packages/dot/README.md b/packages/dot/README.md index 23fdb3f747..f3d782b773 100644 --- a/packages/dot/README.md +++ b/packages/dot/README.md @@ -34,7 +34,7 @@ yarn add @thi.ng/dot ## Usage examples -![example graph](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/dot-example.png) +![example graph](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/dot/dot-example.png) The source code of this example is also available in [/test/example.ts](https://github.com/thi-ng/umbrella/tree/master/packages/dot/test/example.ts). diff --git a/packages/dot/package.json b/packages/dot/package.json index 31c080a3d8..26cf4ddc70 100644 --- a/packages/dot/package.json +++ b/packages/dot/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dot", - "version": "1.1.4", + "version": "1.1.5", "description": "Graphviz DOM abstraction as vanilla JS objects & serialization to DOT format", "module": "./index.js", "main": "./lib/index.js", @@ -33,8 +33,8 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0" + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0" }, "keywords": [ "ES6", diff --git a/packages/dsp/CHANGELOG.md b/packages/dsp/CHANGELOG.md index 6208cc96e9..009534713e 100644 --- a/packages/dsp/CHANGELOG.md +++ b/packages/dsp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.0.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/dsp@1.0.15...@thi.ng/dsp@1.0.16) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/dsp + + + + + ## [1.0.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/dsp@1.0.14...@thi.ng/dsp@1.0.15) (2019-08-21) **Note:** Version bump only for package @thi.ng/dsp diff --git a/packages/dsp/package.json b/packages/dsp/package.json index 0a1ef0f2b7..9decdb0fff 100644 --- a/packages/dsp/package.json +++ b/packages/dsp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/dsp", - "version": "1.0.15", + "version": "1.0.16", "description": "Assorted DSP utils, oscillators etc.", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/math": "^1.4.2" }, "keywords": [ diff --git a/packages/fsm/CHANGELOG.md b/packages/fsm/CHANGELOG.md index ec83775642..ee9cc26007 100644 --- a/packages/fsm/CHANGELOG.md +++ b/packages/fsm/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/fsm@2.2.4...@thi.ng/fsm@2.2.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/fsm + + + + + ## [2.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/fsm@2.2.3...@thi.ng/fsm@2.2.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/fsm diff --git a/packages/fsm/package.json b/packages/fsm/package.json index 2f99909dee..376cb2a695 100644 --- a/packages/fsm/package.json +++ b/packages/fsm/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/fsm", - "version": "2.2.4", + "version": "2.2.5", "description": "Composable primitives for building declarative, transducer based Finite-State machines & parsers for arbitrary data streams", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/arrays": "^0.2.4", + "@thi.ng/api": "^6.4.0", + "@thi.ng/arrays": "^0.2.5", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "ES6", diff --git a/packages/geom-accel/CHANGELOG.md b/packages/geom-accel/CHANGELOG.md index 6519288410..3dd553b77c 100644 --- a/packages/geom-accel/CHANGELOG.md +++ b/packages/geom-accel/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.2.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-accel@1.2.7...@thi.ng/geom-accel@1.2.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-accel + + + + + ## [1.2.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-accel@1.2.6...@thi.ng/geom-accel@1.2.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-accel diff --git a/packages/geom-accel/package.json b/packages/geom-accel/package.json index d6856db998..01632a73b0 100644 --- a/packages/geom-accel/package.json +++ b/packages/geom-accel/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-accel", - "version": "1.2.7", + "version": "1.2.8", "description": "nD spatial indexing data structures", "module": "./index.js", "main": "./lib/index.js", @@ -33,13 +33,13 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/arrays": "^0.2.4", - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/heaps": "^1.1.3", + "@thi.ng/api": "^6.4.0", + "@thi.ng/arrays": "^0.2.5", + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/heaps": "^1.1.4", "@thi.ng/math": "^1.4.2", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-api/CHANGELOG.md b/packages/geom-api/CHANGELOG.md index 8d40f74c59..7414644048 100644 --- a/packages/geom-api/CHANGELOG.md +++ b/packages/geom-api/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.3.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-api@0.3.5...@thi.ng/geom-api@0.3.6) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-api + + + + + ## [0.3.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-api@0.3.4...@thi.ng/geom-api@0.3.5) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-api diff --git a/packages/geom-api/package.json b/packages/geom-api/package.json index 444e5e4cd7..c1e2118be6 100644 --- a/packages/geom-api/package.json +++ b/packages/geom-api/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-api", - "version": "0.3.5", + "version": "0.3.6", "description": "Shared type & interface declarations for @thi.ng/geom packages", "module": "./index.js", "main": "./lib/index.js", @@ -33,8 +33,8 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/api": "^6.4.0", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "ES6", diff --git a/packages/geom-arc/CHANGELOG.md b/packages/geom-arc/CHANGELOG.md index 72c49c387b..b5cea1a27b 100644 --- a/packages/geom-arc/CHANGELOG.md +++ b/packages/geom-arc/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-arc@0.2.7...@thi.ng/geom-arc@0.2.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-arc + + + + + ## [0.2.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-arc@0.2.6...@thi.ng/geom-arc@0.2.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-arc diff --git a/packages/geom-arc/package.json b/packages/geom-arc/package.json index 58a4a98f58..3543123493 100644 --- a/packages/geom-arc/package.json +++ b/packages/geom-arc/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-arc", - "version": "0.2.7", + "version": "0.2.8", "description": "2D circular / elliptic arc operations", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/geom-resample": "^0.2.7", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/geom-resample": "^0.2.8", "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-clip/CHANGELOG.md b/packages/geom-clip/CHANGELOG.md index c7efed37e2..f39d565399 100644 --- a/packages/geom-clip/CHANGELOG.md +++ b/packages/geom-clip/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-clip@0.1.7...@thi.ng/geom-clip@0.1.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-clip + + + + + ## [0.1.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-clip@0.1.6...@thi.ng/geom-clip@0.1.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-clip diff --git a/packages/geom-clip/package.json b/packages/geom-clip/package.json index 8de2327120..d9f8f8546c 100644 --- a/packages/geom-clip/package.json +++ b/packages/geom-clip/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-clip", - "version": "0.1.7", + "version": "0.1.8", "description": "2D line & convex polygon clipping (Liang-Barsky / Sutherland-Hodgeman)", "module": "./index.js", "main": "./lib/index.js", @@ -33,10 +33,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/geom-isec": "^0.3.7", - "@thi.ng/geom-poly-utils": "^0.1.25", + "@thi.ng/geom-isec": "^0.3.8", + "@thi.ng/geom-poly-utils": "^0.1.26", "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-closest-point/CHANGELOG.md b/packages/geom-closest-point/CHANGELOG.md index 29591c6c53..8439b099e2 100644 --- a/packages/geom-closest-point/CHANGELOG.md +++ b/packages/geom-closest-point/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.3.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-closest-point@0.3.7...@thi.ng/geom-closest-point@0.3.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-closest-point + + + + + ## [0.3.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-closest-point@0.3.6...@thi.ng/geom-closest-point@0.3.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-closest-point diff --git a/packages/geom-closest-point/package.json b/packages/geom-closest-point/package.json index c63a5a06f8..d6bf87d86d 100644 --- a/packages/geom-closest-point/package.json +++ b/packages/geom-closest-point/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-closest-point", - "version": "0.3.7", + "version": "0.3.8", "description": "Closest point / proximity helpers", "module": "./index.js", "main": "./lib/index.js", @@ -34,7 +34,7 @@ }, "dependencies": { "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "ES6", diff --git a/packages/geom-hull/CHANGELOG.md b/packages/geom-hull/CHANGELOG.md index 369f460f69..3bf7e13f1e 100644 --- a/packages/geom-hull/CHANGELOG.md +++ b/packages/geom-hull/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.0.28](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-hull@0.0.27...@thi.ng/geom-hull@0.0.28) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-hull + + + + + ## [0.0.27](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-hull@0.0.26...@thi.ng/geom-hull@0.0.27) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-hull diff --git a/packages/geom-hull/package.json b/packages/geom-hull/package.json index 5d17dc524b..0c6f1d8192 100644 --- a/packages/geom-hull/package.json +++ b/packages/geom-hull/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-hull", - "version": "0.0.27", + "version": "0.0.28", "description": "Fast 2D convex hull (Graham Scan)", "module": "./index.js", "main": "./lib/index.js", @@ -34,7 +34,7 @@ }, "dependencies": { "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-isec/CHANGELOG.md b/packages/geom-isec/CHANGELOG.md index 2b689904b6..caa14473f0 100644 --- a/packages/geom-isec/CHANGELOG.md +++ b/packages/geom-isec/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.3.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-isec@0.3.7...@thi.ng/geom-isec@0.3.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-isec + + + + + ## [0.3.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-isec@0.3.6...@thi.ng/geom-isec@0.3.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-isec diff --git a/packages/geom-isec/package.json b/packages/geom-isec/package.json index 8d2fe7a563..ec1ce985dc 100644 --- a/packages/geom-isec/package.json +++ b/packages/geom-isec/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-isec", - "version": "0.3.7", + "version": "0.3.8", "description": "2D/3D shape intersection checks", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/geom-closest-point": "^0.3.7", + "@thi.ng/api": "^6.4.0", + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/geom-closest-point": "^0.3.8", "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-isoline/CHANGELOG.md b/packages/geom-isoline/CHANGELOG.md index 1e9a65d090..439af0c662 100644 --- a/packages/geom-isoline/CHANGELOG.md +++ b/packages/geom-isoline/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.26](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-isoline@0.1.25...@thi.ng/geom-isoline@0.1.26) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-isoline + + + + + ## [0.1.25](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-isoline@0.1.24...@thi.ng/geom-isoline@0.1.25) (2019-08-21) diff --git a/packages/geom-isoline/README.md b/packages/geom-isoline/README.md index 0c124d1c7f..4ec12f6d0c 100644 --- a/packages/geom-isoline/README.md +++ b/packages/geom-isoline/README.md @@ -42,7 +42,7 @@ Animated version: [Live demo](https://demo.thi.ng/umbrella/iso-plasma/) | [Source code](https://github.com/thi-ng/umbrella/tree/master/examples/iso-plasma) -![example output](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/geom-isoline.png) +![example output](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/geom-isoline.png) ```ts import * as g from "@thi.ng/geom"; diff --git a/packages/geom-isoline/package.json b/packages/geom-isoline/package.json index 2496e30a47..3512d26423 100644 --- a/packages/geom-isoline/package.json +++ b/packages/geom-isoline/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-isoline", - "version": "0.1.25", + "version": "0.1.26", "description": "Fast 2D contour line extraction / generation", "module": "./index.js", "main": "./lib/index.js", @@ -33,8 +33,8 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-poly-utils/CHANGELOG.md b/packages/geom-poly-utils/CHANGELOG.md index 4afc52fa42..a1a7112b0c 100644 --- a/packages/geom-poly-utils/CHANGELOG.md +++ b/packages/geom-poly-utils/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.26](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-poly-utils@0.1.25...@thi.ng/geom-poly-utils@0.1.26) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-poly-utils + + + + + ## [0.1.25](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-poly-utils@0.1.24...@thi.ng/geom-poly-utils@0.1.25) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-poly-utils diff --git a/packages/geom-poly-utils/package.json b/packages/geom-poly-utils/package.json index 1e71f70fd6..80da3bc68e 100644 --- a/packages/geom-poly-utils/package.json +++ b/packages/geom-poly-utils/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-poly-utils", - "version": "0.1.25", + "version": "0.1.26", "description": "Polygon / triangle analysis & processing utilities", "module": "./index.js", "main": "./lib/index.js", @@ -34,9 +34,9 @@ }, "dependencies": { "@thi.ng/errors": "^1.2.0", - "@thi.ng/geom-api": "^0.3.5", + "@thi.ng/geom-api": "^0.3.6", "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-resample/CHANGELOG.md b/packages/geom-resample/CHANGELOG.md index b865822874..4cf74de981 100644 --- a/packages/geom-resample/CHANGELOG.md +++ b/packages/geom-resample/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-resample@0.2.7...@thi.ng/geom-resample@0.2.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-resample + + + + + ## [0.2.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-resample@0.2.6...@thi.ng/geom-resample@0.2.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-resample diff --git a/packages/geom-resample/package.json b/packages/geom-resample/package.json index 496301d7a7..4638cbdd65 100644 --- a/packages/geom-resample/package.json +++ b/packages/geom-resample/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-resample", - "version": "0.2.7", + "version": "0.2.8", "description": "Customizable nD polyline interpolation, re-sampling, splitting & nearest point computation", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/geom-closest-point": "^0.3.7", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/geom-closest-point": "^0.3.8", "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-splines/CHANGELOG.md b/packages/geom-splines/CHANGELOG.md index 15951886f5..62ab56aeb7 100644 --- a/packages/geom-splines/CHANGELOG.md +++ b/packages/geom-splines/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.4.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-splines@0.4.0...@thi.ng/geom-splines@0.4.1) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-splines + + + + + # [0.4.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-splines@0.3.4...@thi.ng/geom-splines@0.4.0) (2019-08-21) diff --git a/packages/geom-splines/README.md b/packages/geom-splines/README.md index bc5de4f2f6..be60161cc9 100644 --- a/packages/geom-splines/README.md +++ b/packages/geom-splines/README.md @@ -58,9 +58,9 @@ In this mode the curve always goes through the midpoints each polygon edge, with the original polygon vertices being used to compute control points. -| Proportional tangent scale | Uniform tangent scale | -|------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------| -| ![](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/geom/geom-splines-cp-nonuni.png) | ![](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/geom/geom-splines-cp-uni.png) | +| Proportional tangent scale | Uniform tangent scale | +|-------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------| +| ![](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/geom-splines-cp-nonuni.png) | ![](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/geom-splines-cp-uni.png) | #### Poly vertices as break points @@ -69,9 +69,9 @@ and additional control points are created via symmetric tangents at each poly vertex. The tangents themselves are computed via the bisector of each vertex corner, taking into the convexity of each poly vertex. -| Proportional tangent scale | Uniform tangent scale | -|------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------| -| ![](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/geom/geom-splines-bp-nonuni.png) | ![](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/geom/geom-splines-bp-uni.png) | +| Proportional tangent scale | Uniform tangent scale | +|-------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------| +| ![](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/geom-splines-bp-nonuni.png) | ![](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/geom-splines-bp-uni.png) | ```ts import * as gs from "@thi.ng/geom-splines"; diff --git a/packages/geom-splines/package.json b/packages/geom-splines/package.json index 58877e75c6..75338897e3 100644 --- a/packages/geom-splines/package.json +++ b/packages/geom-splines/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-splines", - "version": "0.4.0", + "version": "0.4.1", "description": "nD cubic & quadratic curve analysis, conversion, interpolation, splitting", "module": "./index.js", "main": "./lib/index.js", @@ -33,12 +33,12 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/geom-arc": "^0.2.7", - "@thi.ng/geom-resample": "^0.2.7", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/geom-arc": "^0.2.8", + "@thi.ng/geom-resample": "^0.2.8", "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-subdiv-curve/CHANGELOG.md b/packages/geom-subdiv-curve/CHANGELOG.md index 18f0fd353f..52c6b13757 100644 --- a/packages/geom-subdiv-curve/CHANGELOG.md +++ b/packages/geom-subdiv-curve/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.25](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-subdiv-curve@0.1.24...@thi.ng/geom-subdiv-curve@0.1.25) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-subdiv-curve + + + + + ## [0.1.24](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-subdiv-curve@0.1.23...@thi.ng/geom-subdiv-curve@0.1.24) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-subdiv-curve diff --git a/packages/geom-subdiv-curve/package.json b/packages/geom-subdiv-curve/package.json index 5bebac8579..f3ab0589e3 100644 --- a/packages/geom-subdiv-curve/package.json +++ b/packages/geom-subdiv-curve/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-subdiv-curve", - "version": "0.1.24", + "version": "0.1.25", "description": "Freely customizable, iterative subdivision curves for open / closed input geometries", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-tessellate/CHANGELOG.md b/packages/geom-tessellate/CHANGELOG.md index 399c9f499e..ab2b5c5df4 100644 --- a/packages/geom-tessellate/CHANGELOG.md +++ b/packages/geom-tessellate/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-tessellate@0.2.7...@thi.ng/geom-tessellate@0.2.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-tessellate + + + + + ## [0.2.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-tessellate@0.2.6...@thi.ng/geom-tessellate@0.2.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-tessellate diff --git a/packages/geom-tessellate/package.json b/packages/geom-tessellate/package.json index 0995f01ef5..ca92752e1f 100644 --- a/packages/geom-tessellate/package.json +++ b/packages/geom-tessellate/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-tessellate", - "version": "0.2.7", + "version": "0.2.8", "description": "2D/3D polygon tessellators", "module": "./index.js", "main": "./lib/index.js", @@ -33,12 +33,12 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/geom-isec": "^0.3.7", - "@thi.ng/geom-poly-utils": "^0.1.25", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/checks": "^2.4.0", + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/geom-isec": "^0.3.8", + "@thi.ng/geom-poly-utils": "^0.1.26", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom-voronoi/CHANGELOG.md b/packages/geom-voronoi/CHANGELOG.md index 9f3158f13b..5b8420603a 100644 --- a/packages/geom-voronoi/CHANGELOG.md +++ b/packages/geom-voronoi/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.26](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-voronoi@0.1.25...@thi.ng/geom-voronoi@0.1.26) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom-voronoi + + + + + ## [0.1.25](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom-voronoi@0.1.24...@thi.ng/geom-voronoi@0.1.25) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom-voronoi diff --git a/packages/geom-voronoi/README.md b/packages/geom-voronoi/README.md index 2731c10d52..deca49a7de 100644 --- a/packages/geom-voronoi/README.md +++ b/packages/geom-voronoi/README.md @@ -53,7 +53,7 @@ yarn add @thi.ng/geom-voronoi ## Usage examples -![example screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/geom-voronoi.jpg) +![example screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/geom/geom-voronoi.jpg) ```ts import { DVMesh } from "@thi.ng/geom-voronoi"; diff --git a/packages/geom-voronoi/package.json b/packages/geom-voronoi/package.json index 3ba221a104..83177cf394 100644 --- a/packages/geom-voronoi/package.json +++ b/packages/geom-voronoi/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom-voronoi", - "version": "0.1.25", + "version": "0.1.26", "description": "Fast, incremental 2D Delaunay & Voronoi mesh implementation", "module": "./index.js", "main": "./lib/index.js", @@ -33,14 +33,14 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/geom-clip": "^0.1.7", - "@thi.ng/geom-isec": "^0.3.7", - "@thi.ng/geom-poly-utils": "^0.1.25", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/geom-clip": "^0.1.8", + "@thi.ng/geom-isec": "^0.3.8", + "@thi.ng/geom-poly-utils": "^0.1.26", "@thi.ng/math": "^1.4.2", "@thi.ng/quad-edge": "^0.2.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/geom/CHANGELOG.md b/packages/geom/CHANGELOG.md index 02b33305a5..c08155b1b5 100644 --- a/packages/geom/CHANGELOG.md +++ b/packages/geom/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.7.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom@1.7.5...@thi.ng/geom@1.7.6) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/geom + + + + + ## [1.7.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/geom@1.7.4...@thi.ng/geom@1.7.5) (2019-08-21) **Note:** Version bump only for package @thi.ng/geom diff --git a/packages/geom/package.json b/packages/geom/package.json index 55992bc9a5..77ac070d57 100644 --- a/packages/geom/package.json +++ b/packages/geom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/geom", - "version": "1.7.5", + "version": "1.7.6", "description": "2D geometry types, polymorphic operations, SVG generation", "module": "./index.js", "main": "./lib/index.js", @@ -33,31 +33,31 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/arrays": "^0.2.4", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/compose": "^1.3.3", - "@thi.ng/defmulti": "^1.1.3", + "@thi.ng/api": "^6.4.0", + "@thi.ng/arrays": "^0.2.5", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/compose": "^1.3.4", + "@thi.ng/defmulti": "^1.1.4", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/geom-arc": "^0.2.7", - "@thi.ng/geom-clip": "^0.1.7", - "@thi.ng/geom-closest-point": "^0.3.7", - "@thi.ng/geom-hull": "^0.0.27", - "@thi.ng/geom-isec": "^0.3.7", - "@thi.ng/geom-poly-utils": "^0.1.25", - "@thi.ng/geom-resample": "^0.2.7", - "@thi.ng/geom-splines": "^0.4.0", - "@thi.ng/geom-subdiv-curve": "^0.1.24", - "@thi.ng/geom-tessellate": "^0.2.7", - "@thi.ng/hiccup": "^3.2.4", - "@thi.ng/hiccup-svg": "^3.3.0", + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/geom-arc": "^0.2.8", + "@thi.ng/geom-clip": "^0.1.8", + "@thi.ng/geom-closest-point": "^0.3.8", + "@thi.ng/geom-hull": "^0.0.28", + "@thi.ng/geom-isec": "^0.3.8", + "@thi.ng/geom-poly-utils": "^0.1.26", + "@thi.ng/geom-resample": "^0.2.8", + "@thi.ng/geom-splines": "^0.4.1", + "@thi.ng/geom-subdiv-curve": "^0.1.25", + "@thi.ng/geom-tessellate": "^0.2.8", + "@thi.ng/hiccup": "^3.2.5", + "@thi.ng/hiccup-svg": "^3.3.1", "@thi.ng/math": "^1.4.2", - "@thi.ng/matrices": "^0.5.7", - "@thi.ng/random": "^1.1.11", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/matrices": "^0.5.8", + "@thi.ng/random": "^1.1.12", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/grid-iterators/.npmignore b/packages/grid-iterators/.npmignore new file mode 100644 index 0000000000..24f388daa6 --- /dev/null +++ b/packages/grid-iterators/.npmignore @@ -0,0 +1,18 @@ +.cache +.meta +.nyc_output +*.gz +*.html +*.svg +*.tgz +*.h +*.o +*.wasm +build +coverage +dev +doc +export +src* +test +tsconfig.json diff --git a/packages/grid-iterators/CHANGELOG.md b/packages/grid-iterators/CHANGELOG.md new file mode 100644 index 0000000000..fa149a5a6b --- /dev/null +++ b/packages/grid-iterators/CHANGELOG.md @@ -0,0 +1,11 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2019-09-21) + + +### Features + +* **grid-iterators:** import as new package, incl. assets ([fe4ee00](https://github.com/thi-ng/umbrella/commit/fe4ee00)) diff --git a/packages/grid-iterators/LICENSE b/packages/grid-iterators/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/grid-iterators/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/grid-iterators/README.md b/packages/grid-iterators/README.md new file mode 100644 index 0000000000..9798051029 --- /dev/null +++ b/packages/grid-iterators/README.md @@ -0,0 +1,69 @@ +# @thi.ng/grid-iterators + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/grid-iterators.svg)](https://www.npmjs.com/package/@thi.ng/grid-iterators) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/grid-iterators.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + +- [About](#about) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) +- [Authors](#authors) +- [License](#license) + + + +## About + +Collection of 2D grid iterators, providing the following orderings: + +| [Diagonal](https://github.com/thi-ng/umbrella/tree/develop/packages/grid-iterators/src/diagonal2d.ts) | [Hilbert curve](https://github.com/thi-ng/umbrella/tree/develop/packages/grid-iterators/src/hilbert2d.ts) | [Outward spiral](https://github.com/thi-ng/umbrella/tree/develop/packages/grid-iterators/src/spiral2d.ts) | +|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------| +| ![anim](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/grid-iterators/grid-diagonal.gif) | ![anim](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/grid-iterators/grid-hilbert.gif) | ![anim](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/grid-iterators/grid-spiral.gif) | +| [Zigzag columns](https://github.com/thi-ng/umbrella/tree/develop/packages/grid-iterators/src/columns2d.ts) | [Zigzag rows](https://github.com/thi-ng/umbrella/tree/develop/packages/grid-iterators/src/rows2d.ts) | | +| ![anim](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/grid-iterators/grid-zigzag-cols.gif) | ![anim](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/grid-iterators/grid-zigzag-rows.gif) | | + +All functions have been ported from [Christopher +Kulla](https://fpsunflower.github.io/ckulla/)'s Java-based [Sunflow +renderer](https://sunflow.sf.net). + +For alternative 2D/3D grid iteration, also see `range2d()` & `range3d()` in +[@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/master/packages/transducers). + +## Installation + +```bash +yarn add @thi.ng/grid-iterators +``` + +## Dependencies + +None + +## Usage examples + +```ts +import * as gi from "@thi.ng/grid-iterators"; + +[...gi.zigzagRows2d(4, 4)] + +// [ +// [ 0, 0 ], [ 1, 0 ], [ 2, 0 ], [ 3, 0 ], +// [ 3, 1 ], [ 2, 1 ], [ 1, 1 ], [ 0, 1 ], +// [ 0, 2 ], [ 1, 2 ], [ 2, 2 ], [ 3, 2 ], +// [ 3, 3 ], [ 2, 3 ], [ 1, 3 ], [ 0, 3 ] +// ] +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2019 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/grid-iterators/package.json b/packages/grid-iterators/package.json new file mode 100644 index 0000000000..cb9f4ec899 --- /dev/null +++ b/packages/grid-iterators/package.json @@ -0,0 +1,49 @@ +{ + "name": "@thi.ng/grid-iterators", + "version": "0.1.0", + "description": "2D grid iterators w/ multiple orderings", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/grid-iterators", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn clean && yarn build:es6 && node ../../scripts/bundle-module", + "build:release": "yarn clean && yarn build:es6 && node ../../scripts/bundle-module all", + "build:es6": "tsc --declaration", + "build:test": "rimraf build && tsc -p test/tsconfig.json", + "test": "yarn build:test && mocha build/test/*.js", + "cover": "yarn build:test && nyc mocha build/test/*.js && nyc report --reporter=lcov", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", + "doc": "node_modules/.bin/typedoc --mode modules --out doc --ignoreCompilerErrors src", + "pub": "yarn build:release && yarn publish --access public" + }, + "devDependencies": { + "@types/mocha": "^5.2.6", + "@types/node": "^12.6.3", + "mocha": "^6.1.4", + "nyc": "^14.0.0", + "typedoc": "^0.14.2", + "typescript": "^3.5.3" + }, + "keywords": [ + "ES6", + "2D", + "grid", + "hilbert", + "iterator", + "spiral", + "typescript", + "zigzag" + ], + "publishConfig": { + "access": "public" + }, + "sideEffects": false +} diff --git a/packages/grid-iterators/src/columns2d.ts b/packages/grid-iterators/src/columns2d.ts new file mode 100644 index 0000000000..1a257f5b97 --- /dev/null +++ b/packages/grid-iterators/src/columns2d.ts @@ -0,0 +1,20 @@ +/** + * Yields sequence of 2D grid coordinates in zigzag column order starting + * from [0,0], given `cols` and `rows`. + * + * Ported & modified from original Java code by Christopher Kulla. + * https://sourceforge.net/p/sunflow/code/HEAD/tree/trunk/src/org/sunflow/core/bucket/SpiralBucketOrder.java + * + * @param cols + * @param rows + * + */ +export function* zigzagColumns2d(cols: number, rows: number) { + const num = cols * rows; + for (let i = 0; i < num; i++) { + const x = (i / rows) | 0; + let y = i % rows; + x & 1 && (y = rows - 1 - y); + yield [x, y]; + } +} diff --git a/packages/grid-iterators/src/diagonal2d.ts b/packages/grid-iterators/src/diagonal2d.ts new file mode 100644 index 0000000000..6860c2e9a7 --- /dev/null +++ b/packages/grid-iterators/src/diagonal2d.ts @@ -0,0 +1,27 @@ +/** + * Yields sequence of 2D grid coordinates in diagonal order starting at + * [0,0] and using given `cols` and `rows`. + * + * Ported & modified from original Java code by Christopher Kulla. + * https://sourceforge.net/p/sunflow/code/HEAD/tree/trunk/src/org/sunflow/core/bucket/DiagonalBucketOrder.java + * + * @param cols + * @param rows + */ +export function* diagonal2d(cols: number, rows: number) { + const num = cols * rows - 1; + for (let x = 0, y = 0, nx = 1, ny = 0, i = 0; i <= num; i++) { + yield [x, y]; + do { + if (y === ny) { + y = 0; + x = nx; + ny++; + nx++; + } else { + x--; + y++; + } + } while ((y >= rows || x >= cols) && i != num); + } +} diff --git a/packages/grid-iterators/src/hilbert2d.ts b/packages/grid-iterators/src/hilbert2d.ts new file mode 100644 index 0000000000..e3769fee54 --- /dev/null +++ b/packages/grid-iterators/src/hilbert2d.ts @@ -0,0 +1,64 @@ +/** + * Yields sequence of 2D grid coordinates along 2D Hilbert curve using + * given `cols` and `rows` (each max. 32768 (2^15)). + * + * Ported & modified from original Java code by Christopher Kulla. + * https://sourceforge.net/p/sunflow/code/HEAD/tree/trunk/src/org/sunflow/core/bucket/HilbertBucketOrder.java + * + * @param cols + * @param rows + */ +export function* hilbert2d(cols: number, rows: number) { + let hIndex = 0; // hilbert curve index + let hOrder = 0; // hilbert curve order + // fit to number of buckets + while ((1 << hOrder < cols || 1 << hOrder < rows) && hOrder < 15) hOrder++; + const numBuckets = 1 << (2 * hOrder); + for (let i = 0, n = cols * rows; i < n; i++) { + let hx, hy; + do { + // adapted from Hacker's Delight + let s, t, comp, swap, cs, sr; + // s is the hilbert index, shifted to start in the middle + s = hIndex | (0x55555555 << (2 * hOrder)); // Pad s on left with 01 + sr = (s >>> 1) & 0x55555555; // (no change) groups. + cs = ((s & 0x55555555) + sr) ^ 0x55555555; + // Compute complement & swap info in two-bit groups. + // Parallel prefix xor op to propagate both complement and + // swap info together from left to right (there is no step + // "cs ^= cs >> 1", so in effect it computes two independent + // parallel prefix operations on two interleaved sets of + // sixteen bits). + cs = cs ^ (cs >>> 2); + cs = cs ^ (cs >>> 4); + cs = cs ^ (cs >>> 8); + cs = cs ^ (cs >>> 16); + // Separate the swap and complement bits. + swap = cs & 0x55555555; + comp = (cs >>> 1) & 0x55555555; + // Calculate x and y in the odd & even bit positions + t = (s & swap) ^ comp; + s = s ^ sr ^ t ^ (t << 1); + // Clear out any junk on the left (unpad). + s = s & ((1 << (2 * hOrder)) - 1); + // Now "unshuffle" to separate the x and y bits. + t = (s ^ (s >>> 1)) & 0x22222222; + s = s ^ t ^ (t << 1); + t = (s ^ (s >>> 2)) & 0x0c0c0c0c; + s = s ^ t ^ (t << 2); + t = (s ^ (s >>> 4)) & 0x00f000f0; + s = s ^ t ^ (t << 4); + t = (s ^ (s >>> 8)) & 0x0000ff00; + s = s ^ t ^ (t << 8); + // Assign the two halves to x and y. + hx = s >>> 16; + hy = s & 0xffff; + hIndex++; + } while ( + // Dont't emit any outside cells + (hx >= cols || hy >= rows || hx < 0 || hy < 0) && + hIndex < numBuckets + ); + yield [hx, hy]; + } +} diff --git a/packages/grid-iterators/src/index.ts b/packages/grid-iterators/src/index.ts new file mode 100644 index 0000000000..8c5a8a4ddc --- /dev/null +++ b/packages/grid-iterators/src/index.ts @@ -0,0 +1,5 @@ +export * from "./columns2d"; +export * from "./diagonal2d"; +export * from "./hilbert2d"; +export * from "./rows2d"; +export * from "./spiral2d"; diff --git a/packages/grid-iterators/src/rows2d.ts b/packages/grid-iterators/src/rows2d.ts new file mode 100644 index 0000000000..6683e4665e --- /dev/null +++ b/packages/grid-iterators/src/rows2d.ts @@ -0,0 +1,20 @@ +/** + * Yields sequence of 2D grid coordinates in zigzag row order starting + * from [0,0], given `cols` and `rows`. + * + * Ported & modified from original Java code by Christopher Kulla. + * https://sourceforge.net/p/sunflow/code/HEAD/tree/trunk/src/org/sunflow/core/bucket/SpiralBucketOrder.java + * + * @param cols + * @param rows + * + */ +export function* zigzagRows2d(cols: number, rows: number) { + const num = cols * rows; + for (let i = 0; i < num; i++) { + let x = i % cols; + const y = (i / cols) | 0; + y & 1 && (x = cols - 1 - x); + yield [x, y]; + } +} diff --git a/packages/grid-iterators/src/spiral2d.ts b/packages/grid-iterators/src/spiral2d.ts new file mode 100644 index 0000000000..c84918c5dd --- /dev/null +++ b/packages/grid-iterators/src/spiral2d.ts @@ -0,0 +1,44 @@ +/** + * Yields sequence of 2D grid coordinates in outward spiral order + * starting from the center, given `cols` and `rows`. + * + * Ported & modified from original Java code by Christopher Kulla. + * https://sourceforge.net/p/sunflow/code/HEAD/tree/trunk/src/org/sunflow/core/bucket/SpiralBucketOrder.java + * + * @param cols + * @param rows + */ +export function* spiral2d(cols: number, rows: number) { + const num = cols * rows; + const center = (Math.min(cols, rows) - 1) >> 1; + for (let i = 0; i < num; i++) { + let nx = cols; + let ny = rows; + while (i < nx * ny) { + nx--; + ny--; + } + const nxny = nx * ny; + const minnxny = Math.min(nx, ny); + const m2 = minnxny >> 1; + let bx, by; + if (minnxny & 1) { + if (i <= nxny + ny) { + bx = nx - m2; + by = -m2 + i - nxny; + } else { + bx = nx - m2 - (i - (nxny + ny)); + by = ny - m2; + } + } else { + if (i <= nxny + ny) { + bx = -m2; + by = ny - m2 - (i - nxny); + } else { + bx = -m2 + (i - (nxny + ny)); + by = -m2; + } + } + yield [bx + center, by + center]; + } +} diff --git a/packages/grid-iterators/test/index.ts b/packages/grid-iterators/test/index.ts new file mode 100644 index 0000000000..ae394d6d00 --- /dev/null +++ b/packages/grid-iterators/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as gi from "../src/index"; + +describe("grid-iterators", () => { + it("tests pending"); +}); diff --git a/packages/grid-iterators/test/tsconfig.json b/packages/grid-iterators/test/tsconfig.json new file mode 100644 index 0000000000..f6e63560dd --- /dev/null +++ b/packages/grid-iterators/test/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build", + "module": "commonjs" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/grid-iterators/tsconfig.json b/packages/grid-iterators/tsconfig.json new file mode 100644 index 0000000000..893b9979c5 --- /dev/null +++ b/packages/grid-iterators/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "module": "es6", + "target": "es6" + }, + "include": [ + "./src/**/*.ts" + ] +} diff --git a/packages/hdom-canvas/CHANGELOG.md b/packages/hdom-canvas/CHANGELOG.md index aff957e4cf..35304117fc 100644 --- a/packages/hdom-canvas/CHANGELOG.md +++ b/packages/hdom-canvas/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [2.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-canvas@2.2.4...@thi.ng/hdom-canvas@2.3.0) (2019-09-21) + + +### Features + +* **hdom-canvas:** add clip attrib support for paths ([2c2909d](https://github.com/thi-ng/umbrella/commit/2c2909d)) + + + + + ## [2.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-canvas@2.2.3...@thi.ng/hdom-canvas@2.2.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/hdom-canvas diff --git a/packages/hdom-canvas/package.json b/packages/hdom-canvas/package.json index 4b27f97a22..3642fd4872 100644 --- a/packages/hdom-canvas/package.json +++ b/packages/hdom-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-canvas", - "version": "2.2.4", + "version": "2.3.0", "description": "Declarative canvas scenegraph & visualization for @thi.ng/hdom", "module": "./index.js", "main": "./lib/index.js", @@ -33,13 +33,13 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/color": "^1.1.0", - "@thi.ng/diff": "^3.2.3", - "@thi.ng/hdom": "^8.0.4", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/color": "^1.1.1", + "@thi.ng/diff": "^3.2.4", + "@thi.ng/hdom": "^8.0.5", "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "ES6", diff --git a/packages/hdom-canvas/src/draw/end-shape.ts b/packages/hdom-canvas/src/draw/end-shape.ts index 40677e4f7e..14acf0d4d7 100644 --- a/packages/hdom-canvas/src/draw/end-shape.ts +++ b/packages/hdom-canvas/src/draw/end-shape.ts @@ -11,4 +11,7 @@ export const endShape = ( if ((v = attribs.stroke) && v !== "none") { ctx.stroke(); } + if ((v = attribs.clip)) { + ctx.clip(v === true ? "nonzero" : v); + } }; diff --git a/packages/hdom-components/CHANGELOG.md b/packages/hdom-components/CHANGELOG.md index d1530812f7..ab3023b707 100644 --- a/packages/hdom-components/CHANGELOG.md +++ b/packages/hdom-components/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@3.1.4...@thi.ng/hdom-components@3.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/hdom-components + + + + + ## [3.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-components@3.1.3...@thi.ng/hdom-components@3.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/hdom-components diff --git a/packages/hdom-components/package.json b/packages/hdom-components/package.json index e364d08e8b..59878c3070 100644 --- a/packages/hdom-components/package.json +++ b/packages/hdom-components/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-components", - "version": "3.1.4", + "version": "3.1.5", "description": "Raw, skinnable UI & SVG components for @thi.ng/hdom", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/math": "^1.4.2", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/transducers-stats": "^1.1.4", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/transducers-stats": "^1.1.5", "@types/webgl2": "^0.0.5" }, "keywords": [ diff --git a/packages/hdom-mock/CHANGELOG.md b/packages/hdom-mock/CHANGELOG.md index 08d4d5775e..9715cdcebc 100644 --- a/packages/hdom-mock/CHANGELOG.md +++ b/packages/hdom-mock/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-mock@1.1.4...@thi.ng/hdom-mock@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/hdom-mock + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom-mock@1.1.3...@thi.ng/hdom-mock@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/hdom-mock diff --git a/packages/hdom-mock/package.json b/packages/hdom-mock/package.json index d6e45bf74f..c964f2ad72 100644 --- a/packages/hdom-mock/package.json +++ b/packages/hdom-mock/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom-mock", - "version": "1.1.4", + "version": "1.1.5", "description": "Mock base implementation for @thi.ng/hdom API", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/hdom": "^8.0.4" + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/hdom": "^8.0.5" }, "keywords": [ "ES6", diff --git a/packages/hdom/CHANGELOG.md b/packages/hdom/CHANGELOG.md index 36e68fe302..618de6a78c 100644 --- a/packages/hdom/CHANGELOG.md +++ b/packages/hdom/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [8.0.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@8.0.4...@thi.ng/hdom@8.0.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/hdom + + + + + ## [8.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/hdom@8.0.3...@thi.ng/hdom@8.0.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/hdom diff --git a/packages/hdom/README.md b/packages/hdom/README.md index e582589682..813bc9aa65 100644 --- a/packages/hdom/README.md +++ b/packages/hdom/README.md @@ -153,7 +153,7 @@ diffing via RAF). ```ts import { fromInterval, stream, sync } from "@thi.ng/rstream"; import { updateDOM } from "@thi.ng/transducers-hdom"; -import { map, scan } from "@thi.ng/transducers"; +import { map, scan, count } from "@thi.ng/transducers"; // root component function const app = ({ ticks, clicks }) => @@ -165,7 +165,7 @@ const app = ({ ticks, clicks }) => ]; // transformed stream to count clicks -const clickStream = stream().transform(scan(tx.count(-1))); +const clickStream = stream().transform(scan(count(-1))); // seed clickStream.next(0); @@ -322,7 +322,7 @@ previous DOM tree. - hdom can be used **without** diffing, i.e. for compact, one-off DOM creation (see [`renderOnce()`](#renderonce)) -![hdom dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/hdom-dataflow.png) +![hdom dataflow](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/hdom/hdom-dataflow.png) The syntax is inspired by Clojure's [Hiccup](https://github.com/weavejester/hiccup) and @@ -759,42 +759,42 @@ Non-exhaustive list: ### Realtime crypto candle chart -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/crypto-chart.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/crypto-chart.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/crypto-chart) | [Live version](https://demo.thi.ng/umbrella/crypto-chart/) ### Git commit log table -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/commit-table-ssr.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/commit-table-ssr.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/commit-table-ssr) | [Live version](https://demo.thi.ng/umbrella/commit-table-ssr/) ### XML/HTML/SVG to Hiccup converter -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/xml-converter.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/xml-converter.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/xml-converter) | [Live version](https://demo.thi.ng/umbrella/xml-converter/) ### Interactive SVG grid generator -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/rstream-grid.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rstream-grid.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/rstream-grid) | [Live version](https://demo.thi.ng/umbrella/rstream-grid/) ### Interactive additive waveform visualization -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/svg-waveform.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/svg-waveform.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/svg-waveform) | [Live version](https://demo.thi.ng/umbrella/svg-waveform/) ### Dataflow graph SVG components -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/estuary.jpg) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/estuary/estuary.jpg) This is a preview of the WIP [@thi.ng/estuary](https://github.com/thi-ng/umbrella/tree/feature/estuary/packages/estuary) @@ -805,14 +805,14 @@ package: ### Mouse gesture analysis -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/gesture-analysis.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/gesture-analysis.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/gesture-analysis) | [Live version](https://demo.thi.ng/umbrella/gesture-analysis) ### Canvas based radial dial input widget -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/canvas-dial.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/canvas-dial.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/canvas-dial) | [Live version](https://demo.thi.ng/umbrella/canvas-dial/) diff --git a/packages/hdom/package.json b/packages/hdom/package.json index b0ce64d01b..16c48473b3 100644 --- a/packages/hdom/package.json +++ b/packages/hdom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hdom", - "version": "8.0.4", + "version": "8.0.5", "description": "Lightweight vanilla ES6 UI component trees with customizable branch-local behaviors", "module": "./index.js", "main": "./lib/index.js", @@ -25,7 +25,7 @@ "pub": "yarn build:release && yarn publish --access public" }, "devDependencies": { - "@thi.ng/atom": "^3.0.4", + "@thi.ng/atom": "^3.1.0", "@types/mocha": "^5.2.6", "@types/node": "^12.6.3", "mocha": "^6.1.4", @@ -34,12 +34,12 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/diff": "^3.2.3", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/diff": "^3.2.4", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/hiccup": "^3.2.4" + "@thi.ng/hiccup": "^3.2.5" }, "keywords": [ "browser", diff --git a/packages/heaps/CHANGELOG.md b/packages/heaps/CHANGELOG.md index d27cc3b74c..ee4da08857 100644 --- a/packages/heaps/CHANGELOG.md +++ b/packages/heaps/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/heaps@1.1.3...@thi.ng/heaps@1.1.4) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/heaps + + + + + ## [1.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/heaps@1.1.2...@thi.ng/heaps@1.1.3) (2019-08-21) **Note:** Version bump only for package @thi.ng/heaps diff --git a/packages/heaps/package.json b/packages/heaps/package.json index 25b0a6c699..2dc0594a31 100644 --- a/packages/heaps/package.json +++ b/packages/heaps/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/heaps", - "version": "1.1.3", + "version": "1.1.4", "description": "Generic binary heap & d-ary heap implementations with customizable ordering", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/compare": "^1.0.9" }, "keywords": [ diff --git a/packages/hiccup-carbon-icons/CHANGELOG.md b/packages/hiccup-carbon-icons/CHANGELOG.md index 3bcbc36507..b7c092f405 100644 --- a/packages/hiccup-carbon-icons/CHANGELOG.md +++ b/packages/hiccup-carbon-icons/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.0.20](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-carbon-icons@1.0.19...@thi.ng/hiccup-carbon-icons@1.0.20) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/hiccup-carbon-icons + + + + + ## [1.0.19](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-carbon-icons@1.0.18...@thi.ng/hiccup-carbon-icons@1.0.19) (2019-08-21) **Note:** Version bump only for package @thi.ng/hiccup-carbon-icons diff --git a/packages/hiccup-carbon-icons/package.json b/packages/hiccup-carbon-icons/package.json index 4589cf6247..e8ff841785 100644 --- a/packages/hiccup-carbon-icons/package.json +++ b/packages/hiccup-carbon-icons/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-carbon-icons", - "version": "1.0.19", + "version": "1.0.20", "description": "Full set of IBM's Carbon icons in hiccup format", "module": "./index.js", "main": "./lib/index.js", @@ -25,7 +25,7 @@ "pub": "yarn build:release && yarn publish --access public" }, "devDependencies": { - "@thi.ng/hiccup": "^3.2.4", + "@thi.ng/hiccup": "^3.2.5", "@types/mocha": "^5.2.6", "@types/node": "^12.6.3", "mocha": "^6.1.4", diff --git a/packages/hiccup-css/CHANGELOG.md b/packages/hiccup-css/CHANGELOG.md index 61bf5c0fe5..c369bd862a 100644 --- a/packages/hiccup-css/CHANGELOG.md +++ b/packages/hiccup-css/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@1.1.4...@thi.ng/hiccup-css@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/hiccup-css + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-css@1.1.3...@thi.ng/hiccup-css@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/hiccup-css diff --git a/packages/hiccup-css/package.json b/packages/hiccup-css/package.json index a36c91f9d4..21ad7aabc4 100644 --- a/packages/hiccup-css/package.json +++ b/packages/hiccup-css/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-css", - "version": "1.1.4", + "version": "1.1.5", "description": "CSS from nested JS data structures", "module": "./index.js", "main": "./lib/index.js", @@ -33,10 +33,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "clojure", diff --git a/packages/hiccup-markdown/CHANGELOG.md b/packages/hiccup-markdown/CHANGELOG.md index 86d20ca439..0d83239e43 100644 --- a/packages/hiccup-markdown/CHANGELOG.md +++ b/packages/hiccup-markdown/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-markdown@1.1.4...@thi.ng/hiccup-markdown@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/hiccup-markdown + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-markdown@1.1.3...@thi.ng/hiccup-markdown@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/hiccup-markdown diff --git a/packages/hiccup-markdown/package.json b/packages/hiccup-markdown/package.json index e733793d18..e837352734 100644 --- a/packages/hiccup-markdown/package.json +++ b/packages/hiccup-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-markdown", - "version": "1.1.4", + "version": "1.1.5", "description": "Markdown serialization of hiccup DOM trees", "module": "./index.js", "main": "./lib/index.js", @@ -33,14 +33,14 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/arrays": "^0.2.4", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/defmulti": "^1.1.3", + "@thi.ng/arrays": "^0.2.5", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/defmulti": "^1.1.4", "@thi.ng/errors": "^1.2.0", - "@thi.ng/fsm": "^2.2.4", - "@thi.ng/hiccup": "^3.2.4", - "@thi.ng/strings": "^1.2.3", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/fsm": "^2.2.5", + "@thi.ng/hiccup": "^3.2.5", + "@thi.ng/strings": "^1.3.0", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "ES6", diff --git a/packages/hiccup-svg/CHANGELOG.md b/packages/hiccup-svg/CHANGELOG.md index f46bc0a75b..7a43327344 100644 --- a/packages/hiccup-svg/CHANGELOG.md +++ b/packages/hiccup-svg/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.3.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@3.3.0...@thi.ng/hiccup-svg@3.3.1) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/hiccup-svg + + + + + # [3.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup-svg@3.2.6...@thi.ng/hiccup-svg@3.3.0) (2019-08-21) diff --git a/packages/hiccup-svg/package.json b/packages/hiccup-svg/package.json index e7cc77cca6..ed14c04bfd 100644 --- a/packages/hiccup-svg/package.json +++ b/packages/hiccup-svg/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup-svg", - "version": "3.3.0", + "version": "3.3.1", "description": "SVG element functions for @thi.ng/hiccup & @thi.ng/hdom", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", - "@thi.ng/color": "^1.1.0", - "@thi.ng/hiccup": "^3.2.4" + "@thi.ng/checks": "^2.4.0", + "@thi.ng/color": "^1.1.1", + "@thi.ng/hiccup": "^3.2.5" }, "keywords": [ "components", diff --git a/packages/hiccup/CHANGELOG.md b/packages/hiccup/CHANGELOG.md index 7eb41e5ca5..b1633f5581 100644 --- a/packages/hiccup/CHANGELOG.md +++ b/packages/hiccup/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@3.2.4...@thi.ng/hiccup@3.2.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/hiccup + + + + + ## [3.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/hiccup@3.2.3...@thi.ng/hiccup@3.2.4) (2019-08-21) diff --git a/packages/hiccup/package.json b/packages/hiccup/package.json index 53d0b5b4e4..07196d3f6e 100644 --- a/packages/hiccup/package.json +++ b/packages/hiccup/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/hiccup", - "version": "3.2.4", + "version": "3.2.5", "description": "HTML/SVG/XML serialization of nested data structures, iterables & closures", "module": "./index.js", "main": "./lib/index.js", @@ -25,7 +25,7 @@ "pub": "yarn build:release && yarn publish --access public" }, "devDependencies": { - "@thi.ng/atom": "^3.0.4", + "@thi.ng/atom": "^3.1.0", "@types/mocha": "^5.2.6", "@types/node": "^12.6.3", "mocha": "^6.1.4", @@ -34,7 +34,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0" }, "keywords": [ diff --git a/packages/iges/CHANGELOG.md b/packages/iges/CHANGELOG.md index 9f522e9db1..e2d2df388f 100644 --- a/packages/iges/CHANGELOG.md +++ b/packages/iges/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.10](https://github.com/thi-ng/umbrella/compare/@thi.ng/iges@1.1.9...@thi.ng/iges@1.1.10) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/iges + + + + + ## [1.1.9](https://github.com/thi-ng/umbrella/compare/@thi.ng/iges@1.1.8...@thi.ng/iges@1.1.9) (2019-08-21) **Note:** Version bump only for package @thi.ng/iges diff --git a/packages/iges/README.md b/packages/iges/README.md index f02f7baf14..f99bdcdd47 100644 --- a/packages/iges/README.md +++ b/packages/iges/README.md @@ -13,7 +13,7 @@ Bare-bones IGES 5.3 serializer for (currently only) polygonal geometry, both open & closed, for use in various CAD applications (e.g. Rhino, Houdini, Fusion 360) -![houdini](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/iges.png) +![houdini](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/iges/iges-houdini.png) ## Installation diff --git a/packages/iges/package.json b/packages/iges/package.json index c66aab57de..96da73e424 100644 --- a/packages/iges/package.json +++ b/packages/iges/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/iges", - "version": "1.1.9", + "version": "1.1.10", "description": "IGES 5.3 serializer for (currently only) polygonal geometry, both open & closed", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/defmulti": "^1.1.3", - "@thi.ng/strings": "^1.2.3", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/defmulti": "^1.1.4", + "@thi.ng/strings": "^1.3.0", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "CAD", diff --git a/packages/imgui/CHANGELOG.md b/packages/imgui/CHANGELOG.md index 1f54ebb010..5b0e4dace5 100644 --- a/packages/imgui/CHANGELOG.md +++ b/packages/imgui/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/imgui@0.1.2...@thi.ng/imgui@0.1.3) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/imgui + + + + + ## [0.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/imgui@0.1.1...@thi.ng/imgui@0.1.2) (2019-08-21) **Note:** Version bump only for package @thi.ng/imgui diff --git a/packages/imgui/README.md b/packages/imgui/README.md index d37e23551a..2cf99e9fc7 100644 --- a/packages/imgui/README.md +++ b/packages/imgui/README.md @@ -27,7 +27,7 @@ This project is part of the ## About -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/imgui-all.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/imgui/imgui-all.png) Currently still somewhat bare-bones, but already usable & customizable [immediate mode GUI](https://github.com/ocornut/imgui#references) implementation, @@ -136,7 +136,7 @@ The `GridLayout` class supports infinite nesting and column/row-based space allocation, based on an initial configuration and supporting multiple column/row spans. -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/imgui-layout.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/imgui/imgui-layout.png) The code producing this structure: diff --git a/packages/imgui/package.json b/packages/imgui/package.json index 0f6ff4f0ec..68584a2d67 100644 --- a/packages/imgui/package.json +++ b/packages/imgui/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/imgui", - "version": "0.1.2", + "version": "0.1.3", "description": "Immediate mode GUI with flexible state handling & data only shape output", "module": "./index.js", "main": "./lib/index.js", @@ -33,15 +33,15 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/geom": "^1.7.5", - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/geom-isec": "^0.3.7", - "@thi.ng/geom-tessellate": "^0.2.7", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/geom": "^1.7.6", + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/geom-isec": "^0.3.8", + "@thi.ng/geom-tessellate": "^0.2.8", "@thi.ng/math": "^1.4.2", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "canvas", diff --git a/packages/interceptors/CHANGELOG.md b/packages/interceptors/CHANGELOG.md index 3755b2c77c..0768e9acc7 100644 --- a/packages/interceptors/CHANGELOG.md +++ b/packages/interceptors/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.2.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@2.2.0...@thi.ng/interceptors@2.2.1) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/interceptors + + + + + # [2.2.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/interceptors@2.1.3...@thi.ng/interceptors@2.2.0) (2019-08-21) diff --git a/packages/interceptors/package.json b/packages/interceptors/package.json index 069dc0402d..3fb209d67f 100644 --- a/packages/interceptors/package.json +++ b/packages/interceptors/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/interceptors", - "version": "2.2.0", + "version": "2.2.1", "description": "Interceptor based event bus, side effect & immutable state handling", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/atom": "^3.0.4", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/atom": "^3.1.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0", - "@thi.ng/paths": "^2.1.4" + "@thi.ng/paths": "^2.1.5" }, "keywords": [ "ES6", diff --git a/packages/intervals/CHANGELOG.md b/packages/intervals/CHANGELOG.md index f588cce06c..5e242c5ea3 100644 --- a/packages/intervals/CHANGELOG.md +++ b/packages/intervals/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.0.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/intervals@1.0.13...@thi.ng/intervals@1.0.14) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/intervals + + + + + ## [1.0.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/intervals@1.0.12...@thi.ng/intervals@1.0.13) (2019-08-21) **Note:** Version bump only for package @thi.ng/intervals diff --git a/packages/intervals/package.json b/packages/intervals/package.json index 6b6c387c02..1aa834d0f8 100644 --- a/packages/intervals/package.json +++ b/packages/intervals/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/intervals", - "version": "1.0.13", + "version": "1.0.14", "description": "Closed/open/semi-open interval data type, queries & operations", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/errors": "^1.2.0" }, "keywords": [ diff --git a/packages/iterators/CHANGELOG.md b/packages/iterators/CHANGELOG.md index 23ae4928ab..f27754d102 100644 --- a/packages/iterators/CHANGELOG.md +++ b/packages/iterators/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@5.1.4...@thi.ng/iterators@5.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/iterators + + + + + ## [5.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/iterators@5.1.3...@thi.ng/iterators@5.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/iterators diff --git a/packages/iterators/package.json b/packages/iterators/package.json index 2907adcd99..b602480426 100644 --- a/packages/iterators/package.json +++ b/packages/iterators/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/iterators", - "version": "5.1.4", + "version": "5.1.5", "description": "clojure.core inspired, composable ES6 iterators & generators", "module": "./index.js", "main": "./lib/index.js", @@ -33,8 +33,8 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/dcons": "^2.1.4", + "@thi.ng/api": "^6.4.0", + "@thi.ng/dcons": "^2.1.5", "@thi.ng/errors": "^1.2.0" }, "keywords": [ diff --git a/packages/leb128/CHANGELOG.md b/packages/leb128/CHANGELOG.md index 81d16c708a..db7fa43a7c 100644 --- a/packages/leb128/CHANGELOG.md +++ b/packages/leb128/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/leb128@0.1.4...@thi.ng/leb128@0.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/leb128 + + + + + ## [0.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/leb128@0.1.3...@thi.ng/leb128@0.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/leb128 diff --git a/packages/leb128/package.json b/packages/leb128/package.json index 08697e9396..c335573674 100644 --- a/packages/leb128/package.json +++ b/packages/leb128/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/leb128", - "version": "0.1.4", + "version": "0.1.5", "description": "WASM based LEB128 encoder / decoder (signed & unsigned)", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0", - "@thi.ng/transducers-binary": "^0.4.4" + "@thi.ng/transducers-binary": "^0.4.5" }, "keywords": [ "LEB128", diff --git a/packages/lsys/CHANGELOG.md b/packages/lsys/CHANGELOG.md index 5ec3d47f21..7a18348fc0 100644 --- a/packages/lsys/CHANGELOG.md +++ b/packages/lsys/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.23](https://github.com/thi-ng/umbrella/compare/@thi.ng/lsys@0.2.22...@thi.ng/lsys@0.2.23) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/lsys + + + + + ## [0.2.22](https://github.com/thi-ng/umbrella/compare/@thi.ng/lsys@0.2.21...@thi.ng/lsys@0.2.22) (2019-08-21) **Note:** Version bump only for package @thi.ng/lsys diff --git a/packages/lsys/README.md b/packages/lsys/README.md index aae9b7d9cb..2712c80a75 100644 --- a/packages/lsys/README.md +++ b/packages/lsys/README.md @@ -60,10 +60,10 @@ yarn add @thi.ng/lsys ## Usage examples -| Examples | | -|----------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------| -| ![example](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/lsys-0.png) | ![example](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/lsys-1.png) | -| ![example](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/lsys-2.png) | ![example](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/lsys-3.png) | +| Examples | | +|----------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| +| ![example](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/lsys/lsys-0.png) | ![example](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/lsys/lsys-1.png) | +| ![example](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/lsys/lsys-2.png) | ![example](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/lsys/lsys-3.png) | ```ts import * as lsys from "@thi.ng/lsys"; @@ -109,7 +109,7 @@ stochastic features, e.g. randomization of growth direction and stochastic branch termination. This enables the creation of more organic looking structures, like shown in the following example: - ![stochastic L-system](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/lsys-tree.png) + ![stochastic L-system](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/lsys/lsys-tree.png) ```ts import { XsAdd } from "@thi.ng/random"; diff --git a/packages/lsys/package.json b/packages/lsys/package.json index 250e76de90..6dd50782da 100644 --- a/packages/lsys/package.json +++ b/packages/lsys/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/lsys", - "version": "0.2.22", + "version": "0.2.23", "description": "Functional, extensible L-System architecture w/ support for probabilistic rules", "module": "./index.js", "main": "./lib/index.js", @@ -33,13 +33,13 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/compose": "^1.3.3", + "@thi.ng/api": "^6.4.0", + "@thi.ng/compose": "^1.3.4", "@thi.ng/errors": "^1.2.0", "@thi.ng/math": "^1.4.2", - "@thi.ng/random": "^1.1.11", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/random": "^1.1.12", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "axiom", diff --git a/packages/malloc/CHANGELOG.md b/packages/malloc/CHANGELOG.md index f5cff736ca..e012416236 100644 --- a/packages/malloc/CHANGELOG.md +++ b/packages/malloc/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.0.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/malloc@4.0.4...@thi.ng/malloc@4.0.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/malloc + + + + + ## [4.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/malloc@4.0.3...@thi.ng/malloc@4.0.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/malloc diff --git a/packages/malloc/package.json b/packages/malloc/package.json index 2cb0ccff80..ebd0b0137f 100644 --- a/packages/malloc/package.json +++ b/packages/malloc/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/malloc", - "version": "4.0.4", + "version": "4.0.5", "description": "ArrayBuffer based malloc() impl for hybrid JS/WASM use cases, based on thi.ng/tinyalloc", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/binary": "^1.1.0", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0" }, "keywords": [ diff --git a/packages/matrices/CHANGELOG.md b/packages/matrices/CHANGELOG.md index 1d515989f5..3fa225c539 100644 --- a/packages/matrices/CHANGELOG.md +++ b/packages/matrices/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.5.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/matrices@0.5.7...@thi.ng/matrices@0.5.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/matrices + + + + + ## [0.5.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/matrices@0.5.6...@thi.ng/matrices@0.5.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/matrices diff --git a/packages/matrices/package.json b/packages/matrices/package.json index 6271001252..c0396ead8a 100644 --- a/packages/matrices/package.json +++ b/packages/matrices/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/matrices", - "version": "0.5.7", + "version": "0.5.8", "description": "Matrix & quaternion operations for 2D/3D geometry processing", "module": "./index.js", "main": "./lib/index.js", @@ -33,10 +33,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/math": "^1.4.2", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2D", diff --git a/packages/matrices/src/frustum.ts b/packages/matrices/src/frustum.ts index 28ceb4e830..9132f667c8 100644 --- a/packages/matrices/src/frustum.ts +++ b/packages/matrices/src/frustum.ts @@ -3,7 +3,8 @@ import { setC } from "@thi.ng/vectors"; import { Mat } from "./api"; /** - * Constructs a M44 representing the given view frustum. + * Constructs a 4x4 matrix representing the given view frustum. Creates + * new matrix if `out` is `null`. * * @param out * @param left diff --git a/packages/matrices/src/invert.ts b/packages/matrices/src/invert.ts index 2112601f24..9080d3da59 100644 --- a/packages/matrices/src/invert.ts +++ b/packages/matrices/src/invert.ts @@ -16,7 +16,11 @@ const dp4 = dotC4; const dp6 = dotC6; /** - * Matrix inversion. + * Matrix inversion. Returns `undefined` if matrix is not invertible. + * Mutates `mat` if `out` is `null`. + * + * @param out + * @param mat */ export const invert: MultiMatOpMU = vop(1); diff --git a/packages/matrices/src/lookat.ts b/packages/matrices/src/lookat.ts index 3c456a9bbd..81ab1759c7 100644 --- a/packages/matrices/src/lookat.ts +++ b/packages/matrices/src/lookat.ts @@ -9,8 +9,9 @@ import { import { Mat } from "./api"; /** - * Constructs a M44 camera matrix for given `eye` position, look-at `target` - * (both in world space) and `up` vector. + * Constructs a 4x4 camera matrix for given `eye` position, look-at + * `target` (both in world space) and normalized `up` vector. Creates + * new matrix if `out` is `null`. * * @param out * @param eye diff --git a/packages/matrices/src/m22-m23.ts b/packages/matrices/src/m22-m23.ts index 6f7648017f..19f162fcb9 100644 --- a/packages/matrices/src/m22-m23.ts +++ b/packages/matrices/src/m22-m23.ts @@ -2,7 +2,8 @@ import { set4 } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** - * Converts M22 to M23 and writes result to `out`. + * Converts 2x2 to 2x3 matrix and writes result to `out`. Creates new + * matrix if `out` is `null`. * * @param out * @param m22 diff --git a/packages/matrices/src/m23-m22.ts b/packages/matrices/src/m23-m22.ts index 48451632fa..a3d4b625c5 100644 --- a/packages/matrices/src/m23-m22.ts +++ b/packages/matrices/src/m23-m22.ts @@ -2,7 +2,8 @@ import { set4 } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** - * Converts M23 to M22 and writes result to `out`. + * Converts 2x3 to 2x2 matrix and writes result to `out`. Creates new + * matrix if `out` is `null`. * * @param out * @param m23 diff --git a/packages/matrices/src/m23-m44.ts b/packages/matrices/src/m23-m44.ts index 981e4ed3db..bab36883f1 100644 --- a/packages/matrices/src/m23-m44.ts +++ b/packages/matrices/src/m23-m44.ts @@ -1,20 +1,34 @@ +import { setC } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** - * Converts M23 to M44 and writes result to `out`. + * Converts 2x3 to 4x4 matrix and writes result to `out`. Creates new + * matrix if `out` is `null`. * * @param out * @param m23 */ -export const mat23to44: MatOpM = (out, m23) => ( - !out && (out = []), - (out[0] = m23[0]), - (out[1] = m23[1]), - (out[4] = m23[2]), - (out[5] = m23[3]), - (out[12] = m23[4]), - (out[13] = m23[5]), - (out[10] = out[15] = 1), - (out[2] = out[3] = out[6] = out[7] = out[8] = out[9] = out[11] = out[14] = 0), - out -); +export const mat23to44: MatOpM = (out, m23) => + setC( + out || [], + // x + m23[0], + m23[1], + 0, + 0, + // y + m23[2], + m23[3], + 0, + 0, + // z + 0, + 0, + 1, + 0, + // w + m23[4], + m23[5], + 0, + 1 + ); diff --git a/packages/matrices/src/m33-m44.ts b/packages/matrices/src/m33-m44.ts index f36fbd4036..20a6a3fca3 100644 --- a/packages/matrices/src/m33-m44.ts +++ b/packages/matrices/src/m33-m44.ts @@ -1,17 +1,34 @@ -import { setS3, setS4, ZERO4 } from "@thi.ng/vectors"; +import { setC } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** - * Converts M33 to M44 and writes result to `out`. + * Converts 3x3 to 4x4 matrix and writes result to `out`. Creates new + * matrix if `out` is `null`. * * @param out * @param m33 */ -export const mat33to44: MatOpM = (out, m33) => ( - !out && (out = []), - setS3(out, m33, 0, 0), - setS3(out, m33, 4, 3), - setS3(out, m33, 8, 6), - setS3(out, ZERO4, 12), - setS4(out, [0, 0, 0, 1], 3, 0, 4) -); +export const mat33to44: MatOpM = (out, m33) => + setC( + out || [], + // x + m33[0], + m33[1], + m33[2], + 0, + // y + m33[3], + m33[4], + m33[5], + 0, + // z + m33[6], + m33[7], + m33[8], + 0, + // w + 0, + 0, + 0, + 1 + ); diff --git a/packages/matrices/src/m44-m33.ts b/packages/matrices/src/m44-m33.ts index 44331e1065..7cebbfc342 100644 --- a/packages/matrices/src/m44-m33.ts +++ b/packages/matrices/src/m44-m33.ts @@ -2,7 +2,8 @@ import { setS3 } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** - * Converts M44 to M33 and writes result to `out`. + * Converts 4x4 to 3x3 matrix and writes result to `out`. Creates new + * matrix if `out` is `null`. * * @param out * @param m44 diff --git a/packages/matrices/src/matv.ts b/packages/matrices/src/matv.ts index a4f57d89af..9ecf4ee92e 100644 --- a/packages/matrices/src/matv.ts +++ b/packages/matrices/src/matv.ts @@ -5,10 +5,42 @@ import { setVV9 } from "@thi.ng/vectors"; +/** + * Initializes 2x2 matrix from 2D column vectors. + * + * @param out + * @param x + * @param y + */ export const mat22v = setVV4; +/** + * Initializes 2x3 matrix (affine transform) from 2D column vectors. + * + * @param out + * @param x + * @param y + * @param translate + */ export const mat23v = setVV6; +/** + * Initializes 3x3 matrix from 3D column vectors. + * + * @param out + * @param x + * @param y + * @param z + */ export const mat33v = setVV9; +/** + * Initializes 4x4 matrix from 4D column vectors. + * + * @param out + * @param x + * @param y + * @param z + * @param w + */ export const mat44v = setVV16; diff --git a/packages/matrices/src/mixq.ts b/packages/matrices/src/mixq.ts index c9645127b7..016e300139 100644 --- a/packages/matrices/src/mixq.ts +++ b/packages/matrices/src/mixq.ts @@ -8,10 +8,10 @@ import { } from "@thi.ng/vectors"; /** - * Interpolates quaternion `a` to `b` by given amount `t`, using SLERP. - * Writes result to `out`. The optional `eps` (default 1e-3) is used to - * switch to linear interpolation if the angular difference is very - * small. + * Interpolates quaternion `a` to `b` by given amount `t` [0...1], using + * SLERP. Writes result to `out`. The optional `eps` (default 1e-3) is + * used to switch to linear interpolation if the angular difference is + * very small. * * @param out * @param a diff --git a/packages/matrices/src/mulm.ts b/packages/matrices/src/mulm.ts index 6d0c8e0e28..1c7a0d9ff7 100644 --- a/packages/matrices/src/mulm.ts +++ b/packages/matrices/src/mulm.ts @@ -1,9 +1,17 @@ -import { dotS2, dotS3, dotS4, setC, setC4, setC6, vop } from "@thi.ng/vectors"; +import { + dotS2, + dotS3, + dotS4, + setC, + setC4, + setC6, + vop +} from "@thi.ng/vectors"; import { MultiMatOpMM } from "./api"; /** - * Performs matrix-matrix multiplication. If `out` is not given, writes - * result in `a`. + * Multi-method. Performs matrix-matrix multiplication. If `out` is not + * given, writes result in `a`. * * @param out * @param a @@ -11,6 +19,14 @@ import { MultiMatOpMM } from "./api"; */ export const mulM: MultiMatOpMM = vop(1); +/** + * 2x2 matrix-matrix multiplication. If `out` is not given, writes + * result in `a`. + * + * @param out + * @param a + * @param b + */ export const mulM22 = mulM.add(4, (out, a, b) => setC4( out || a, @@ -21,6 +37,14 @@ export const mulM22 = mulM.add(4, (out, a, b) => ) ); +/** + * 2x3 matrix-matrix multiplication. If `out` is not given, writes + * result in `a`. + * + * @param out + * @param a + * @param b + */ export const mulM23 = mulM.add(6, (out, a, b) => setC6( out || a, @@ -33,6 +57,14 @@ export const mulM23 = mulM.add(6, (out, a, b) => ) ); +/** + * 3x3 matrix-matrix multiplication. If `out` is not given, writes + * result in `a`. + * + * @param out + * @param a + * @param b + */ export const mulM33 = mulM.add(9, (out, a, b) => setC( out || a, @@ -48,6 +80,14 @@ export const mulM33 = mulM.add(9, (out, a, b) => ) ); +/** + * 4x4 matrix-matrix multiplication. If `out` is not given, writes + * result in `a`. + * + * @param out + * @param a + * @param b + */ export const mulM44 = mulM.add(16, (out, a, b) => setC( out || a, diff --git a/packages/matrices/src/mulv.ts b/packages/matrices/src/mulv.ts index 30a0e1667f..9ecfc11bd3 100644 --- a/packages/matrices/src/mulv.ts +++ b/packages/matrices/src/mulv.ts @@ -21,7 +21,7 @@ import { MatOpMV, MultiMatOpMV } from "./api"; export const mulV: MultiMatOpMV = vop(1); /** - * Multiplies M22 `m` with 2D vector `v`. Supports in-place + * Multiplies 2x2 matrix `m` with 2D vector `v`. Supports in-place * modification, i.e. if `out === v`. * * @param out @@ -33,7 +33,7 @@ export const mulV22: MatOpMV = mulV.add(4, (out, m, v) => ); /** - * Multiplies M23 `m` with 2D vector `v`. Supports in-place + * Multiplies 2x3 matrix `m` with 2D vector `v`. Supports in-place * modification, i.e. if `out === v`. * * @param out @@ -45,7 +45,7 @@ export const mulV23: MatOpMV = mulV.add(6, (out, m, v) => ); /** - * Multiplies M33 `m` with 3D vector `v`. Supports in-place + * Multiplies 3x3 matrix `m` with 3D vector `v`. Supports in-place * modification, i.e. if `out === v`. * * @param out @@ -62,7 +62,7 @@ export const mulV33: MatOpMV = mulV.add(9, (out, m, v) => ); /** - * Multiplies M44 `m` with 4D vector `v`. Supports in-place + * Multiplies 4x4 matrix `m` with 4D vector `v`. Supports in-place * modification, i.e. if `out === v`. * * @param out @@ -80,9 +80,9 @@ export const mulV44: MatOpMV = mulV.add(16, (out, m, v) => ); /** - * Multiplies M44 `m` with 3D vector `v` and assumes `w=1`, i.e. the - * vector is interpreted as `[x,y,z,1]`. After transformation applies - * perspective divide of the resulting XYZ components. + * Multiplies 4x4 matrix `m` with 3D vector `v` and assumes `w=1`, i.e. + * the vector is interpreted as `[x,y,z,1]`. After transformation + * applies perspective divide of the resulting XYZ components. * * @param out * @param m diff --git a/packages/matrices/src/normal-mat.ts b/packages/matrices/src/normal-mat.ts index 39b555d925..bdf0a51c75 100644 --- a/packages/matrices/src/normal-mat.ts +++ b/packages/matrices/src/normal-mat.ts @@ -4,10 +4,10 @@ import { mat44to33 } from "./m44-m33"; import { transpose33, transpose44 } from "./transpose"; /** - * Converts given M44 to a M33 normal matrix, i.e. the transposed + * Converts given 4x4 matrix to a 3x3 normal matrix, i.e. the transposed * inverse of its upper-left 3x3 region. If `out` is null a new result * matrix will be created. Returns `undefined` if matrix inversion - * fails. + * failed. * * @param out * @param m @@ -18,9 +18,9 @@ export const normal33: MatOpMU = (out, m) => { }; /** - * Converts given M44 to a M44 normal matrix, i.e. the transposed - * inverse. Writes results to `m` if `out` is null. Returns `undefined` - * if matrix inversion fails. + * Converts given 4x4 matrix to a 4x4 matrix normal matrix, i.e. the + * transposed inverse. Writes results to `m` if `out` is null. Returns + * `undefined` if matrix inversion failed. * * @param out * @param m diff --git a/packages/matrices/src/ortho.ts b/packages/matrices/src/ortho.ts index 71464a4831..144abce0de 100644 --- a/packages/matrices/src/ortho.ts +++ b/packages/matrices/src/ortho.ts @@ -2,8 +2,8 @@ import { setC } from "@thi.ng/vectors"; import { Mat } from "./api"; /** - * Computes a M44 orthographic projection matrix and writes result to - * `out`. + * Creates a 4x4 matrix orthographic projection matrix and writes result + * to `out`. * * @param out * @param left diff --git a/packages/matrices/src/perspective.ts b/packages/matrices/src/perspective.ts index 4c46b80f4e..3a28f5f3bb 100644 --- a/packages/matrices/src/perspective.ts +++ b/packages/matrices/src/perspective.ts @@ -2,8 +2,8 @@ import { Mat } from "./api"; import { frustum, frustumBounds } from "./frustum"; /** - * Computes a M44 perspective projection matrix and writes result to - * `out`. + * Creates a 4x4 matrix perspective projection matrix and writes result + * to `out`. * * @param out * @param fov diff --git a/packages/matrices/src/project.ts b/packages/matrices/src/project.ts index 3c7b78ec35..80bf7450ae 100644 --- a/packages/matrices/src/project.ts +++ b/packages/matrices/src/project.ts @@ -10,14 +10,14 @@ import { invert23, invert44 } from "./invert"; import { mulV23, mulV344, mulV44 } from "./mulv"; /** - * Transforms given point `p` (4D, homogeneous) with M44 `mvp`, applies - * perspective divide and then transforms XY components with M23 `view` - * matrix. Returns 3D vector. The result Z component can be used for - * depth sorting. + * Transforms given point `p` (4D, homogeneous coordinates) with 4x4 + * matrix `mvp`, applies perspective divide and then transforms XY + * components with 2x3 matrix `view` matrix. Returns 3D vector. The + * result Z component can be used for depth sorting. * * @param out - * @param mvp - * @param view + * @param mvp 4x4 matrix + * @param view 2x3 matrix * @param p */ export const project = ( @@ -31,14 +31,14 @@ export const project = ( ); /** - * Reverse operation of project. If `invert` is true (default: false), - * both `mvp` and `view` matrices will be inverted first + * Reverse operation of `project()`. If `invert` is true (default: + * false), both `mvp` and `view` matrices will be inverted first * (non-destructively), else they're both assumed to be inverted * already. * * @param out - * @param mvp - * @param view + * @param mvp 4x4 matrix + * @param view 2x3 matrix * @param p * @param invert */ diff --git a/packages/matrices/src/quat-m33.ts b/packages/matrices/src/quat-m33.ts index f32a704af8..7cbbbc21fe 100644 --- a/packages/matrices/src/quat-m33.ts +++ b/packages/matrices/src/quat-m33.ts @@ -2,7 +2,7 @@ import { ReadonlyVec, setC } from "@thi.ng/vectors"; import { Mat } from "./api"; /** - * Converts quaternion into M33 and writes result to `out`. + * Converts quaternion into 3x3 matrix and writes result to `out`. * * @param out * @param q diff --git a/packages/matrices/src/quat-m44.ts b/packages/matrices/src/quat-m44.ts index 00f3a5464e..c7a84b15a1 100644 --- a/packages/matrices/src/quat-m44.ts +++ b/packages/matrices/src/quat-m44.ts @@ -2,8 +2,8 @@ import { ReadonlyVec, setC, ZERO3 } from "@thi.ng/vectors"; import { Mat } from "./api"; /** - * Converts quaternion into M44 with optional translation offset `t`, - * then writes result to `out`. + * Converts quaternion into 4x4 matrix with optional translation offset + * `t`, then writes result to `out`. * * @param out * @param q diff --git a/packages/matrices/src/rotation-around-axis.ts b/packages/matrices/src/rotation-around-axis.ts index 325ac17915..38e2b41436 100644 --- a/packages/matrices/src/rotation-around-axis.ts +++ b/packages/matrices/src/rotation-around-axis.ts @@ -3,9 +3,9 @@ import { Mat } from "./api"; import { mat33to44 } from "./m33-m44"; /** - * Constructs a M33 representing a rotation of `theta` around `axis` and - * writes result to `out`. If `normalize` is true (default false), - * non-destructively first normalizes axis vector. + * Constructs a 3x3 matrix representing a rotation of `theta` around + * `axis` and writes result to `out`. If `normalize` is true (default + * false), non-destructively first normalizes axis vector. * * @param out * @param axis @@ -37,9 +37,9 @@ export const rotationAroundAxis33 = ( }; /** - * Constructs a M44 representing a rotation of `theta` around `axis` and - * writes result to `out`. If `normalize` is true (default false), - * non-destructively first normalizes axis vector. + * Constructs a 4x4 matrix representing a rotation of `theta` around + * `axis` and writes result to `out`. If `normalize` is true (default + * false), non-destructively first normalizes axis vector. * * @param out * @param axis diff --git a/packages/matrices/src/rotation.ts b/packages/matrices/src/rotation.ts index a2b4b0ea0e..afba5c5b83 100644 --- a/packages/matrices/src/rotation.ts +++ b/packages/matrices/src/rotation.ts @@ -3,7 +3,7 @@ import { setC, setC4, setC6 } from "@thi.ng/vectors"; import { Mat } from "./api"; /** - * Constructs a M22 rotation matrix for given `theta`. + * Constructs a 2x2 matrix rotation matrix for given `theta`. * * @param out * @param theta @@ -14,7 +14,7 @@ export const rotation22 = (out: Mat | null, theta: number) => { }; /** - * Constructs a M23 rotation matrix for given `theta`. + * Constructs a 2x3 matrix rotation matrix for given `theta`. * * @param out * @param theta @@ -25,7 +25,7 @@ export const rotation23 = (out: Mat | null, theta: number) => { }; /** - * Constructs a M33 X rotation matrix for given `theta`. + * Constructs a 3x3 matrix X rotation matrix for given `theta`. * * @param out * @param theta @@ -36,7 +36,7 @@ export const rotationX33 = (out: Mat | null, theta: number) => { }; /** - * Constructs a M33 Y rotation matrix for given `theta`. + * Constructs a 3x3 matrix Y rotation matrix for given `theta`. * * @param out * @param theta @@ -47,7 +47,7 @@ export const rotationY33 = (out: Mat | null, theta: number) => { }; /** - * Constructs a M33 Z rotation matrix for given `theta`. + * Constructs a 3x3 matrix Z rotation matrix for given `theta`. * * @param out * @param theta @@ -58,7 +58,7 @@ export const rotationZ33 = (out: Mat | null, theta: number) => { }; /** - * Constructs a M44 X rotation matrix for given `theta`. + * Constructs a 4x4 matrix X rotation matrix for given `theta`. * * @param out * @param theta @@ -69,7 +69,7 @@ export const rotationX44 = (out: Mat | null, theta: number) => { }; /** - * Constructs a M44 Y rotation matrix for given `theta`. + * Constructs a 4x4 matrix Y rotation matrix for given `theta`. * * @param out * @param theta @@ -80,7 +80,7 @@ export const rotationY44 = (out: Mat | null, theta: number) => { }; /** - * Constructs a M44 Z rotation matrix for given `theta`. + * Constructs a 4x4 matrix Z rotation matrix for given `theta`. * * @param out * @param theta diff --git a/packages/matrices/src/scale-center.ts b/packages/matrices/src/scale-center.ts index 657306d2ac..4eb54e0947 100644 --- a/packages/matrices/src/scale-center.ts +++ b/packages/matrices/src/scale-center.ts @@ -5,8 +5,8 @@ import { scale23, scale44 } from "./scale"; import { translation23, translation44 } from "./translation"; /** - * Computes a M23 representing a scale operation with origin `p` and - * writes result to `out`. + * Computes a 2x3 matrix representing a scale operation with origin `p` + * and writes result to `out`. * * @param out * @param m @@ -24,8 +24,8 @@ export const scaleWithCenter23 = ( ); /** - * Computes a M44 representing a scale operation with origin `p` and - * writes result to `out`. + * Computes a 4x4 matrix representing a scale operation with origin `p` + * and writes result to `out`. * * @param out * @param m diff --git a/packages/matrices/src/scale.ts b/packages/matrices/src/scale.ts index 73c0dbbc45..540a5c2987 100644 --- a/packages/matrices/src/scale.ts +++ b/packages/matrices/src/scale.ts @@ -8,8 +8,8 @@ import { import { Mat } from "./api"; /** - * Computes M22 scale matrix and writes result to `out`. If `s` is a - * number, scaling will be uniform. + * Computes 2x2 matrix scale matrix and writes result to `out`. If `s` + * is a number, scaling will be uniform. * * @param m * @param s @@ -19,8 +19,8 @@ export const scale22 = (m: Mat | null, s: number | ReadonlyVec) => ( ); /** - * Computes M23 scale matrix and writes result to `out`. If `s` is a - * number, scaling will be uniform. + * Computes 2x3 matrix scale matrix and writes result to `out`. If `s` + * is a number, scaling will be uniform. * * @param m * @param s @@ -30,8 +30,8 @@ export const scale23 = (m: Mat | null, s: number | ReadonlyVec) => ( ); /** - * Computes M33 scale matrix and writes result to `out`. If `s` is a - * number, scaling will be uniform. + * Computes 3x3 matrix scale matrix and writes result to `out`. If `s` + * is a number, scaling will be uniform. * * @param m * @param s @@ -42,8 +42,8 @@ export const scale33 = (m: Mat | null, s: number | ReadonlyVec) => ( ); /** - * Computes M44 scale matrix and writes result to `out`. If `s` is a - * number, scaling will be uniform. + * Computes 4x4 matrix scale matrix and writes result to `out`. If `s` + * is a number, scaling will be uniform. * * @param m * @param s @@ -52,18 +52,22 @@ export const scale44 = (m: Mat | null, s: number | ReadonlyVec) => ( (s = isNumber(s) ? [s, s, s] : s), setC( m || [], + // x s[0], 0, 0, 0, + // y 0, s[1], 0, 0, + // z 0, 0, s[2], 0, + // w 0, 0, 0, diff --git a/packages/matrices/src/transform.ts b/packages/matrices/src/transform.ts index e4fe27fdfb..f7ff0474b9 100644 --- a/packages/matrices/src/transform.ts +++ b/packages/matrices/src/transform.ts @@ -9,7 +9,7 @@ import { scale23, scale44 } from "./scale"; import { translation23 } from "./translation"; /** - * Creates M23 TRS transformation matrix from given translation vector, + * Creates 2x3 TRS transformation matrix from given translation vector, * rotation angle and scale factor/vector. * * @param out @@ -31,10 +31,11 @@ export const transform23 = ( ); /** - * Creates M44 TRS transformation matrix from given translation vector, + * Creates 4x4 TRS transformation matrix from given translation vector, * rotation angles (given as 3D vector) and scale factor/vector. * Internally, uses a quaternion for constructing the rotation matrix - * part. + * part. The quaternion is created via `quatFromEuler()` with ZYX + * ordering. * * @param out * @param translate diff --git a/packages/matrices/src/translation.ts b/packages/matrices/src/translation.ts index d5dd010783..cdc6c77bae 100644 --- a/packages/matrices/src/translation.ts +++ b/packages/matrices/src/translation.ts @@ -2,7 +2,7 @@ import { ReadonlyVec, setC, setC6 } from "@thi.ng/vectors"; import { Mat } from "./api"; /** - * Constructs a M23 translation matrix. + * Constructs a 2x3 translation matrix. * * @param out * @param v @@ -11,7 +11,7 @@ export const translation23 = (m: Mat | null, v: ReadonlyVec) => setC6(m || [], 1, 0, 0, 1, v[0], v[1]); /** - * Constructs a M44 translation matrix. + * Constructs a 4x4 translation matrix. * * @param out * @param v diff --git a/packages/matrices/src/transpose.ts b/packages/matrices/src/transpose.ts index 4e841140f8..a7de851cc5 100644 --- a/packages/matrices/src/transpose.ts +++ b/packages/matrices/src/transpose.ts @@ -2,7 +2,8 @@ import { setC, setC4 } from "@thi.ng/vectors"; import { MatOpM } from "./api"; /** - * Writes transposition of M22 `m` to `out`. + * Writes transposition of 2x2 matrix `m` to `out`. Creates new matrix + * if `out` is `null` * * @param out * @param m @@ -11,7 +12,8 @@ export const transpose22: MatOpM = (out, m) => setC4(out || [], m[0], m[2], m[1], m[3]); /** - * Writes transposition of M33 `m` to `out`. + * Writes transposition of 3x3 matrix `m` to `out`. Creates new matrix + * if `out` is `null` * * @param out * @param m @@ -20,7 +22,8 @@ export const transpose33: MatOpM = (out, m) => setC(out || [], m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8]); /** - * Writes transposition of M44 `m` to `out`. + * Writes transposition of 4x4 matrix `m` to `out`. Creates new matrix + * if `out` is `null` * * @param out * @param m diff --git a/packages/matrices/src/viewport.ts b/packages/matrices/src/viewport.ts index 8e09a472a6..2c42b5f27b 100644 --- a/packages/matrices/src/viewport.ts +++ b/packages/matrices/src/viewport.ts @@ -4,7 +4,7 @@ import { scale23 } from "./scale"; import { translation23 } from "./translation"; /** - * Produces a M23 viewport matrix to transform projected coordinates to + * Produces a 2x3 viewport matrix to transform projected coordinates to * screen space. * * @param out diff --git a/packages/memoize/CHANGELOG.md b/packages/memoize/CHANGELOG.md index 59b7f19a06..180ee442d4 100644 --- a/packages/memoize/CHANGELOG.md +++ b/packages/memoize/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/memoize@1.1.3...@thi.ng/memoize@1.1.4) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/memoize + + + + + ## [1.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/memoize@1.1.2...@thi.ng/memoize@1.1.3) (2019-08-21) **Note:** Version bump only for package @thi.ng/memoize diff --git a/packages/memoize/package.json b/packages/memoize/package.json index 74092a09ad..233b3a8fc3 100644 --- a/packages/memoize/package.json +++ b/packages/memoize/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/memoize", - "version": "1.1.3", + "version": "1.1.4", "description": "Function memoization with configurable caches", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3" + "@thi.ng/api": "^6.4.0" }, "keywords": [ "cache", diff --git a/packages/paths/CHANGELOG.md b/packages/paths/CHANGELOG.md index 102296f610..2f1767eec7 100644 --- a/packages/paths/CHANGELOG.md +++ b/packages/paths/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@2.1.4...@thi.ng/paths@2.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/paths + + + + + ## [2.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/paths@2.1.3...@thi.ng/paths@2.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/paths diff --git a/packages/paths/package.json b/packages/paths/package.json index 00c7f1856a..3996044f78 100644 --- a/packages/paths/package.json +++ b/packages/paths/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/paths", - "version": "2.1.4", + "version": "2.1.5", "description": "immutable, optimized path-based object property / array accessors", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0" }, "keywords": [ diff --git a/packages/pixel/CHANGELOG.md b/packages/pixel/CHANGELOG.md index 560aba8c43..9d45fd88c9 100644 --- a/packages/pixel/CHANGELOG.md +++ b/packages/pixel/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.3...@thi.ng/pixel@0.1.4) (2019-09-21) + + +### Bug Fixes + +* **pixel:** clamp values in PackedChannel.setFloat() ([ce78467](https://github.com/thi-ng/umbrella/commit/ce78467)) + + + + + ## [0.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.2...@thi.ng/pixel@0.1.3) (2019-08-21) **Note:** Version bump only for package @thi.ng/pixel diff --git a/packages/pixel/README.md b/packages/pixel/README.md index 4b18a87f11..f653162d49 100644 --- a/packages/pixel/README.md +++ b/packages/pixel/README.md @@ -23,7 +23,7 @@ This project is part of the ## About -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/pixel-basics.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/pixel/pixel-basics.png) Typed array backed, packed integer pixel buffers with customizable layout formats and the following operations: @@ -33,9 +33,9 @@ layout formats and the following operations: - Buffer-to-buffer blitting w/ automatic format conversion - Buffer-to-canvas blitting - Buffer-to-buffer blending w/ [Porter-Duff - operators](https://github.com/thi-ng/umbrella/tree/master/packages/color#rgba-porter-duff-compositing) + operators](https://github.com/thi-ng/umbrella/tree/master/packages/porter-duff) - Pre/post-multiply alpha -- Region / subimage extraction +- Region / sub-image extraction - Single-channel manipulation / extraction / replacement / conversion - Inversion - XY pixel accessors @@ -106,7 +106,7 @@ Porter-Duff operators: [Live demo](http://demo.thi.ng/umbrella/porter-duff/) | [Source](https://github.com/thi-ng/umbrella/tree/master/examples/porter-duff) -![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/porter-duff2.png) +![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/porter-duff/porter-duff2.png) Code for the screenshot at the top of this readme... diff --git a/packages/pixel/package.json b/packages/pixel/package.json index 99e14280e9..e38bc4eba8 100644 --- a/packages/pixel/package.json +++ b/packages/pixel/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/pixel", - "version": "0.1.3", + "version": "0.1.4", "description": "TODO", "module": "./index.js", "main": "./lib/index.js", @@ -33,10 +33,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/math": "^1.4.2", - "@thi.ng/porter-duff": "^0.1.2" + "@thi.ng/porter-duff": "^0.1.3" }, "keywords": [ "ES6", diff --git a/packages/pixel/src/format.ts b/packages/pixel/src/format.ts index 583b4cf4a9..f79f99ecc4 100644 --- a/packages/pixel/src/format.ts +++ b/packages/pixel/src/format.ts @@ -1,4 +1,5 @@ import { assert, Type } from "@thi.ng/api"; +import { clamp01 } from "@thi.ng/math"; import { Lane, PackedChannel, @@ -31,7 +32,7 @@ const defChannel = ( int, setInt, float: (x) => int(x) / mask0, - setFloat: (src, x) => setInt(src, x * mask0) + setFloat: (src, x) => setInt(src, clamp01(x) * mask0) }; }; diff --git a/packages/pointfree-lang/CHANGELOG.md b/packages/pointfree-lang/CHANGELOG.md index 764c0d32e5..9e2c56be90 100644 --- a/packages/pointfree-lang/CHANGELOG.md +++ b/packages/pointfree-lang/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@1.1.4...@thi.ng/pointfree-lang@1.1.5) (2019-09-21) + + +### Bug Fixes + +* **pointfree-lang:** update imports ([8de1366](https://github.com/thi-ng/umbrella/commit/8de1366)) + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree-lang@1.1.3...@thi.ng/pointfree-lang@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/pointfree-lang diff --git a/packages/pointfree-lang/package.json b/packages/pointfree-lang/package.json index 1cb80b0fc0..3bbb6d2551 100644 --- a/packages/pointfree-lang/package.json +++ b/packages/pointfree-lang/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/pointfree-lang", - "version": "1.1.4", + "version": "1.1.5", "description": "Forth style syntax layer/compiler for the @thi.ng/pointfree DSL", "module": "./index.js", "main": "./lib/index.js", @@ -35,9 +35,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/errors": "^1.2.0", - "@thi.ng/pointfree": "^1.2.0" + "@thi.ng/pointfree": "^1.2.1" }, "keywords": [ "concatenative", diff --git a/packages/pointfree-lang/test/readme.ts b/packages/pointfree-lang/test/readme.ts index c124a8c57f..5ee44854a7 100644 --- a/packages/pointfree-lang/test/readme.ts +++ b/packages/pointfree-lang/test/readme.ts @@ -1,4 +1,4 @@ -import { StackContext } from "@thi.ng/pointfree/api"; +import { StackContext } from "@thi.ng/pointfree"; import * as pf from "../src"; const src = ` diff --git a/packages/pointfree/CHANGELOG.md b/packages/pointfree/CHANGELOG.md index 3fa997677e..f23d7059a0 100644 --- a/packages/pointfree/CHANGELOG.md +++ b/packages/pointfree/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.2.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@1.2.0...@thi.ng/pointfree@1.2.1) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/pointfree + + + + + # [1.2.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/pointfree@1.1.3...@thi.ng/pointfree@1.2.0) (2019-08-21) diff --git a/packages/pointfree/package.json b/packages/pointfree/package.json index 94f8630531..3036fa6716 100644 --- a/packages/pointfree/package.json +++ b/packages/pointfree/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/pointfree", - "version": "1.2.0", + "version": "1.2.1", "description": "Pointfree functional composition / Forth style stack execution engine", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/compose": "^1.3.3", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/compose": "^1.3.4", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0" }, diff --git a/packages/poisson/CHANGELOG.md b/packages/poisson/CHANGELOG.md index cb6617be78..b04b06bcee 100644 --- a/packages/poisson/CHANGELOG.md +++ b/packages/poisson/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.2.25](https://github.com/thi-ng/umbrella/compare/@thi.ng/poisson@0.2.24...@thi.ng/poisson@0.2.25) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/poisson + + + + + ## [0.2.24](https://github.com/thi-ng/umbrella/compare/@thi.ng/poisson@0.2.23...@thi.ng/poisson@0.2.24) (2019-08-21) **Note:** Version bump only for package @thi.ng/poisson diff --git a/packages/poisson/README.md b/packages/poisson/README.md index d7a90aa282..0d759895c7 100644 --- a/packages/poisson/README.md +++ b/packages/poisson/README.md @@ -48,7 +48,7 @@ yarn add @thi.ng/poisson ## Usage examples -![example output](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/poisson.jpg) +![example output](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/poisson/poisson.jpg) ```ts import { samplePoisson } from "@thi.ng/poisson"; diff --git a/packages/poisson/package.json b/packages/poisson/package.json index afd40fbde5..1a3dde4a19 100644 --- a/packages/poisson/package.json +++ b/packages/poisson/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/poisson", - "version": "0.2.24", + "version": "0.2.25", "description": "nD Poisson-disc sampling w/ support for spatial density functions and custom PRNGs", "module": "./index.js", "main": "./lib/index.js", @@ -33,10 +33,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", - "@thi.ng/geom-api": "^0.3.5", - "@thi.ng/random": "^1.1.11", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/checks": "^2.4.0", + "@thi.ng/geom-api": "^0.3.6", + "@thi.ng/random": "^1.1.12", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "2d", diff --git a/packages/porter-duff/CHANGELOG.md b/packages/porter-duff/CHANGELOG.md index 890638f75e..31a2dbdab1 100644 --- a/packages/porter-duff/CHANGELOG.md +++ b/packages/porter-duff/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/porter-duff@0.1.2...@thi.ng/porter-duff@0.1.3) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/porter-duff + + + + + ## [0.1.2](https://github.com/thi-ng/umbrella/compare/@thi.ng/porter-duff@0.1.1...@thi.ng/porter-duff@0.1.2) (2019-08-21) **Note:** Version bump only for package @thi.ng/porter-duff diff --git a/packages/porter-duff/README.md b/packages/porter-duff/README.md index 573cd35b03..fd2d4ea958 100644 --- a/packages/porter-duff/README.md +++ b/packages/porter-duff/README.md @@ -37,7 +37,7 @@ ints or RGBA float vectors. [@thi.ng/color](https://github.com/thi-ng/umbrella/tree/master/packages/color) package (prior to v1.0.0). -![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/porter-duff2.png) +![porter-duff compositing modes](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/porter-duff/porter-duff2.png) ### References @@ -124,7 +124,7 @@ to extract blend coefficients from the src & dest colors: const customOp = porterDuffInt(() => -0.5, () => 1); ``` -![custom operator](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/porter-duff-custom.png) +![custom operator](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/porter-duff/porter-duff-custom.png) The following coefficient functions are included by default (and are used by all standard operators): diff --git a/packages/porter-duff/package.json b/packages/porter-duff/package.json index c917c1f983..1339a45b44 100644 --- a/packages/porter-duff/package.json +++ b/packages/porter-duff/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/porter-duff", - "version": "0.1.2", + "version": "0.1.3", "description": "Porter-Duff operators for packed ints & float-array alpha compositing", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/math": "^1.4.2" }, "keywords": [ diff --git a/packages/random/CHANGELOG.md b/packages/random/CHANGELOG.md index 8a720de785..ef339fa1af 100644 --- a/packages/random/CHANGELOG.md +++ b/packages/random/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.12](https://github.com/thi-ng/umbrella/compare/@thi.ng/random@1.1.11...@thi.ng/random@1.1.12) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/random + + + + + ## [1.1.11](https://github.com/thi-ng/umbrella/compare/@thi.ng/random@1.1.10...@thi.ng/random@1.1.11) (2019-08-21) **Note:** Version bump only for package @thi.ng/random diff --git a/packages/random/package.json b/packages/random/package.json index a28b552a91..0d182c534e 100644 --- a/packages/random/package.json +++ b/packages/random/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/random", - "version": "1.1.11", + "version": "1.1.12", "description": "Pseudo-random number generators w/ unified API", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3" + "@thi.ng/api": "^6.4.0" }, "keywords": [ "ES6", diff --git a/packages/range-coder/CHANGELOG.md b/packages/range-coder/CHANGELOG.md index 1eeb8e72b3..988aa0dd43 100644 --- a/packages/range-coder/CHANGELOG.md +++ b/packages/range-coder/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.0.25](https://github.com/thi-ng/umbrella/compare/@thi.ng/range-coder@1.0.24...@thi.ng/range-coder@1.0.25) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/range-coder + + + + + ## [1.0.24](https://github.com/thi-ng/umbrella/compare/@thi.ng/range-coder@1.0.23...@thi.ng/range-coder@1.0.24) (2019-08-21) **Note:** Version bump only for package @thi.ng/range-coder diff --git a/packages/range-coder/package.json b/packages/range-coder/package.json index 0421d79725..524e24b894 100644 --- a/packages/range-coder/package.json +++ b/packages/range-coder/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/range-coder", - "version": "1.0.24", + "version": "1.0.25", "description": "Binary data range encoder / decoder", "module": "./index.js", "main": "./lib/index.js", @@ -25,7 +25,7 @@ "pub": "yarn build:release && yarn publish --access public" }, "devDependencies": { - "@thi.ng/transducers": "^5.4.4", + "@thi.ng/transducers": "^5.4.5", "@types/mocha": "^5.2.6", "@types/node": "^12.6.3", "mocha": "^6.1.4", diff --git a/packages/resolve-map/CHANGELOG.md b/packages/resolve-map/CHANGELOG.md index b2c68de9c9..ca3b25def8 100644 --- a/packages/resolve-map/CHANGELOG.md +++ b/packages/resolve-map/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.1.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@4.1.6...@thi.ng/resolve-map@4.1.7) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/resolve-map + + + + + ## [4.1.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/resolve-map@4.1.5...@thi.ng/resolve-map@4.1.6) (2019-08-21) **Note:** Version bump only for package @thi.ng/resolve-map diff --git a/packages/resolve-map/package.json b/packages/resolve-map/package.json index fe4039f466..6fa404343d 100644 --- a/packages/resolve-map/package.json +++ b/packages/resolve-map/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/resolve-map", - "version": "4.1.6", + "version": "4.1.7", "description": "DAG resolution of vanilla objects & arrays with internally linked values", "module": "./index.js", "main": "./lib/index.js", @@ -32,10 +32,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0", - "@thi.ng/paths": "^2.1.4" + "@thi.ng/paths": "^2.1.5" }, "keywords": [ "configuration", diff --git a/packages/rle-pack/README.md b/packages/rle-pack/README.md index ca749ae0c9..f8cfa841ca 100644 --- a/packages/rle-pack/README.md +++ b/packages/rle-pack/README.md @@ -19,7 +19,7 @@ will be encoded using additional RLE chunks... ### Encoding format -![data layout](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/rle-layout.png) +![data layout](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rle/rle-layout.png) - 32 bits - original number of words - 5 bits - word size diff --git a/packages/router/CHANGELOG.md b/packages/router/CHANGELOG.md index bb8809cf01..2475a2b0f6 100644 --- a/packages/router/CHANGELOG.md +++ b/packages/router/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@2.0.4...@thi.ng/router@2.0.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/router + + + + + ## [2.0.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/router@2.0.3...@thi.ng/router@2.0.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/router diff --git a/packages/router/package.json b/packages/router/package.json index a5854025f4..85be9361fb 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/router", - "version": "2.0.4", + "version": "2.0.5", "description": "Generic router for browser & non-browser based applications", "module": "./index.js", "main": "./lib/index.js", @@ -33,8 +33,8 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0" }, diff --git a/packages/rstream-csp/CHANGELOG.md b/packages/rstream-csp/CHANGELOG.md index 213dfa50cf..d13fdcfcf4 100644 --- a/packages/rstream-csp/CHANGELOG.md +++ b/packages/rstream-csp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.0.32](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@1.0.31...@thi.ng/rstream-csp@1.0.32) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/rstream-csp + + + + + ## [1.0.31](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-csp@1.0.30...@thi.ng/rstream-csp@1.0.31) (2019-08-21) **Note:** Version bump only for package @thi.ng/rstream-csp diff --git a/packages/rstream-csp/package.json b/packages/rstream-csp/package.json index 5dbf4a2ce4..1a4ac282f0 100644 --- a/packages/rstream-csp/package.json +++ b/packages/rstream-csp/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-csp", - "version": "1.0.31", + "version": "1.0.32", "description": "@thi.ng/csp bridge module for @thi.ng/rstream", "module": "./index.js", "main": "./lib/index.js", @@ -33,8 +33,8 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/csp": "^1.1.4", - "@thi.ng/rstream": "^2.5.4" + "@thi.ng/csp": "^1.1.5", + "@thi.ng/rstream": "^2.5.5" }, "keywords": [ "bridge", diff --git a/packages/rstream-dot/CHANGELOG.md b/packages/rstream-dot/CHANGELOG.md index 5d007fb3f1..689d061f4d 100644 --- a/packages/rstream-dot/CHANGELOG.md +++ b/packages/rstream-dot/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@1.1.4...@thi.ng/rstream-dot@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/rstream-dot + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-dot@1.1.3...@thi.ng/rstream-dot@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/rstream-dot diff --git a/packages/rstream-dot/README.md b/packages/rstream-dot/README.md index 979d362cdc..12e4db1ba8 100644 --- a/packages/rstream-dot/README.md +++ b/packages/rstream-dot/README.md @@ -75,7 +75,7 @@ dot -Tsvg -o graph.svg graph.dot This will generate this diagram: -![graphviz output](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/rs-dot-example.svg) +![graphviz output](../../assets/examples/rs-dot-example.svg) ## Authors diff --git a/packages/rstream-dot/package.json b/packages/rstream-dot/package.json index d72135755b..69411bc603 100644 --- a/packages/rstream-dot/package.json +++ b/packages/rstream-dot/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-dot", - "version": "1.1.4", + "version": "1.1.5", "description": "Graphviz DOT conversion of @thi.ng/rstream dataflow graph topologies", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/rstream": "^2.5.4" + "@thi.ng/rstream": "^2.5.5" }, "keywords": [ "conversion", diff --git a/packages/rstream-gestures/CHANGELOG.md b/packages/rstream-gestures/CHANGELOG.md index c554033600..0636965c95 100644 --- a/packages/rstream-gestures/CHANGELOG.md +++ b/packages/rstream-gestures/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.2.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@1.2.4...@thi.ng/rstream-gestures@1.2.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/rstream-gestures + + + + + ## [1.2.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-gestures@1.2.3...@thi.ng/rstream-gestures@1.2.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/rstream-gestures diff --git a/packages/rstream-gestures/README.md b/packages/rstream-gestures/README.md index 001b7678ee..2a426e09f3 100644 --- a/packages/rstream-gestures/README.md +++ b/packages/rstream-gestures/README.md @@ -44,7 +44,7 @@ yarn add @thi.ng/rstream-gestures Several small, fully commented projects can be found in the `/examples` folder: -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/canvas-dial.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/canvas-dial.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/canvas-dial) | [Live version](https://demo.thi.ng/umbrella/canvas-dial) diff --git a/packages/rstream-gestures/package.json b/packages/rstream-gestures/package.json index c925d690c5..3d447e1ddb 100644 --- a/packages/rstream-gestures/package.json +++ b/packages/rstream-gestures/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-gestures", - "version": "1.2.4", + "version": "1.2.5", "description": "Unified mouse, mouse wheel & single-touch event stream abstraction", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/rstream": "^2.5.4", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/api": "^6.4.0", + "@thi.ng/rstream": "^2.5.5", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "dataflow", diff --git a/packages/rstream-graph/CHANGELOG.md b/packages/rstream-graph/CHANGELOG.md index 70eb00392b..add50239e0 100644 --- a/packages/rstream-graph/CHANGELOG.md +++ b/packages/rstream-graph/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.1.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@3.1.6...@thi.ng/rstream-graph@3.1.7) (2019-09-21) + + +### Bug Fixes + +* **rstream-graph:** const zero input spec handling ([27e9d30](https://github.com/thi-ng/umbrella/commit/27e9d30)) + + + + + ## [3.1.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-graph@3.1.5...@thi.ng/rstream-graph@3.1.6) (2019-08-21) **Note:** Version bump only for package @thi.ng/rstream-graph diff --git a/packages/rstream-graph/README.md b/packages/rstream-graph/README.md index b797abb671..3e9d9a6307 100644 --- a/packages/rstream-graph/README.md +++ b/packages/rstream-graph/README.md @@ -43,6 +43,9 @@ yarn add @thi.ng/rstream-graph Small(ish), fully commented projects can be found in the `/examples` folder: +- **Spreadsheet w/ Lisp-style DSL** - + [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/rstream-spreadsheet), + [Live version](https://demo.thi.ng/umbrella/rstream-spreadsheet) - **SVG grid gen** - [Source](https://github.com/thi-ng/umbrella/tree/master/examples/rstream-grid), [Live version](https://demo.thi.ng/umbrella/rstream-grid) diff --git a/packages/rstream-graph/package.json b/packages/rstream-graph/package.json index 27c771edf6..7a0780c5b7 100644 --- a/packages/rstream-graph/package.json +++ b/packages/rstream-graph/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-graph", - "version": "3.1.6", + "version": "3.1.7", "description": "Declarative dataflow graph construction for @thi.ng/rstream", "module": "./index.js", "main": "./lib/index.js", @@ -33,13 +33,13 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0", - "@thi.ng/paths": "^2.1.4", - "@thi.ng/resolve-map": "^4.1.6", - "@thi.ng/rstream": "^2.5.4", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/paths": "^2.1.5", + "@thi.ng/resolve-map": "^4.1.7", + "@thi.ng/rstream": "^2.5.5", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "compute", diff --git a/packages/rstream-graph/src/graph.ts b/packages/rstream-graph/src/graph.ts index e2e7a8c38e..35f74d3e9a 100644 --- a/packages/rstream-graph/src/graph.ts +++ b/packages/rstream-graph/src/graph.ts @@ -116,7 +116,7 @@ const prepareNodeInputs = ( s = fromView(state, i.path); } else if (i.stream) { s = isString(i.stream) ? resolve(i.stream) : i.stream(resolve); - } else if (i.const) { + } else if (i.const != null) { s = fromIterableSync( [isFunction(i.const) ? i.const(resolve) : i.const], false diff --git a/packages/rstream-log-file/CHANGELOG.md b/packages/rstream-log-file/CHANGELOG.md index 6d1f0a7f06..1317b34724 100644 --- a/packages/rstream-log-file/CHANGELOG.md +++ b/packages/rstream-log-file/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.20](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log-file@0.1.19...@thi.ng/rstream-log-file@0.1.20) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/rstream-log-file + + + + + ## [0.1.19](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log-file@0.1.18...@thi.ng/rstream-log-file@0.1.19) (2019-08-21) **Note:** Version bump only for package @thi.ng/rstream-log-file diff --git a/packages/rstream-log-file/package.json b/packages/rstream-log-file/package.json index 0d57e38711..03ecbac1bc 100644 --- a/packages/rstream-log-file/package.json +++ b/packages/rstream-log-file/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-log-file", - "version": "0.1.19", + "version": "0.1.20", "description": "File output handler for structured, multilevel & hierarchical loggers based on @thi.ng/rstream", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/rstream": "^2.5.4" + "@thi.ng/rstream": "^2.5.5" }, "keywords": [ "append", diff --git a/packages/rstream-log/CHANGELOG.md b/packages/rstream-log/CHANGELOG.md index 3970e09e8e..03a9f56419 100644 --- a/packages/rstream-log/CHANGELOG.md +++ b/packages/rstream-log/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@3.1.4...@thi.ng/rstream-log@3.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/rstream-log + + + + + ## [3.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-log@3.1.3...@thi.ng/rstream-log@3.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/rstream-log diff --git a/packages/rstream-log/package.json b/packages/rstream-log/package.json index b76e195bc0..88d4d672bd 100644 --- a/packages/rstream-log/package.json +++ b/packages/rstream-log/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-log", - "version": "3.1.4", + "version": "3.1.5", "description": "Structured, multilevel & hierarchical loggers based on @thi.ng/rstream", "module": "./index.js", "main": "./lib/index.js", @@ -33,11 +33,11 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0", - "@thi.ng/rstream": "^2.5.4", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/rstream": "^2.5.5", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "ES6", diff --git a/packages/rstream-query/CHANGELOG.md b/packages/rstream-query/CHANGELOG.md index 7b0a3c1a7c..240d1df828 100644 --- a/packages/rstream-query/CHANGELOG.md +++ b/packages/rstream-query/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@1.1.4...@thi.ng/rstream-query@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/rstream-query + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream-query@1.1.3...@thi.ng/rstream-query@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/rstream-query diff --git a/packages/rstream-query/README.md b/packages/rstream-query/README.md index 1f3c927fe0..1ee0130838 100644 --- a/packages/rstream-query/README.md +++ b/packages/rstream-query/README.md @@ -162,7 +162,7 @@ addCity("paris", "france"); After setting up the above query and its internal transformations, the generated dataflow topology then looks as follows: -![graphviz output](../../assets/rs-query1.svg) +![graphviz output](../../assets/examples/rs-query1.svg) - The blue nodes are `TripleStore`-internal index stream sources, emitting changes when new triples are added diff --git a/packages/rstream-query/package.json b/packages/rstream-query/package.json index f440624d97..079c6a1d9a 100644 --- a/packages/rstream-query/package.json +++ b/packages/rstream-query/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream-query", - "version": "1.1.4", + "version": "1.1.5", "description": "@thi.ng/rstream based triple store & reactive query engine", "module": "./index.js", "main": "./lib/index.js", @@ -33,15 +33,15 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/associative": "^3.0.0", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/associative": "^3.0.1", + "@thi.ng/checks": "^2.4.0", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", "@thi.ng/math": "^1.4.2", - "@thi.ng/rstream": "^2.5.4", - "@thi.ng/rstream-dot": "^1.1.4", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/rstream": "^2.5.5", + "@thi.ng/rstream-dot": "^1.1.5", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "dataflow", diff --git a/packages/rstream/CHANGELOG.md b/packages/rstream/CHANGELOG.md index 0a6e96fa47..b3b161ac56 100644 --- a/packages/rstream/CHANGELOG.md +++ b/packages/rstream/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.5.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@2.5.4...@thi.ng/rstream@2.5.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/rstream + + + + + ## [2.5.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@2.5.3...@thi.ng/rstream@2.5.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/rstream diff --git a/packages/rstream/README.md b/packages/rstream/README.md index aee0c0cfc9..a77a783ba6 100644 --- a/packages/rstream/README.md +++ b/packages/rstream/README.md @@ -9,28 +9,28 @@ This project is part of the -- [About](#about) -- [Support packages](#support-packages) -- [Conceptual differences to RxJS](#conceptual-differences-to-rxjs) -- [Installation](#installation) -- [Dependencies](#dependencies) -- [Usage examples](#usage-examples) - - [Realtime crypto candle chart](#realtime-crypto-candle-chart) - - [Worker-based mandelbrot fractal renderer](#worker-based-mandelbrot-fractal-renderer) - - [Interactive SVG grid generator](#interactive-svg-grid-generator) - - [Mouse gesture analysis](#mouse-gesture-analysis) - - [Declarative dataflow graph](#declarative-dataflow-graph) - - [@thi.ng/hdom benchmark](#thinghdom-benchmark) -- [API](#api) - - [Stream creation](#stream-creation) - - [Meta streams](#meta-streams) - - [Stream merging](#stream-merging) - - [Stream splitting](#stream-splitting) - - [Side-chaining](#side-chaining) - - [Worker support](#worker-support) - - [Other subscription ops](#other-subscription-ops) -- [Authors](#authors) -- [License](#license) +- [About](#about) +- [Support packages](#support-packages) +- [Conceptual differences to RxJS](#conceptual-differences-to-rxjs) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) + - [Realtime crypto candle chart](#realtime-crypto-candle-chart) + - [Worker-based mandelbrot fractal renderer](#worker-based-mandelbrot-fractal-renderer) + - [Interactive SVG grid generator](#interactive-svg-grid-generator) + - [Mouse gesture analysis](#mouse-gesture-analysis) + - [Declarative dataflow graph](#declarative-dataflow-graph) + - [@thi.ng/hdom benchmark](#thinghdom-benchmark) +- [API](#api) + - [Stream creation](#stream-creation) + - [Meta streams](#meta-streams) + - [Stream merging](#stream-merging) + - [Stream splitting](#stream-splitting) + - [Side-chaining](#side-chaining) + - [Worker support](#worker-support) + - [Other subscription ops](#other-subscription-ops) +- [Authors](#authors) +- [License](#license) @@ -117,28 +117,28 @@ A small selection: ### Realtime crypto candle chart -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/crypto-chart.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/crypto-chart.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/crypto-chart) | [Live version](https://demo.thi.ng/umbrella/crypto-chart/) ### Worker-based mandelbrot fractal renderer -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/mandelbrot.jpg) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/mandelbrot.jpg) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/mandelbrot) | [Live version](https://demo.thi.ng/umbrella/mandelbrot/) ### Interactive SVG grid generator -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/rstream-grid.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rstream-grid.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/rstream-grid) | [Live version](https://demo.thi.ng/umbrella/rstream-grid/) ### Mouse gesture analysis -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/gesture-analysis.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/gesture-analysis.png) [Source](https://github.com/thi-ng/umbrella/tree/master/examples/gesture-analysis) | [Live version](https://demo.thi.ng/umbrella/gesture-analysis) @@ -334,7 +334,7 @@ m.next(true); #### [merge()](https://github.com/thi-ng/umbrella/tree/master/packages/rstream/src/stream-merge.ts) - unsorted merge from multiple inputs (dynamic add/remove) -![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/rstream-merge.png) +![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-merge.png) Returns a new `StreamMerge` instance, a subscription type consuming inputs from multiple inputs and passing received values on to any @@ -417,7 +417,7 @@ a.next("a"); #### [sync()](https://github.com/thi-ng/umbrella/tree/master/packages/rstream/src/stream-sync.ts) - synchronized merge and labeled tuple objects -![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/rstream-sync.png) +![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-sync.png) Similar to `StreamMerge` above, but with extra synchronization of inputs. Before emitting any new values, `StreamSync` collects values @@ -468,7 +468,7 @@ for further reference of the various behavior options. #### [pubsub()](https://github.com/thi-ng/umbrella/tree/master/packages/rstream/src/pubsub.ts) - topic based splitting -![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/rstream-pubsub.png) +![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-pubsub.png) Topic based stream splitter. Applies `topic` function to each received value and only forwards it to child subscriptions for @@ -534,7 +534,7 @@ rs.fromIterable([1, 2, 3, 4]).subscribe(rs.bisect((x) => !!(x & 1), odd, even)); #### [sidechainPartition()](https://github.com/thi-ng/umbrella/tree/master/packages/rstream/src/subs/sidechain-partition.ts) - chunks input, controlled by sidechain -![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/rstream-sidechain-partition.png) +![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-sidechain-partition.png) Buffers values from `src` until side chain fires, then emits buffer (unless empty) and repeats process until either input is done. By @@ -557,7 +557,7 @@ merge([ #### [sidechainToggle()](https://github.com/thi-ng/umbrella/tree/master/packages/rstream/src/subs/sidechain-toggle.ts) - toggles input, controlled by sidechain -![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/rstream-sidechain-toggle.png) +![diagram](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/rstream/rstream-sidechain-toggle.png) Filters values from input based on values received from side chain. By default, the value read from the side chain is ignored, however the diff --git a/packages/rstream/package.json b/packages/rstream/package.json index 16d159b5dd..86236c7f35 100644 --- a/packages/rstream/package.json +++ b/packages/rstream/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/rstream", - "version": "2.5.4", + "version": "2.5.5", "description": "Reactive multi-tap streams, dataflow & transformation pipeline constructs", "module": "./index.js", "main": "./lib/index.js", @@ -33,13 +33,13 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/associative": "^3.0.0", - "@thi.ng/atom": "^3.0.4", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/associative": "^3.0.1", + "@thi.ng/atom": "^3.1.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0", - "@thi.ng/paths": "^2.1.4", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/paths": "^2.1.5", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "datastructure", diff --git a/packages/sax/CHANGELOG.md b/packages/sax/CHANGELOG.md index 3642b26cd6..0d36c3530d 100644 --- a/packages/sax/CHANGELOG.md +++ b/packages/sax/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/sax@1.1.4...@thi.ng/sax@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/sax + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/sax@1.1.3...@thi.ng/sax@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/sax diff --git a/packages/sax/package.json b/packages/sax/package.json index 3e1cdfd08f..d9c7e07f04 100644 --- a/packages/sax/package.json +++ b/packages/sax/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/sax", - "version": "1.1.4", + "version": "1.1.5", "description": "Transducer-based, SAX-like, non-validating, speedy & tiny XML parser", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/transducers-fsm": "^1.1.4" + "@thi.ng/api": "^6.4.0", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/transducers-fsm": "^1.1.5" }, "keywords": [ "ES6", diff --git a/packages/sexpr/.npmignore b/packages/sexpr/.npmignore new file mode 100644 index 0000000000..24f388daa6 --- /dev/null +++ b/packages/sexpr/.npmignore @@ -0,0 +1,18 @@ +.cache +.meta +.nyc_output +*.gz +*.html +*.svg +*.tgz +*.h +*.o +*.wasm +build +coverage +dev +doc +export +src* +test +tsconfig.json diff --git a/packages/sexpr/CHANGELOG.md b/packages/sexpr/CHANGELOG.md new file mode 100644 index 0000000000..7e63c9a896 --- /dev/null +++ b/packages/sexpr/CHANGELOG.md @@ -0,0 +1,13 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2019-09-21) + + +### Features + +* **sexpr:** add ParseError ([7998afe](https://github.com/thi-ng/umbrella/commit/7998afe)) +* **sexpr:** import as new package ([f526b7c](https://github.com/thi-ng/umbrella/commit/f526b7c)) +* **sexpr:** update SyntaxOpts, runtime, update scope parsing, types ([7c840e1](https://github.com/thi-ng/umbrella/commit/7c840e1)) diff --git a/packages/sexpr/LICENSE b/packages/sexpr/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/sexpr/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/sexpr/README.md b/packages/sexpr/README.md new file mode 100644 index 0000000000..8e2fcd1355 --- /dev/null +++ b/packages/sexpr/README.md @@ -0,0 +1,245 @@ +# @thi.ng/sexpr + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/sexpr.svg)](https://www.npmjs.com/package/@thi.ng/sexpr) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/sexpr.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + +- [About](#about) +- [Status](#status) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) + - [Tokenize only (iterator)](#tokenize-only-iterator) + - [AST generation](#ast-generation) + - [Interpreter](#interpreter) + - [Custom syntax](#custom-syntax) +- [Authors](#authors) +- [License](#license) + + + +## About + +Basic, but configurable and extensible +[S-Expression](https://en.wikipedia.org/wiki/S-expression) tokenizer, +parser, AST builder and runtime / interpreter skeleton for custom, +sandboxed DSL implementations. + +The following default syntax rules are used: + +- whitespace: space, tab, newline, comma +- expression delimiters: `(`, `)` +- numbers: any float notation valid in JS, hex ints prefixed w/ `0x` +- string delimiters: `"` + +Everything else is parsed as is, i.e. as symbol. + +## Status + +ALPHA + +## Installation + +```bash +yarn add @thi.ng/sexpr +``` + +## Dependencies + +- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/master/packages/api) +- [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/master/packages/defmulti) + +## Usage examples + +- [DSL for spreadsheet formulas](https://github.com/thi-ng/umbrella/tree/develop/examples/rstream-spreadsheet) + +```ts +import { tokenize, parse, runtime } from "@thi.ng/sexpr"; +``` + +### Tokenize only (iterator) + +```ts +[...tokenize(`(* (+ 3 5) 10)`)]; +// [ '(', '*', '(', '+', '3', '5', ')', '10', ')'] +``` + +### AST generation + +```ts +parse(tokenize(`(* (+ 3 5) 10)`)); +``` + +```json +{ + "type": "root", + "children": [ + { + "type": "expr", + "value": "(", + "children": [ + { + "type": "sym", + "value": "*" + }, + { + "type": "expr", + "value": "(", + "children": [ + { + "type": "sym", + "value": "+" + }, + { + "type": "num", + "value": 3 + }, + { + "type": "num", + "value": 5 + } + ] + }, + { + "type": "num", + "value": 10 + } + ] + } + ] +} +``` + +### Interpreter + +```ts +import { Fn2 } from "@thi.ng/api"; +import { defmulti, DEFAULT } from "@thi.ng/defmulti"; +import { ASTNode, Implementations, Sym } from "@thi.ng/sexpr"; + +// multi-dispatch fn for DSL builtins +// we will call this function for each S-expression +// and will delegate to the actual implementation based on +// the expression's first item (a symbol name) +const builtins = defmulti((x) => x.value); + +// build runtime w/ impls for all AST node types +// the generics are the types of: the custom environment (if used) +// and the result type(s) +const rt = runtime, any, any>({ + // delegate to builtins + expr: (x, env) => builtins(x.children[0], x.children, env), + // lookup symbol in environment + sym: (x, env) => env[x.value], + // strings and numbers evaluate verbatim + str: (x) => x.value, + num: (x) => x.value +}); + +// helper HOF for math ops +const op = (fn: Fn2) => + (_: ASTNode, vals: ASTNode[], env: any) => + vals.slice(2).reduce( + (acc, x) => fn(acc, rt(x, env)), + rt(vals[1], env) + ); + +// add builtins +builtins.addAll({ + "+": op((acc, x) => acc + x), + "*": op((acc, x) => acc * x), + "-": op((acc, x) => acc - x), + "/": op((acc, x) => acc / x), + count: (_, [__, x]) => rt(x).length +}); + +// add default/fallback implementation +// to allow calling functions stored in environment +builtins.add(DEFAULT, (x, [_, ...args], env) => { + const f = env[(x).value]; + assert(!!f, "missing impl"); + return f.apply(null, args.map((a) => rt(a, env))); +}); + +// evaluator +const $eval = (src: string, env: any = {}) => + rt(parse(tokenize(src)).children[0], env); + +// evaluate expression w/ given env bindings +$eval(`(* foo (+ 1 2 3 (count "abcd")))`, { foo: 10 }); +// 100 +// i.e. 100 = 10 * (1 + 2 + 3 + 4) + +// call env function +$eval( + `(join (+ 1 2) (* 3 4))`, + { join: (...xs: any[]) => xs.join(",") } +); +// "3,12" +``` + +See +[test/](https://github.com/thi-ng/umbrella/tree/master/packages/sexpr/test/) +for a more in-depth version of this example... + +### Custom syntax + +```ts +// define syntax overrides (keep default whitespace rules) +const syntax = { scopes: [["<", ">"], ["{", "}"]], string: "'" }; + +parse(tokenize(``, syntax), syntax); +``` + +```json +{ + "type": "root", + "children": [ + { + "type": "expr", + "value": "<", + "children": [ + { + "type": "sym", + "value": "nest" + }, + { + "type": "expr", + "value": "{", + "children": [ + { + "type": "sym", + "value": "a" + }, + { + "type": "str", + "value": "2" + }, + { + "type": "sym", + "value": "b" + }, + { + "type": "num", + "value": 3 + } + ] + } + ] + } + ] +} +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2016 - 2019 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/sexpr/package.json b/packages/sexpr/package.json new file mode 100644 index 0000000000..8e9a9bf558 --- /dev/null +++ b/packages/sexpr/package.json @@ -0,0 +1,56 @@ +{ + "name": "@thi.ng/sexpr", + "version": "0.1.0", + "description": "Extensible S-Expression parser & runtime infrastructure", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/sexpr", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn clean && yarn build:es6 && node ../../scripts/bundle-module", + "build:release": "yarn clean && yarn build:es6 && node ../../scripts/bundle-module all", + "build:es6": "tsc --declaration", + "build:test": "rimraf build && tsc -p test/tsconfig.json", + "test": "yarn build:test && mocha build/test/*.js", + "cover": "yarn build:test && nyc mocha build/test/*.js && nyc report --reporter=lcov", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", + "doc": "node_modules/.bin/typedoc --mode modules --out doc --ignoreCompilerErrors src", + "pub": "yarn build:release && yarn publish --access public" + }, + "devDependencies": { + "@types/mocha": "^5.2.6", + "@types/node": "^12.6.3", + "mocha": "^6.1.4", + "nyc": "^14.0.0", + "typedoc": "^0.14.2", + "typescript": "^3.5.3" + }, + "dependencies": { + "@thi.ng/api": "^6.4.0", + "@thi.ng/defmulti": "^1.1.4", + "@thi.ng/errors": "1.2.0" + }, + "keywords": [ + "DSL", + "ES6", + "interpreter", + "lisp", + "parser", + "runtime", + "s-expression", + "tokenizer", + "typescript", + "WAST" + ], + "publishConfig": { + "access": "public" + }, + "sideEffects": false +} diff --git a/packages/sexpr/src/api.ts b/packages/sexpr/src/api.ts new file mode 100644 index 0000000000..dc39c5159a --- /dev/null +++ b/packages/sexpr/src/api.ts @@ -0,0 +1,95 @@ +import { Fn2 } from "@thi.ng/api"; + +export interface SyntaxOpts { + /** + * An array of string pairs defining possible S-expression / scope + * delimiters [open, close]. By default only the classic ["(",")"] + * pair is defined. Only single character delimiters are supported. + * + * @see DEFAULT_SYNTAX + */ + scopes: string[][]; + /** + * Regex to identify whitespace a single whitespace character. + * Default: space, tab, newline, comma + */ + whiteSpace: RegExp; + /** + * Single character string to delineate string values. + * Default: `"` + */ + string: string; +} + +export type NodeType = "root" | "expr" | "sym" | "str" | "num"; + +export type ASTNode = Root | Expression | Sym | Str | Numeric; + +/** + * Base interface for custom AST nodes + */ +export interface INode { + type: string; + parent?: INode; +} + +export interface Root extends INode { + type: "root"; + children: ASTNode[]; +} + +/** + * AST Node defining an S-expression. + */ +export interface Expression extends INode { + type: "expr"; + /** + * Child nodes + */ + children: ASTNode[]; + /** + * Scope type char (as per configured syntax) + */ + value: string; +} + +/** + * AST symbol node. Merely holds symbol name. + */ +export interface Sym extends INode { + type: "sym"; + value: string; +} + +/** + * AST string node. Merely wraps string value. + */ +export interface Str extends INode { + type: "str"; + value: string; +} + +/** + * AST numeric node. Merely wraps parsed numeric value. + */ +export interface Numeric extends INode { + type: "num"; + value: number; +} + +/** + * Type hinted runtime implementations. + */ +export interface Implementations { + root: Fn2; + expr: Fn2; + sym: Fn2; + str: Fn2; + num: Fn2; +} + +export const DEFAULT_SYNTAX: SyntaxOpts = { + scopes: [["(", ")"]], + whiteSpace: /(\s|,)/, + string: '"' +}; diff --git a/packages/sexpr/src/index.ts b/packages/sexpr/src/index.ts new file mode 100644 index 0000000000..bc454ae03f --- /dev/null +++ b/packages/sexpr/src/index.ts @@ -0,0 +1,4 @@ +export * from "./api"; +export * from "./parse"; +export * from "./runtime"; +export * from "./tokenize"; diff --git a/packages/sexpr/src/parse.ts b/packages/sexpr/src/parse.ts new file mode 100644 index 0000000000..3fbf1c5454 --- /dev/null +++ b/packages/sexpr/src/parse.ts @@ -0,0 +1,55 @@ +import { defError } from "@thi.ng/errors"; +import { + ASTNode, + DEFAULT_SYNTAX, + Expression, + Root, + SyntaxOpts +} from "./api"; + +const ParseError = defError((msg?) => msg || "Parser error", () => ""); + +export const parse = (tokens: Iterable, opts?: Partial) => { + const { scopes } = { + ...DEFAULT_SYNTAX, + ...opts + }; + const scopeOpen = scopes.map((x) => x[0]); + const scopeClose = scopes.map((x) => x[1]); + const tree: ASTNode[] = [{ type: "root", children: [] }]; + let currScope = -1; + for (let t of tokens) { + let tmp: number; + if ((tmp = scopeOpen.indexOf(t)) !== -1) { + tree.push({ type: "expr", value: t, children: [] }); + currScope = tmp; + } else if ((tmp = scopeClose.indexOf(t)) !== -1) { + if (tree.length < 2 || currScope !== tmp) { + throw new ParseError(`unmatched '${t}'`); + } + (tree[tree.length - 2]).children!.push(tree.pop()!); + currScope = scopeOpen.indexOf( + (tree[tree.length - 1]).value + ); + } else { + let node: ASTNode; + let value: number; + if (t.startsWith('"')) { + node = { type: "str", value: t.substring(1, t.length - 1) }; + } else if ( + (t.startsWith("0x") && + !isNaN((value = parseInt(t.substr(2), 16)))) || + !isNaN((value = parseFloat(t))) + ) { + node = { type: "num", value }; + } else { + node = { type: "sym", value: t }; + } + (tree[tree.length - 1]).children!.push(node); + } + } + if (tree.length > 1) { + throw new ParseError("unclosed s-expr"); + } + return tree[0]; +}; diff --git a/packages/sexpr/src/runtime.ts b/packages/sexpr/src/runtime.ts new file mode 100644 index 0000000000..1339a517ee --- /dev/null +++ b/packages/sexpr/src/runtime.ts @@ -0,0 +1,10 @@ +import { defmulti, MultiFn1O } from "@thi.ng/defmulti"; +import { ASTNode, Implementations } from "./api"; + +export const runtime = , ENV, RES>( + impls: Partial +) => { + const rt: MultiFn1O = defmulti((x: ASTNode) => x.type); + rt.addAll(impls); + return rt; +}; diff --git a/packages/sexpr/src/tokenize.ts b/packages/sexpr/src/tokenize.ts new file mode 100644 index 0000000000..bea1f70199 --- /dev/null +++ b/packages/sexpr/src/tokenize.ts @@ -0,0 +1,48 @@ +import { DEFAULT_SYNTAX, SyntaxOpts } from "./api"; + +/** + * Yields iterator of tokens from `src` string (or a **characterwise** + * iterable). Scope and string delimiters and whitespace characters can be + * configured via given `opts`. By default `DEFAULT_SYNTAX` is used. + * + * @see SyntaxOpts + * + * @param src + * @param opts + */ +export function* tokenize(src: Iterable, opts?: Partial) { + const { scopes: rawScopes, whiteSpace, string } = { + ...DEFAULT_SYNTAX, + ...opts + }; + const scopes = rawScopes + .reduce((acc, x) => acc.concat(x), []) + .join(""); + let curr = ""; + let isString = false; + for (let c of src) { + if (!isString) { + if (whiteSpace.test(c)) { + curr && (yield curr); + curr = ""; + } else if (scopes.indexOf(c) !== -1) { + curr && (yield curr); + yield c; + curr = ""; + } else if (c === string) { + curr && (yield curr); + curr = '"'; + isString = true; + } else { + curr += c; + } + } else if (c === string && curr[curr.length - 1] !== "\\") { + curr += '"'; + yield curr; + curr = ""; + isString = false; + } else { + curr += c; + } + } +} diff --git a/packages/sexpr/test/index.ts b/packages/sexpr/test/index.ts new file mode 100644 index 0000000000..8941a1c8c2 --- /dev/null +++ b/packages/sexpr/test/index.ts @@ -0,0 +1,149 @@ +import { Fn2 } from "@thi.ng/api"; +import { DEFAULT, defmulti } from "@thi.ng/defmulti"; +import * as assert from "assert"; +import { + ASTNode, + Implementations, + parse, + runtime, + Sym, + SyntaxOpts, + tokenize +} from "../src/index"; + +const ops = defmulti((x) => (x).value); +const rt = runtime, any, any>({ + expr: (x, env) => ops(x.children[0], x.children, env), + sym: (x, env) => env[x.value], + str: (x) => x.value, + num: (x) => x.value +}); + +const $eval = (src: string, env: any = {}) => + rt(parse(tokenize(src)).children[0], env); + +const op = (fn: Fn2) => ( + _: ASTNode, + vals: ASTNode[], + env: any +) => vals.slice(2).reduce((acc, x) => fn(acc, rt(x, env)), rt(vals[1], env)); + +ops.addAll({ + "+": op((acc, x) => acc + x), + "*": op((acc, x) => acc * x), + "-": op((acc, x) => acc - x), + "/": op((acc, x) => acc / x), + count: (_, [__, x]) => rt(x).length +}); + +ops.add(DEFAULT, (x, [_, ...args], env) => { + const f = env[(x).value]; + assert(!!f, "missing impl"); + return f.apply(null, args.map((a) => rt(a, env))); +}); + +describe("sexpr", () => { + it("basic", () => { + assert.deepEqual(parse(tokenize(`(+ 1 (len "234"))`)), { + type: "root", + children: [ + { + type: "expr", + value: "(", + children: [ + { type: "sym", value: "+" }, + { type: "num", value: 1 }, + { + type: "expr", + value: "(", + children: [ + { type: "sym", value: "len" }, + { type: "str", value: "234" } + ] + } + ] + } + ] + }); + }); + + it("custom syntax", () => { + const syntax: Partial = { + scopes: [["<", ">"], ["{", "}"]], + string: "'" + }; + assert.deepEqual( + parse(tokenize(``, syntax), syntax), + { + type: "root", + children: [ + { + type: "expr", + value: "<", + children: [ + { + type: "sym", + value: "nest" + }, + { + type: "expr", + value: "{", + children: [ + { + type: "sym", + value: "a" + }, + { + type: "str", + value: "2" + }, + { + type: "sym", + value: "b" + }, + { + type: "num", + value: 3 + } + ] + } + ] + } + ] + } + ); + }); + + it("unmatched", () => { + assert.throws(() => parse(tokenize(`(`))); + assert.throws(() => parse(tokenize(`((`))); + assert.throws(() => parse(tokenize(`(()`))); + }); + + it("math", () => { + assert.equal( + $eval( + `(/ + (- + (* (count "abc") (+ 100 (* 3 4 5))) + foo) + 100)`, + { foo: -20 } + ), + (3 * (100 + 3 * 4 * 5) - -20) / 100 + ); + }); + + it("fn in env", () => { + assert.equal( + $eval(`(join (+ 1 2) (+ 3 4))`, { + join: (...xs: any[]) => xs.join(",") + }), + "3,7" + ); + }); + + it("missing fn in env", () => { + assert.throws(() => $eval("(foo)")); + }); +}); diff --git a/packages/sexpr/test/tsconfig.json b/packages/sexpr/test/tsconfig.json new file mode 100644 index 0000000000..f6e63560dd --- /dev/null +++ b/packages/sexpr/test/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build", + "module": "commonjs" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/sexpr/tsconfig.json b/packages/sexpr/tsconfig.json new file mode 100644 index 0000000000..893b9979c5 --- /dev/null +++ b/packages/sexpr/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "module": "es6", + "target": "es6" + }, + "include": [ + "./src/**/*.ts" + ] +} diff --git a/packages/shader-ast-glsl/CHANGELOG.md b/packages/shader-ast-glsl/CHANGELOG.md index 19808b1292..3ea18584ac 100644 --- a/packages/shader-ast-glsl/CHANGELOG.md +++ b/packages/shader-ast-glsl/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/shader-ast-glsl@0.1.6...@thi.ng/shader-ast-glsl@0.1.7) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/shader-ast-glsl + + + + + ## [0.1.6](https://github.com/thi-ng/umbrella/compare/@thi.ng/shader-ast-glsl@0.1.5...@thi.ng/shader-ast-glsl@0.1.6) (2019-08-21) **Note:** Version bump only for package @thi.ng/shader-ast-glsl diff --git a/packages/shader-ast-glsl/package.json b/packages/shader-ast-glsl/package.json index bd03bc486b..3239d99832 100644 --- a/packages/shader-ast-glsl/package.json +++ b/packages/shader-ast-glsl/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/shader-ast-glsl", - "version": "0.1.6", + "version": "0.1.7", "description": "Customizable GLSL code generator for @thi.ng/shader-ast", "module": "./index.js", "main": "./lib/index.js", @@ -33,10 +33,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0", - "@thi.ng/shader-ast": "^0.3.0" + "@thi.ng/shader-ast": "^0.3.1" }, "keywords": [ "AST", diff --git a/packages/shader-ast-js/CHANGELOG.md b/packages/shader-ast-js/CHANGELOG.md index cec827a06c..55da66f6b0 100644 --- a/packages/shader-ast-js/CHANGELOG.md +++ b/packages/shader-ast-js/CHANGELOG.md @@ -3,6 +3,23 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.4.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/shader-ast-js@0.3.1...@thi.ng/shader-ast-js@0.4.0) (2019-09-21) + + +### Bug Fixes + +* **shader-ast-js:** fix divisions ([bc81ff8](https://github.com/thi-ng/umbrella/commit/bc81ff8)) + + +### Features + +* **shader-ast-js:** add div-by-zero guards ([233528d](https://github.com/thi-ng/umbrella/commit/233528d)) +* **shader-ast-js:** replace JS runtime fns, add doc strings ([0798a35](https://github.com/thi-ng/umbrella/commit/0798a35)) + + + + + ## [0.3.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/shader-ast-js@0.3.0...@thi.ng/shader-ast-js@0.3.1) (2019-08-21) **Note:** Version bump only for package @thi.ng/shader-ast-js diff --git a/packages/shader-ast-js/package.json b/packages/shader-ast-js/package.json index 306c8ff836..a3e69b5fe9 100644 --- a/packages/shader-ast-js/package.json +++ b/packages/shader-ast-js/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/shader-ast-js", - "version": "0.3.1", + "version": "0.4.0", "description": "Customizable JS code generator, compiler & runtime for @thi.ng/shader-ast", "module": "./index.js", "main": "./lib/index.js", @@ -33,13 +33,14 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/errors": "^1.2.0", "@thi.ng/math": "^1.4.2", - "@thi.ng/matrices": "^0.5.7", - "@thi.ng/shader-ast": "^0.3.0", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/matrices": "^0.5.8", + "@thi.ng/pixel": "^0.1.4", + "@thi.ng/shader-ast": "^0.3.1", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "AST", diff --git a/packages/shader-ast-js/src/env/ivec2.ts b/packages/shader-ast-js/src/env/ivec2.ts index b27de1e141..84ef90beda 100644 --- a/packages/shader-ast-js/src/env/ivec2.ts +++ b/packages/shader-ast-js/src/env/ivec2.ts @@ -26,16 +26,16 @@ export const IVEC2: JSBuiltinsIntVec = { addnv: (a, b) => addNI2([], b, a), div: (a, b) => divI2([], a, b), divvn: (a, b) => divNI2([], a, b), - divnv: (a, b) => mulNI2([], b, 1 / a), + divnv: (a, b) => divI2(null, [a, a], b), modi: (a, b) => mod2([], a, b), modivn: (a, b) => modN2([], a, b), - modinv: (a, b) => mod2([], [a, a], b), + modinv: (a, b) => mod2(null, [a, a], b), mul: (a, b) => mulI2([], a, b), mulvn: (a, b) => mulNI2([], a, b), mulnv: (a, b) => mulNI2([], b, a), sub: (a, b) => subI2([], a, b), subvn: (a, b) => subNI2([], a, b), - subnv: (a, b) => subI2([], [a, a], b), + subnv: (a, b) => subI2(null, [a, a], b), bitand: (a, b) => bitAndI2([], a, b), lshift: (a, b) => lshiftI2([], a, b), bitnot1: (a) => bitNotI2([], a), diff --git a/packages/shader-ast-js/src/env/ivec3.ts b/packages/shader-ast-js/src/env/ivec3.ts index d9c31a9fd2..a5496ab76e 100644 --- a/packages/shader-ast-js/src/env/ivec3.ts +++ b/packages/shader-ast-js/src/env/ivec3.ts @@ -26,16 +26,16 @@ export const IVEC3: JSBuiltinsIntVec = { addnv: (a, b) => addNI3([], b, a), div: (a, b) => divI3([], a, b), divvn: (a, b) => divNI3([], a, b), - divnv: (a, b) => mulNI3([], b, 1 / a), + divnv: (a, b) => divI3(null, [a, a, a], b), modi: (a, b) => mod3([], a, b), modivn: (a, b) => modN3([], a, b), - modinv: (a, b) => mod3([], [a, a, a], b), + modinv: (a, b) => mod3(null, [a, a, a], b), mul: (a, b) => mulI3([], a, b), mulvn: (a, b) => mulNI3([], a, b), mulnv: (a, b) => mulNI3([], b, a), sub: (a, b) => subI3([], a, b), subvn: (a, b) => subNI3([], a, b), - subnv: (a, b) => subI3([], [a, a, a], b), + subnv: (a, b) => subI3(null, [a, a, a], b), bitand: (a, b) => bitAndI3([], a, b), lshift: (a, b) => lshiftI3([], a, b), bitnot1: (a) => bitNotI3([], a), diff --git a/packages/shader-ast-js/src/env/ivec4.ts b/packages/shader-ast-js/src/env/ivec4.ts index d40f917712..ad0ed5f36a 100644 --- a/packages/shader-ast-js/src/env/ivec4.ts +++ b/packages/shader-ast-js/src/env/ivec4.ts @@ -26,16 +26,16 @@ export const IVEC4: JSBuiltinsIntVec = { addnv: (a, b) => addNI4([], b, a), div: (a, b) => divI4([], a, b), divvn: (a, b) => divNI4([], a, b), - divnv: (a, b) => mulNI4([], b, 1 / a), + divnv: (a, b) => divI4(null, [a, a, a, a], b), modi: (a, b) => mod4([], a, b), modivn: (a, b) => modN4([], a, b), - modinv: (a, b) => mod4([], [a, a, a, a], b), + modinv: (a, b) => mod4(null, [a, a, a, a], b), mul: (a, b) => mulI4([], a, b), mulvn: (a, b) => mulNI4([], a, b), mulnv: (a, b) => mulNI4([], b, a), sub: (a, b) => subI4([], a, b), subvn: (a, b) => subNI4([], a, b), - subnv: (a, b) => subI4([], [a, a, a, a], b), + subnv: (a, b) => subI4(null, [a, a, a, a], b), bitand: (a, b) => bitAndI4([], a, b), lshift: (a, b) => lshiftI4([], a, b), bitnot1: (a) => bitNotI4([], a), diff --git a/packages/shader-ast-js/src/env/mat2.ts b/packages/shader-ast-js/src/env/mat2.ts index 500f2d893e..fe8450bbf3 100644 --- a/packages/shader-ast-js/src/env/mat2.ts +++ b/packages/shader-ast-js/src/env/mat2.ts @@ -20,7 +20,7 @@ export const MAT2: JSBuiltinsMat = { addvn: (a, b) => addN22([], a, b), dec: (a) => subN22([], a, 1), div: (a, b) => div22([], a, b), - divnv: (a, b) => mulN22([], b, 1 / a), + divnv: (a, b) => div22(null, [a, a, a, a], b), divvn: (a, b) => divN22([], a, b), inc: (a) => addN22([], a, 1), mul: (a, b) => mul22([], a, b), diff --git a/packages/shader-ast-js/src/env/mat3.ts b/packages/shader-ast-js/src/env/mat3.ts index 6e8fe9cfec..69b96ecf85 100644 --- a/packages/shader-ast-js/src/env/mat3.ts +++ b/packages/shader-ast-js/src/env/mat3.ts @@ -20,7 +20,7 @@ export const MAT3: JSBuiltinsMat = { addvn: (a, b) => addN33([], a, b), dec: (a) => subN33([], a, 1), div: (a, b) => div33([], a, b), - divnv: (a, b) => mulN33([], b, 1 / a), + divnv: (a, b) => div33(null, vecOf(9, a), b), divvn: (a, b) => divN33([], a, b), inc: (a) => addN33([], a, 1), mul: (a, b) => mul33([], a, b), diff --git a/packages/shader-ast-js/src/env/mat4.ts b/packages/shader-ast-js/src/env/mat4.ts index 7a17278a53..30805a2fe4 100644 --- a/packages/shader-ast-js/src/env/mat4.ts +++ b/packages/shader-ast-js/src/env/mat4.ts @@ -20,7 +20,7 @@ export const MAT4: JSBuiltinsMat = { addvn: (a, b) => addN44([], a, b), dec: (a) => subN44([], a, 1), div: (a, b) => div44([], a, b), - divnv: (a, b) => mulN44([], b, 1 / a), + divnv: (a, b) => div44(null, vecOf(16, a), b), divvn: (a, b) => divN44([], a, b), inc: (a) => addN44([], a, 1), mul: (a, b) => mul44([], a, b), diff --git a/packages/shader-ast-js/src/env/uvec2.ts b/packages/shader-ast-js/src/env/uvec2.ts index cc90be6b78..adb7145514 100644 --- a/packages/shader-ast-js/src/env/uvec2.ts +++ b/packages/shader-ast-js/src/env/uvec2.ts @@ -26,16 +26,16 @@ export const UVEC2: JSBuiltinsIntVec = { addnv: (a, b) => addNU2([], b, a), div: (a, b) => divU2([], a, b), divvn: (a, b) => divNU2([], a, b), - divnv: (a, b) => mulNU2([], b, 1 / a), + divnv: (a, b) => divU2(null, [a, a], b), modi: (a, b) => mod2([], a, b), modivn: (a, b) => modN2([], a, b), - modinv: (a, b) => mod2([], [a, a], b), + modinv: (a, b) => mod2(null, [a, a], b), mul: (a, b) => mulU2([], a, b), mulvn: (a, b) => mulNU2([], a, b), mulnv: (a, b) => mulNU2([], b, a), sub: (a, b) => subU2([], a, b), subvn: (a, b) => subNU2([], a, b), - subnv: (a, b) => subU2([], [a, a], b), + subnv: (a, b) => subU2(null, [a, a], b), bitand: (a, b) => bitAndU2([], a, b), lshift: (a, b) => lshiftU2([], a, b), bitnot1: (a) => bitNotU2([], a), diff --git a/packages/shader-ast-js/src/env/uvec3.ts b/packages/shader-ast-js/src/env/uvec3.ts index dc1290e7e9..6303925fc2 100644 --- a/packages/shader-ast-js/src/env/uvec3.ts +++ b/packages/shader-ast-js/src/env/uvec3.ts @@ -26,16 +26,16 @@ export const UVEC3: JSBuiltinsIntVec = { addnv: (a, b) => addNU3([], b, a), div: (a, b) => divU3([], a, b), divvn: (a, b) => divNU3([], a, b), - divnv: (a, b) => mulNU3([], b, 1 / a), + divnv: (a, b) => divU3(null, [a, a, a], b), modi: (a, b) => mod3([], a, b), modivn: (a, b) => modN3([], a, b), - modinv: (a, b) => mod3([], [a, a, a], b), + modinv: (a, b) => mod3(null, [a, a, a], b), mul: (a, b) => mulU3([], a, b), mulvn: (a, b) => mulNU3([], a, b), mulnv: (a, b) => mulNU3([], b, a), sub: (a, b) => subU3([], a, b), subvn: (a, b) => subNU3([], a, b), - subnv: (a, b) => subU3([], [a, a, a], b), + subnv: (a, b) => subU3(null, [a, a, a], b), bitand: (a, b) => bitAndU3([], a, b), lshift: (a, b) => lshiftU3([], a, b), bitnot1: (a) => bitNotU3([], a), diff --git a/packages/shader-ast-js/src/env/uvec4.ts b/packages/shader-ast-js/src/env/uvec4.ts index f2755b9586..94c0c4709a 100644 --- a/packages/shader-ast-js/src/env/uvec4.ts +++ b/packages/shader-ast-js/src/env/uvec4.ts @@ -26,16 +26,16 @@ export const UVEC4: JSBuiltinsIntVec = { addnv: (a, b) => addNU4([], b, a), div: (a, b) => divU4([], a, b), divvn: (a, b) => divNU4([], a, b), - divnv: (a, b) => mulNU4([], b, 1 / a), + divnv: (a, b) => divU4(null, [a, a, a, a], b), modi: (a, b) => mod4([], a, b), modivn: (a, b) => modN4([], a, b), - modinv: (a, b) => mod4([], [a, a, a, a], b), + modinv: (a, b) => mod4(null, [a, a, a, a], b), mul: (a, b) => mulU4([], a, b), mulvn: (a, b) => mulNU4([], a, b), mulnv: (a, b) => mulNU4([], b, a), sub: (a, b) => subU4([], a, b), subvn: (a, b) => subNU4([], a, b), - subnv: (a, b) => subU4([], [a, a, a, a], b), + subnv: (a, b) => subU4(null, [a, a, a, a], b), bitand: (a, b) => bitAndU4([], a, b), lshift: (a, b) => lshiftU4([], a, b), bitnot1: (a) => bitNotU4([], a), diff --git a/packages/shader-ast-js/src/env/vec2.ts b/packages/shader-ast-js/src/env/vec2.ts index 2da481bbac..ebea99558e 100644 --- a/packages/shader-ast-js/src/env/vec2.ts +++ b/packages/shader-ast-js/src/env/vec2.ts @@ -67,7 +67,7 @@ export const VEC2: JSBuiltinsVec = { dFdy: () => ZERO2, distance: dist, div: (a, b) => div2([], a, b), - divnv: (a, b) => mulN2([], b, 1 / a), + divnv: (a, b) => div2(null, [a, a], b), divvn: (a, b) => divN2([], a, b), dot: (a, b) => dot2(a, b), exp: (a) => exp2([], a), diff --git a/packages/shader-ast-js/src/env/vec3.ts b/packages/shader-ast-js/src/env/vec3.ts index acb6278f1a..e475d4fdb8 100644 --- a/packages/shader-ast-js/src/env/vec3.ts +++ b/packages/shader-ast-js/src/env/vec3.ts @@ -69,7 +69,7 @@ export const VEC3: JSBuiltinsVec3 = { dFdy: () => ZERO3, distance: dist, div: (a, b) => div3([], a, b), - divnv: (a, b) => mulN3([], b, 1 / a), + divnv: (a, b) => div3(null, [a, a, a], b), divvn: (a, b) => divN3([], a, b), dot: (a, b) => dot3(a, b), exp: (a) => exp3([], a), diff --git a/packages/shader-ast-js/src/env/vec4.ts b/packages/shader-ast-js/src/env/vec4.ts index 5a53bca273..ef2479bfbc 100644 --- a/packages/shader-ast-js/src/env/vec4.ts +++ b/packages/shader-ast-js/src/env/vec4.ts @@ -67,7 +67,7 @@ export const VEC4: JSBuiltinsVec = { dFdy: () => ZERO4, distance: dist, div: (a, b) => div4([], a, b), - divnv: (a, b) => mulN4([], b, 1 / a), + divnv: (a, b) => div4(null, [a, a, a, a], b), divvn: (a, b) => divN4([], a, b), dot: (a, b) => dot4(a, b), exp: (a) => exp4([], a), diff --git a/packages/shader-ast-js/src/runtime.ts b/packages/shader-ast-js/src/runtime.ts index 1acb086b1b..41b51f5c19 100644 --- a/packages/shader-ast-js/src/runtime.ts +++ b/packages/shader-ast-js/src/runtime.ts @@ -1,32 +1,137 @@ -import { Fn } from "@thi.ng/api"; -import { clamp01 } from "@thi.ng/math"; +import { assert, Fn } from "@thi.ng/api"; +import { clamp, clamp01 } from "@thi.ng/math"; +import { ABGR8888, PackedBuffer } from "@thi.ng/pixel"; +import { ReadonlyVec, Vec } from "@thi.ng/vectors"; -export interface RuntimeOpts { - canvas: HTMLCanvasElement; -} -export const initRuntime = (opts: RuntimeOpts) => { - const W = opts.canvas.width; - const H = opts.canvas.height - 1; - const ctx = opts.canvas.getContext("2d")!; - const img = ctx.getImageData(0, 0, W, H); - const u32 = new Uint32Array(img.data.buffer); - return { - update(fn: Fn) { - const frag = []; - for (let y = 0, i = 0; y <= H; y++) { - frag[1] = H - y; - for (let x = 0; x < W; x++) { - frag[0] = x; - u32[i++] = rgba2bgra(fn(frag)); - } - } - ctx.putImageData(img, 0, 0); +const rgba2bgra = (rgba: ReadonlyVec) => + ((clamp01(rgba[0]) * 255.5) << 0) | + ((clamp01(rgba[1]) * 255.5) << 8) | + ((clamp01(rgba[2]) * 255.5) << 16) | + ((clamp01(rgba[3]) * 255.5) << 24); + +const clampCoord = (x: number, maxW: number, w?: number) => + w !== undefined ? Math.min(x + w, maxW) : maxW; + +/** + * Low-level function used by `canvasRenderer()` and `renderToBuffer()`. + * Applies shader function `fn` to each pixel in the given region of the + * `u32` raw ABGR buffer (a `Uint32Array`). The region is defined by the + * top-left `x`, `y` coords and `w`, `h` dimensions. The remaining + * parameters `bufW`, `bufH`, `bufOffsetX`, `bufOffsetY` and `imgH` are + * used to define the actual location of the given buffer in the full + * image to be computed and to support use cases where the target array + * only defines a sub-region of the full image (e.g. when splitting + * rendering over multiple workers, each with their own buffer). + * + * @param fn + * @param u32 + * @param bufW + * @param bufH + * @param x + * @param y + * @param w + * @param h + * @param bufOffsetX + * @param bufOffsetY + * @param imgH + */ +export const renderPixels = ( + fn: Fn, + u32: Uint32Array, + bufW: number, + bufH: number, + x: number, + y: number, + w?: number, + h?: number, + bufOffsetX = 0, + bufOffsetY = 0, + imgH = bufH +) => { + const frag = []; + x = clamp(x, 0, bufW); + y = clamp(y, 0, bufH); + const x2 = clampCoord(x, bufW, w); + const y2 = clampCoord(y, bufH, h); + for (let yy = y; yy < y2; yy++) { + frag[1] = imgH - 1 - yy - bufOffsetY; + let i = yy * bufW + x; + for (let xx = x; xx < x2; xx++) { + frag[0] = xx + bufOffsetX; + u32[i++] = rgba2bgra(fn(frag)); } - }; + } + return u32; }; -const rgba2bgra = (rgba: number[]) => - ((clamp01(rgba[0]) * 0xff) << 0) | - ((clamp01(rgba[1]) * 0xff) << 8) | - ((clamp01(rgba[2]) * 0xff) << 16) | - ((clamp01(rgba[3]) * 0xff) << 24); +/** + * Takes a `PackedBuffer` pixel buffer from thi.ng/pixel w/ `ABGR8888` + * format, an optional buffer local region defined by `x`, `y`, `w`, `h` + * and applies shader function `fn` to each pixel in that region (or + * full buffer by default). + * + * In case the buffer only defines a sub-region of a larger image, + * `bufOffsetX`, `bufOffsetY` and `imgH` can be given to configure the + * location and full image height. + * + * @param fn + * @param buf + * @param x + * @param y + * @param w + * @param h + * @param bufOffsetX + * @param bufOffsetY + * @param imgH + */ +export const renderBuffer = ( + fn: Fn, + buf: PackedBuffer, + x = 0, + y = 0, + w?: number, + h?: number, + bufOffsetX = 0, + bufOffsetY = 0, + imgH = buf.height +) => { + assert(buf.format === ABGR8888, `invalid buffer pixel format`); + renderPixels( + fn, + buf.pixels, + buf.width, + buf.height, + x, + y, + w, + h, + bufOffsetX, + bufOffsetY, + imgH + ); + return buf; +}; + +/** + * Higher order function accepting an `HTMLCanvasElement` and returning + * a render function which accepts the following parameters: + * + * - `fn` - shader function (compiled via `targetJS().compile(ast)`) + * - `x`, `y`, `w`, `h` - optional args to define a sub-region to be + * updated (default to full image update) + * + * @param canvas + */ +export const canvasRenderer = (canvas: HTMLCanvasElement) => { + const buf = PackedBuffer.fromCanvas(canvas); + return ( + fn: Fn, + x = 0, + y = 0, + w = canvas.width, + h = canvas.height + ) => { + renderBuffer(fn, buf, x, y, w, h); + buf.blitCanvas(canvas); + }; +}; diff --git a/packages/shader-ast-js/test/index.ts b/packages/shader-ast-js/test/index.ts index 1f01c2dccb..c1e8c4ec3d 100644 --- a/packages/shader-ast-js/test/index.ts +++ b/packages/shader-ast-js/test/index.ts @@ -1,6 +1,61 @@ -// import * as assert from "assert"; -// import * as saj from "../src/index"; +import { eqDelta2 } from "@thi.ng/vectors"; +import * as assert from "assert"; +import { JS_DEFAULT_ENV } from "../src/"; describe("shader-ast-js", () => { - it("tests pending"); + it("vec2", () => { + const V2 = JS_DEFAULT_ENV.vec2; + assert.deepEqual(V2.abs([-1, 2]), [1, 2]); + assert.deepEqual(V2.acos([0, 1]), [Math.PI / 2, 0]); + assert.deepEqual(V2.add([1, 2], [10, 20]), [11, 22]); + assert.deepEqual(V2.addnv(10, [1, 2]), [11, 12]); + assert.deepEqual(V2.addvn([1, 2], 10), [11, 12]); + assert.deepEqual(V2.asin([0, 1]), [0, Math.PI / 2]); + assert.deepEqual(V2.atan([0, 1]), [0, 0.7853981633974483]); + assert.deepEqual(V2.atannn([0, 1], [1, 0]), [0, Math.PI / 2]); + assert.deepEqual(V2.ceil([-1.8, 1.2]), [-1, 2]); + assert.deepEqual(V2.cos([0, Math.PI]), [1, -1]); + assert.deepEqual(V2.clamp([-1.8, 1.2], [-1, -1], [1, 1]), [-1, 1]); + assert.deepEqual(V2.dec([-1, 1]), [-2, 0]); + assert.deepEqual(V2.degrees([Math.PI / 2, -Math.PI / 4]), [90, -45]); + assert.deepEqual(V2.distance([10, 20], [11, 19]), Math.SQRT2); + assert.deepEqual(V2.div([1, 2], [10, -10]), [0.1, -0.2], "d1"); + assert.deepEqual(V2.divnv(10, [2, 4]), [5, 2.5], "d2"); + assert.deepEqual(V2.divvn([1, 2], 10), [0.1, 0.2], "d3"); + assert.deepEqual(V2.dot([1, 2], [10, 20]), 50); + assert.deepEqual(V2.exp([2, -3]), [Math.exp(2), Math.exp(-3)]); + assert.deepEqual(V2.exp2([2, -3]), [Math.pow(2, 2), Math.pow(2, -3)]); + // assert.deepEqual(V2.faceForward(), []); + assert.deepEqual(V2.floor([-1.2, 1.2]), [-2, 1], "floor"); + assert.ok(eqDelta2(V2.fract([-1.8, 1.8]), [0.2, 0.8]), "fract"); + assert.ok(eqDelta2(V2.inc([-1.2, 1.2]), [-0.2, 2.2]), "inc"); + assert.deepEqual(V2.inversesqrt([4, 9]), [1 / 2, 1 / 3]); + assert.deepEqual(V2.length([100, 100]), 100 * Math.SQRT2); + assert.deepEqual(V2.log([2, 10]), [Math.LN2, Math.LN10]); + assert.deepEqual(V2.log2([4, 32]), [2, 5]); + //assert.deepEqual(V2.max(), []); + //assert.deepEqual(V2.min(), []); + //assert.deepEqual(V2.mix(), []); + //assert.deepEqual(V2.mixn(), []); + //assert.deepEqual(V2.mod(), []); + //assert.deepEqual(V2.modn(), []); + //assert.deepEqual(V2.mul(), []); + //assert.deepEqual(V2.mulnv(), []); + //assert.deepEqual(V2.mulvn(), []); + //assert.deepEqual(V2.normalize(), []); + //assert.deepEqual(V2.pow(), []); + //assert.deepEqual(V2.radians(), []); + //assert.deepEqual(V2.reflect(), []); + //assert.deepEqual(V2.refract(), []); + //assert.deepEqual(V2.sign(), []); + //assert.deepEqual(V2.sin(), []); + //assert.deepEqual(V2.smoothstep(), []); + //assert.deepEqual(V2.sqrt(), []); + //assert.deepEqual(V2.step(), []); + //assert.deepEqual(V2.sub(), []); + //assert.deepEqual(V2.sub1(), []); + //assert.deepEqual(V2.subnv(), []); + //assert.deepEqual(V2.subvn(), []); + //assert.deepEqual(V2.tan(), []); + }); }); diff --git a/packages/shader-ast-stdlib/CHANGELOG.md b/packages/shader-ast-stdlib/CHANGELOG.md index c58b7a9cdc..1d400f91fa 100644 --- a/packages/shader-ast-stdlib/CHANGELOG.md +++ b/packages/shader-ast-stdlib/CHANGELOG.md @@ -3,6 +3,26 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/shader-ast-stdlib@0.2.3...@thi.ng/shader-ast-stdlib@0.3.0) (2019-09-21) + + +### Bug Fixes + +* **shader-ast-stdlib:** fix imports ([188309a](https://github.com/thi-ng/umbrella/commit/188309a)) +* **shader-ast-stdlib:** fix imports ([16823b2](https://github.com/thi-ng/umbrella/commit/16823b2)) + + +### Features + +* **shader-ast-stdlib:** add fragUV() ([b85dc8b](https://github.com/thi-ng/umbrella/commit/b85dc8b)) +* **shader-ast-stdlib:** add guassian blur fns ([759ace7](https://github.com/thi-ng/umbrella/commit/759ace7)) +* **shader-ast-stdlib:** add rotationAroundAxis3/4, matrix conversions ([8a473c1](https://github.com/thi-ng/umbrella/commit/8a473c1)) +* **shader-ast-stdlib:** add snoise3 & curlNoise3 ([a7dc75d](https://github.com/thi-ng/umbrella/commit/a7dc75d)) + + + + + ## [0.2.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/shader-ast-stdlib@0.2.2...@thi.ng/shader-ast-stdlib@0.2.3) (2019-08-21) **Note:** Version bump only for package @thi.ng/shader-ast-stdlib diff --git a/packages/shader-ast-stdlib/package.json b/packages/shader-ast-stdlib/package.json index 5dbef11b48..e15d5e82e2 100644 --- a/packages/shader-ast-stdlib/package.json +++ b/packages/shader-ast-stdlib/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/shader-ast-stdlib", - "version": "0.2.3", + "version": "0.3.0", "description": "Useful functions for GPGPU / shader programming w/ @thi.ng/shader-ast", "module": "./index.js", "main": "./lib/index.js", @@ -33,7 +33,7 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/shader-ast": "^0.3.0" + "@thi.ng/shader-ast": "^0.3.1" }, "keywords": [ "AST", diff --git a/packages/shader-ast-stdlib/src/index.ts b/packages/shader-ast-stdlib/src/index.ts index ad140b0c7b..03e36bc3a6 100644 --- a/packages/shader-ast-stdlib/src/index.ts +++ b/packages/shader-ast-stdlib/src/index.ts @@ -30,9 +30,11 @@ export * from "./matrix/mvp"; export * from "./matrix/normal"; export * from "./matrix/rotation"; +export * from "./noise/curl3"; export * from "./noise/hash"; export * from "./noise/permute"; export * from "./noise/simplex2"; +export * from "./noise/simplex3"; export * from "./noise/voronoi2"; export * from "./noise/worley2"; @@ -60,6 +62,7 @@ export * from "./sdf/torus"; export * from "./sdf/tri"; export * from "./sdf/union"; +export * from "./tex/blur"; export * from "./tex/index-coord"; export * from "./tex/index-uv"; export * from "./tex/read-index"; diff --git a/packages/shader-ast-stdlib/src/matrix/convert.ts b/packages/shader-ast-stdlib/src/matrix/convert.ts new file mode 100644 index 0000000000..02219c07dd --- /dev/null +++ b/packages/shader-ast-stdlib/src/matrix/convert.ts @@ -0,0 +1,28 @@ +import { + defn, + indexMat, + mat3, + mat4, + ret, + vec3, + vec4 +} from "@thi.ng/shader-ast"; + +export const m22ToM33 = defn("mat3", "m22ToM33", ["mat2"], (m) => { + return [ + ret(mat3(vec3(indexMat(m, 0), 0), vec3(indexMat(m, 1), 0), vec3())) + ]; +}); + +export const m33ToM44 = defn("mat4", "m33ToM44", ["mat3"], (m) => { + return [ + ret( + mat4( + vec4(indexMat(m, 0), 0), + vec4(indexMat(m, 1), 0), + vec4(indexMat(m, 2), 0), + vec4() + ) + ) + ]; +}); diff --git a/packages/shader-ast-stdlib/src/matrix/rotation.ts b/packages/shader-ast-stdlib/src/matrix/rotation.ts index e83f5e6138..087ca491d7 100644 --- a/packages/shader-ast-stdlib/src/matrix/rotation.ts +++ b/packages/shader-ast-stdlib/src/matrix/rotation.ts @@ -1,17 +1,27 @@ import { $x, $y, + $z, + add, + cos, defn, + FloatSym, mat2, mat3, mat4, + mul, neg, + NumericF, ret, + sin, + sub, sym, - Vec2Term + Vec2Term, + vec3 } from "@thi.ng/shader-ast"; import { perpendicularCCW } from "../math/orthogonal"; import { cossin } from "../math/sincos"; +import { m33ToM44 } from "./convert"; export const rotation2 = defn("mat2", "rotation2", ["float"], (theta) => { let cs: Vec2Term; @@ -122,3 +132,42 @@ export const rotationZ4 = defn("mat4", "rotationZ4", ["float"], (theta) => { ) ]; }); + +export const rotationAroundAxis3 = defn( + "mat3", + "rotationAroundAxis3", + ["vec3", "float"], + (axis, theta) => { + let s: FloatSym; + let c: FloatSym; + let t: FloatSym; + const $$ = ( + a: NumericF, + b: NumericF, + c: NumericF, + d: NumericF, + e: NumericF, + f: NumericF, + g: NumericF + ) => add(mul(mul(axis, a), t), mul(vec3(b, c, d), vec3(e, f, g))); + return [ + (s = sym(sin(theta))), + (c = sym(cos(theta))), + (t = sym(sub(1, c))), + ret( + mat3( + $$($x(axis), 1, $z(axis), neg($y(axis)), c, s, s), + $$($y(axis), neg($z(axis)), 1, $x(axis), s, c, s), + $$($z(axis), $y(axis), neg($x(axis)), 1, s, s, c) + ) + ) + ]; + } +); + +export const rotationAroundAxis4 = defn( + "mat4", + "rotationAroundAxis4", + ["vec3", "float"], + (axis, theta) => [ret(m33ToM44(rotationAroundAxis3(axis, theta)))] +); diff --git a/packages/shader-ast-stdlib/src/noise/curl3.ts b/packages/shader-ast-stdlib/src/noise/curl3.ts new file mode 100644 index 0000000000..dbf94087bc --- /dev/null +++ b/packages/shader-ast-stdlib/src/noise/curl3.ts @@ -0,0 +1,52 @@ +import { + $, + $x, + $y, + $z, + add, + defn, + div, + mul, + ret, + sub, + sym, + vec2, + Vec2Sym, + vec3, + Vec3Sym +} from "@thi.ng/shader-ast"; +import { snoiseVec3 } from "./simplex3"; + +export const curlNoise3 = defn( + "vec3", + "curlNoise3", + ["vec3", "float"], + (p, e) => { + let D: Vec2Sym; + let px0: Vec3Sym; + let px1: Vec3Sym; + let py0: Vec3Sym; + let py1: Vec3Sym; + let pz0: Vec3Sym; + let pz1: Vec3Sym; + return [ + (D = sym(vec2(e, 0))), + (px0 = sym(snoiseVec3(sub(p, $(D, "xyy"))))), + (px1 = sym(snoiseVec3(add(p, $(D, "xyy"))))), + (py0 = sym(snoiseVec3(sub(p, $(D, "yxy"))))), + (py1 = sym(snoiseVec3(add(p, $(D, "yxy"))))), + (pz0 = sym(snoiseVec3(sub(p, $(D, "yyx"))))), + (pz1 = sym(snoiseVec3(add(p, $(D, "yyx"))))), + ret( + div( + vec3( + add(sub(sub($z(py1), $z(py0)), $y(pz1)), $y(pz0)), + add(sub(sub($x(pz1), $x(pz0)), $z(px1)), $z(px0)), + add(sub(sub($y(px1), $y(px0)), $x(py1)), $x(py0)) + ), + mul(2, e) + ) + ) + ]; + } +); diff --git a/packages/shader-ast-stdlib/src/noise/simplex3.ts b/packages/shader-ast-stdlib/src/noise/simplex3.ts new file mode 100644 index 0000000000..5fd0f2a114 --- /dev/null +++ b/packages/shader-ast-stdlib/src/noise/simplex3.ts @@ -0,0 +1,170 @@ +import { + $, + $w, + $x, + $xy, + $y, + $z, + abs, + add, + assign, + defn, + dot, + float, + FLOAT0, + FLOAT05, + FLOAT1, + FLOAT2, + floor, + max, + min, + mod, + mul, + neg, + ret, + step, + sub, + sym, + vec3, + Vec3Sym, + vec4, + Vec4Sym +} from "@thi.ng/shader-ast"; +import { permute4 } from "./permute"; + +export const snoise3 = defn("float", "snoise3", ["vec3"], (v) => { + let g: Vec3Sym; + let j: Vec4Sym; + let l: Vec3Sym; + let m: Vec4Sym; + let p: Vec4Sym; + let norm: Vec4Sym; + let _x: Vec4Sym; + let x: Vec4Sym; + let y: Vec4Sym; + let h: Vec4Sym; + let sh: Vec4Sym; + let a0: Vec4Sym; + let a1: Vec4Sym; + let b0: Vec4Sym; + let b1: Vec4Sym; + let x0: Vec3Sym; + let x1: Vec3Sym; + let x2: Vec3Sym; + let x3: Vec3Sym; + let p0: Vec3Sym; + let p1: Vec3Sym; + let p2: Vec3Sym; + let p3: Vec3Sym; + let i: Vec3Sym; + let i1: Vec3Sym; + let i2: Vec3Sym; + const NS = 1 / 7; + const NSX = NS * 2; + const NSY = NS * 0.5 - 1; + return [ + (i = sym(floor(add(v, dot(v, vec3(1 / 3)))))), + (x0 = sym(add(sub(v, i), dot(i, vec3(1 / 6))))), + (g = sym(step($(x0, "yzx"), x0))), + (l = sym($(sub(FLOAT1, g), "zxy"))), + (i1 = sym(min(g, l))), + (i2 = sym(max(g, l))), + (x1 = sym(add(sub(x0, i1), 1 / 6))), + (x2 = sym(add(sub(x0, i2), 1 / 3))), + (x3 = sym(sub(x0, FLOAT05))), + assign(i, mod(i, float(289))), + (p = sym( + permute4( + add( + permute4( + add( + permute4( + add(vec4(FLOAT0, $z(i1), $z(i2), FLOAT1), $z(i)) + ), + add(vec4(FLOAT0, $y(i1), $y(i2), FLOAT1), $y(i)) + ) + ), + add(vec4(FLOAT0, $x(i1), $x(i2), FLOAT1), $x(i)) + ) + ) + )), + (j = sym(sub(p, mul(floor(mul(p, NS * NS)), 49)))), + (_x = sym(floor(mul(j, NS)))), + (x = sym(add(mul(_x, NSX), NSY))), + (y = sym(add(mul(floor(sub(j, mul(_x, 7))), NSX), NSY))), + (h = sym(sub(sub(FLOAT1, abs(x)), abs(y)))), + (sh = sym(neg(step(h, vec4())))), + (b0 = sym(vec4($xy(x), $xy(y)))), + (b1 = sym(vec4($(x, "zw"), $(y, "zw")))), + (a0 = sym( + add( + $(b0, "xzyw"), + mul( + $(add(mul(floor(b0), FLOAT2), FLOAT1), "xzyw"), + $(sh, "xxyy") + ) + ) + )), + (a1 = sym( + add( + $(b1, "xzyw"), + mul( + $(add(mul(floor(b1), FLOAT2), FLOAT1), "xzyw"), + $(sh, "zzww") + ) + ) + )), + (p0 = sym(vec3($xy(a0), $x(h)))), + (p1 = sym(vec3($(a0, "zw"), $y(h)))), + (p2 = sym(vec3($xy(a1), $z(h)))), + (p3 = sym(vec3($(a1, "zw"), $w(h)))), + (norm = sym( + sub( + 1.79284291400159, + mul( + vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)), + 0.85373472095314 + ) + ) + )), + assign(p0, mul(p0, $x(norm))), + assign(p1, mul(p1, $y(norm))), + assign(p2, mul(p2, $z(norm))), + assign(p3, mul(p3, $w(norm))), + (m = sym( + max( + vec4(), + sub( + 0.6, + vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)) + ) + ) + )), + assign(m, mul(m, m)), + ret( + mul( + 42, + dot( + mul(m, m), + vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)) + ) + ) + ) + ]; +}); + +export const snoiseVec3 = defn("vec3", "snoiseVec3", ["vec3"], (p) => { + return [ + ret( + vec3( + snoise3(p), + snoise3( + vec3(sub($y(p), 19.1), add($z(p), 33.4), add($x(p), 47.2)) + ), + snoise3( + vec3(add($z(p), 74.2), sub($x(p), 124.5), add($y(p), 99.4)) + ) + ) + ) + ]; +}); diff --git a/packages/shader-ast-stdlib/src/screen/uv.ts b/packages/shader-ast-stdlib/src/screen/uv.ts index 5b119ed8f0..924b96235a 100644 --- a/packages/shader-ast-stdlib/src/screen/uv.ts +++ b/packages/shader-ast-stdlib/src/screen/uv.ts @@ -1,5 +1,6 @@ import { $x, + $xy, $y, assign, defn, @@ -7,10 +8,21 @@ import { mul, ret, sym, - Vec2Sym + Vec2Sym, + Vec2Term, + Vec4Term } from "@thi.ng/shader-ast"; import { fit0111 } from "../math/fit"; +/** + * Computes UV coord in [0..1] interval from given `fragCoord` and screen `res`. + * + * @param fragCoord + * @param res + */ +export const fragUV = (fragCoord: Vec4Term, res: Vec2Term) => + div($xy(fragCoord), res); + /** * Takes `pos`, a screen coord (e.g. gl_FragCoord) and viewport * resolution `res`, returns aspect corrected uv, with uv.y in [-1..1] diff --git a/packages/shader-ast-stdlib/src/tex/blur.ts b/packages/shader-ast-stdlib/src/tex/blur.ts new file mode 100644 index 0000000000..8a0faa3217 --- /dev/null +++ b/packages/shader-ast-stdlib/src/tex/blur.ts @@ -0,0 +1,137 @@ +import { + add, + assign, + defn, + div, + mul, + ret, + Sampler2DSym, + sub, + sym, + texture, + vec2, + Vec2Sym, + Vec4Sym +} from "@thi.ng/shader-ast"; + +/** + * Inline function. Computes single blur step for given +/- offset & + * weight. + * + * @param col + * @param tex + * @param uv + * @param off + * @param k + */ +const singlePass = ( + col: Vec4Sym, + tex: Sampler2DSym, + uv: Vec2Sym, + off: Vec2Sym, + k: number +) => + assign( + col, + add( + col, + mul(add(texture(tex, add(uv, off)), texture(tex, sub(uv, off))), k) + ) + ); + +/** + * 5x5 gaussian blur texture lookup, optimized, but based on: + * + * - http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ + * - https://github.com/Jam3/glsl-fast-gaussian-blur + * + * @param tex sampler2D + * @param res resolution + * @param uv + * @param dir blur pass direction (`vec2(1,0)` or `vec2(0,1)`) + */ +export const blur5 = defn( + "vec4", + "blur5", + ["sampler2D", "vec2", "vec2", "vec2"], + (tex, res, uv, dir) => { + let col: Vec4Sym; + let off: Vec2Sym; + const k1 = 0.29411764705882354; + const k2 = 0.35294117647058826; + return [ + (off = sym(div(mul(vec2(1 + 1 / 3), dir), res))), + (col = sym(mul(texture(tex, uv), k1))), + singlePass(col, tex, uv, off, k2), + ret(col) + ]; + } +); + +/** + * 9x9 gaussian blur texture lookup, optimized, but based on: + * + * - http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ + * - https://github.com/Jam3/glsl-fast-gaussian-blur + * + * @param tex sampler2D + * @param res resolution + * @param uv + * @param dir blur pass direction (`vec2(1,0)` or `vec2(0,1)`) + */ +export const blur9 = defn( + "vec4", + "blur9", + ["sampler2D", "vec2", "vec2", "vec2"], + (tex, res, uv, dir) => { + let col: Vec4Sym; + let off: Vec2Sym; + let off2: Vec2Sym; + const k1 = 0.3162162162; + const k2 = 0.0702702703; + return [ + (off = sym(div(mul(vec2(1.3846153846), dir), res))), + (off2 = sym(div(mul(vec2(3.2307692308), dir), res))), + (col = sym(mul(texture(tex, uv), 0.227027027))), + singlePass(col, tex, uv, off, k1), + singlePass(col, tex, uv, off2, k2), + ret(col) + ]; + } +); + +/** + * 13x13 gaussian blur texture lookup, optimized, but based on: + * + * - http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ + * - https://github.com/Jam3/glsl-fast-gaussian-blur + * + * @param tex sampler2D + * @param res resolution + * @param uv + * @param dir blur pass direction (`vec2(1,0)` or `vec2(0,1)`) + */ +export const blur13 = defn( + "vec4", + "blur13", + ["sampler2D", "vec2", "vec2", "vec2"], + (tex, res, uv, dir) => { + let col: Vec4Sym; + let off: Vec2Sym; + let off2: Vec2Sym; + let off3: Vec2Sym; + const k1 = 0.2969069646728344; + const k2 = 0.09447039785044732; + const k3 = 0.010381362401148057; + return [ + (off = sym(div(mul(vec2(1.411764705882353), dir), res))), + (off2 = sym(div(mul(vec2(3.2941176470588234), dir), res))), + (off3 = sym(div(mul(vec2(5.176470588235294), dir), res))), + (col = sym(mul(texture(tex, uv), 0.1964825501511404))), + singlePass(col, tex, uv, off, k1), + singlePass(col, tex, uv, off2, k2), + singlePass(col, tex, uv, off3, k3), + ret(col) + ]; + } +); diff --git a/packages/shader-ast/CHANGELOG.md b/packages/shader-ast/CHANGELOG.md index c9ce3bbac8..be0e0664ba 100644 --- a/packages/shader-ast/CHANGELOG.md +++ b/packages/shader-ast/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.3.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/shader-ast@0.3.0...@thi.ng/shader-ast@0.3.1) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/shader-ast + + + + + # [0.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/shader-ast@0.2.3...@thi.ng/shader-ast@0.3.0) (2019-08-21) diff --git a/packages/shader-ast/README.md b/packages/shader-ast/README.md index 894b755929..0667eb7b2a 100644 --- a/packages/shader-ast/README.md +++ b/packages/shader-ast/README.md @@ -37,7 +37,7 @@ This project is part of the ## About -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/shader-ast-01.jpg) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/shader-ast/shader-ast-01.jpg) Example shader running in plain JS & Canvas 2D context, cross-compiled JS/GLSL outputs shown on the right @@ -62,13 +62,13 @@ VEX](http://www.sidefx.com/docs/houdini/vex/index.html) (in-progress), [WASM](https://webassembly.org), [WHLSL for WebGPU](https://github.com/gpuweb/WHLSL) in the near future as well. -![webgl/canvas2d comparison](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/shader-ast-raymarch-compare.jpg) +![webgl/canvas2d comparison](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/shader-ast/shader-ast-raymarch-compare.jpg) Comparison of the raymarch shader example (link further below), cross compiled to both GLSL/WebGL and JavaScript w/ Canvas2D API and showing the difference image of both results. -![VEX plane displacement](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/shader-ast-raymarch-vex-sm.gif) +![VEX plane displacement](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/shader-ast/shader-ast-raymarch-vex-sm.gif) The same raymarching example compiled to Houdini VEX and used as "Point Wrangle" to displace a grid geometry (using only the depth value of the diff --git a/packages/shader-ast/package.json b/packages/shader-ast/package.json index 81a63d87c2..d3d20aa2b1 100644 --- a/packages/shader-ast/package.json +++ b/packages/shader-ast/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/shader-ast", - "version": "0.3.0", + "version": "0.3.1", "description": "DSL to define shader code in TypeScript and cross-compile to GLSL, JS and other targets", "module": "./index.js", "main": "./lib/index.js", @@ -33,10 +33,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/defmulti": "^1.1.3", - "@thi.ng/dgraph": "^1.1.14", + "@thi.ng/api": "^6.4.0", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/defmulti": "^1.1.4", + "@thi.ng/dgraph": "^1.1.15", "@thi.ng/errors": "^1.2.0" }, "keywords": [ diff --git a/packages/sparse/CHANGELOG.md b/packages/sparse/CHANGELOG.md index e52f39c7b2..65981fdea0 100644 --- a/packages/sparse/CHANGELOG.md +++ b/packages/sparse/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.21](https://github.com/thi-ng/umbrella/compare/@thi.ng/sparse@0.1.20...@thi.ng/sparse@0.1.21) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/sparse + + + + + ## [0.1.20](https://github.com/thi-ng/umbrella/compare/@thi.ng/sparse@0.1.19...@thi.ng/sparse@0.1.20) (2019-08-21) **Note:** Version bump only for package @thi.ng/sparse diff --git a/packages/sparse/package.json b/packages/sparse/package.json index 1f14a84452..fb7798eddc 100644 --- a/packages/sparse/package.json +++ b/packages/sparse/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/sparse", - "version": "0.1.20", + "version": "0.1.21", "description": "Sparse vector & matrix implementations", "module": "./index.js", "main": "./lib/index.js", @@ -33,8 +33,8 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/api": "^6.4.0", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "adjacency", diff --git a/packages/strings/CHANGELOG.md b/packages/strings/CHANGELOG.md index 8901cefb2d..8b69ff4dc0 100644 --- a/packages/strings/CHANGELOG.md +++ b/packages/strings/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/strings@1.2.3...@thi.ng/strings@1.3.0) (2019-09-21) + + +### Features + +* **strings:** add charRange(), add radix & zero-pad presets ([c9e5a63](https://github.com/thi-ng/umbrella/commit/c9e5a63)) + + + + + ## [1.2.3](https://github.com/thi-ng/umbrella/compare/@thi.ng/strings@1.2.2...@thi.ng/strings@1.2.3) (2019-08-21) **Note:** Version bump only for package @thi.ng/strings diff --git a/packages/strings/package.json b/packages/strings/package.json index 23fb2083a1..e289561830 100644 --- a/packages/strings/package.json +++ b/packages/strings/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/strings", - "version": "1.2.3", + "version": "1.3.0", "description": "Various string formatting & utility functions", "module": "./index.js", "main": "./lib/index.js", @@ -34,7 +34,7 @@ }, "dependencies": { "@thi.ng/errors": "^1.2.0", - "@thi.ng/memoize": "^1.1.3" + "@thi.ng/memoize": "^1.1.4" }, "keywords": [ "composition", diff --git a/packages/strings/src/index.ts b/packages/strings/src/index.ts index b4e8c7bbfa..cf2fef6ed3 100644 --- a/packages/strings/src/index.ts +++ b/packages/strings/src/index.ts @@ -9,6 +9,7 @@ export * from "./pad-right"; export * from "./parse"; export * from "./percent"; export * from "./radix"; +export * from "./range"; export * from "./repeat"; export * from "./slugify"; export * from "./splice"; diff --git a/packages/strings/src/pad-left.ts b/packages/strings/src/pad-left.ts index f3073f7daa..12b35fe938 100644 --- a/packages/strings/src/pad-left.ts +++ b/packages/strings/src/pad-left.ts @@ -20,3 +20,18 @@ export const padLeft: ( ? ((x = x.toString()), x.length < n ? buf.substr(x.length) + x : x) : buf; }); + +/** + * Zero-padded 2 digit formatter. + */ +export const Z2 = padLeft(2, "0"); + +/** + * Zero-padded 3 digit formatter. + */ +export const Z3 = padLeft(3, "0"); + +/** + * Zero-padded 4 digit formatter. + */ +export const Z4 = padLeft(4, "0"); diff --git a/packages/strings/src/radix.ts b/packages/strings/src/radix.ts index c7e7808a5f..6c4f06fa04 100644 --- a/packages/strings/src/radix.ts +++ b/packages/strings/src/radix.ts @@ -29,6 +29,16 @@ export const radix: ( */ export const B8 = radix(2, 8); +/** + * 16bit binary conversion preset. + */ +export const B16 = radix(2, 16); + +/** + * 32bit binary conversion preset. + */ +export const B32 = radix(2, 32); + /** * 8bit hex conversion preset. * Assumes unsigned inputs. diff --git a/packages/strings/src/range.ts b/packages/strings/src/range.ts new file mode 100644 index 0000000000..422e528c07 --- /dev/null +++ b/packages/strings/src/range.ts @@ -0,0 +1,20 @@ +/** + * Yields iterator of characters [`from`..`to`] (inclusive). Uses + * reverse ordering if `to` < `from`. + * + * @param from + * @param to + */ +export function* charRange(from: string | number, to: string | number) { + let i = typeof from === "string" ? from.charCodeAt(0) : from; + const end = typeof to === "string" ? to.charCodeAt(0) : to; + if (i <= end) { + for (; i <= end; i++) { + yield String.fromCharCode(i); + } + } else { + for (; i >= end; i--) { + yield String.fromCharCode(i); + } + } +} diff --git a/packages/transducers-binary/CHANGELOG.md b/packages/transducers-binary/CHANGELOG.md index 356afda23c..8262ac56d6 100644 --- a/packages/transducers-binary/CHANGELOG.md +++ b/packages/transducers-binary/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.4.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-binary@0.4.4...@thi.ng/transducers-binary@0.4.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/transducers-binary + + + + + ## [0.4.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-binary@0.4.3...@thi.ng/transducers-binary@0.4.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/transducers-binary diff --git a/packages/transducers-binary/package.json b/packages/transducers-binary/package.json index dce4cb06a2..60a2f64473 100644 --- a/packages/transducers-binary/package.json +++ b/packages/transducers-binary/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-binary", - "version": "0.4.4", + "version": "0.4.5", "description": "Binary data related transducers & reducers", "module": "./index.js", "main": "./lib/index.js", @@ -33,10 +33,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/compose": "^1.3.3", - "@thi.ng/random": "^1.1.11", - "@thi.ng/strings": "^1.2.3", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/compose": "^1.3.4", + "@thi.ng/random": "^1.1.12", + "@thi.ng/strings": "^1.3.0", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "base64", diff --git a/packages/transducers-fsm/CHANGELOG.md b/packages/transducers-fsm/CHANGELOG.md index 1beb4e3e26..213fbc12e7 100644 --- a/packages/transducers-fsm/CHANGELOG.md +++ b/packages/transducers-fsm/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-fsm@1.1.4...@thi.ng/transducers-fsm@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/transducers-fsm + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-fsm@1.1.3...@thi.ng/transducers-fsm@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/transducers-fsm diff --git a/packages/transducers-fsm/README.md b/packages/transducers-fsm/README.md index 4ef903b81e..f4a6d61eb6 100644 --- a/packages/transducers-fsm/README.md +++ b/packages/transducers-fsm/README.md @@ -50,7 +50,11 @@ state and once entered will cause processing to terminate (also see API description further below). ```ts -const testFSM = fsm.fsm({ +import { fsm } from '@thi.ng/transducers-fsm' +import * as tx from '@thi.ng/transducers' +import { isOdd } from '@thi.ng/checks' + +const testFSM = fsm({ // initial state initializer // (called before processing 1st input) @@ -107,7 +111,7 @@ const testFSM = fsm.fsm({ tx.mapcat((x) => x.split(/[,\s]+/g)), tx.map((x) => parseInt(x)), testFSM, - tx.filter(tx.odd), + tx.filter(isOdd) ), ["9,8,7,6", "14 1 0 17 15 16", "19,23,12,42,4"] ) diff --git a/packages/transducers-fsm/package.json b/packages/transducers-fsm/package.json index 039188dfed..eb4860a065 100644 --- a/packages/transducers-fsm/package.json +++ b/packages/transducers-fsm/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-fsm", - "version": "1.1.4", + "version": "1.1.5", "description": "Transducer-based Finite State Machine transformer", "module": "./index.js", "main": "./lib/index.js", @@ -33,8 +33,8 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/api": "^6.4.0", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "ES6", diff --git a/packages/transducers-hdom/CHANGELOG.md b/packages/transducers-hdom/CHANGELOG.md index e712b93905..6397a2bf13 100644 --- a/packages/transducers-hdom/CHANGELOG.md +++ b/packages/transducers-hdom/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.0.29](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-hdom@2.0.28...@thi.ng/transducers-hdom@2.0.29) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/transducers-hdom + + + + + ## [2.0.28](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-hdom@2.0.27...@thi.ng/transducers-hdom@2.0.28) (2019-08-21) **Note:** Version bump only for package @thi.ng/transducers-hdom diff --git a/packages/transducers-hdom/package.json b/packages/transducers-hdom/package.json index c2a0f5cacb..b070800c36 100644 --- a/packages/transducers-hdom/package.json +++ b/packages/transducers-hdom/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-hdom", - "version": "2.0.28", + "version": "2.0.29", "description": "Transducer based UI updater for @thi.ng/hdom", "module": "./index.js", "main": "./lib/index.js", @@ -33,9 +33,9 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/hdom": "^8.0.4", - "@thi.ng/hiccup": "^3.2.4", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/hdom": "^8.0.5", + "@thi.ng/hiccup": "^3.2.5", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "diff", diff --git a/packages/transducers-stats/CHANGELOG.md b/packages/transducers-stats/CHANGELOG.md index ab95c3b9f0..4c7ec1ff7d 100644 --- a/packages/transducers-stats/CHANGELOG.md +++ b/packages/transducers-stats/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.1.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-stats@1.1.4...@thi.ng/transducers-stats@1.1.5) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/transducers-stats + + + + + ## [1.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers-stats@1.1.3...@thi.ng/transducers-stats@1.1.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/transducers-stats diff --git a/packages/transducers-stats/README.md b/packages/transducers-stats/README.md index c2428a49e7..73ef611d41 100644 --- a/packages/transducers-stats/README.md +++ b/packages/transducers-stats/README.md @@ -68,7 +68,7 @@ For some realworld use, please see the [crypto chart](https://github.com/thi-ng/umbrella/tree/master/examples/crypto-chart) example. -![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/master/assets/screenshots/crypto-chart.png) +![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/crypto-chart.png) ```ts import * as tx from "@thi.ng/transducers"; diff --git a/packages/transducers-stats/package.json b/packages/transducers-stats/package.json index bd961ffcf9..e7f895e665 100644 --- a/packages/transducers-stats/package.json +++ b/packages/transducers-stats/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers-stats", - "version": "1.1.4", + "version": "1.1.5", "description": "Transducers for statistical / technical analysis", "module": "./index.js", "main": "./lib/index.js", @@ -33,10 +33,10 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/checks": "^2.3.0", - "@thi.ng/dcons": "^2.1.4", + "@thi.ng/checks": "^2.4.0", + "@thi.ng/dcons": "^2.1.5", "@thi.ng/errors": "^1.2.0", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "ES6", diff --git a/packages/transducers/CHANGELOG.md b/packages/transducers/CHANGELOG.md index bab2b881f3..a943c8a0f3 100644 --- a/packages/transducers/CHANGELOG.md +++ b/packages/transducers/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [5.4.5](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers@5.4.4...@thi.ng/transducers@5.4.5) (2019-09-21) + + +### Bug Fixes + +* **transducers:** fix mean() for reduce w/ init value ([d993bf2](https://github.com/thi-ng/umbrella/commit/d993bf2)) + + + + + ## [5.4.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/transducers@5.4.3...@thi.ng/transducers@5.4.4) (2019-08-21) **Note:** Version bump only for package @thi.ng/transducers diff --git a/packages/transducers/package.json b/packages/transducers/package.json index 46d0c12737..4509df0844 100644 --- a/packages/transducers/package.json +++ b/packages/transducers/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/transducers", - "version": "5.4.4", + "version": "5.4.5", "description": "Lightweight transducer implementations for ES6 / TypeScript", "module": "./index.js", "main": "./lib/index.js", @@ -33,15 +33,15 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/arrays": "^0.2.4", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/arrays": "^0.2.5", + "@thi.ng/checks": "^2.4.0", "@thi.ng/compare": "^1.0.9", - "@thi.ng/compose": "^1.3.3", + "@thi.ng/compose": "^1.3.4", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/random": "^1.1.11", - "@thi.ng/strings": "^1.2.3" + "@thi.ng/random": "^1.1.12", + "@thi.ng/strings": "^1.3.0" }, "keywords": [ "array", diff --git a/packages/transducers/src/rfn/mean.ts b/packages/transducers/src/rfn/mean.ts index ac8e58ee14..7022083d84 100644 --- a/packages/transducers/src/rfn/mean.ts +++ b/packages/transducers/src/rfn/mean.ts @@ -8,11 +8,11 @@ import { reduce } from "../reduce"; export function mean(): Reducer; export function mean(xs: Iterable): number; export function mean(xs?: Iterable): any { - let n = 0; + let n = 1; return xs ? reduce(mean(), xs) : >[ - () => 0, + () => (n = 0), (acc) => (n > 1 ? acc / n : acc), (acc, x) => (n++, acc + x) ]; diff --git a/packages/vector-pools/CHANGELOG.md b/packages/vector-pools/CHANGELOG.md index da20cd441e..1b8280546d 100644 --- a/packages/vector-pools/CHANGELOG.md +++ b/packages/vector-pools/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.0.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/vector-pools@1.0.7...@thi.ng/vector-pools@1.0.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/vector-pools + + + + + ## [1.0.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/vector-pools@1.0.6...@thi.ng/vector-pools@1.0.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/vector-pools diff --git a/packages/vector-pools/package.json b/packages/vector-pools/package.json index e31c0de650..b10b1a2305 100644 --- a/packages/vector-pools/package.json +++ b/packages/vector-pools/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/vector-pools", - "version": "1.0.7", + "version": "1.0.8", "description": "Data structures for managing & working with strided, memory mapped vectors", "module": "./index.js", "main": "./lib/index.js", @@ -33,12 +33,12 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/binary": "^1.1.0", - "@thi.ng/checks": "^2.3.0", - "@thi.ng/malloc": "^4.0.4", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/checks": "^2.4.0", + "@thi.ng/malloc": "^4.0.5", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "ES6", diff --git a/packages/vectors/CHANGELOG.md b/packages/vectors/CHANGELOG.md index 3faa28b15a..ebdb12c97c 100644 --- a/packages/vectors/CHANGELOG.md +++ b/packages/vectors/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.3.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/vectors@3.3.0...@thi.ng/vectors@3.3.1) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/vectors + + + + + # [3.3.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/vectors@3.2.0...@thi.ng/vectors@3.3.0) (2019-08-21) diff --git a/packages/vectors/package.json b/packages/vectors/package.json index b8a234bf2a..3a64486e42 100644 --- a/packages/vectors/package.json +++ b/packages/vectors/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/vectors", - "version": "3.3.0", + "version": "3.3.1", "description": "Optimized 2d/3d/4d and arbitrary length vector operations", "module": "./index.js", "main": "./lib/index.js", @@ -33,15 +33,15 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", + "@thi.ng/api": "^6.4.0", "@thi.ng/binary": "^1.1.0", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", "@thi.ng/math": "^1.4.2", - "@thi.ng/memoize": "^1.1.3", - "@thi.ng/random": "^1.1.11", - "@thi.ng/transducers": "^5.4.4" + "@thi.ng/memoize": "^1.1.4", + "@thi.ng/random": "^1.1.12", + "@thi.ng/transducers": "^5.4.5" }, "keywords": [ "2D", diff --git a/packages/webgl-msdf/CHANGELOG.md b/packages/webgl-msdf/CHANGELOG.md index 09ce8c530c..d83b7e5fc2 100644 --- a/packages/webgl-msdf/CHANGELOG.md +++ b/packages/webgl-msdf/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.8](https://github.com/thi-ng/umbrella/compare/@thi.ng/webgl-msdf@0.1.7...@thi.ng/webgl-msdf@0.1.8) (2019-09-21) + +**Note:** Version bump only for package @thi.ng/webgl-msdf + + + + + ## [0.1.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/webgl-msdf@0.1.6...@thi.ng/webgl-msdf@0.1.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/webgl-msdf diff --git a/packages/webgl-msdf/package.json b/packages/webgl-msdf/package.json index ce965e4d01..bc4e93ee39 100644 --- a/packages/webgl-msdf/package.json +++ b/packages/webgl-msdf/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/webgl-msdf", - "version": "0.1.7", + "version": "0.1.8", "description": "TODO", "module": "./index.js", "main": "./lib/index.js", @@ -33,12 +33,12 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/shader-ast": "^0.3.0", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vector-pools": "^1.0.7", - "@thi.ng/vectors": "^3.3.0", - "@thi.ng/webgl": "^0.1.7" + "@thi.ng/api": "^6.4.0", + "@thi.ng/shader-ast": "^0.3.1", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vector-pools": "^1.0.8", + "@thi.ng/vectors": "^3.3.1", + "@thi.ng/webgl": "^0.2.0" }, "keywords": [ "ES6", diff --git a/packages/webgl-msdf/src/shader.ts b/packages/webgl-msdf/src/shader.ts index 5ef47ed058..22b22b21f2 100644 --- a/packages/webgl-msdf/src/shader.ts +++ b/packages/webgl-msdf/src/shader.ts @@ -1,6 +1,6 @@ import { - $, $x, + $xyz, $y, $z, add, @@ -30,7 +30,7 @@ import { vec4 } from "@thi.ng/shader-ast"; import { ONE4, ZERO4 } from "@thi.ng/vectors"; -import { DEFAULT_BLEND, GLVec4, ShaderSpec } from "@thi.ng/webgl"; +import { BLEND_NORMAL, GLVec4, ShaderSpec } from "@thi.ng/webgl"; export interface MSDFShaderOpts { color: boolean; @@ -48,7 +48,7 @@ export const msdfSample = defn( let sd: FloatSym; let w: FloatSym; return [ - (sd = sym(sub(median3($(texture(tex, uv), "xyz")), FLOAT05))), + (sd = sym(sub(median3($xyz(texture(tex, uv))), FLOAT05))), (w = sym(clamp(add(div(sd, fwidth(sd)), FLOAT05), FLOAT0, FLOAT1))), ret(vec2(sd, w)) ]; @@ -101,6 +101,6 @@ export const msdfShader = (opts: Partial = {}): ShaderSpec => ({ }, state: { blend: true, - blendFn: DEFAULT_BLEND + blendFn: BLEND_NORMAL } }); diff --git a/packages/webgl-shadertoy/.npmignore b/packages/webgl-shadertoy/.npmignore new file mode 100644 index 0000000000..74ea62d1fa --- /dev/null +++ b/packages/webgl-shadertoy/.npmignore @@ -0,0 +1,12 @@ +.meta +.nyc_output +*.html +*.tgz +build +coverage +dev +doc +export +src* +test +tsconfig.json diff --git a/packages/webgl-shadertoy/CHANGELOG.md b/packages/webgl-shadertoy/CHANGELOG.md new file mode 100644 index 0000000000..fc0127758f --- /dev/null +++ b/packages/webgl-shadertoy/CHANGELOG.md @@ -0,0 +1,22 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2019-09-21) + + +### Bug Fixes + +* **webgl-shadertoy:** update imports ([7d6ed77](https://github.com/thi-ng/umbrella/commit/7d6ed77)) +* **webgl-shadertoy:** update texture/sampler & FBO handling ([25845e5](https://github.com/thi-ng/umbrella/commit/25845e5)) + + +### Features + +* **webgl-shadertoy:** add optional per-pass ModelSpec & vert shader support ([a45725a](https://github.com/thi-ng/umbrella/commit/a45725a)) +* **webgl-shadertoy:** fix & update drawPass viewport, add update() method ([5d2c17e](https://github.com/thi-ng/umbrella/commit/5d2c17e)) +* **webgl-shadertoy:** import new pkg ([35d9b68](https://github.com/thi-ng/umbrella/commit/35d9b68)) +* **webgl-shadertoy:** initial multipass skeleton ([c287dab](https://github.com/thi-ng/umbrella/commit/c287dab)) +* **webgl-shadertoy:** simplify mainImage user fn handling, update types & readme ([bd1b88e](https://github.com/thi-ng/umbrella/commit/bd1b88e)) +* **webgl-shadertoy:** update multipass uniform handling ([2071133](https://github.com/thi-ng/umbrella/commit/2071133)) diff --git a/packages/webgl-shadertoy/LICENSE b/packages/webgl-shadertoy/LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/packages/webgl-shadertoy/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/webgl-shadertoy/README.md b/packages/webgl-shadertoy/README.md new file mode 100644 index 0000000000..20bcc7e571 --- /dev/null +++ b/packages/webgl-shadertoy/README.md @@ -0,0 +1,75 @@ +# @thi.ng/webgl-shadertoy + +[![npm (scoped)](https://img.shields.io/npm/v/@thi.ng/webgl-shadertoy.svg)](https://www.npmjs.com/package/@thi.ng/webgl-shadertoy) +![npm downloads](https://img.shields.io/npm/dm/@thi.ng/webgl-shadertoy.svg) +[![Twitter Follow](https://img.shields.io/twitter/follow/thing_umbrella.svg?style=flat-square&label=twitter)](https://twitter.com/thing_umbrella) + +This project is part of the +[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo. + + + +- [About](#about) +- [Status](#status) +- [Installation](#installation) +- [Dependencies](#dependencies) +- [Usage examples](#usage-examples) +- [Authors](#authors) +- [License](#license) + + + +## About + +Basic WebGL scaffolding for running interactive fragment shaders defined +via +[@thi.ng/shader-ast](https://github.com/thi-ng/umbrella/tree/master/packages/shader-ast). + +## Status + +ALPHA - multi-pass support forthcoming + +## Installation + +```bash +yarn add @thi.ng/webgl-shadertoy +``` + +## Dependencies + +- [@thi.ng/shader-ast](https://github.com/thi-ng/umbrella/tree/master/packages/shader-ast) +- [@thi.ng/webgl](https://github.com/thi-ng/umbrella/tree/master/packages/webgl) + +## Usage examples + +```ts +import { glCanvas } from "@thi.ng/webgl"; +import { shaderToy } from "@thi.ng/webgl-shadertoy"; +import { assign, div, mul, ret, vec4 } from "@thi.ng/shader-ast"; + +const canvas = glCanvas({ + width: 600, + height: 600, + parent: document.body, + version: 2 +}); + +const toy = shaderToy({ + canvas: canvas.canvas + gl: canvas.gl, + main: (gl, unis) => [ + assign(unis.mouse, div(unis.mouse, unis.res)), + ret(vec4(mul(mouse, div(gl.gl_FragCoord, res)), 0, 1)) + ] +}); + +toy.start(); +``` + +## Authors + +- Karsten Schmidt + +## License + +© 2018 Karsten Schmidt // Apache Software License 2.0 diff --git a/packages/webgl-shadertoy/package.json b/packages/webgl-shadertoy/package.json new file mode 100644 index 0000000000..4570a9bd8c --- /dev/null +++ b/packages/webgl-shadertoy/package.json @@ -0,0 +1,56 @@ +{ + "name": "@thi.ng/webgl-shadertoy", + "version": "0.1.0", + "description": "Basic WebGL scaffolding for running interactive fragment shaders", + "module": "./index.js", + "main": "./lib/index.js", + "umd:main": "./lib/index.umd.js", + "typings": "./index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/thi-ng/umbrella.git" + }, + "homepage": "https://github.com/thi-ng/umbrella/tree/master/packages/webgl", + "author": "Karsten Schmidt ", + "license": "Apache-2.0", + "scripts": { + "build": "yarn clean && yarn build:es6 && node ../../scripts/bundle-module", + "build:release": "yarn clean && yarn build:es6 && node ../../scripts/bundle-module all", + "build:es6": "tsc --declaration", + "build:test": "rimraf build && tsc -p test/tsconfig.json", + "test": "yarn build:test && mocha build/test/*.js", + "cover": "yarn build:test && nyc mocha build/test/*.js && nyc report --reporter=lcov", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib", + "doc": "node_modules/.bin/typedoc --mode modules --out doc src", + "pub": "yarn build && yarn publish --access public" + }, + "devDependencies": { + "@types/mocha": "^5.2.6", + "@types/node": "^12.6.3", + "mocha": "^6.1.4", + "nyc": "^14.0.0", + "typedoc": "^0.14.2", + "typescript": "^3.5.3" + }, + "dependencies": { + "@thi.ng/api": "^6.4.0", + "@thi.ng/shader-ast": "^0.3.1", + "@thi.ng/shader-ast-glsl": "^0.1.7", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/webgl": "^0.2.0" + }, + "keywords": [ + "ES6", + "graphics", + "shader-ast", + "shadertoy", + "texture", + "typescript", + "webgl", + "webgl2" + ], + "publishConfig": { + "access": "public" + }, + "sideEffects": false +} diff --git a/packages/webgl-shadertoy/src/api.ts b/packages/webgl-shadertoy/src/api.ts new file mode 100644 index 0000000000..3a151d5e00 --- /dev/null +++ b/packages/webgl-shadertoy/src/api.ts @@ -0,0 +1,43 @@ +import { Fn2 } from "@thi.ng/api"; +import { + FloatSym, + IntSym, + ScopeBody, + Vec2Sym +} from "@thi.ng/shader-ast"; +import { GLSLTarget } from "@thi.ng/shader-ast-glsl"; +import { ITexture, ModelSpec, ShaderUniformSpecs } from "@thi.ng/webgl"; + +export type MainImageFn = Fn2; + +export interface ShaderToyUniforms { + resolution: Vec2Sym; + mouse: Vec2Sym; + mouseButtons: IntSym; + time: FloatSym; +} + +export interface ShaderToyOpts { + canvas: HTMLCanvasElement; + gl: WebGLRenderingContext; + /** + * Main user shader function + */ + main: MainImageFn; + /** + * Optional additional uniforms + */ + uniforms?: ShaderUniformSpecs; + /** + * Optional textures to bind + */ + textures?: ITexture[]; +} + +export interface ShaderToy { + start(): void; + stop(): void; + update(time?: number): void; + recompile(main: MainImageFn): void; + model: ModelSpec; +} diff --git a/packages/webgl-shadertoy/src/index.ts b/packages/webgl-shadertoy/src/index.ts new file mode 100644 index 0000000000..cd686c7701 --- /dev/null +++ b/packages/webgl-shadertoy/src/index.ts @@ -0,0 +1,2 @@ +export * from "./api"; +export * from "./shadertoy"; diff --git a/packages/webgl-shadertoy/src/shadertoy.ts b/packages/webgl-shadertoy/src/shadertoy.ts new file mode 100644 index 0000000000..beaa24d27e --- /dev/null +++ b/packages/webgl-shadertoy/src/shadertoy.ts @@ -0,0 +1,108 @@ +import { + assign, + defMain, + defn, + FLOAT0, + FLOAT1, + vec4 +} from "@thi.ng/shader-ast"; +import { + compileModel, + draw, + quad, + shader +} from "@thi.ng/webgl"; +import { MainImageFn, ShaderToy, ShaderToyOpts } from "./api"; + +export const shaderToy = (opts: ShaderToyOpts) => { + const gl = opts.gl; + + const model = quad(false); + model.textures = opts.textures || []; + compileModel(gl, model); + + opts.canvas.addEventListener("mousemove", (e) => { + const rect = opts.canvas.getBoundingClientRect(); + const dpr = window.devicePixelRatio; + model.uniforms!.mouse = [ + (e.clientX - rect.left) * dpr, + (rect.height - (e.clientY - rect.top)) * dpr + ]; + }); + opts.canvas.addEventListener("mousedown", (e) => { + model.uniforms!.mouseButtons = e.buttons; + }); + opts.canvas.addEventListener("mouseup", (e) => { + model.uniforms!.mouseButtons = e.buttons; + }); + + let active: boolean; + let t0: number; + + const update = (time: number) => { + const w = gl.drawingBufferWidth; + const h = gl.drawingBufferHeight; + model.uniforms!.time = time; + model.uniforms!.resolution = [w, h]; + + gl.viewport(0, 0, w, h); + draw(model); + }; + + const updateRAF = () => { + update((Date.now() - t0) * 1e-3); + active && requestAnimationFrame(updateRAF); + }; + + const instance: ShaderToy = { + start() { + t0 = Date.now(); + active = true; + requestAnimationFrame(updateRAF); + }, + stop() { + active = false; + }, + update(time: number) { + update(time); + }, + recompile(main: MainImageFn) { + if (model.shader) { + model.shader.release(); + } + model.shader = shader(gl, { + vs: (gl, _, ins) => [ + defMain(() => [ + assign( + gl.gl_Position, + vec4(ins.position, FLOAT0, FLOAT1) + ) + ]) + ], + fs: (gl, unis, _, outputs) => [ + defMain(() => [ + assign( + outputs.fragColor, + defn("vec4", "mainImage", [], () => + main(gl, unis) + )() + ) + ]) + ], + attribs: { + position: "vec2" + }, + uniforms: { + resolution: "vec2", + mouse: ["vec2", [0, 0]], + mouseButtons: ["int", 0], + time: "float", + ...opts.uniforms + } + }); + }, + model + }; + instance.recompile(opts.main); + return instance; +}; diff --git a/packages/webgl-shadertoy/test/index.ts b/packages/webgl-shadertoy/test/index.ts new file mode 100644 index 0000000000..294a59348c --- /dev/null +++ b/packages/webgl-shadertoy/test/index.ts @@ -0,0 +1,6 @@ +// import * as assert from "assert"; +// import * as ws from "../src/index"; + +describe("webgl-shadertoy", () => { + it("tests pending"); +}); diff --git a/packages/webgl-shadertoy/test/tsconfig.json b/packages/webgl-shadertoy/test/tsconfig.json new file mode 100644 index 0000000000..f6e63560dd --- /dev/null +++ b/packages/webgl-shadertoy/test/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../build", + "module": "commonjs" + }, + "include": [ + "./**/*.ts", + "../src/**/*.ts" + ] +} diff --git a/packages/webgl-shadertoy/tsconfig.json b/packages/webgl-shadertoy/tsconfig.json new file mode 100644 index 0000000000..893b9979c5 --- /dev/null +++ b/packages/webgl-shadertoy/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": ".", + "module": "es6", + "target": "es6" + }, + "include": [ + "./src/**/*.ts" + ] +} diff --git a/packages/webgl/CHANGELOG.md b/packages/webgl/CHANGELOG.md index 084f2601e0..69c3441f3d 100644 --- a/packages/webgl/CHANGELOG.md +++ b/packages/webgl/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.2.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/webgl@0.1.7...@thi.ng/webgl@0.2.0) (2019-09-21) + + +### Bug Fixes + +* **webgl:** update extension handling in shader(), add ExtensionInfo ([12abaa0](https://github.com/thi-ng/umbrella/commit/12abaa0)) +* **webgl:** update samplerXX[] uniform decl types ([48b8906](https://github.com/thi-ng/umbrella/commit/48b8906)) + + +### Features + +* **webgl:** add blending & stencil enums/types ([c8898a0](https://github.com/thi-ng/umbrella/commit/c8898a0)) +* **webgl:** add initial coll of blend mode presets ([58e0b04](https://github.com/thi-ng/umbrella/commit/58e0b04)) +* **webgl:** add readPixels/readTexture(), add ReadableTextureFormat ([355f785](https://github.com/thi-ng/umbrella/commit/355f785)) +* **webgl:** add renderExt to TextureFormatDecl, add FBO tex fmt checks ([180e89c](https://github.com/thi-ng/umbrella/commit/180e89c)) +* **webgl:** migrate multipass() & types from webgl-shadertoy pkg, reorg ([2aa31ce](https://github.com/thi-ng/umbrella/commit/2aa31ce)) +* **webgl:** update multipass / PassOpts ([95aba16](https://github.com/thi-ng/umbrella/commit/95aba16)) +* **webgl:** update texture config, split api.ts into mult files ([052552f](https://github.com/thi-ng/umbrella/commit/052552f)) +* **webgl:** update Texture.configure, store target, format, type, size ([9131310](https://github.com/thi-ng/umbrella/commit/9131310)) + + + + + ## [0.1.7](https://github.com/thi-ng/umbrella/compare/@thi.ng/webgl@0.1.6...@thi.ng/webgl@0.1.7) (2019-08-21) **Note:** Version bump only for package @thi.ng/webgl diff --git a/packages/webgl/README.md b/packages/webgl/README.md index 2f181ba81c..48cbdf60a4 100644 --- a/packages/webgl/README.md +++ b/packages/webgl/README.md @@ -41,12 +41,13 @@ updated from Clojure/ClojureScript versions of - customizable shader presets - Declarative geometry, attribute & index buffer specs - Declarative instancing (always available in WebGL2, or via ANGLE ext in WebGL1) - - also supported by bundled shader presets -- Texture wrapper & declarative config +- Texture wrapper, declarative config +- Comprehensive texture format info (channels, strides, renderable, filterable etc.) - FBO support with multiple attachments & render buffers -- GPGPU job utilities +- Multi-pass shader pipeline (e.g. for GPGPU tasks) +- Pixel reading from main color buffer and textures - Geometry & texture generators -- WebGL extension helpers +- WebGL extension helpers & semi-automatic extension enabling - WebGL canvas creation / setup Status: Alpha / WIP @@ -76,6 +77,7 @@ yarn add @thi.ng/webgl - [@thi.ng/shader-ast-stdlib](https://github.com/thi-ng/umbrella/tree/master/packages/shader-ast-stdlib) (also see readme for reference) - [@thi.ng/webgl-msdf](https://github.com/thi-ng/umbrella/tree/master/packages/webgl-msdf) +- [@thi.ng/webgl-shadertoy](https://github.com/thi-ng/umbrella/tree/master/packages/webgl-shadertoy) ## Usage examples @@ -88,8 +90,9 @@ folder of this repo... - [Textured tunnel](https://github.com/thi-ng/umbrella/tree/master/examples/shader-ast-tunnel) - [Cubemap](https://github.com/thi-ng/umbrella/tree/master/examples/webgl-cubemap) - [Grid instancing](https://github.com/thi-ng/umbrella/tree/master/examples/webgl-grid) -- [GPGPU basics](https://github.com/thi-ng/umbrella/tree/master/examples/webgl-gpgpu-basics) +- [Multipass / GPGPU](https://github.com/thi-ng/umbrella/tree/master/examples/webgl-multipass) - [MSDF font rendering](https://github.com/thi-ng/umbrella/tree/master/examples/webgl-msdf) +- [Minimal shadertoy](https://github.com/thi-ng/umbrella/tree/master/examples/webgl-shadertoy) - [SSAO deferred rendering](https://github.com/thi-ng/umbrella/tree/master/examples/webgl-ssao) ## Authors diff --git a/packages/webgl/package.json b/packages/webgl/package.json index 49a5a18fcf..92e1274d3a 100644 --- a/packages/webgl/package.json +++ b/packages/webgl/package.json @@ -1,6 +1,6 @@ { "name": "@thi.ng/webgl", - "version": "0.1.7", + "version": "0.2.0", "description": "WebGL abstraction layer", "module": "./index.js", "main": "./lib/index.js", @@ -20,7 +20,7 @@ "build:test": "rimraf build && tsc -p test/tsconfig.json", "test": "yarn build:test && mocha build/test/*.js", "cover": "yarn build:test && nyc mocha build/test/*.js && nyc report --reporter=lcov", - "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib geo shaders textures", + "clean": "rimraf *.js *.d.ts .nyc_output build coverage doc lib api geo shaders textures", "doc": "node_modules/.bin/typedoc --mode modules --out doc --ignoreCompilerErrors src", "pub": "yarn build:release && yarn publish --access public" }, @@ -33,20 +33,20 @@ "typescript": "^3.5.3" }, "dependencies": { - "@thi.ng/api": "^6.3.3", - "@thi.ng/associative": "^3.0.0", + "@thi.ng/api": "^6.4.0", + "@thi.ng/associative": "^3.0.1", "@thi.ng/binary": "^1.1.0", - "@thi.ng/checks": "^2.3.0", + "@thi.ng/checks": "^2.4.0", "@thi.ng/equiv": "^1.0.9", "@thi.ng/errors": "^1.2.0", - "@thi.ng/matrices": "^0.5.7", - "@thi.ng/pixel": "^0.1.3", - "@thi.ng/shader-ast": "^0.3.0", - "@thi.ng/shader-ast-glsl": "^0.1.6", - "@thi.ng/shader-ast-stdlib": "^0.2.3", - "@thi.ng/transducers": "^5.4.4", - "@thi.ng/vector-pools": "^1.0.7", - "@thi.ng/vectors": "^3.3.0" + "@thi.ng/matrices": "^0.5.8", + "@thi.ng/pixel": "^0.1.4", + "@thi.ng/shader-ast": "^0.3.1", + "@thi.ng/shader-ast-glsl": "^0.1.7", + "@thi.ng/shader-ast-stdlib": "^0.3.0", + "@thi.ng/transducers": "^5.4.5", + "@thi.ng/vector-pools": "^1.0.8", + "@thi.ng/vectors": "^3.3.1" }, "keywords": [ "declarative", diff --git a/packages/webgl/src/api.ts b/packages/webgl/src/api.ts deleted file mode 100644 index 57de6c98b7..0000000000 --- a/packages/webgl/src/api.ts +++ /dev/null @@ -1,1153 +0,0 @@ -import { - Fn, - Fn2, - Fn3, - Fn4, - IBind, - IDeref, - IObjectOf, - IRelease, - Tuple, - TypedArray -} from "@thi.ng/api"; -import { Func, Sym, Type } from "@thi.ng/shader-ast"; -import { GLSLTarget } from "@thi.ng/shader-ast-glsl"; -import { AttribPool } from "@thi.ng/vector-pools"; -import { ReadonlyVec } from "@thi.ng/vectors"; - -export const enum TextureFormat { - ALPHA = 0x1906, - DEPTH_COMPONENT = 0x1902, - DEPTH_COMPONENT16 = 0x81a5, - DEPTH_COMPONENT24 = 0x81a6, - DEPTH_COMPONENT32F = 0x8cac, - DEPTH_STENCIL = 0x84f9, - DEPTH24_STENCIL8 = 0x88f0, - DEPTH32F_STENCIL8 = 0x8cad, - LUMINANCE = 0x1909, - LUMINANCE_ALPHA = 0x190a, - R11F_G11F_B10F = 0x8c3a, - R16F = 0x822d, - R16I = 0x8233, - R16UI = 0x8234, - R32F = 0x822e, - R32I = 0x8235, - R32UI = 0x8236, - R8 = 0x8229, - R8_SNORM = 0x8f94, - R8I = 0x8231, - R8UI = 0x8232, - RED = 0x1903, - RED_INTEGER = 0x8d94, - RG = 0x8227, - RG_INTEGER = 0x8228, - RG16F = 0x822f, - RG16I = 0x8239, - RG16UI = 0x823a, - RG32F = 0x8230, - RG32I = 0x823b, - RG32UI = 0x823c, - RG8 = 0x822b, - RG8_SNORM = 0x8f95, - RG8I = 0x8237, - RG8UI = 0x8238, - RGB = 0x1907, - RGB_INTEGER = 0x8d98, - RGB10_A2 = 0x8059, - RGB10_A2UI = 0x906f, - RGB16F = 0x881b, - RGB16I = 0x8d89, - RGB16UI = 0x8d77, - RGB32F = 0x8815, - RGB32I = 0x8d83, - RGB32UI = 0x8d71, - RGB5_A1 = 0x8057, - RGB565 = 0x8d62, - RGB8 = 0x8051, - RGB8_SNORM = 0x8f96, - RGB8I = 0x8d8f, - RGB8UI = 0x8d7d, - RGB9_E5 = 0x8c3d, - RGBA = 0x1908, - RGBA_INTEGER = 0x8d99, - RGBA16F = 0x881a, - RGBA16I = 0x8d88, - RGBA16UI = 0x8d76, - RGBA32F = 0x8814, - RGBA32I = 0x8d82, - RGBA32UI = 0x8d70, - RGBA4 = 0x8056, - RGBA8 = 0x8058, - RGBA8_SNORM = 0x8f97, - RGBA8I = 0x8d8e, - RGBA8UI = 0x8d7c, - SRGB8 = 0x8c41, - SRGB8_ALPHA8 = 0x8c43 -} - -export const enum TextureType { - BYTE = 0x1400, - UNSIGNED_BYTE, - SHORT, - UNSIGNED_SHORT, - INT, - UNSIGNED_INT, - FLOAT, - HALF_FLOAT = 0x140b, - UNSIGNED_SHORT_4_4_4_4 = 0x8033, - UNSIGNED_SHORT_5_5_5_1 = 0x8034, - UNSIGNED_SHORT_5_6_5 = 0x8363, - UNSIGNED_INT_2_10_10_10_REV = 0x8368, - UNSIGNED_INT_24_8 = 0x84fa, - UNSIGNED_INT_10F_11F_11F_REV = 0x8c3b, - UNSIGNED_INT_5_9_9_9_REV = 0x8c3e, - HALF_FLOAT_OES = 0x8d61, - FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8dad -} - -export interface TextureFormatDecl { - /** - * Base format - */ - format: TextureFormat; - /** - * Acceptable types and their byte sizes - */ - types: { [id: number]: number }; - /** - * Number of color components - */ - num: number; - /** - * Format is renderable - */ - render?: boolean; - /** - * Format is filterable (other than GL_NEAREST) - */ - filter?: boolean; - /** - * WebGL 2 only - */ - gl2?: boolean; -} - -export const TEX_FORMATS: IObjectOf = { - [TextureFormat.ALPHA]: { - format: TextureFormat.ALPHA, - render: true, - filter: true, - num: 1, - types: { - [TextureType.UNSIGNED_BYTE]: 1, - [TextureType.HALF_FLOAT]: 2, - [TextureType.HALF_FLOAT_OES]: 2, - [TextureType.FLOAT]: 4 - } - }, - [TextureFormat.DEPTH_COMPONENT16]: { - format: TextureFormat.DEPTH_COMPONENT, - render: true, - num: 1, - types: { - [TextureType.UNSIGNED_SHORT]: 2, - [TextureType.UNSIGNED_INT]: 4 - } - }, - [TextureFormat.DEPTH_COMPONENT24]: { - format: TextureFormat.DEPTH_COMPONENT, - render: true, - num: 1, - types: { [TextureType.UNSIGNED_INT]: 4 } - }, - [TextureFormat.DEPTH_COMPONENT32F]: { - format: TextureFormat.DEPTH_COMPONENT, - render: true, - num: 1, - types: { [TextureType.FLOAT]: 4 } - }, - [TextureFormat.DEPTH24_STENCIL8]: { - format: TextureFormat.DEPTH_STENCIL, - render: true, - num: 1, - types: { [TextureType.UNSIGNED_INT_24_8]: 4 } - }, - [TextureFormat.DEPTH32F_STENCIL8]: { - format: TextureFormat.DEPTH_STENCIL, - render: true, - num: 1, - types: { [TextureType.FLOAT_32_UNSIGNED_INT_24_8_REV]: 4 } - }, - [TextureFormat.LUMINANCE_ALPHA]: { - format: TextureFormat.LUMINANCE_ALPHA, - render: true, - filter: true, - num: 2, - types: { - [TextureType.UNSIGNED_BYTE]: 2, - [TextureType.HALF_FLOAT]: 4, - [TextureType.HALF_FLOAT_OES]: 4, - [TextureType.FLOAT]: 8 - } - }, - [TextureFormat.LUMINANCE]: { - format: TextureFormat.LUMINANCE, - render: true, - filter: true, - num: 1, - types: { - [TextureType.UNSIGNED_BYTE]: 1, - [TextureType.HALF_FLOAT]: 2, - [TextureType.HALF_FLOAT_OES]: 2, - [TextureType.FLOAT]: 4 - } - }, - [TextureFormat.R11F_G11F_B10F]: { - format: TextureFormat.RGB, - filter: true, - num: 3, - types: { - [TextureType.FLOAT]: 12, - [TextureType.HALF_FLOAT]: 6, - [TextureType.UNSIGNED_INT_10F_11F_11F_REV]: 4 - } - }, - [TextureFormat.R16F]: { - format: TextureFormat.RED, - filter: true, - num: 1, - types: { [TextureType.FLOAT]: 4, [TextureType.HALF_FLOAT]: 2 } - }, - [TextureFormat.R16I]: { - format: TextureFormat.RED_INTEGER, - render: true, - num: 1, - types: { [TextureType.SHORT]: 2 } - }, - [TextureFormat.R16UI]: { - format: TextureFormat.RED_INTEGER, - render: true, - num: 1, - types: { [TextureType.UNSIGNED_SHORT]: 2 } - }, - [TextureFormat.R32F]: { - format: TextureFormat.RED, - num: 1, - types: { [TextureType.FLOAT]: 4 } - }, - [TextureFormat.R32I]: { - format: TextureFormat.RED_INTEGER, - render: true, - num: 1, - types: { [TextureType.INT]: 4 } - }, - [TextureFormat.R32UI]: { - format: TextureFormat.RED_INTEGER, - render: true, - num: 1, - types: { [TextureType.UNSIGNED_INT]: 4 } - }, - [TextureFormat.R8_SNORM]: { - format: TextureFormat.RED, - filter: true, - num: 1, - types: { [TextureType.BYTE]: 1 } - }, - [TextureFormat.R8]: { - format: TextureFormat.RED, - render: true, - filter: true, - num: 1, - types: { [TextureType.UNSIGNED_BYTE]: 1 } - }, - [TextureFormat.R8I]: { - format: TextureFormat.RED_INTEGER, - render: true, - num: 1, - types: { [TextureType.BYTE]: 1 } - }, - [TextureFormat.R8UI]: { - format: TextureFormat.RED_INTEGER, - render: true, - num: 1, - types: { [TextureType.UNSIGNED_BYTE]: 1 } - }, - [TextureFormat.RG16F]: { - format: TextureFormat.RG, - filter: true, - num: 2, - types: { [TextureType.FLOAT]: 8, [TextureType.HALF_FLOAT]: 4 } - }, - [TextureFormat.RG16I]: { - format: TextureFormat.RG_INTEGER, - render: true, - num: 2, - types: { [TextureType.SHORT]: 4 } - }, - [TextureFormat.RG16UI]: { - format: TextureFormat.RG_INTEGER, - render: true, - num: 2, - types: { [TextureType.UNSIGNED_SHORT]: 4 } - }, - [TextureFormat.RG32F]: { - format: TextureFormat.RG, - num: 2, - types: { [TextureType.FLOAT]: 8 } - }, - [TextureFormat.RG32I]: { - format: TextureFormat.RG_INTEGER, - render: true, - num: 2, - types: { [TextureType.INT]: 8 } - }, - [TextureFormat.RG32UI]: { - format: TextureFormat.RG_INTEGER, - render: true, - num: 2, - types: { [TextureType.UNSIGNED_INT]: 8 } - }, - [TextureFormat.RG8_SNORM]: { - format: TextureFormat.RG, - filter: true, - num: 2, - types: { [TextureType.BYTE]: 2 } - }, - [TextureFormat.RG8]: { - format: TextureFormat.RG, - render: true, - filter: true, - num: 2, - types: { [TextureType.UNSIGNED_BYTE]: 2 } - }, - [TextureFormat.RG8I]: { - format: TextureFormat.RG_INTEGER, - render: true, - num: 2, - types: { [TextureType.BYTE]: 2 } - }, - [TextureFormat.RG8UI]: { - format: TextureFormat.RG_INTEGER, - render: true, - num: 2, - types: { [TextureType.UNSIGNED_BYTE]: 2 } - }, - [TextureFormat.RGB]: { - format: TextureFormat.RGB, - render: true, - filter: true, - num: 3, - types: { - [TextureType.UNSIGNED_BYTE]: 3, - [TextureType.HALF_FLOAT]: 6, - [TextureType.HALF_FLOAT_OES]: 6, - [TextureType.FLOAT]: 12, - [TextureType.UNSIGNED_SHORT_5_6_5]: 2 - } - }, - [TextureFormat.RGB10_A2]: { - format: TextureFormat.RGBA, - render: true, - filter: true, - num: 4, - types: { [TextureType.UNSIGNED_INT_2_10_10_10_REV]: 4 } - }, - [TextureFormat.RGB10_A2UI]: { - format: TextureFormat.RGBA_INTEGER, - render: true, - num: 4, - types: { [TextureType.UNSIGNED_INT_2_10_10_10_REV]: 4 } - }, - [TextureFormat.RGB16F]: { - format: TextureFormat.RGB, - filter: true, - num: 3, - types: { [TextureType.FLOAT]: 12, [TextureType.HALF_FLOAT]: 6 } - }, - [TextureFormat.RGB16I]: { - format: TextureFormat.RGB_INTEGER, - num: 3, - types: { [TextureType.SHORT]: 6 } - }, - [TextureFormat.RGB16UI]: { - format: TextureFormat.RGB_INTEGER, - num: 3, - types: { [TextureType.UNSIGNED_SHORT]: 6 } - }, - [TextureFormat.RGB32F]: { - format: TextureFormat.RGB, - num: 3, - types: { [TextureType.FLOAT]: 12 } - }, - [TextureFormat.RGB32I]: { - format: TextureFormat.RGB_INTEGER, - num: 3, - types: { [TextureType.INT]: 12 } - }, - [TextureFormat.RGB32UI]: { - format: TextureFormat.RGB_INTEGER, - num: 3, - types: { [TextureType.UNSIGNED_INT]: 12 } - }, - [TextureFormat.RGB5_A1]: { - format: TextureFormat.RGBA, - render: true, - filter: true, - num: 4, - types: { - [TextureType.UNSIGNED_BYTE]: 4, - [TextureType.UNSIGNED_SHORT_5_5_5_1]: 2, - [TextureType.UNSIGNED_INT_2_10_10_10_REV]: 4 - } - }, - [TextureFormat.RGB565]: { - format: TextureFormat.RGB, - render: true, - filter: true, - num: 3, - types: { - [TextureType.UNSIGNED_BYTE]: 3, - [TextureType.UNSIGNED_SHORT_5_6_5]: 2 - } - }, - [TextureFormat.RGB8_SNORM]: { - format: TextureFormat.RGB, - filter: true, - num: 3, - types: { [TextureType.BYTE]: 3 } - }, - [TextureFormat.RGB8]: { - format: TextureFormat.RGB, - render: true, - filter: true, - num: 3, - types: { [TextureType.UNSIGNED_BYTE]: 3 } - }, - [TextureFormat.RGB8I]: { - format: TextureFormat.RGB_INTEGER, - num: 3, - types: { [TextureType.BYTE]: 3 } - }, - [TextureFormat.RGB8UI]: { - format: TextureFormat.RGB_INTEGER, - num: 3, - types: { [TextureType.UNSIGNED_BYTE]: 3 } - }, - [TextureFormat.RGB9_E5]: { - format: TextureFormat.RGB, - filter: true, - num: 3, - types: { - [TextureType.FLOAT]: 12, - [TextureType.HALF_FLOAT]: 6, - [TextureType.UNSIGNED_INT_5_9_9_9_REV]: 4 - } - }, - [TextureFormat.RGBA]: { - format: TextureFormat.RGBA, - render: true, - filter: true, - num: 4, - types: { - [TextureType.UNSIGNED_BYTE]: 4, - [TextureType.HALF_FLOAT]: 8, - [TextureType.HALF_FLOAT_OES]: 8, - [TextureType.FLOAT]: 16, - [TextureType.UNSIGNED_SHORT_4_4_4_4]: 2, - [TextureType.UNSIGNED_SHORT_5_5_5_1]: 2 - } - }, - [TextureFormat.RGBA16F]: { - format: TextureFormat.RGBA, - filter: true, - num: 4, - types: { [TextureType.FLOAT]: 16, [TextureType.HALF_FLOAT]: 8 } - }, - [TextureFormat.RGBA16I]: { - format: TextureFormat.RGBA_INTEGER, - render: true, - num: 4, - types: { [TextureType.SHORT]: 8 } - }, - [TextureFormat.RGBA16UI]: { - format: TextureFormat.RGBA_INTEGER, - render: true, - num: 4, - types: { [TextureType.UNSIGNED_SHORT]: 8 } - }, - [TextureFormat.RGBA32F]: { - format: TextureFormat.RGBA, - num: 4, - types: { [TextureType.FLOAT]: 16 } - }, - [TextureFormat.RGBA32I]: { - format: TextureFormat.RGBA_INTEGER, - render: true, - num: 4, - types: { [TextureType.INT]: 16 } - }, - [TextureFormat.RGBA32UI]: { - format: TextureFormat.RGBA_INTEGER, - render: true, - num: 4, - types: { [TextureType.UNSIGNED_INT]: 16 } - }, - [TextureFormat.RGBA4]: { - format: TextureFormat.RGBA, - render: true, - filter: true, - num: 4, - types: { - [TextureType.UNSIGNED_BYTE]: 4, - [TextureType.UNSIGNED_SHORT_4_4_4_4]: 2 - } - }, - [TextureFormat.RGBA8_SNORM]: { - format: TextureFormat.RGBA, - filter: true, - num: 4, - types: { [TextureType.BYTE]: 4 } - }, - [TextureFormat.RGBA8]: { - format: TextureFormat.RGBA, - render: true, - filter: true, - num: 4, - types: { [TextureType.UNSIGNED_BYTE]: 4 } - }, - [TextureFormat.RGBA8I]: { - format: TextureFormat.RGBA_INTEGER, - render: true, - num: 4, - types: { [TextureType.BYTE]: 4 } - }, - [TextureFormat.RGBA8UI]: { - format: TextureFormat.RGBA_INTEGER, - render: true, - num: 4, - types: { [TextureType.UNSIGNED_BYTE]: 4 } - }, - [TextureFormat.SRGB8_ALPHA8]: { - format: TextureFormat.RGBA, - render: true, - filter: true, - num: 4, - types: { [TextureType.UNSIGNED_BYTE]: 4 } - }, - [TextureFormat.SRGB8]: { - format: TextureFormat.RGB, - filter: true, - num: 3, - types: { - [TextureType.UNSIGNED_BYTE]: 3 - } - } -}; - -export type GLSL = Type; - -export type GLVec = number[] | Float32Array; -export type GLVec2 = Tuple | Float32Array; -export type GLVec3 = Tuple | Float32Array; -export type GLVec4 = Tuple | Float32Array; - -export type GLIntVec = number[] | Int32Array; -export type GLUintVec = number[] | Uint32Array; -export type GLIntVec2 = Tuple | Int32Array; -export type GLIntVec3 = Tuple | Int32Array; -export type GLIntVec4 = Tuple | Int32Array; - -export type GLMat2 = Tuple | Float32Array; -export type GLMat3 = Tuple | Float32Array; -export type GLMat4 = Tuple | Float32Array; -export type GLMat23 = Tuple | Float32Array; -export type GLMat24 = Tuple | Float32Array; -export type GLMat34 = Tuple | Float32Array; - -export type AttribType = "bool" | "float" | "int" | "vec2" | "vec3" | "vec4"; - -export type AttribBufferData = - | Int8Array - | Uint8Array - | Uint8ClampedArray - | Int16Array - | Uint16Array - | Float32Array; - -export type IndexBufferData = Uint16Array | Uint32Array; - -export type ModelAttributeSpecs = IObjectOf; - -export type UniformValue = number | number[] | TypedArray; - -export type UniformValues = IObjectOf< - UniformValue | Fn2 | IDeref ->; - -export type ShaderType = "vs" | "fs"; - -export type GLSLScalarType = - | "bool" - | "float" - | "int" - | "uint" - | "sampler2D" - | "samplerCube"; - -export type GLSLArrayType = - | "bool[]" - | "int[]" - | "uint[]" - | "float[]" - | "bvec2[]" - | "bvec3[]" - | "bvec4[]" - | "ivec2[]" - | "ivec3[]" - | "ivec4[]" - | "uvec2[]" - | "uvec3[]" - | "uvec4[]" - | "vec2[]" - | "vec3[]" - | "vec4[]" - | "mat2[]" - | "mat3[]" - | "mat4[]" - // | "mat2x3[]" - // | "mat2x4[]" - // | "mat3x2[]" - // | "mat3x4[]" - // | "mat4x2[]" - // | "mat4x3[]" - | "sampler2D[]" - | "sampler3D[]" - | "samplerCube[]"; - -export type UniformDefault = - | T - | Fn2, T>; - -export type UniformDecl = - | GLSL - | [GLSLScalarType, UniformDefault] - | ["bvec2", UniformDefault] - | ["bvec3", UniformDefault] - | ["bvec4", UniformDefault] - | ["ivec2", UniformDefault] - | ["ivec3", UniformDefault] - | ["ivec4", UniformDefault] - | ["vec2", UniformDefault] - | ["vec3", UniformDefault] - | ["vec4", UniformDefault] - | ["mat2", UniformDefault] - | ["mat3", UniformDefault] - | ["mat4", UniformDefault] - // | ["mat2x3", UniformDefault] - // | ["mat2x4", UniformDefault] - // | ["mat3x2", UniformDefault] - // | ["mat3x4", UniformDefault] - // | ["mat4x2", UniformDefault] - // | ["mat4x3", UniformDefault] - | ["bool[]", number, UniformDefault?] - | ["int[]", number, UniformDefault?] - | ["uint[]", number, UniformDefault?] - | ["float[]", number, UniformDefault?] - | ["bvec2[]", number, UniformDefault?] - | ["bvec3[]", number, UniformDefault?] - | ["bvec4[]", number, UniformDefault?] - | ["ivec2[]", number, UniformDefault?] - | ["ivec3[]", number, UniformDefault?] - | ["ivec4[]", number, UniformDefault?] - | ["uvec2[]", number, UniformDefault?] - | ["uvec3[]", number, UniformDefault?] - | ["uvec4[]", number, UniformDefault?] - | ["vec2[]", number, UniformDefault?] - | ["vec3[]", number, UniformDefault?] - | ["vec4[]", number, UniformDefault?] - | ["mat2[]", number, UniformDefault?] - | ["mat3[]", number, UniformDefault?] - | ["mat4[]", number, UniformDefault?] - // | ["mat2x3[]", number, UniformDefault?] - // | ["mat2x4[]", number, UniformDefault?] - // | ["mat3x2[]", number, UniformDefault?] - // | ["mat3x4[]", number, UniformDefault?] - // | ["mat4x2[]", number, UniformDefault?] - // | ["mat4x3[]", number, UniformDefault?] - | ["sampler2D[]", number, UniformDefault?] - | ["sampler3D[]", number, UniformDefault?] - | ["samplerCube[]", number, UniformDefault?]; - -/** - * Object of attribute types w/ optional locations. - */ -export type ShaderAttribSpecs = IObjectOf; - -export type ShaderAttribSpec = AttribType | [AttribType, number]; - -/** - * Object of instantiated shader attributes. - */ -export type ShaderAttribs = IObjectOf; - -export interface ShaderAttrib { - type: AttribType; - loc: number; -} - -export type ShaderVaryingSpecs = IObjectOf; - -export type ShaderVaryingSpec = GLSL | [GLSLArrayType, number]; - -export type ShaderUniformSpecs = IObjectOf; - -export type ShaderUniforms = IObjectOf; - -export type ShaderOutputSpecs = IObjectOf; - -export type ShaderOutputSpec = GLSL | [GLSL, number]; - -export interface ShaderUniform { - type: GLSL; - loc: WebGLUniformLocation; - setter: Fn; - defaultFn?: (shaderUnis: any, specUnis: any) => UniformValue; - defaultVal?: UniformValue; -} - -export interface GLSLSyntax { - number: number; - attrib: Fn3; - uniform: Fn3; - varying: Record< - ShaderType, - Fn3 - >; - output: Fn3; -} - -export interface GLSLDeclPrefixes { - a: string; - v: string; - u: string; - o: string; -} - -export type GLSLExtensionBehavior = "require" | "warn" | boolean; - -export interface ShaderSnippet { - /** - * Array of dependent snippets. - */ - deps?: ShaderSnippet[]; - /** - * Snippet source code. - */ - src: string; -} - -export const DEFAULT_OUTPUT: ShaderOutputSpecs = { fragColor: ["vec4", 0] }; - -export type ShaderFn = Fn4< - GLSLTarget, - IObjectOf>, // uni - IObjectOf>, // attribs - IObjectOf>, // vary - (Sym | Func)[] ->; - -export interface ShaderSpec { - /** - * Vertex shader GLSL source code. - */ - vs: string | ShaderFn; - /** - * Fragment shader GLSL source code. - */ - fs: string | ShaderFn; - /** - * Attribute type declarations. - */ - attribs: ShaderAttribSpecs; - /** - * Varying type declarations. - */ - varying?: ShaderVaryingSpecs; - /** - * Uniform type declarations with optional defaults. - */ - uniforms?: ShaderUniformSpecs; - /** - * WebGL2 only. Fragment shader output variable type declarations. - * Default: `{ fragColor: GLSL.vec4 }` - */ - outputs?: ShaderOutputSpecs; - /** - * Flag to indicate code generation for attribs, varying, uniforms - * and outputs. Default: true. - */ - generateDecls?: boolean; - /** - * Variable naming convention variable prefixes for GLSL code gen. - * - * Defaults: - * - * - Attributes: `a_` - * - Varying: `v_` - * - Uniforms: `u_` - * - Outputs: `o_` - */ - declPrefixes?: Partial; - /** - * Optional prelude source, prepended before main shader code, the - * default prelude (unless disabled) and any other generated code. - */ - pre?: string; - /** - * Optional source code to be appended after main shader code. - */ - post?: string; - /** - * If true, disables default prelude. Default: false - */ - replacePrelude?: boolean; - /** - * Optional shader drawing state flags. Default: none. - */ - state?: Partial; - /** - * WebGL extension config for code generation. Keys in this object - * are extension names and their values specify the desired - * behavior. Boolean values will be translated in "enable" / - * "disable". - */ - ext?: IObjectOf; -} - -export interface ShaderState { - /** - * Enable depth test - */ - depth: boolean; - /** - * Cull faces - */ - cull: boolean; - /** - * Cull mode - */ - cullMode: GLenum; - /** - * Enable blending - */ - blend: boolean; - /** - * 2-element array of glBlendFunction coefficients - * (default: `[gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA]`) - */ - blendFn: Tuple; - /** - * glBlendEquation mode - */ - blendEq: GLenum; - /** - * Enable stencil test - */ - stencil: boolean; - /** - * glStencilFn params - */ - stencilFn: Tuple; - /** - * glStencilOp params - */ - stencilOp: Tuple; - /** - * glStencilMask arg - */ - stencilMask: GLenum; -} - -export interface ShaderOpts { - instancePos: string; - instanceColor: string; - color: string; - uv: string; - material: Partial; - state: Partial; -} - -export interface IShader extends IBind, IRelease { - gl: WebGLRenderingContext; - attribs: IObjectOf; - uniforms: ShaderUniforms; - - bindAttribs(specAttribs: ModelAttributeSpecs): void; - bindUniforms(specUnis: UniformValues): void; - prepareState(state?: Partial): void; -} - -export interface IWebGLBuffer extends IBind, IRelease { - set(data: T, mode?: GLenum): void; - setChunk(data: T, offset: number): void; -} - -export interface IConfigure { - configure(opts: T): boolean; -} - -export interface ITexture - extends IBind, - IConfigure>, - IRelease { - tex: WebGLTexture; -} - -export interface IFbo - extends IBind, - IConfigure>, - IRelease {} - -export interface IRenderBuffer extends IBind, IRelease { - buffer: WebGLRenderbuffer; - format: GLenum; - width: number; - height: number; -} - -export interface ModelSpec { - /** - * Initialized `IShader` instance - */ - shader: IShader; - /** - * GLSL attribute declarations - */ - attribs: ModelAttributeSpecs; - /** - * Geometry attributes given as `AttribPool` instance. - */ - attribPool?: AttribPool; - /** - * GLSL uniform value overrides - */ - uniforms?: UniformValues; - /** - * Buffer spec for indexed geometry - */ - indices?: IndexBufferSpec; - /** - * Array of initialized `ITexture` instances. - * Each non-null item will be auto-bound to its respective texture unit, - * each time the model is drawn via `draw()` - */ - textures?: ITexture[]; - /** - * Extra configuration for instanced geometry - */ - instances?: InstancingSpec; - /** - * WebGL draw mode. Defaults to `TRIANGLES` - */ - mode?: GLenum; - /** - * Number of vertices/indices to draw - */ - num: number; -} - -/** - * Data specification of a single WebGL attribute - */ -export interface ModelAttributeSpec { - /** - * Backing `WebGLArrayBuffer` instance. Usually this will be - * auto-initialized by `compileBuffers()` - */ - buffer?: IWebGLBuffer; - /** - * Raw attribute data from which `buffer` will be initialized - */ - data?: AttribBufferData; - /** - * Attribute element size (in component values, not bytes). - * Default: 3 - */ - size?: number; - /** - * Auto-normalization flag when writing buffer data. - * Default: false - */ - normalized?: boolean; - /** - * Byte offset of 1st attrib component. - * Default: 0 - */ - offset?: number; - /** - * Attribute stride in bytes. - * Default: 0 = densely packed - */ - stride?: number; - /** - * Attribute's WebGL data type. - * Default: gl.FLOAT - */ - type?: GLenum; - /** - * Only used for instanced attributes. - * See: https://www.khronos.org/registry/OpenGL/extensions/ANGLE/ANGLE_instanced_arrays.txt - */ - divisor?: number; -} - -export interface IndexBufferSpec { - /** - * Backing `WebGLBuffer` instance. Usually this will be - * auto-initialized by `makeBuffersInSpec()` - */ - buffer?: IWebGLBuffer; - /** - * Raw attribute data from which `buffer` will be initialized - */ - data: IndexBufferData; -} - -export interface InstancingSpec { - attribs: IObjectOf; - num: number; -} - -export interface TextureOpts { - image: ArrayBufferView | TexImageSource | null; - target: GLenum; - type: GLenum; - filter: GLenum | [GLenum, GLenum?]; - wrap: GLenum | [GLenum, GLenum?, GLenum?]; - lod: [GLenum, GLenum?]; - minMaxLevel: [GLenum, GLenum]; - level: GLenum; - format: GLenum; - internalFormat: GLenum; - width: number; - height: number; - mipmap: boolean; - flip: boolean; - premultiply: boolean; - sub: boolean; - pos: number[]; -} - -export interface FboOpts { - /** - * Array of Texture instances to be used as color attachments. - * Multiple attachments are only allowed if the `webgl_draw_buffers` - * extension is available. The texture at `[0]` will be mapped to - * `COLOR_ATTACHMENT0` (or `COLOR_ATTACHMENT0_WEBGL`), other indices - * are mapped to their respective attachment IDs. - */ - tex: ITexture[]; - /** - * Optional pre-instantiated `RenderBuffer` to be used as depth - * buffer for this FBO. - */ - depth?: ITexture | IRenderBuffer; -} - -export interface RboOpts { - format?: number; - width: number; - height: number; -} - -export interface Material { - ambientCol: GLVec3; - diffuseCol: GLVec3; - specularCol: GLVec3; -} - -export interface WeblGLCanvasOpts { - canvas: string | HTMLCanvasElement; - parent: HTMLElement; - opts: Partial; - version: 1 | 2; - width: number; - height: number; - autoScale: boolean; - onContextLost: EventListener; - ext: (keyof WebGLExtensionMap)[]; -} - -export interface GPGPUOpts { - size: number; - inputs?: number | GPGPUTextureConfig[]; - outputs?: number | GPGPUTextureConfig[]; - gl?: WebGLRenderingContext; - version?: 1 | 2; -} - -export interface GPGPUTextureConfig - extends Partial< - Pick - > { - stride: number; -} - -export interface GPGPUJobConfig { - shader: ShaderSpec; - src: string | ShaderFn; - uniforms: ShaderUniformSpecs; - inputs: number; - outputs?: number; -} - -export interface GPGPUJobExecOpts { - inputs: (ITexture | TypedArray)[]; - outputs?: number[]; - uniforms?: UniformValues; -} - -export const GL_COLOR_ATTACHMENT0_WEBGL = 0x8ce0; -export const GL_MAX_COLOR_ATTACHMENTS_WEBGL = 0x8cdf; -export const GL_RGBA = 0x1908; -export const GL_RGBA32F = 0x8814; - -// [SRC_ALPHA, ONE_MINUS_SRC_ALPHA] -export const DEFAULT_BLEND: Tuple = [0x302, 0x303]; - -export const GL_EXT_INFO = { - WEBGL_draw_buffers: { - gl: true, - alias: "GL_EXT_draw_buffers" - }, - OES_standard_derivatives: { - gl: true, - alias: "GL_OES_standard_derivatives" - } -}; - -export interface WebGLExtensionMap { - EXT_blend_minmax: EXT_blend_minmax; - EXT_color_buffer_float: WEBGL_color_buffer_float; - EXT_texture_filter_anisotropic: EXT_texture_filter_anisotropic; - EXT_frag_depth: EXT_frag_depth; - EXT_shader_texture_lod: EXT_shader_texture_lod; - EXT_sRGB: EXT_sRGB; - OES_vertex_array_object: OES_vertex_array_object; - WEBGL_color_buffer_float: WEBGL_color_buffer_float; - WEBGL_compressed_texture_astc: WEBGL_compressed_texture_astc; - WEBGL_compressed_texture_s3tc_srgb: WEBGL_compressed_texture_s3tc_srgb; - WEBGL_debug_shaders: WEBGL_debug_shaders; - WEBGL_draw_buffers: WEBGL_draw_buffers; - WEBGL_lose_context: WEBGL_lose_context; - WEBGL_depth_texture: WEBGL_depth_texture; - WEBGL_debug_renderer_info: WEBGL_debug_renderer_info; - WEBGL_compressed_texture_s3tc: WEBGL_compressed_texture_s3tc; - OES_texture_half_float_linear: OES_texture_half_float_linear; - OES_texture_half_float: OES_texture_half_float; - OES_texture_float_linear: OES_texture_float_linear; - OES_texture_float: OES_texture_float; - OES_standard_derivatives: OES_standard_derivatives; - OES_element_index_uint: OES_element_index_uint; - ANGLE_instanced_arrays: ANGLE_instanced_arrays; -} diff --git a/packages/webgl/src/api/blend.ts b/packages/webgl/src/api/blend.ts new file mode 100644 index 0000000000..63fb59d669 --- /dev/null +++ b/packages/webgl/src/api/blend.ts @@ -0,0 +1,39 @@ +import { Tuple } from "@thi.ng/api"; + +export const enum Blend { + ZERO = 0, + ONE = 1, + SRC_COLOR = 768, + ONE_MINUS_SRC_COLOR = 769, + DST_COLOR = 774, + ONE_MINUS_DST_COLOR = 775, + SRC_ALPHA = 770, + ONE_MINUS_SRC_ALPHA = 771, + DST_ALPHA = 772, + ONE_MINUS_DST_ALPHA = 773, + CONSTANT_COLOR = 32769, + ONE_MINUS_CONSTANT_COLOR = 32770, + CONSTANT_ALPHA = 32771, + ONE_MINUS_CONSTANT_ALPHA = 32772, + SRC_ALPHA_SATURATE = 776 +} + +export const enum BlendEquation { + FUNC_ADD = 32774, + FUNC_REVERSE_SUBTRACT = 32779, + FUNC_SUBTRACT = 32778, + MAX = 32776, + MIN = 32775 +} + +export type BlendFunc = Tuple; + +// TODO blend func presets +// https://www.andersriggelsen.dk/glblendfunc.php + +export const BLEND_NORMAL: BlendFunc = [ + Blend.SRC_ALPHA, + Blend.ONE_MINUS_SRC_ALPHA +]; + +export const BLEND_ADD: BlendFunc = [Blend.SRC_ALPHA, Blend.DST_ALPHA]; diff --git a/packages/webgl/src/api/buffers.ts b/packages/webgl/src/api/buffers.ts new file mode 100644 index 0000000000..e0b1734314 --- /dev/null +++ b/packages/webgl/src/api/buffers.ts @@ -0,0 +1,59 @@ +import { IBind, IRelease } from "@thi.ng/api"; +import { ITexture } from "./texture"; + +export type IndexBufferData = Uint16Array | Uint32Array; + +export interface IWebGLBuffer extends IBind, IRelease { + set(data: T, mode?: GLenum): void; + setChunk(data: T, offset: number): void; +} + +export interface IConfigure { + configure(opts: T): boolean; +} + +export interface IFbo + extends IBind, + IConfigure>, + IRelease {} + +export interface IRenderBuffer extends IBind, IRelease { + buffer: WebGLRenderbuffer; + format: GLenum; + width: number; + height: number; +} + +export interface IndexBufferSpec { + /** + * Backing `WebGLBuffer` instance. Usually this will be + * auto-initialized by `makeBuffersInSpec()` + */ + buffer?: IWebGLBuffer; + /** + * Raw attribute data from which `buffer` will be initialized + */ + data: IndexBufferData; +} + +export interface FboOpts { + /** + * Array of Texture instances to be used as color attachments. + * Multiple attachments are only allowed if the `webgl_draw_buffers` + * extension is available. The texture at `[0]` will be mapped to + * `COLOR_ATTACHMENT0` (or `COLOR_ATTACHMENT0_WEBGL`), other indices + * are mapped to their respective attachment IDs. + */ + tex: ITexture[]; + /** + * Optional pre-instantiated `RenderBuffer` to be used as depth + * buffer for this FBO. + */ + depth?: ITexture | IRenderBuffer; +} + +export interface RboOpts { + format?: number; + width: number; + height: number; +} diff --git a/packages/webgl/src/api/canvas.ts b/packages/webgl/src/api/canvas.ts new file mode 100644 index 0000000000..5fbd3752d1 --- /dev/null +++ b/packages/webgl/src/api/canvas.ts @@ -0,0 +1,13 @@ +import { WebGLExtensionMap } from "./ext"; + +export interface WeblGLCanvasOpts { + canvas: string | HTMLCanvasElement; + parent: HTMLElement; + opts: Partial; + version: 1 | 2; + width: number; + height: number; + autoScale: boolean; + onContextLost: EventListener; + ext: (keyof WebGLExtensionMap)[]; +} diff --git a/packages/webgl/src/api/ext.ts b/packages/webgl/src/api/ext.ts new file mode 100644 index 0000000000..b363e76822 --- /dev/null +++ b/packages/webgl/src/api/ext.ts @@ -0,0 +1,52 @@ +import { IObjectOf } from "@thi.ng/api"; + +export const GL_EXT_INFO: IObjectOf = { + WEBGL_draw_buffers: { + gl: true, + alias: "GL_EXT_draw_buffers" + }, + OES_standard_derivatives: { + gl: true, + alias: "GL_OES_standard_derivatives" + } +}; + +export interface ExtensionInfo { + gl?: boolean; + gl2?: boolean; + alias: string; +} + +export interface WebGLExtensionMap { + ANGLE_instanced_arrays: ANGLE_instanced_arrays; + EXT_blend_minmax: EXT_blend_minmax; + EXT_color_buffer_float: WEBGL_color_buffer_float; + EXT_frag_depth: EXT_frag_depth; + EXT_shader_texture_lod: EXT_shader_texture_lod; + EXT_sRGB: EXT_sRGB; + EXT_texture_filter_anisotropic: EXT_texture_filter_anisotropic; + OES_element_index_uint: OES_element_index_uint; + OES_standard_derivatives: OES_standard_derivatives; + OES_texture_float_linear: OES_texture_float_linear; + OES_texture_float: OES_texture_float; + OES_texture_half_float_linear: OES_texture_half_float_linear; + OES_texture_half_float: OES_texture_half_float; + OES_vertex_array_object: OES_vertex_array_object; + WEBGL_color_buffer_float: WEBGL_color_buffer_float; + WEBGL_compressed_texture_astc: WEBGL_compressed_texture_astc; + WEBGL_compressed_texture_s3tc_srgb: WEBGL_compressed_texture_s3tc_srgb; + WEBGL_compressed_texture_s3tc: WEBGL_compressed_texture_s3tc; + WEBGL_debug_renderer_info: WEBGL_debug_renderer_info; + WEBGL_debug_shaders: WEBGL_debug_shaders; + WEBGL_depth_texture: WEBGL_depth_texture; + WEBGL_draw_buffers: WEBGL_draw_buffers; + WEBGL_lose_context: WEBGL_lose_context; +} + +export type ExtensionName = keyof WebGLExtensionMap; + +export type ExtensionBehavior = "require" | "warn" | boolean; + +export type ExtensionBehaviors = Partial< + Record +>; diff --git a/packages/webgl/src/api/glsl.ts b/packages/webgl/src/api/glsl.ts new file mode 100644 index 0000000000..d37442956c --- /dev/null +++ b/packages/webgl/src/api/glsl.ts @@ -0,0 +1,60 @@ +import { Tuple } from "@thi.ng/api"; +import { Type } from "@thi.ng/shader-ast"; + +export type GLSL = Type; + +export type GLVec = number[] | Float32Array; +export type GLVec2 = Tuple | Float32Array; +export type GLVec3 = Tuple | Float32Array; +export type GLVec4 = Tuple | Float32Array; + +export type GLIntVec = number[] | Int32Array; +export type GLUintVec = number[] | Uint32Array; +export type GLIntVec2 = Tuple | Int32Array; +export type GLIntVec3 = Tuple | Int32Array; +export type GLIntVec4 = Tuple | Int32Array; + +export type GLMat2 = Tuple | Float32Array; +export type GLMat3 = Tuple | Float32Array; +export type GLMat4 = Tuple | Float32Array; +export type GLMat23 = Tuple | Float32Array; +export type GLMat24 = Tuple | Float32Array; +export type GLMat34 = Tuple | Float32Array; + +export type GLSLScalarType = + | "bool" + | "float" + | "int" + | "uint" + | "sampler2D" + | "samplerCube"; + +export type GLSLArrayType = + | "bool[]" + | "int[]" + | "uint[]" + | "float[]" + | "bvec2[]" + | "bvec3[]" + | "bvec4[]" + | "ivec2[]" + | "ivec3[]" + | "ivec4[]" + | "uvec2[]" + | "uvec3[]" + | "uvec4[]" + | "vec2[]" + | "vec3[]" + | "vec4[]" + | "mat2[]" + | "mat3[]" + | "mat4[]" + // | "mat2x3[]" + // | "mat2x4[]" + // | "mat3x2[]" + // | "mat3x4[]" + // | "mat4x2[]" + // | "mat4x3[]" + | "sampler2D[]" + | "sampler3D[]" + | "samplerCube[]"; diff --git a/packages/webgl/src/api/material.ts b/packages/webgl/src/api/material.ts new file mode 100644 index 0000000000..f9459f20a6 --- /dev/null +++ b/packages/webgl/src/api/material.ts @@ -0,0 +1,7 @@ +import { GLVec3 } from "./glsl"; + +export interface Material { + ambientCol: GLVec3; + diffuseCol: GLVec3; + specularCol: GLVec3; +} diff --git a/packages/webgl/src/api/model.ts b/packages/webgl/src/api/model.ts new file mode 100644 index 0000000000..f03f7dba27 --- /dev/null +++ b/packages/webgl/src/api/model.ts @@ -0,0 +1,98 @@ +import { IObjectOf } from "@thi.ng/api"; +import { AttribPool } from "@thi.ng/vector-pools"; +import { IndexBufferSpec, IWebGLBuffer } from "./buffers"; +import { AttribBufferData, IShader, UniformValues } from "./shader"; +import { ITexture } from "./texture"; + +export type ModelAttributeSpecs = IObjectOf; + +export interface ModelSpec { + /** + * Initialized `IShader` instance + */ + shader: IShader; + /** + * GLSL attribute declarations + */ + attribs: ModelAttributeSpecs; + /** + * Geometry attributes given as `AttribPool` instance. + */ + attribPool?: AttribPool; + /** + * GLSL uniform value overrides + */ + uniforms?: UniformValues; + /** + * Buffer spec for indexed geometry + */ + indices?: IndexBufferSpec; + /** + * Array of initialized `ITexture` instances. + * Each non-null item will be auto-bound to its respective texture unit, + * each time the model is drawn via `draw()` + */ + textures?: ITexture[]; + /** + * Extra configuration for instanced geometry + */ + instances?: InstancingSpec; + /** + * WebGL draw mode. Defaults to `TRIANGLES` + */ + mode?: GLenum; + /** + * Number of vertices/indices to draw + */ + num: number; +} + +/** + * Data specification of a single WebGL attribute + */ +export interface ModelAttributeSpec { + /** + * Backing `WebGLArrayBuffer` instance. Usually this will be + * auto-initialized by `compileBuffers()` + */ + buffer?: IWebGLBuffer; + /** + * Raw attribute data from which `buffer` will be initialized + */ + data?: AttribBufferData; + /** + * Attribute element size (in component values, not bytes). + * Default: 3 + */ + size?: number; + /** + * Auto-normalization flag when writing buffer data. + * Default: false + */ + normalized?: boolean; + /** + * Byte offset of 1st attrib component. + * Default: 0 + */ + offset?: number; + /** + * Attribute stride in bytes. + * Default: 0 = densely packed + */ + stride?: number; + /** + * Attribute's WebGL data type. + * Default: gl.FLOAT + */ + type?: GLenum; + /** + * Only used for instanced attributes. + * See: https://www.khronos.org/registry/OpenGL/extensions/ANGLE/ANGLE_instanced_arrays.txt + */ + divisor?: number; +} + +export interface InstancingSpec { + attribs: IObjectOf; + num: number; +} diff --git a/packages/webgl/src/api/multipass.ts b/packages/webgl/src/api/multipass.ts new file mode 100644 index 0000000000..8de762f002 --- /dev/null +++ b/packages/webgl/src/api/multipass.ts @@ -0,0 +1,68 @@ +import { IObjectOf } from "@thi.ng/api"; +import { AttribPool } from "@thi.ng/vector-pools"; +import { IFbo, IndexBufferSpec } from "./buffers"; +import { InstancingSpec, ModelAttributeSpecs, ModelSpec } from "./model"; +import { + ShaderAttribSpecs, + ShaderFn, + ShaderState, + ShaderVaryingSpecs, + UniformDecl, + UniformValues +} from "./shader"; +import { ITexture, TextureOpts } from "./texture"; + +export interface Multipass { + start(): void; + stop(): void; + update(time?: number): void; + + fbos: IFbo[]; + models: ModelSpec[]; + passes: PassOpts[]; + textures: IObjectOf; +} + +export interface MultipassOpts { + gl: WebGLRenderingContext; + textures: IObjectOf>; + passes: PassOpts[]; + width: number; + height: number; + uniforms?: Partial; + uniformVals?: UniformValues; +} + +export interface PassOpts { + vs?: string | ShaderFn; + fs: string | ShaderFn; + model?: PassModelSpec; + inputs: string[]; + outputs: string[]; + attribs?: ShaderAttribSpecs; + varying?: ShaderVaryingSpecs; + uniforms?: Partial; + uniformVals?: UniformValues; + pre?: string; + post?: string; + replacePrelude?: boolean; + generateDecls?: boolean; + state?: Partial; +} + +export interface PassUniforms { + inputs: never; + outputs: never; + resolution: "vec2"; + time: "float"; + [id: string]: UniformDecl; +} + +export interface PassModelSpec { + attribs: ModelAttributeSpecs; + attribPool?: AttribPool; + indices?: IndexBufferSpec; + instances?: InstancingSpec; + mode?: GLenum; + num: number; +} diff --git a/packages/webgl/src/api/shader.ts b/packages/webgl/src/api/shader.ts new file mode 100644 index 0000000000..e11d0a40ab --- /dev/null +++ b/packages/webgl/src/api/shader.ts @@ -0,0 +1,303 @@ +import { + Fn, + Fn2, + Fn3, + Fn4, + IBind, + IDeref, + IObjectOf, + IRelease, + TypedArray +} from "@thi.ng/api"; +import { Func, Sym } from "@thi.ng/shader-ast"; +import { GLSLTarget } from "@thi.ng/shader-ast-glsl"; +import { ReadonlyVec } from "@thi.ng/vectors"; +import { BlendEquation, BlendFunc } from "./blend"; +import { ExtensionBehaviors } from "./ext"; +import { + GLIntVec, + GLIntVec2, + GLIntVec3, + GLIntVec4, + GLMat2, + GLMat3, + GLMat4, + GLSL, + GLSLArrayType, + GLSLScalarType, + GLUintVec, + GLVec, + GLVec2, + GLVec3, + GLVec4 +} from "./glsl"; +import { ModelAttributeSpecs, ModelSpec } from "./model"; +import { StencilFnParams, StencilOpParams } from "./stencil"; + +export interface GLSLSyntax { + number: number; + attrib: Fn3; + uniform: Fn3; + varying: Record< + ShaderType, + Fn3 + >; + output: Fn3; +} + +export interface GLSLDeclPrefixes { + a: string; + v: string; + u: string; + o: string; +} + +export type ShaderType = "vs" | "fs"; + +export type AttribType = "bool" | "float" | "int" | "vec2" | "vec3" | "vec4"; + +export type AttribBufferData = + | Int8Array + | Uint8Array + | Uint8ClampedArray + | Int16Array + | Uint16Array + | Float32Array; + +export type UniformValue = number | number[] | TypedArray; + +export type UniformValues = IObjectOf< + UniformValue | Fn2 | IDeref +>; + +export type UniformDefault = + | T + | Fn2, T>; + +export type UniformDecl = + | GLSL + | [GLSLScalarType, UniformDefault] + | ["bvec2", UniformDefault] + | ["bvec3", UniformDefault] + | ["bvec4", UniformDefault] + | ["ivec2", UniformDefault] + | ["ivec3", UniformDefault] + | ["ivec4", UniformDefault] + | ["vec2", UniformDefault] + | ["vec3", UniformDefault] + | ["vec4", UniformDefault] + | ["mat2", UniformDefault] + | ["mat3", UniformDefault] + | ["mat4", UniformDefault] + // | ["mat2x3", UniformDefault] + // | ["mat2x4", UniformDefault] + // | ["mat3x2", UniformDefault] + // | ["mat3x4", UniformDefault] + // | ["mat4x2", UniformDefault] + // | ["mat4x3", UniformDefault] + | ["bool[]", number, UniformDefault?] + | ["int[]", number, UniformDefault?] + | ["uint[]", number, UniformDefault?] + | ["float[]", number, UniformDefault?] + | ["bvec2[]", number, UniformDefault?] + | ["bvec3[]", number, UniformDefault?] + | ["bvec4[]", number, UniformDefault?] + | ["ivec2[]", number, UniformDefault?] + | ["ivec3[]", number, UniformDefault?] + | ["ivec4[]", number, UniformDefault?] + | ["uvec2[]", number, UniformDefault?] + | ["uvec3[]", number, UniformDefault?] + | ["uvec4[]", number, UniformDefault?] + | ["vec2[]", number, UniformDefault?] + | ["vec3[]", number, UniformDefault?] + | ["vec4[]", number, UniformDefault?] + | ["mat2[]", number, UniformDefault?] + | ["mat3[]", number, UniformDefault?] + | ["mat4[]", number, UniformDefault?] + // | ["mat2x3[]", number, UniformDefault?] + // | ["mat2x4[]", number, UniformDefault?] + // | ["mat3x2[]", number, UniformDefault?] + // | ["mat3x4[]", number, UniformDefault?] + // | ["mat4x2[]", number, UniformDefault?] + // | ["mat4x3[]", number, UniformDefault?] + | ["sampler2D[]", number, UniformDefault?] + | ["sampler3D[]", number, UniformDefault?] + | ["samplerCube[]", number, UniformDefault?]; + +/** + * Object of attribute types w/ optional locations. + */ +export type ShaderAttribSpecs = IObjectOf; + +export type ShaderAttribSpec = AttribType | [AttribType, number]; + +/** + * Object of instantiated shader attributes. + */ +export type ShaderAttribs = IObjectOf; + +export interface ShaderAttrib { + type: AttribType; + loc: number; +} + +export type ShaderVaryingSpecs = IObjectOf; + +export type ShaderVaryingSpec = GLSL | [GLSLArrayType, number]; + +export type ShaderUniformSpecs = IObjectOf; + +export type ShaderUniforms = IObjectOf; + +export type ShaderOutputSpecs = IObjectOf; + +export type ShaderOutputSpec = GLSL | [GLSL, number]; + +export interface ShaderUniform { + type: GLSL; + loc: WebGLUniformLocation; + setter: Fn; + defaultFn?: (shaderUnis: any, specUnis: any) => UniformValue; + defaultVal?: UniformValue; +} + +export const DEFAULT_OUTPUT: ShaderOutputSpecs = { fragColor: ["vec4", 0] }; + +export type ShaderFn = Fn4< + GLSLTarget, + IObjectOf>, // uni + IObjectOf>, // attribs + IObjectOf>, // vary + (Sym | Func)[] +>; + +export interface ShaderSpec { + /** + * Vertex shader GLSL source code. + */ + vs: string | ShaderFn; + /** + * Fragment shader GLSL source code. + */ + fs: string | ShaderFn; + /** + * Attribute type declarations. + */ + attribs: ShaderAttribSpecs; + /** + * Varying type declarations. + */ + varying?: ShaderVaryingSpecs; + /** + * Uniform type declarations with optional defaults. + */ + uniforms?: ShaderUniformSpecs; + /** + * WebGL2 only. Fragment shader output variable type declarations. + * Default: `{ fragColor: GLSL.vec4 }` + */ + outputs?: ShaderOutputSpecs; + /** + * Flag to indicate code generation for attribs, varying, uniforms + * and outputs. Default: true. + */ + generateDecls?: boolean; + /** + * Variable naming convention variable prefixes for GLSL code gen. + * + * Defaults: + * + * - Attributes: `a_` + * - Varying: `v_` + * - Uniforms: `u_` + * - Outputs: `o_` + */ + declPrefixes?: Partial; + /** + * Optional prelude source, prepended before main shader code, the + * default prelude (unless disabled) and any other generated code. + */ + pre?: string; + /** + * Optional source code to be appended after main shader code. + */ + post?: string; + /** + * If true, disables default prelude. Default: false + */ + replacePrelude?: boolean; + /** + * Optional shader drawing state flags. Default: none. + */ + state?: Partial; + /** + * WebGL extension config for code generation. Keys in this object + * are extension names and their values specify the desired + * behavior. Boolean values will be translated in "enable" / + * "disable". + */ + ext?: ExtensionBehaviors; +} + +export interface ShaderState { + /** + * Enable depth test + */ + depth: boolean; + /** + * Cull faces + */ + cull: boolean; + /** + * Cull mode + */ + cullMode: GLenum; + /** + * Enable blending + */ + blend: boolean; + /** + * 2-element array of glBlendFunction coefficients + * (default: `[gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA]`) + */ + blendFn: BlendFunc; + /** + * glBlendEquation mode + */ + blendEq: BlendEquation; + /** + * Enable stencil test + */ + stencil: boolean; + /** + * glStencilFn params + */ + stencilFn: StencilFnParams; + /** + * glStencilOp params + */ + stencilOp: StencilOpParams; + /** + * glStencilMask arg + */ + stencilMask: number; +} + +export interface ShaderOpts { + instancePos: string; + instanceColor: string; + color: string; + uv: string; + material: Partial; + state: Partial; +} + +export interface IShader extends IBind, IRelease { + gl: WebGLRenderingContext; + attribs: IObjectOf; + uniforms: ShaderUniforms; + + bindAttribs(specAttribs: ModelAttributeSpecs): void; + bindUniforms(specUnis: UniformValues): void; + prepareState(state?: Partial): void; +} diff --git a/packages/webgl/src/api/stencil.ts b/packages/webgl/src/api/stencil.ts new file mode 100644 index 0000000000..5e8aa76cf2 --- /dev/null +++ b/packages/webgl/src/api/stencil.ts @@ -0,0 +1,27 @@ +import { Tuple } from "@thi.ng/api"; + +export const enum StencilOp { + KEEP = 7680, + ZERO = 0, + REPLACE = 7681, + INCR = 7682, + INCR_WRAP = 34055, + DECR = 7683, + DECR_WRAP = 34056, + INVERT = 5386 +} + +export const enum StencilFn { + NEVER = 512, + LESS = 513, + EQUAL = 514, + LEQUAL = 515, + GREATER = 516, + NOTEQUAL = 517, + GEQUAL = 518, + ALWAYS = 519 +} + +export type StencilOpParams = Tuple; + +export type StencilFnParams = [StencilFn, number, number]; diff --git a/packages/webgl/src/api/texture.ts b/packages/webgl/src/api/texture.ts new file mode 100644 index 0000000000..8b8c69942f --- /dev/null +++ b/packages/webgl/src/api/texture.ts @@ -0,0 +1,665 @@ +import { IBind, IObjectOf, IRelease } from "@thi.ng/api"; +import { IConfigure } from "./buffers"; + +export const enum TextureFormat { + ALPHA = 0x1906, + DEPTH_COMPONENT = 0x1902, + DEPTH_COMPONENT16 = 0x81a5, + DEPTH_COMPONENT24 = 0x81a6, + DEPTH_COMPONENT32F = 0x8cac, + DEPTH_STENCIL = 0x84f9, + DEPTH24_STENCIL8 = 0x88f0, + DEPTH32F_STENCIL8 = 0x8cad, + LUMINANCE = 0x1909, + LUMINANCE_ALPHA = 0x190a, + R11F_G11F_B10F = 0x8c3a, + R16F = 0x822d, + R16I = 0x8233, + R16UI = 0x8234, + R32F = 0x822e, + R32I = 0x8235, + R32UI = 0x8236, + R8 = 0x8229, + R8_SNORM = 0x8f94, + R8I = 0x8231, + R8UI = 0x8232, + RED = 0x1903, + RED_INTEGER = 0x8d94, + RG = 0x8227, + RG_INTEGER = 0x8228, + RG16F = 0x822f, + RG16I = 0x8239, + RG16UI = 0x823a, + RG32F = 0x8230, + RG32I = 0x823b, + RG32UI = 0x823c, + RG8 = 0x822b, + RG8_SNORM = 0x8f95, + RG8I = 0x8237, + RG8UI = 0x8238, + RGB = 0x1907, + RGB_INTEGER = 0x8d98, + RGB10_A2 = 0x8059, + RGB10_A2UI = 0x906f, + RGB16F = 0x881b, + RGB16I = 0x8d89, + RGB16UI = 0x8d77, + RGB32F = 0x8815, + RGB32I = 0x8d83, + RGB32UI = 0x8d71, + RGB5_A1 = 0x8057, + RGB565 = 0x8d62, + RGB8 = 0x8051, + RGB8_SNORM = 0x8f96, + RGB8I = 0x8d8f, + RGB8UI = 0x8d7d, + RGB9_E5 = 0x8c3d, + RGBA = 0x1908, + RGBA_INTEGER = 0x8d99, + RGBA16F = 0x881a, + RGBA16I = 0x8d88, + RGBA16UI = 0x8d76, + RGBA32F = 0x8814, + RGBA32I = 0x8d82, + RGBA32UI = 0x8d70, + RGBA4 = 0x8056, + RGBA8 = 0x8058, + RGBA8_SNORM = 0x8f97, + RGBA8I = 0x8d8e, + RGBA8UI = 0x8d7c, + SRGB8 = 0x8c41, + SRGB8_ALPHA8 = 0x8c43 +} + +export const enum TextureType { + BYTE = 0x1400, + UNSIGNED_BYTE, + SHORT, + UNSIGNED_SHORT, + INT, + UNSIGNED_INT, + FLOAT, + HALF_FLOAT = 0x140b, + UNSIGNED_SHORT_4_4_4_4 = 0x8033, + UNSIGNED_SHORT_5_5_5_1 = 0x8034, + UNSIGNED_SHORT_5_6_5 = 0x8363, + UNSIGNED_INT_2_10_10_10_REV = 0x8368, + UNSIGNED_INT_24_8 = 0x84fa, + UNSIGNED_INT_10F_11F_11F_REV = 0x8c3b, + UNSIGNED_INT_5_9_9_9_REV = 0x8c3e, + HALF_FLOAT_OES = 0x8d61, + FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8dad +} + +export const enum TextureTarget { + TEXTURE_2D = 3553, + TEXTURE_3D = 32879, + TEXTURE_CUBE_MAP = 34067, + TEXTURE_2D_ARRAY = 35866 +} + +export const enum TextureFilter { + LINEAR = 9729, + NEAREST = 9728, + NEAREST_MIPMAP_NEAREST = 9984, + LINEAR_MIPMAP_NEAREST = 9985, + NEAREST_MIPMAP_LINEAR = 9986, + LINEAR_MIPMAP_LINEAR = 9987 +} + +export const enum TextureRepeat { + REPEAT = 10497, + CLAMP = 33071, + REPEAT_MIRROR = 33648 +} + +export interface TextureFormatDecl { + /** + * Base format + */ + format: TextureFormat; + /** + * Acceptable types and their resulting byte size per pixel. + * Interleaved layout `[format, size, format, size...]` + */ + types: (TextureType | number)[]; + /** + * Number of color components + */ + num: number; + /** + * Format is renderable + */ + render?: boolean; + /** + * Format is renderable via extension + */ + renderExt?: boolean; + /** + * Format is filterable (other than GL_NEAREST) + */ + filter?: boolean; + /** + * WebGL 2 only + */ + gl2?: boolean; +} + +const $ = ( + format: TextureFormat, + types: (TextureType | number)[], + num: number, + render = false, + filter = false, + renderExt = render +) => ({ + format, + types, + render, + renderExt, + filter, + num +}); + +export const TEX_FORMATS: IObjectOf = { + [TextureFormat.ALPHA]: $( + TextureFormat.ALPHA, + [ + TextureType.UNSIGNED_BYTE, + 1, + TextureType.HALF_FLOAT, + 2, + TextureType.HALF_FLOAT_OES, + 2, + TextureType.FLOAT, + 4 + ], + 1, + true, + true + ), + [TextureFormat.DEPTH_COMPONENT16]: $( + TextureFormat.DEPTH_COMPONENT, + [TextureType.UNSIGNED_SHORT, 2, TextureType.UNSIGNED_INT, 4], + 1, + true + ), + [TextureFormat.DEPTH_COMPONENT24]: $( + TextureFormat.DEPTH_COMPONENT, + [TextureType.UNSIGNED_INT, 4], + 1, + true + ), + [TextureFormat.DEPTH_COMPONENT32F]: $( + TextureFormat.DEPTH_COMPONENT, + [TextureType.FLOAT, 4], + 1, + true + ), + [TextureFormat.DEPTH24_STENCIL8]: $( + TextureFormat.DEPTH_STENCIL, + [TextureType.UNSIGNED_INT_24_8, 4], + 1, + true + ), + [TextureFormat.DEPTH32F_STENCIL8]: $( + TextureFormat.DEPTH_STENCIL, + [TextureType.FLOAT_32_UNSIGNED_INT_24_8_REV, 4], + 1, + true + ), + [TextureFormat.LUMINANCE_ALPHA]: $( + TextureFormat.LUMINANCE_ALPHA, + [ + TextureType.UNSIGNED_BYTE, + 2, + TextureType.HALF_FLOAT, + 4, + TextureType.HALF_FLOAT_OES, + 4, + TextureType.FLOAT, + 8 + ], + 2, + true, + true + ), + [TextureFormat.LUMINANCE]: $( + TextureFormat.LUMINANCE, + [ + TextureType.UNSIGNED_BYTE, + 1, + TextureType.HALF_FLOAT, + 2, + TextureType.HALF_FLOAT_OES, + 2, + TextureType.FLOAT, + 4 + ], + 1, + true, + true + ), + [TextureFormat.R11F_G11F_B10F]: $( + TextureFormat.RGB, + [ + TextureType.FLOAT, + 12, + TextureType.HALF_FLOAT, + 6, + TextureType.UNSIGNED_INT_10F_11F_11F_REV, + 4 + ], + 3, + false, + true, + true + ), + [TextureFormat.R16F]: $( + TextureFormat.RED, + [TextureType.FLOAT, 4, TextureType.HALF_FLOAT, 2], + 1, + false, + true, + true + ), + [TextureFormat.R16I]: $( + TextureFormat.RED_INTEGER, + [TextureType.SHORT, 2], + 1, + true + ), + [TextureFormat.R16UI]: $( + TextureFormat.RED_INTEGER, + [TextureType.UNSIGNED_SHORT, 2], + 1, + true + ), + [TextureFormat.R32F]: $( + TextureFormat.RED, + [TextureType.FLOAT, 4], + 1, + false, + false, + true + ), + [TextureFormat.R32I]: $( + TextureFormat.RED_INTEGER, + [TextureType.INT, 4], + 1, + true + ), + [TextureFormat.R32UI]: $( + TextureFormat.RED_INTEGER, + [TextureType.UNSIGNED_INT, 4], + 1, + true + ), + [TextureFormat.R8_SNORM]: $( + TextureFormat.RED, + [TextureType.BYTE, 1], + 1, + false, + true + ), + [TextureFormat.R8]: $( + TextureFormat.RED, + [TextureType.UNSIGNED_BYTE, 1], + 1, + true, + true + ), + [TextureFormat.R8I]: $( + TextureFormat.RED_INTEGER, + [TextureType.BYTE, 1], + 1, + true + ), + [TextureFormat.R8UI]: $( + TextureFormat.RED_INTEGER, + [TextureType.UNSIGNED_BYTE, 1], + 1, + true + ), + [TextureFormat.RG16F]: $( + TextureFormat.RG, + [TextureType.FLOAT, 8, TextureType.HALF_FLOAT, 4], + 2, + false, + true, + true + ), + [TextureFormat.RG16I]: $( + TextureFormat.RG_INTEGER, + [TextureType.SHORT, 4], + 2, + true + ), + [TextureFormat.RG16UI]: $( + TextureFormat.RG_INTEGER, + [TextureType.UNSIGNED_SHORT, 4], + 2, + true + ), + [TextureFormat.RG32F]: $( + TextureFormat.RG, + [TextureType.FLOAT, 8], + 2, + false, + false, + true + ), + [TextureFormat.RG32I]: $( + TextureFormat.RG_INTEGER, + [TextureType.INT, 8], + 2, + true + ), + [TextureFormat.RG32UI]: $( + TextureFormat.RG_INTEGER, + [TextureType.UNSIGNED_INT, 8], + 2, + true + ), + [TextureFormat.RG8_SNORM]: $( + TextureFormat.RG, + [TextureType.BYTE, 2], + 2, + false, + true + ), + [TextureFormat.RG8]: $( + TextureFormat.RG, + [TextureType.UNSIGNED_BYTE, 2], + 2, + true, + true + ), + [TextureFormat.RG8I]: $( + TextureFormat.RG_INTEGER, + [TextureType.BYTE, 2], + 2, + true + ), + [TextureFormat.RG8UI]: $( + TextureFormat.RG_INTEGER, + [TextureType.UNSIGNED_BYTE, 2], + 2, + true + ), + [TextureFormat.RGB]: $( + TextureFormat.RGB, + [ + TextureType.UNSIGNED_BYTE, + 3, + TextureType.HALF_FLOAT, + 6, + TextureType.HALF_FLOAT_OES, + 6, + TextureType.FLOAT, + 12, + TextureType.UNSIGNED_SHORT_5_6_5, + 2 + ], + 3, + true, + true + ), + [TextureFormat.RGB10_A2]: $( + TextureFormat.RGBA, + [TextureType.UNSIGNED_INT_2_10_10_10_REV, 4], + 4, + true, + true + ), + [TextureFormat.RGB10_A2UI]: $( + TextureFormat.RGBA_INTEGER, + [TextureType.UNSIGNED_INT_2_10_10_10_REV, 4], + 4, + true + ), + [TextureFormat.RGB16F]: $( + TextureFormat.RGB, + [TextureType.FLOAT, 12, TextureType.HALF_FLOAT, 6], + 3, + false, + true + ), + [TextureFormat.RGB16I]: $( + TextureFormat.RGB_INTEGER, + [TextureType.SHORT, 6], + 3 + ), + [TextureFormat.RGB16UI]: $( + TextureFormat.RGB_INTEGER, + [TextureType.UNSIGNED_SHORT, 6], + 3 + ), + [TextureFormat.RGB32F]: $(TextureFormat.RGB, [TextureType.FLOAT, 12], 3), + [TextureFormat.RGB32I]: $( + TextureFormat.RGB_INTEGER, + [TextureType.INT, 12], + 3 + ), + [TextureFormat.RGB32UI]: $( + TextureFormat.RGB_INTEGER, + [TextureType.UNSIGNED_INT, 12], + 3 + ), + [TextureFormat.RGB5_A1]: $( + TextureFormat.RGBA, + [ + TextureType.UNSIGNED_BYTE, + 4, + TextureType.UNSIGNED_SHORT_5_5_5_1, + 2, + TextureType.UNSIGNED_INT_2_10_10_10_REV, + 4 + ], + 4, + true, + true + ), + [TextureFormat.RGB565]: $( + TextureFormat.RGB, + [TextureType.UNSIGNED_BYTE, 3, TextureType.UNSIGNED_SHORT_5_6_5, 2], + 3, + true, + true + ), + [TextureFormat.RGB8_SNORM]: $( + TextureFormat.RGB, + [TextureType.BYTE, 3], + 3, + false, + true + ), + [TextureFormat.RGB8]: $( + TextureFormat.RGB, + [TextureType.UNSIGNED_BYTE, 3], + 3, + true, + true + ), + [TextureFormat.RGB8I]: $( + TextureFormat.RGB_INTEGER, + [TextureType.BYTE, 3], + 3 + ), + [TextureFormat.RGB8UI]: $( + TextureFormat.RGB_INTEGER, + [TextureType.UNSIGNED_BYTE, 3], + 3 + ), + [TextureFormat.RGB9_E5]: $( + TextureFormat.RGB, + [ + TextureType.FLOAT, + 12, + TextureType.HALF_FLOAT, + 6, + TextureType.UNSIGNED_INT_5_9_9_9_REV, + 4 + ], + 3, + false, + true + ), + [TextureFormat.RGBA]: $( + TextureFormat.RGBA, + [ + TextureType.UNSIGNED_BYTE, + 4, + TextureType.HALF_FLOAT, + 8, + TextureType.HALF_FLOAT_OES, + 8, + TextureType.FLOAT, + 16, + TextureType.UNSIGNED_SHORT_4_4_4_4, + 2, + TextureType.UNSIGNED_SHORT_5_5_5_1, + 2 + ], + 4, + true, + true + ), + [TextureFormat.RGBA16F]: $( + TextureFormat.RGBA, + [TextureType.FLOAT, 16, TextureType.HALF_FLOAT, 8], + 4, + false, + true, + true + ), + [TextureFormat.RGBA16I]: $( + TextureFormat.RGBA_INTEGER, + [TextureType.SHORT, 8], + 4, + true + ), + [TextureFormat.RGBA16UI]: $( + TextureFormat.RGBA_INTEGER, + [TextureType.UNSIGNED_SHORT, 8], + 4, + true + ), + [TextureFormat.RGBA32F]: $( + TextureFormat.RGBA, + [TextureType.FLOAT, 16], + 4, + false, + false, + true + ), + [TextureFormat.RGBA32I]: $( + TextureFormat.RGBA_INTEGER, + [TextureType.INT, 16], + 4, + true + ), + [TextureFormat.RGBA32UI]: $( + TextureFormat.RGBA_INTEGER, + [TextureType.UNSIGNED_INT, 16], + 4, + true + ), + [TextureFormat.RGBA4]: $( + TextureFormat.RGBA, + [TextureType.UNSIGNED_BYTE, 4, TextureType.UNSIGNED_SHORT_4_4_4_4, 2], + 4, + true, + true + ), + [TextureFormat.RGBA8_SNORM]: $( + TextureFormat.RGBA, + [TextureType.BYTE, 4], + 4, + false, + true + ), + [TextureFormat.RGBA8]: $( + TextureFormat.RGBA, + [TextureType.UNSIGNED_BYTE, 4], + 4, + true, + true + ), + [TextureFormat.RGBA8I]: $( + TextureFormat.RGBA_INTEGER, + [TextureType.BYTE, 4], + 4, + true + ), + [TextureFormat.RGBA8UI]: $( + TextureFormat.RGBA_INTEGER, + [TextureType.UNSIGNED_BYTE, 4], + 4, + true + ), + [TextureFormat.SRGB8_ALPHA8]: $( + TextureFormat.RGBA, + [TextureType.UNSIGNED_BYTE, 4], + 4, + true, + true + ), + [TextureFormat.SRGB8]: $( + TextureFormat.RGB, + [TextureType.UNSIGNED_BYTE, 3], + 3, + false, + true + ) +}; + +export type ReadableTextureFormat = + | TextureFormat.ALPHA + | TextureFormat.RED + | TextureFormat.RG + | TextureFormat.RGB + | TextureFormat.RGBA + | TextureFormat.RED_INTEGER + | TextureFormat.RG_INTEGER + | TextureFormat.RGB_INTEGER + | TextureFormat.RGBA_INTEGER; + +// export const RENDERABLE_TEX_FORMATS = Object.keys(TEX_FORMATS).filter( +// (id) => TEX_FORMATS[id].render! +// ); + +// export const FILTERABLE_TEX_FORMATS = Object.keys(TEX_FORMATS).filter( +// (id) => TEX_FORMATS[id].filter! +// ); + +export interface TextureOpts { + image: ArrayBufferView | TexImageSource | null; + target: TextureTarget; + type: TextureType; + filter: TextureFilter | [TextureFilter, TextureFilter?]; + wrap: TextureRepeat | [TextureRepeat, TextureRepeat?, TextureRepeat?]; + lod: [number, number?]; + minMaxLevel: [number, number]; + level: number; + format: TextureFormat; + width: number; + height: number; + depth: number; + mipmap: boolean; + flip: boolean; + premultiply: boolean; + sub: boolean; + pos: number[]; +} + +export interface ITexture + extends IBind, + IConfigure>, + IRelease { + tex: WebGLTexture; + target: TextureTarget; + format: TextureFormat; + type: TextureType; + size: number[]; +} diff --git a/packages/webgl/src/buffer.ts b/packages/webgl/src/buffer.ts index 336362bcfa..be9b5f9621 100644 --- a/packages/webgl/src/buffer.ts +++ b/packages/webgl/src/buffer.ts @@ -1,13 +1,9 @@ import { TypedArray } from "@thi.ng/api"; import { AttribPool } from "@thi.ng/vector-pools"; -import { - IndexBufferSpec, - IWebGLBuffer, - ModelAttributeSpecs, - ModelSpec -} from "./api"; +import { IndexBufferSpec, IWebGLBuffer } from "./api/buffers"; +import { ModelAttributeSpecs, ModelSpec } from "./api/model"; +import { isGL2Context } from "./checks"; import { error } from "./error"; -import { isGL2Context } from "./utils"; export class WebGLArrayBuffer implements IWebGLBuffer { gl: WebGLRenderingContext; diff --git a/packages/webgl/src/canvas.ts b/packages/webgl/src/canvas.ts index 46d5ebb7bb..aeda69e730 100644 --- a/packages/webgl/src/canvas.ts +++ b/packages/webgl/src/canvas.ts @@ -1,5 +1,6 @@ import { isString } from "@thi.ng/checks"; -import { WebGLExtensionMap, WeblGLCanvasOpts } from "./api"; +import { WeblGLCanvasOpts } from "./api/canvas"; +import { WebGLExtensionMap } from "./api/ext"; import { error } from "./error"; const defaultOpts: WebGLContextAttributes = { diff --git a/packages/webgl/src/checks.ts b/packages/webgl/src/checks.ts new file mode 100644 index 0000000000..cc70c4dc78 --- /dev/null +++ b/packages/webgl/src/checks.ts @@ -0,0 +1,13 @@ +import { ITexture, TextureType } from "./api/texture"; + +export const isGL2Context = ( + gl: WebGLRenderingContext +): gl is WebGL2RenderingContext => + typeof WebGL2RenderingContext !== "undefined" && + gl instanceof WebGL2RenderingContext; + +export const isFloatTexture = (tex: ITexture) => + tex.type === TextureType.FLOAT || + tex.type === TextureType.HALF_FLOAT || + tex.type === TextureType.HALF_FLOAT_OES || + tex.type === TextureType.FLOAT_32_UNSIGNED_INT_24_8_REV; diff --git a/packages/webgl/src/draw.ts b/packages/webgl/src/draw.ts index 231ae20945..6b005adfba 100644 --- a/packages/webgl/src/draw.ts +++ b/packages/webgl/src/draw.ts @@ -1,8 +1,8 @@ import { isArray } from "@thi.ng/checks"; -import { ModelSpec } from "./api"; +import { ModelSpec } from "./api/model"; +import { isGL2Context } from "./checks"; import { error } from "./error"; import { bindTextures } from "./texture"; -import { isGL2Context } from "./utils"; export const draw = (specs: ModelSpec | ModelSpec[]) => { const _specs = isArray(specs) ? specs : [specs]; diff --git a/packages/webgl/src/fbo.ts b/packages/webgl/src/fbo.ts index edd11bc728..f102a231bc 100644 --- a/packages/webgl/src/fbo.ts +++ b/packages/webgl/src/fbo.ts @@ -1,14 +1,12 @@ import { assert } from "@thi.ng/api"; -import { - FboOpts, - GL_COLOR_ATTACHMENT0_WEBGL, - GL_MAX_COLOR_ATTACHMENTS_WEBGL, - IFbo, - ITexture -} from "./api"; +import { FboOpts, IFbo } from "./api/buffers"; +import { ITexture, TEX_FORMATS } from "./api/texture"; +import { isGL2Context } from "./checks"; import { error } from "./error"; import { RBO } from "./rbo"; -import { isGL2Context } from "./utils"; + +const GL_COLOR_ATTACHMENT0_WEBGL = 0x8ce0; +const GL_MAX_COLOR_ATTACHMENTS_WEBGL = 0x8cdf; /** * WebGL framebuffer wrapper w/ automatic detection & support for @@ -34,10 +32,11 @@ export class FBO implements IFbo { constructor(gl: WebGLRenderingContext, opts?: Partial) { this.gl = gl; this.fbo = gl.createFramebuffer() || error("error creating FBO"); - this.ext = (!isGL2Context(gl) && opts && opts!.tex && opts!.tex!.length > 1) - ? gl.getExtension("WEBGL_draw_buffers") || - error("missing WEBGL_draw_buffers ext") - : undefined; + this.ext = + !isGL2Context(gl) && opts && opts!.tex && opts!.tex!.length > 1 + ? gl.getExtension("WEBGL_draw_buffers") || + error("missing WEBGL_draw_buffers ext") + : undefined; this.maxAttachments = gl.getParameter(GL_MAX_COLOR_ATTACHMENTS_WEBGL); opts && this.configure(opts); } @@ -69,12 +68,20 @@ export class FBO implements IFbo { ); const attachments: number[] = []; for (let i = 0; i < opts.tex.length; i++) { + const tex = opts.tex[i]; + assert( + !!( + TEX_FORMATS[tex.format].render || + TEX_FORMATS[tex.format].renderExt + ), + `texture #${i} has non-renderable format` + ); const attach = GL_COLOR_ATTACHMENT0_WEBGL + i; gl.framebufferTexture2D( gl.FRAMEBUFFER, attach, gl.TEXTURE_2D, - opts.tex[i].tex, + tex.tex, 0 ); attachments[i] = attach; diff --git a/packages/webgl/src/geo/cube.ts b/packages/webgl/src/geo/cube.ts index 9fe00b1bc7..365c3d1b16 100644 --- a/packages/webgl/src/geo/cube.ts +++ b/packages/webgl/src/geo/cube.ts @@ -1,4 +1,4 @@ -import { ModelSpec } from "../api"; +import { ModelSpec } from "../api/model"; export interface CubeOpts { size: number; diff --git a/packages/webgl/src/geo/quad.ts b/packages/webgl/src/geo/quad.ts index bae6ee1423..245731247f 100644 --- a/packages/webgl/src/geo/quad.ts +++ b/packages/webgl/src/geo/quad.ts @@ -1,4 +1,4 @@ -import { ModelSpec } from "../api"; +import { ModelSpec } from "../api/model"; export const quad = (uv = true): ModelSpec => ({ attribs: { diff --git a/packages/webgl/src/gpgpu.ts b/packages/webgl/src/gpgpu.ts deleted file mode 100644 index 20bb105ce0..0000000000 --- a/packages/webgl/src/gpgpu.ts +++ /dev/null @@ -1,282 +0,0 @@ -import { assert, IRelease } from "@thi.ng/api"; -import { mergeDeepObj } from "@thi.ng/associative"; -import { ceilPow2 } from "@thi.ng/binary"; -import { isNumber, isTypedArray } from "@thi.ng/checks"; -import { illegalArgs } from "@thi.ng/errors"; -import { - assocObj, - map, - range, - transduce -} from "@thi.ng/transducers"; -import { - GL_RGBA, - GL_RGBA32F, - GPGPUJobConfig, - GPGPUJobExecOpts, - GPGPUOpts, - GPGPUTextureConfig, - ITexture, - ModelSpec, - ShaderSpec -} from "./api"; -import { compileModel } from "./buffer"; -import { getExtensions, glCanvas } from "./canvas"; -import { draw } from "./draw"; -import { FBO } from "./fbo"; -import { quad } from "./geo/quad"; -import { FX_SHADER_SPEC } from "./pipeline"; -import { shader } from "./shader"; -import { floatTexture, texture } from "./texture"; -import { isGL2Context } from "./utils"; - -export const gpgpu = (opts: GPGPUOpts) => new GPGPU(opts); - -interface GPGPUIO { - tex: ITexture; - opts: GPGPUTextureConfig; -} - -export class GPGPU implements IRelease { - canvas?: HTMLCanvasElement; - gl: WebGLRenderingContext; - fbo: FBO; - inputs: GPGPUIO[]; - outputs: GPGPUIO[]; - spec: ModelSpec; - opts: GPGPUOpts; - width: number; - size: number; - - constructor(opts: GPGPUOpts) { - opts = { version: 1, inputs: 1, outputs: 1, ...opts }; - const width = ceilPow2(Math.ceil(Math.sqrt(opts.size / 4))); - let gl; - if (opts.gl) { - gl = opts.gl; - opts.version = isGL2Context(gl) ? 2 : 1; - } else { - const res = glCanvas({ - opts: { antialias: false, alpha: false, depth: false }, - width: 1, - height: 1, - autoScale: false, - version: opts.version - }); - this.canvas = res.canvas; - gl = res.gl; - } - getExtensions( - gl, - opts.version === 1 - ? ["WEBGL_color_buffer_float", "OES_texture_float"] - : ["EXT_color_buffer_float"] - ); - this.gl = gl; - this.opts = opts; - this.width = width; - this.size = width * width; - // let tmp = new Float32Array(this.size); - this.inputs = this.initTextures(opts.inputs!); - this.outputs = this.initTextures(opts.outputs!); - // tmp = null; - this.fbo = new FBO(gl); - this.spec = compileModel(gl, { - ...quad(), - textures: this.inputs.map((t) => t.tex) - }); - } - - inputSize(id: number) { - return this.inputs[id].opts.stride * this.size; - } - - outputSize(id: number) { - return this.outputs[id].opts.stride * this.size; - } - - newJob(opts: Partial) { - return new GPGPUJob(this, opts); - } - - release() { - this.fbo.release(); - for (let t of this.inputs) { - t.tex.release(); - } - for (let t of this.outputs) { - t.tex.release(); - } - delete this.inputs; - delete this.outputs; - delete this.spec; - delete this.canvas; - delete this.gl; - delete this.fbo; - delete this.opts; - return true; - } - - protected initTextures(specs: number | GPGPUTextureConfig[]) { - const gl = this.gl; - const width = this.width; - if (isNumber(specs)) { - return [ - ...map( - () => - { - tex: floatTexture(gl, null, width, width), - opts: { stride: 4 } - }, - range(specs) - ) - ]; - } else { - return specs.map( - (opts) => - { - tex: texture(gl, { - image: null, - width: width, - height: width, - filter: gl.NEAREST, - wrap: gl.CLAMP_TO_EDGE, - ...opts - }), - opts - } - ); - } - } -} - -export class GPGPUJob implements IRelease { - ctx: GPGPU; - spec: ModelSpec; - opts: GPGPUJobConfig; - - constructor(ctx: GPGPU, opts: Partial) { - opts = { - inputs: 1, - outputs: 1, - ...opts - }; - assert( - opts.inputs! <= ctx.opts.inputs!, - `context only supports max. ${ctx.opts.inputs} inputs` - ); - assert( - opts.outputs! <= ctx.opts.outputs!, - `context only supports max. ${ctx.opts.outputs} outputs` - ); - this.ctx = ctx; - this.opts = opts; - this.spec = this.buildSpec(); - } - - run(runOpts: GPGPUJobExecOpts) { - const inputs = runOpts.inputs; - const outputs = runOpts.outputs || [...range(this.opts.outputs!)]; - assert(inputs.length <= this.opts.inputs, "too many inputs"); - assert(outputs.length <= this.opts.outputs!, "too many outputs"); - const ctx = this.ctx; - const gl = ctx.gl; - const width = ctx.width; - const internalFormat = ctx.opts.version === 2 ? GL_RGBA32F : GL_RGBA; - const spec = this.spec; - for (let i = 0; i < inputs.length; i++) { - let tex = inputs[i]; - if (isTypedArray(tex)) { - const expectedSize = ctx.inputSize(i); - assert( - tex.length >= expectedSize, - `input #${i} too small (got ${ - tex.length - }, expected ${expectedSize})` - ); - const input = ctx.inputs[i]; - input.tex.configure({ - image: tex, - type: input.opts.type || gl.FLOAT, - internalFormat: input.opts.internalFormat || internalFormat, - format: input.opts.format || GL_RGBA, - filter: gl.NEAREST, - wrap: gl.CLAMP_TO_EDGE, - height: width, - width - }); - tex = input.tex; - } - spec.textures![i] = tex; - } - spec.uniforms = { ...spec.uniforms, ...runOpts.uniforms }; - ctx.fbo.configure({ tex: outputs.map((i) => ctx.outputs[i].tex) }); - gl.viewport(0, 0, width, width); - draw(spec); - return this; - } - - result(out?: Float32Array | null, id = 0) { - const ctx = this.ctx; - const width = ctx.width; - const gl = ctx.gl; - const output = ctx.outputs[id]; - const opts = output.opts; - const fbo = new FBO(gl, { tex: [output.tex] }); - out = out || new Float32Array(ctx.outputSize(id)); - gl.readPixels( - 0, - 0, - width, - width, - opts.format || gl.RGBA, - opts.type || gl.FLOAT, - out - ); - fbo.release(); - return out; - } - - release() { - this.spec.shader.release(); - delete this.spec; - delete this.ctx; - return true; - } - - protected buildSpec() { - const opts = this.opts; - const ctx = this.ctx; - const spec: ModelSpec = mergeDeepObj({}, ctx.spec); - let shaderSpec: ShaderSpec; - if (opts.src) { - shaderSpec = { - ...FX_SHADER_SPEC, - pre: `#define WIDTH (${ctx.width})\n#define SIZE (ivec2(${ - ctx.width - }))`, - fs: opts.src, - uniforms: { ...opts.uniforms }, - outputs: transduce( - map((i) => [`output${i}`, ["vec4", i]]), - assocObj(), - range(opts.outputs!) - ) - }; - } else if (opts.shader) { - shaderSpec = opts.shader; - shaderSpec.uniforms = shaderSpec.uniforms || {}; - shaderSpec.ext = shaderSpec.ext || {}; - } else { - return illegalArgs("require either `src` or `shader` option"); - } - shaderSpec.uniforms!.inputs = ["sampler2D[]", opts.inputs]; - if (ctx.opts.version === 1 && opts.outputs! > 1) { - shaderSpec.ext!.WEBGL_draw_buffers = "require"; - } - spec.uniforms!.inputs = [...range(opts.inputs)]; - spec.textures = ctx.inputs.slice(0, opts.inputs).map((t) => t.tex); - spec.shader = shader(ctx.gl, shaderSpec); - return spec; - } -} diff --git a/packages/webgl/src/index.ts b/packages/webgl/src/index.ts index 51f39e20c0..d9cc6e9ff0 100644 --- a/packages/webgl/src/index.ts +++ b/packages/webgl/src/index.ts @@ -1,14 +1,24 @@ -export * from "./api"; +export * from "./api/blend"; +export * from "./api/buffers"; +export * from "./api/canvas"; +export * from "./api/ext"; +export * from "./api/glsl"; +export * from "./api/material"; +export * from "./api/model"; +export * from "./api/shader"; +export * from "./api/texture"; + export * from "./buffer"; export * from "./canvas"; +export * from "./checks"; export * from "./draw"; export * from "./error"; export * from "./fbo"; -export * from "./gpgpu"; export * from "./material"; export * from "./matrices"; -export * from "./pipeline"; +export * from "./multipass"; export * from "./rbo"; +export * from "./readpixels"; export * from "./shader"; export * from "./syntax"; export * from "./texture"; @@ -16,6 +26,7 @@ export * from "./utils"; export * from "./shaders/lambert"; export * from "./shaders/phong"; +export * from "./shaders/pipeline"; export * from "./textures/checkerboard"; export * from "./textures/stripes"; diff --git a/packages/webgl/src/material.ts b/packages/webgl/src/material.ts index e09ac7a6d9..fe9065bc88 100644 --- a/packages/webgl/src/material.ts +++ b/packages/webgl/src/material.ts @@ -1,4 +1,6 @@ -import { GLSL, Material, ShaderUniformSpecs } from "./api"; +import { GLSL } from "./api/glsl"; +import { Material } from "./api/material"; +import { ShaderUniformSpecs } from "./api/shader"; export const DEFAULT_MATERIAL: Material = { ambientCol: [0.1, 0.1, 0.1], diff --git a/packages/webgl/src/matrices.ts b/packages/webgl/src/matrices.ts index 680c4a2788..879c97279a 100644 --- a/packages/webgl/src/matrices.ts +++ b/packages/webgl/src/matrices.ts @@ -7,7 +7,8 @@ import { ortho } from "@thi.ng/matrices"; import { ReadonlyVec } from "@thi.ng/vectors"; -import { GLMat4, ShaderUniforms } from "./api"; +import { GLMat4 } from "./api/glsl"; +import { ShaderUniforms } from "./api/shader"; const $ = (a: any, b: any, id: string) => a[id] || b[id].defaultVal || IDENT44; diff --git a/packages/webgl/src/multipass.ts b/packages/webgl/src/multipass.ts new file mode 100644 index 0000000000..96f9099e1d --- /dev/null +++ b/packages/webgl/src/multipass.ts @@ -0,0 +1,161 @@ +import { assert, IObjectOf } from "@thi.ng/api"; +import { + assocObj, + map, + range, + some, + transduce +} from "@thi.ng/transducers"; +import { ExtensionBehaviors } from "./api/ext"; +import { Multipass, MultipassOpts, PassOpts } from "./api/multipass"; +import { ShaderSpec, ShaderUniformSpecs } from "./api/shader"; +import { ITexture } from "./api/texture"; +import { compileModel } from "./buffer"; +import { isFloatTexture, isGL2Context } from "./checks"; +import { draw } from "./draw"; +import { fbo } from "./fbo"; +import { quad } from "./geo/quad"; +import { shader } from "./shader"; +import { PASSTHROUGH_VS } from "./shaders/pipeline"; +import { texture } from "./texture"; + +export const multipass = (opts: MultipassOpts) => { + const gl = opts.gl; + const isGL2 = isGL2Context(gl); + const numPasses = opts.passes.length; + assert(numPasses > 0, "require at least one shader pass"); + + const initShader = (pass: PassOpts) => { + const numIns = pass.inputs.length; + const numOuts = pass.outputs.length; + const ext: ExtensionBehaviors = {}; + const spec: ShaderSpec = { + vs: pass.vs || PASSTHROUGH_VS, + fs: pass.fs, + attribs: pass.attribs || { + position: "vec2" + }, + varying: pass.varying, + uniforms: { + ...pass.uniforms, + ...(numIns + ? { + inputs: ["sampler2D[]", numIns, [...range(numIns)]] + } + : null) + }, + outputs: numOuts + ? transduce( + map((i) => [`output${i}`, ["vec4", i]]), + assocObj(), + range(numOuts) + ) + : undefined, + state: pass.state, + pre: pass.pre, + post: pass.post, + replacePrelude: pass.replacePrelude, + generateDecls: pass.generateDecls, + ext + }; + const floatIn = some((id) => isFloatTexture(textures[id]), pass.inputs); + const floatOut = some( + (id) => isFloatTexture(textures[id]), + pass.outputs + ); + if (!isGL2) { + floatIn && (ext.OES_texture_float = "require"); + numOuts > 1 && (ext.WEBGL_draw_buffers = "require"); + } + if (floatOut) { + ext[isGL2 ? "EXT_color_buffer_float" : "WEBGL_color_buffer_float"] = + "require"; + } + return shader(gl, spec); + }; + + const textures = Object.keys(opts.textures).reduce( + (acc, id) => { + acc[id] = texture(gl, { + width: opts.width, + height: opts.height, + filter: gl.NEAREST, + wrap: gl.CLAMP_TO_EDGE, + image: null, + ...opts.textures[id] + }); + return acc; + }, + >{} + ); + + const model = compileModel(gl, quad(false)); + const models = opts.passes.map((pass) => { + const m = pass.model ? compileModel(gl, pass.model) : { ...model }; + m.shader = initShader(pass); + m.uniforms = { ...pass.uniformVals }; + pass.inputs.length > 0 && + (m.textures = pass.inputs.map((id) => textures[id])); + return m; + }); + + const useMainBuffer = !opts.passes[numPasses - 1].outputs.length; + const fbos = (useMainBuffer + ? opts.passes.slice(0, numPasses - 1) + : opts.passes + ).map((pass) => fbo(gl, { tex: pass.outputs.map((id) => textures[id]) })); + + const drawPass = (i: number, time: number) => { + const pass = opts.passes[i]; + const model = models[i]; + const shader = model.shader; + const size = pass.outputs.length + ? textures[pass.outputs[0]].size + : [gl.drawingBufferWidth, gl.drawingBufferHeight]; + shader.uniforms.resolution && (model.uniforms!.resolution = size); + shader.uniforms.time && (model.uniforms!.time = time); + gl.viewport(0, 0, size[0], size[1]); + draw(model); + }; + + const update = (time: number) => { + for (let i = 0; i < fbos.length; i++) { + fbos[i].bind(); + drawPass(i, time); + fbos[i].unbind(); + } + useMainBuffer && drawPass(numPasses - 1, time); + }; + + const updateRAF = () => { + update((Date.now() - t0) * 1e-3); + active && (rafID = requestAnimationFrame(updateRAF)); + }; + + let active: boolean; + let t0 = Date.now(); + let rafID: number; + + const instance: Multipass = { + start() { + t0 = Date.now(); + active = true; + rafID = requestAnimationFrame(updateRAF); + }, + stop() { + if (active) { + active = false; + cancelAnimationFrame(rafID); + } + }, + update(time: number) { + update(time); + }, + passes: opts.passes, + fbos, + models, + textures + }; + + return instance; +}; diff --git a/packages/webgl/src/pipeline.ts b/packages/webgl/src/pipeline.ts deleted file mode 100644 index 2de1748f84..0000000000 --- a/packages/webgl/src/pipeline.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { - assign, - defMain, - FLOAT0, - FLOAT1, - texture, - vec4 -} from "@thi.ng/shader-ast"; -import { ShaderFn, ShaderSpec } from "./api"; - -export const PASSTHROUGH_VS: ShaderFn = (gl, _, ins, outs) => [ - defMain(() => [ - assign(outs.v_uv, ins.uv), - assign(gl.gl_Position, vec4(ins.position, FLOAT0, FLOAT1)) - ]) -]; - -export const PASSTHROUGH_FS: ShaderFn = (_, unis, ins, outs) => [ - defMain(() => [assign(outs.fragColor, texture(unis.tex, ins.v_uv))]) -]; - -export const FX_SHADER_SPEC: ShaderSpec = { - vs: PASSTHROUGH_VS, - fs: PASSTHROUGH_FS, - attribs: { position: "vec2", uv: "vec2" }, - varying: { v_uv: "vec2" }, - uniforms: { tex: "sampler2D" }, - state: { depth: false }, - ext: {} -}; diff --git a/packages/webgl/src/rbo.ts b/packages/webgl/src/rbo.ts index 2cb991afba..e20951abed 100644 --- a/packages/webgl/src/rbo.ts +++ b/packages/webgl/src/rbo.ts @@ -1,4 +1,4 @@ -import { IRenderBuffer, RboOpts } from "./api"; +import { IRenderBuffer, RboOpts } from "./api/buffers"; import { error } from "./error"; export class RBO implements IRenderBuffer { diff --git a/packages/webgl/src/readpixels.ts b/packages/webgl/src/readpixels.ts new file mode 100644 index 0000000000..4edfd2dfdf --- /dev/null +++ b/packages/webgl/src/readpixels.ts @@ -0,0 +1,34 @@ +import { ITexture, ReadableTextureFormat, TextureType } from "./api/texture"; +import { FBO } from "./fbo"; + +export const readPixels = < + T extends Uint8Array | Uint16Array | Uint32Array | Float32Array +>( + gl: WebGLRenderingContext, + x: number, + y: number, + w: number, + h: number, + format: ReadableTextureFormat, + type: TextureType, + out: T +) => { + gl.readPixels(x, y, w, h, format, type, out); + return out; +}; + +export const readTexture = < + T extends Uint8Array | Uint16Array | Uint32Array | Float32Array +>( + gl: WebGLRenderingContext, + tex: ITexture, + format: ReadableTextureFormat, + type: TextureType, + out: T +) => { + const fbo = new FBO(gl, { tex: [tex] }); + gl.readPixels(0, 0, tex.size[0], tex.size[1], format, type, out); + fbo.unbind(); + fbo.release(); + return out; +}; diff --git a/packages/webgl/src/shader.ts b/packages/webgl/src/shader.ts index 81f8c6aed4..125cd68122 100644 --- a/packages/webgl/src/shader.ts +++ b/packages/webgl/src/shader.ts @@ -17,15 +17,18 @@ import { } from "@thi.ng/shader-ast"; import { GLSLVersion, targetGLSL } from "@thi.ng/shader-ast-glsl"; import { vals } from "@thi.ng/transducers"; +import { + ExtensionBehavior, + ExtensionBehaviors, + ExtensionName, + GL_EXT_INFO +} from "./api/ext"; +import { GLSL } from "./api/glsl"; +import { ModelAttributeSpecs, ModelSpec } from "./api/model"; import { DEFAULT_OUTPUT, - GL_EXT_INFO, - GLSL, GLSLDeclPrefixes, - GLSLExtensionBehavior, IShader, - ModelAttributeSpecs, - ModelSpec, ShaderAttrib, ShaderAttribSpecs, ShaderFn, @@ -37,12 +40,12 @@ import { ShaderUniformSpecs, UniformValue, UniformValues -} from "./api"; +} from "./api/shader"; import { getExtensions } from "./canvas"; +import { isGL2Context } from "./checks"; import { error } from "./error"; import { GLSL_HEADER, NO_PREFIXES, SYNTAX } from "./syntax"; import { UNIFORM_SETTERS } from "./uniforms"; -import { isGL2Context } from "./utils"; const ERROR_REGEXP = /ERROR: \d+:(\d+): (.*)/; @@ -233,13 +236,13 @@ const compileVars = ( const compileExtensionPragma = ( id: string, - behavior: GLSLExtensionBehavior, + behavior: ExtensionBehavior, version: GLSLVersion ) => { - const ext = (GL_EXT_INFO)[id]; + const ext = GL_EXT_INFO[id]; const gl2 = version === GLSLVersion.GLES_300; - return !ext || (!gl2 && ext.gl) || (gl2 && ext.gl2) - ? `#extension ${ext.alias || id} : ${ + return ext && ((!gl2 && ext.gl) || (gl2 && ext.gl2)) + ? `#extension ${(ext && ext.alias) || id} : ${ isBoolean(behavior) ? (behavior ? "enable" : "disable") : behavior }\n` : ""; @@ -247,11 +250,11 @@ const compileExtensionPragma = ( const initShaderExtensions = ( gl: WebGLRenderingContext, - exts: IObjectOf | undefined + exts: ExtensionBehaviors | undefined ) => { if (exts) { for (let id in exts) { - const state = exts[id]; + const state = exts[id]; if (state === true || state === "require") { getExtensions(gl, [id], state === "require"); } @@ -272,7 +275,11 @@ export const shaderSourceFromAST = ( : GLSL_HEADER; if (spec.ext) { for (let id in spec.ext) { - prelude += compileExtensionPragma(id, spec.ext[id], version); + prelude += compileExtensionPragma( + id, + spec.ext[id]!, + version + ); } } const inputs: IObjectOf> = {}; @@ -370,7 +377,11 @@ export const prepareShaderSource = ( : GLSL_HEADER; if (spec.ext) { for (let id in spec.ext) { - src += compileExtensionPragma(id, spec.ext[id], version); + src += compileExtensionPragma( + id, + spec.ext[id]!, + version + ); } } if (spec.generateDecls !== false) { diff --git a/packages/webgl/src/shaders/lambert.ts b/packages/webgl/src/shaders/lambert.ts index 8982375ae9..4c6a09feaa 100644 --- a/packages/webgl/src/shaders/lambert.ts +++ b/packages/webgl/src/shaders/lambert.ts @@ -14,7 +14,8 @@ import { surfaceNormal, transformMVP } from "@thi.ng/shader-ast-stdlib"; -import { Material, ShaderOpts, ShaderSpec } from "../api"; +import { Material } from "../api/material"; +import { ShaderOpts, ShaderSpec } from "../api/shader"; import { defMaterial } from "../material"; import { autoNormalMatrix2 } from "../matrices"; import { colorAttrib, positionAttrib } from "../utils"; diff --git a/packages/webgl/src/shaders/phong.ts b/packages/webgl/src/shaders/phong.ts index 0d86d21fa8..fbf93a9875 100644 --- a/packages/webgl/src/shaders/phong.ts +++ b/packages/webgl/src/shaders/phong.ts @@ -17,7 +17,8 @@ import { vec4 } from "@thi.ng/shader-ast"; import { diffuseLighting, surfaceNormal } from "@thi.ng/shader-ast-stdlib"; -import { Material, ShaderOpts, ShaderSpec } from "../api"; +import { Material } from "../api/material"; +import { ShaderOpts, ShaderSpec } from "../api/shader"; import { defMaterial } from "../material"; import { autoNormalMatrix1 } from "../matrices"; import { colorAttrib, positionAttrib } from "../utils"; diff --git a/packages/webgl/src/shaders/pipeline.ts b/packages/webgl/src/shaders/pipeline.ts new file mode 100644 index 0000000000..87b6e996ca --- /dev/null +++ b/packages/webgl/src/shaders/pipeline.ts @@ -0,0 +1,49 @@ +import { + $xy, + assign, + defMain, + FLOAT0, + FLOAT1, + texture, + vec4 +} from "@thi.ng/shader-ast"; +import { ShaderFn, ShaderSpec } from "../api/shader"; + +export const PASSTHROUGH_VS: ShaderFn = (gl, _, ins) => [ + defMain(() => [assign(gl.gl_Position, vec4(ins.position, FLOAT0, FLOAT1))]) +]; + +export const PASSTHROUGH_VS_UV: ShaderFn = (gl, _, ins, outs) => [ + defMain(() => [ + assign(outs.v_uv, ins.uv), + assign(gl.gl_Position, vec4(ins.position, FLOAT0, FLOAT1)) + ]) +]; + +export const PASSTHROUGH_FS: ShaderFn = (gl, _, __, outs) => [ + defMain(() => [assign(outs.fragColor, $xy(gl.gl_FragCoord))]) +]; + +export const PASSTHROUGH_FS_UV: ShaderFn = (_, unis, ins, outs) => [ + defMain(() => [assign(outs.fragColor, texture(unis.tex, ins.v_uv))]) +]; + +export const FX_SHADER_SPEC: ShaderSpec = { + vs: PASSTHROUGH_VS, + fs: PASSTHROUGH_FS, + attribs: { position: "vec2" }, + varying: {}, + uniforms: {}, + state: { depth: false }, + ext: {} +}; + +export const FX_SHADER_SPEC_UV: ShaderSpec = { + vs: PASSTHROUGH_VS_UV, + fs: PASSTHROUGH_FS_UV, + attribs: { position: "vec2", uv: "vec2" }, + varying: { v_uv: "vec2" }, + uniforms: { tex: "sampler2D" }, + state: { depth: false }, + ext: {} +}; diff --git a/packages/webgl/src/syntax.ts b/packages/webgl/src/syntax.ts index b4ed10c53e..d6b3b81310 100644 --- a/packages/webgl/src/syntax.ts +++ b/packages/webgl/src/syntax.ts @@ -1,6 +1,7 @@ import { isArray } from "@thi.ng/checks"; import { GLSLVersion } from "@thi.ng/shader-ast-glsl"; -import { GLSL, GLSLDeclPrefixes, GLSLSyntax } from "./api"; +import { GLSL } from "./api/glsl"; +import { GLSLDeclPrefixes, GLSLSyntax } from "./api/shader"; export const PREFIXES: GLSLDeclPrefixes = { a: "a_", diff --git a/packages/webgl/src/texture.ts b/packages/webgl/src/texture.ts index e49611282a..9567c076c4 100644 --- a/packages/webgl/src/texture.ts +++ b/packages/webgl/src/texture.ts @@ -1,8 +1,15 @@ import { withoutKeysObj } from "@thi.ng/associative"; import { isArray } from "@thi.ng/checks"; -import { ITexture, TextureOpts } from "./api"; +import { + ITexture, + TEX_FORMATS, + TextureFormat, + TextureOpts, + TextureTarget, + TextureType +} from "./api/texture"; +import { isGL2Context } from "./checks"; import { error } from "./error"; -import { isGL2Context } from "./utils"; export const bindTextures = (textures: ITexture[]) => { if (!textures) return; @@ -14,23 +21,30 @@ export const bindTextures = (textures: ITexture[]) => { export class Texture implements ITexture { gl: WebGLRenderingContext; tex: WebGLTexture; - target: GLenum; + target!: TextureTarget; + format!: TextureFormat; + type!: TextureType; + size!: number[]; constructor(gl: WebGLRenderingContext, opts: Partial = {}) { this.gl = gl; this.tex = gl.createTexture() || error("error creating WebGL texture"); - this.target = opts!.target || gl.TEXTURE_2D; this.configure(opts); } configure(opts: Partial = {}) { const gl = this.gl; const isGL2 = isGL2Context(gl); - const target = this.target; - const imgTarget = opts.target || target; - const format = opts.format || gl.RGBA; - const internalFormat = opts.internalFormat || format; - const type = opts.type || gl.UNSIGNED_BYTE; + const target = opts.target || this.target || TextureTarget.TEXTURE_2D; + const format = opts.format || this.format || TextureFormat.RGBA; + const decl = TEX_FORMATS[format]; + const baseFormat = decl.format; + const type = opts.type || this.type || decl.types[0]; + + !this.target && (this.target = target); + this.format = format; + this.type = type; + let t1: GLenum, t2: GLenum, t3: GLenum; gl.bindTexture(this.target, this.tex); @@ -46,50 +60,94 @@ export class Texture implements ITexture { if (opts.image !== undefined) { const level = opts.level || 0; - const pos = opts.pos || [0, 0]; - if (opts.width && opts.height) { - opts.sub - ? gl.texSubImage2D( - imgTarget, - level, - pos[0], - pos[1], - opts.width, - opts.height, - format, - type, - opts.image - ) - : gl.texImage2D( - imgTarget, - level, - internalFormat, - opts.width, - opts.height, - 0, - format, - type, - opts.image - ); + const pos = opts.pos || [0, 0, 0]; + if (target === TextureTarget.TEXTURE_3D) { + if (opts.width && opts.height && opts.depth) { + if (opts.sub) { + (gl).texSubImage3D( + target, + level, + pos[0], + pos[1], + pos[2], + opts.width, + opts.height, + opts.depth, + baseFormat, + type, + opts.image + ); + } else { + if (level === 0) { + this.size = [opts.width, opts.height, opts.depth]; + } + (gl).texImage3D( + target, + level, + format, + opts.width, + opts.height, + opts.depth, + 0, + baseFormat, + type, + opts.image + ); + } + } } else { - opts.sub - ? gl.texSubImage2D( - imgTarget, - level, - pos[0], - pos[1], - format, - type, - opts.image - ) - : gl.texImage2D( - imgTarget, - level, - internalFormat, - format, - type, - opts.image - ); + if (opts.width && opts.height) { + if (opts.sub) { + gl.texSubImage2D( + target, + level, + pos[0], + pos[1], + opts.width, + opts.height, + baseFormat, + type, + opts.image + ); + } else { + if (level === 0) { + this.size = [opts.width, opts.height]; + } + gl.texImage2D( + target, + level, + format, + opts.width, + opts.height, + 0, + baseFormat, + type, + opts.image + ); + } + } else { + if (opts.sub) { + gl.texSubImage2D( + target, + level, + pos[0], + pos[1], + baseFormat, + type, + opts.image + ); + } else { + if (opts.image != null && level == 0) { + this.size = [ + (opts.image).width, + (opts.image).height + ]; + } + gl.texImage2D(target, level, format, baseFormat, type, < + TexImageSource + >opts.image); + } + } } } @@ -243,22 +301,24 @@ export const cubeMap = ( * @param data texture data * @param width width * @param height height + * @param format + * @param type */ export const floatTexture = ( gl: WebGLRenderingContext, data: Float32Array | undefined | null, width: number, height: number, - internalFormat?: GLenum, - format?: GLenum + format?: TextureFormat, + type?: TextureType ) => new Texture(gl, { filter: gl.NEAREST, wrap: gl.CLAMP_TO_EDGE, - internalFormat: - internalFormat || (isGL2Context(gl) ? gl.RGBA32F : gl.RGBA), - format: format || gl.RGBA, - type: gl.FLOAT, + format: + format || + (isGL2Context(gl) ? TextureFormat.RGBA32F : TextureFormat.RGBA), + type: type || gl.FLOAT, image: data, width, height diff --git a/packages/webgl/src/uniforms.ts b/packages/webgl/src/uniforms.ts index c80f8e1216..1cce5003c1 100644 --- a/packages/webgl/src/uniforms.ts +++ b/packages/webgl/src/uniforms.ts @@ -7,7 +7,8 @@ import { ZERO3, ZERO4 } from "@thi.ng/vectors"; -import { GLVec, UniformValue } from "./api"; +import { GLVec } from "./api/glsl"; +import { UniformValue } from "./api/shader"; type SetterS = "f" | "i" | "ui"; diff --git a/packages/webgl/src/utils.ts b/packages/webgl/src/utils.ts index 625522d3f5..3059f6e55c 100644 --- a/packages/webgl/src/utils.ts +++ b/packages/webgl/src/utils.ts @@ -5,13 +5,7 @@ import { Sym, Term } from "@thi.ng/shader-ast"; -import { ShaderOpts } from "./api"; - -export const isGL2Context = ( - gl: WebGLRenderingContext -): gl is WebGL2RenderingContext => - typeof WebGL2RenderingContext !== "undefined" && - gl instanceof WebGL2RenderingContext; +import { ShaderOpts } from "./api/shader"; export const positionAttrib = ( opts: Partial>,