p5.tree 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -30
- package/dist/p5.tree.esm.js +26 -26
- package/dist/p5.tree.esm.js.map +1 -1
- package/dist/p5.tree.js +26 -26
- package/dist/p5.tree.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# p5.tree
|
|
2
|
+
[](https://www.npmjs.com/package/p5.tree)
|
|
2
3
|
|
|
3
4
|
Shader development, camera keyframes interpolation and space transformations for [WEBGL](https://p5js.org/reference/#/p5/WEBGL) / WebGPU-ready [p5.js v2](https://beta.p5js.org/).
|
|
4
5
|
|
|
@@ -188,8 +189,8 @@ This section covers matrix operations, matrix/frustum queries, and coordinate sp
|
|
|
188
189
|
|
|
189
190
|
## Coordinate space conversions
|
|
190
191
|
|
|
191
|
-
1. `
|
|
192
|
-
2. `
|
|
192
|
+
1. `mapLocation(point = p5.Tree.ORIGIN, [{ [from = p5.Tree.EYE], [to = p5.Tree.WORLD], [pMatrix], [vMatrix], [eMatrix], [pvMatrix], [ipvMatrix] }])`
|
|
193
|
+
2. `mapDirection(vector = p5.Tree._k, [{ [from = p5.Tree.EYE], [to = p5.Tree.WORLD], [vMatrix], [eMatrix], [pMatrix] }])`
|
|
193
194
|
|
|
194
195
|
Pass matrix parameters when you have **cached** those matrices (see [Matrix queries](#matrix-queries)) to speed up repeated conversions:
|
|
195
196
|
|
|
@@ -200,8 +201,8 @@ function draw() {
|
|
|
200
201
|
cachedPVI = ipvMatrix() // compute once per frame
|
|
201
202
|
|
|
202
203
|
// many fast conversions using the cached matrix
|
|
203
|
-
const a =
|
|
204
|
-
const b =
|
|
204
|
+
const a = mapLocation([0, 0, 0], { from: p5.Tree.WORLD, to: p5.Tree.SCREEN, ipvMatrix: cachedPVI })
|
|
205
|
+
const b = mapLocation([100, 0, 0], { from: p5.Tree.WORLD, to: p5.Tree.SCREEN, ipvMatrix: cachedPVI })
|
|
205
206
|
// ...
|
|
206
207
|
}
|
|
207
208
|
```
|
|
@@ -222,7 +223,7 @@ function draw() {
|
|
|
222
223
|
pop()
|
|
223
224
|
|
|
224
225
|
// screen projection of the model origin
|
|
225
|
-
const s =
|
|
226
|
+
const s = mapLocation(p5.Tree.ORIGIN, { from: model, to: p5.Tree.SCREEN })
|
|
226
227
|
beginHUD()
|
|
227
228
|
bullsEye({ x: s.x, y: s.y, size: 30 })
|
|
228
229
|
endHUD()
|
|
@@ -234,8 +235,8 @@ function draw() {
|
|
|
234
235
|
1. Returned vectors are `p5.Vector` instances.
|
|
235
236
|
2. `from` and `to` may be matrices or any of: `p5.Tree.WORLD`, `p5.Tree.EYE`, `p5.Tree.SCREEN`, `p5.Tree.NDC`, `p5.Tree.MODEL`.
|
|
236
237
|
3. When no matrix params are passed, current renderer values are used.
|
|
237
|
-
4. The default `
|
|
238
|
-
5. The default `
|
|
238
|
+
4. The default `mapLocation()` call (i.e. eye → world at origin) returns the camera world position.
|
|
239
|
+
5. The default `mapDirection()` call returns the normalized camera viewing direction.
|
|
239
240
|
6. Useful vector constants: `p5.Tree.ORIGIN`, `p5.Tree._k`, `p5.Tree.i`, `p5.Tree.j`, `p5.Tree.k`, `p5.Tree._i`, `p5.Tree._j`.
|
|
240
241
|
|
|
241
242
|
## Heads Up Display
|
|
@@ -272,36 +273,98 @@ Debug / teaching primitives for visualizing common 3D concepts:
|
|
|
272
273
|
|
|
273
274
|
---
|
|
274
275
|
|
|
275
|
-
#
|
|
276
|
+
# Releases
|
|
276
277
|
|
|
277
|
-
|
|
278
|
+
- **Latest (v0.0.2):**
|
|
279
|
+
These links always point to the latest published version on npm.
|
|
280
|
+
- [p5.tree.js (unminified, IIFE)](https://cdn.jsdelivr.net/npm/p5.tree/dist/p5.tree.js)
|
|
281
|
+
- [p5.tree.min.js (minified, IIFE)](https://cdn.jsdelivr.net/npm/p5.tree/dist/p5.tree.min.js)
|
|
282
|
+
- [p5.tree.esm.js (ES module)](https://cdn.jsdelivr.net/npm/p5.tree/dist/p5.tree.esm.js)
|
|
283
|
+
- [npm package](https://www.npmjs.com/package/p5.tree)
|
|
278
284
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
285
|
+
- **Current tagged version (v0.0.2):**
|
|
286
|
+
Use these if you want to lock to a specific version.
|
|
287
|
+
- [p5.tree@0.0.2.js (unminified, IIFE)](https://cdn.jsdelivr.net/npm/p5.tree@0.0.2/dist/p5.tree.js)
|
|
288
|
+
- [p5.tree@0.0.2.min.js (minified, IIFE)](https://cdn.jsdelivr.net/npm/p5.tree@0.0.2/dist/p5.tree.min.js)
|
|
289
|
+
- [p5.tree@0.0.2.esm.js (ES module)](https://cdn.jsdelivr.net/npm/p5.tree@0.0.2/dist/p5.tree.esm.js)
|
|
290
|
+
- [npm package (v0.0.2)](https://www.npmjs.com/package/p5.tree/v/0.0.2)
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
# Usage
|
|
295
|
+
|
|
296
|
+
The library works in two setups:
|
|
297
|
+
|
|
298
|
+
- **[CDN](#cdn)**: Use the [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE)
|
|
299
|
+
(Immediately Invoked Function Expression) format with `<script>` tags directly in the browser,
|
|
300
|
+
along with [p5.js](https://beta.p5js.org/).
|
|
301
|
+
- **[npm](#npm-esm)**: Use the
|
|
302
|
+
[ES module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
|
|
303
|
+
version in modern projects with [Vite](https://vitejs.dev/) or another bundler.
|
|
304
|
+
|
|
305
|
+
## CDN
|
|
292
306
|
|
|
293
|
-
|
|
307
|
+
Include both libraries using `<script>` tags, which run in both [global](https://github.com/processing/p5.js/wiki/Global-and-instance-mode) and [instance mode](https://github.com/processing/p5.js/wiki/Global-and-instance-mode).
|
|
294
308
|
|
|
295
309
|
```html
|
|
296
|
-
|
|
310
|
+
<!-- index.html -->
|
|
311
|
+
<!-- Load p5.js first (required by p5.tree) -->
|
|
312
|
+
<script src="https://cdn.jsdelivr.net/npm/p5/lib/p5.min.js"></script>
|
|
313
|
+
|
|
314
|
+
<!-- Load p5.tree (latest stable version) -->
|
|
315
|
+
<script src="https://cdn.jsdelivr.net/npm/p5.tree/dist/p5.tree.js"></script>
|
|
316
|
+
|
|
317
|
+
<script>
|
|
318
|
+
function setup() {
|
|
319
|
+
createCanvas(600, 400, WEBGL)
|
|
320
|
+
|
|
321
|
+
// Example: draw world axes
|
|
322
|
+
axes(100)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function draw() {
|
|
326
|
+
background(0.15)
|
|
327
|
+
orbitControl()
|
|
328
|
+
}
|
|
329
|
+
</script>
|
|
330
|
+
````
|
|
331
|
+
|
|
332
|
+
You can run the example, which uses global mode, by opening the `index.html` file in a browser, or by using
|
|
333
|
+
[VSCodium](https://vscodium.com/) (recommended) or [Visual Studio Code](https://code.visualstudio.com/)
|
|
334
|
+
with the [Live Server extension](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer).
|
|
335
|
+
|
|
336
|
+
## npm (ESM)
|
|
337
|
+
|
|
338
|
+
Install both [`p5`](https://www.npmjs.com/package/p5) and [`p5.tree`](https://www.npmjs.com/package/p5.tree) as dependencies:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
npm i p5 p5.tree
|
|
297
342
|
```
|
|
298
343
|
|
|
299
|
-
|
|
344
|
+
Then import them in your project’s entry file (e.g. `main.js`) using a
|
|
345
|
+
modern bundler like [Vite](https://vitejs.dev/), which runs in
|
|
346
|
+
[instance mode](https://github.com/processing/p5.js/wiki/Global-and-instance-mode) only:
|
|
300
347
|
|
|
301
|
-
|
|
348
|
+
```js
|
|
349
|
+
// main.js
|
|
350
|
+
import p5 from 'p5'
|
|
351
|
+
import 'p5.tree'
|
|
352
|
+
|
|
353
|
+
const sketch = p => {
|
|
354
|
+
p.setup = () => {
|
|
355
|
+
p.createCanvas(600, 400, p.WEBGL)
|
|
356
|
+
|
|
357
|
+
// Example: draw world axes
|
|
358
|
+
p.axes(100)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
p.draw = () => {
|
|
362
|
+
p.background(0.15)
|
|
363
|
+
p.orbitControl()
|
|
364
|
+
}
|
|
365
|
+
}
|
|
302
366
|
|
|
303
|
-
|
|
367
|
+
new p5(sketch)
|
|
368
|
+
```
|
|
304
369
|
|
|
305
|
-
|
|
306
|
-
2. [p5.js source architecture](https://github.com/processing/p5.js/blob/main/src/core/README.md)
|
|
307
|
-
3. [WEBGL mode architecture](https://github.com/processing/p5.js/blob/main/contributor_docs/webgl_mode_architecture.md)
|
|
370
|
+
This approach provides full modularity, clean instance isolation, and compatibility with modern JavaScript tooling.
|
package/dist/p5.tree.esm.js
CHANGED
|
@@ -2,7 +2,7 @@ import p5 from 'p5';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @file Adds Tree rendering functions to the p5 prototype.
|
|
5
|
-
* @version 0.0.
|
|
5
|
+
* @version 0.0.2
|
|
6
6
|
* @author JP Charalambos
|
|
7
7
|
* @license GPL-3.0-only
|
|
8
8
|
*
|
|
@@ -38,7 +38,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
38
38
|
const CONST = value => ({ value, writable: false, enumerable: true, configurable: false });
|
|
39
39
|
|
|
40
40
|
Object.defineProperties(p5.Tree, {
|
|
41
|
-
VERSION: CONST('0.0.
|
|
41
|
+
VERSION: CONST('0.0.2'),
|
|
42
42
|
|
|
43
43
|
NONE: CONST(0),
|
|
44
44
|
|
|
@@ -301,7 +301,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
301
301
|
|
|
302
302
|
/**
|
|
303
303
|
* lMatrix({ from, to }):
|
|
304
|
-
*
|
|
304
|
+
* Position transform (mat4) mapping points from `from` space to `to` space.
|
|
305
305
|
* treegl semantics: to^-1 * from.
|
|
306
306
|
* @param {object} [opts]
|
|
307
307
|
* @param {p5.Matrix} [opts.from=new p5.Matrix()] Source frame matrix.
|
|
@@ -317,7 +317,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
317
317
|
|
|
318
318
|
/**
|
|
319
319
|
* lMatrix({ from, to }):
|
|
320
|
-
*
|
|
320
|
+
* Position transform (mat4) mapping points from `from` space to `to` space.
|
|
321
321
|
* Requires WEBGL.
|
|
322
322
|
* @param {object} [opts]
|
|
323
323
|
* @param {p5.Matrix} [opts.from]
|
|
@@ -815,7 +815,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
815
815
|
|
|
816
816
|
/**
|
|
817
817
|
* Interpolate camera pose at normalized global t in [0..1] along the whole path.
|
|
818
|
-
* Also updates internal seg/f so playPath resumes from that
|
|
818
|
+
* Also updates internal seg/f so playPath resumes from that position.
|
|
819
819
|
*/
|
|
820
820
|
const seekGlobal = function (cam, t) {
|
|
821
821
|
const path = ensurePath(cam);
|
|
@@ -1441,7 +1441,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1441
1441
|
};
|
|
1442
1442
|
|
|
1443
1443
|
// ---------------------------------------------------------------------------
|
|
1444
|
-
// Space transforms:
|
|
1444
|
+
// Space transforms: mapLocation / mapDirection
|
|
1445
1445
|
// ---------------------------------------------------------------------------
|
|
1446
1446
|
|
|
1447
1447
|
p5.RendererGL.prototype._parseTransformArgs = function (defaultMainArg, ...args) {
|
|
@@ -1461,8 +1461,8 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1461
1461
|
// Points (positions)
|
|
1462
1462
|
// ---------------------------------------------------------------------------
|
|
1463
1463
|
|
|
1464
|
-
fn.
|
|
1465
|
-
return _rendererGL(this)?.
|
|
1464
|
+
fn.mapLocation = function (...args) {
|
|
1465
|
+
return _rendererGL(this)?.mapLocation(...args);
|
|
1466
1466
|
};
|
|
1467
1467
|
|
|
1468
1468
|
/**
|
|
@@ -1479,12 +1479,12 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1479
1479
|
* @param {p5.Matrix} [opts.ipvMatrix]
|
|
1480
1480
|
* @returns {p5.Vector}
|
|
1481
1481
|
*/
|
|
1482
|
-
p5.RendererGL.prototype.
|
|
1482
|
+
p5.RendererGL.prototype.mapLocation = function (...args) {
|
|
1483
1483
|
const { mainArg, options } = this._parseTransformArgs(p5.Tree.ORIGIN, ...args);
|
|
1484
|
-
return this.
|
|
1484
|
+
return this._location(mainArg, options);
|
|
1485
1485
|
};
|
|
1486
1486
|
|
|
1487
|
-
p5.RendererGL.prototype.
|
|
1487
|
+
p5.RendererGL.prototype._location = function (
|
|
1488
1488
|
point = p5.Tree.ORIGIN,
|
|
1489
1489
|
{
|
|
1490
1490
|
from = p5.Tree.EYE,
|
|
@@ -1598,7 +1598,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1598
1598
|
if (from == p5.Tree.EYE && to instanceof p5.Matrix) {
|
|
1599
1599
|
return to.copy().invert(to).mult4((eMatrix ?? this.eMatrix()).mult4(point));
|
|
1600
1600
|
}
|
|
1601
|
-
console.error('couldn\'t parse your
|
|
1601
|
+
console.error('couldn\'t parse your mapLocation query!');
|
|
1602
1602
|
return point;
|
|
1603
1603
|
};
|
|
1604
1604
|
|
|
@@ -1670,8 +1670,8 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1670
1670
|
// Directions (vector displacements)
|
|
1671
1671
|
// ---------------------------------------------------------------------------
|
|
1672
1672
|
|
|
1673
|
-
fn.
|
|
1674
|
-
return _rendererGL(this)?.
|
|
1673
|
+
fn.mapDirection = function (...args) {
|
|
1674
|
+
return _rendererGL(this)?.mapDirection(...args);
|
|
1675
1675
|
};
|
|
1676
1676
|
|
|
1677
1677
|
/**
|
|
@@ -1686,7 +1686,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1686
1686
|
* @param {p5.Matrix} [opts.pMatrix]
|
|
1687
1687
|
* @returns {p5.Vector}
|
|
1688
1688
|
*/
|
|
1689
|
-
p5.RendererGL.prototype.
|
|
1689
|
+
p5.RendererGL.prototype.mapDirection = function (...args) {
|
|
1690
1690
|
const { mainArg, options } = this._parseTransformArgs(p5.Tree._k, ...args);
|
|
1691
1691
|
return this._direction(mainArg, options);
|
|
1692
1692
|
};
|
|
@@ -1781,7 +1781,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1781
1781
|
this._screenToWorldDirection(this._ndcToScreenDirection(vector), pMatrix)
|
|
1782
1782
|
);
|
|
1783
1783
|
}
|
|
1784
|
-
console.error('[p5.tree]
|
|
1784
|
+
console.error('[p5.tree] mapDirection: could not parse query.');
|
|
1785
1785
|
return vector;
|
|
1786
1786
|
};
|
|
1787
1787
|
|
|
@@ -1792,7 +1792,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1792
1792
|
let dy = eyeVector.y;
|
|
1793
1793
|
const perspective = pMatrix.mat4[15] === 0;
|
|
1794
1794
|
if (perspective) {
|
|
1795
|
-
const zEye = this.
|
|
1795
|
+
const zEye = this._location(p5.Tree.ORIGIN, { from: p5.Tree.WORLD, to: p5.Tree.EYE }).z;
|
|
1796
1796
|
const k = Math.abs(zEye * Math.tan(pMatrix.fov() / 2));
|
|
1797
1797
|
dx /= 2 * k / this.height;
|
|
1798
1798
|
dy /= 2 * k / this.height;
|
|
@@ -1814,7 +1814,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1814
1814
|
|
|
1815
1815
|
const perspective = pMatrix.mat4[15] === 0;
|
|
1816
1816
|
if (perspective) {
|
|
1817
|
-
const zEye = this.
|
|
1817
|
+
const zEye = this._location(p5.Tree.ORIGIN, { from: p5.Tree.WORLD, to: p5.Tree.EYE }).z;
|
|
1818
1818
|
const k = Math.abs(zEye * Math.tan(pMatrix.fov() / 2));
|
|
1819
1819
|
dx *= 2 * k / this.height;
|
|
1820
1820
|
dy *= 2 * k / this.height;
|
|
@@ -1869,7 +1869,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
1869
1869
|
return this.isOrtho()
|
|
1870
1870
|
? Math.abs(this.tPlane() - this.bPlane()) / this.height
|
|
1871
1871
|
: 2 * Math.abs(
|
|
1872
|
-
this.
|
|
1872
|
+
this.mapLocation(point, { from: p5.Tree.WORLD, to: p5.Tree.EYE }).z
|
|
1873
1873
|
) * Math.tan(this.fov() / 2) / this.height;
|
|
1874
1874
|
};
|
|
1875
1875
|
|
|
@@ -2158,10 +2158,10 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
2158
2158
|
// If target screen position not provided, derive it from mMatrix.
|
|
2159
2159
|
// In that case, treat `size` as world units and convert to pixels locally.
|
|
2160
2160
|
if (x == null || y == null) {
|
|
2161
|
-
const screen = this.
|
|
2161
|
+
const screen = this.mapLocation({ from: mMatrix, to: p5.Tree.SCREEN, pMatrix, vMatrix, pvMatrix });
|
|
2162
2162
|
x = screen.x;
|
|
2163
2163
|
y = screen.y;
|
|
2164
|
-
const world = this.
|
|
2164
|
+
const world = this.mapLocation({ from: mMatrix, to: p5.Tree.WORLD, eMatrix });
|
|
2165
2165
|
size = size / this.pixelRatio(world);
|
|
2166
2166
|
}
|
|
2167
2167
|
const r = size / 2.0;
|
|
@@ -2262,10 +2262,10 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
2262
2262
|
if (!p) return;
|
|
2263
2263
|
|
|
2264
2264
|
if (x == null || y == null) {
|
|
2265
|
-
const screen = this.
|
|
2265
|
+
const screen = this.mapLocation({ from: mMatrix, to: p5.Tree.SCREEN, pMatrix, vMatrix, pvMatrix });
|
|
2266
2266
|
x = screen.x;
|
|
2267
2267
|
y = screen.y;
|
|
2268
|
-
const world = this.
|
|
2268
|
+
const world = this.mapLocation({ from: mMatrix, to: p5.Tree.WORLD, eMatrix });
|
|
2269
2269
|
size = size / this.pixelRatio(world);
|
|
2270
2270
|
}
|
|
2271
2271
|
const half = size / 2.0;
|
|
@@ -2315,10 +2315,10 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
2315
2315
|
const p = this._pInst;
|
|
2316
2316
|
if (!p) return;
|
|
2317
2317
|
if (x == null || y == null) {
|
|
2318
|
-
const screen = this.
|
|
2318
|
+
const screen = this.mapLocation({ from: mMatrix, to: p5.Tree.SCREEN, pMatrix, vMatrix, pvMatrix });
|
|
2319
2319
|
x = screen.x;
|
|
2320
2320
|
y = screen.y;
|
|
2321
|
-
const world = this.
|
|
2321
|
+
const world = this.mapLocation({ from: mMatrix, to: p5.Tree.WORLD, eMatrix });
|
|
2322
2322
|
size = size / this.pixelRatio(world);
|
|
2323
2323
|
}
|
|
2324
2324
|
const half = size / 2.0;
|
|
@@ -2666,7 +2666,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
|
|
|
2666
2666
|
const normals = Array(6);
|
|
2667
2667
|
const distances = Array(6);
|
|
2668
2668
|
// Camera position and basis in world space.
|
|
2669
|
-
const pos = this.
|
|
2669
|
+
const pos = this._location([0, 0, 0], { from: p5.Tree.EYE, to: p5.Tree.WORLD, eMatrix });
|
|
2670
2670
|
const viewDir = this._direction([0, 0, -1], { from: p5.Tree.EYE, to: p5.Tree.WORLD, vMatrix });
|
|
2671
2671
|
const up = this._direction([0, 1, 0], { from: p5.Tree.EYE, to: p5.Tree.WORLD, vMatrix });
|
|
2672
2672
|
const right = this._direction([1, 0, 0], { from: p5.Tree.EYE, to: p5.Tree.WORLD, vMatrix });
|