p5.tree 0.0.3 → 0.0.4

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.
@@ -2,16 +2,16 @@ import p5 from 'p5';
2
2
 
3
3
  /**
4
4
  * @file Adds Tree rendering functions to the p5 prototype.
5
- * @version 0.0.3
5
+ * @version 0.0.4
6
6
  * @author JP Charalambos
7
7
  * @license GPL-3.0-only
8
8
  *
9
9
  * @description
10
- * A p5.js WEBGL addon for shader development and space transformations.
10
+ * A p5.js 3D addon for matrix queries, shader workflows, and space transformations.
11
11
  *
12
12
  * Camera path recording/playback section.
13
13
  *
14
- * Requires WEBGL (p5.Camera).
14
+ * Requires 3D renderer (p5.Camera).
15
15
  *
16
16
  * Camera API:
17
17
  * camera.path : p5.Camera[]
@@ -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.3'),
41
+ VERSION: CONST('0.0.4'),
42
42
 
43
43
  NONE: CONST(0),
44
44
 
@@ -97,13 +97,13 @@ p5.registerAddon((p5, fn, lifecycles) => {
97
97
 
98
98
  /**
99
99
  * @private
100
- * Returns the WEBGL renderer or undefined.
101
- * @param {p5} pInst
102
- * @returns {p5.RendererGL|undefined}
100
+ * Returns the active 3D renderer (WEBGL or WEBGPU) or undefined.
101
+ * @param {p5} pInst - The p5 instance.
102
+ * @returns {p5.Renderer3D|undefined} The active 3D renderer if available.
103
103
  */
104
- const _rendererGL = function (pInst) {
105
- const r = pInst._renderer;
106
- return r instanceof p5.RendererGL ? r : undefined;
104
+ const _renderer3D = function (pInst) {
105
+ const r = pInst?._renderer;
106
+ return r instanceof p5.Renderer3D ? r : undefined;
107
107
  };
108
108
 
109
109
  // ---------------------------------------------------------------------------
@@ -216,34 +216,34 @@ p5.registerAddon((p5, fn, lifecycles) => {
216
216
  * Returns the current projection matrix (immutable copy).
217
217
  * @returns {p5.Matrix}
218
218
  */
219
- p5.RendererGL.prototype.pMatrix = function () {
219
+ p5.Renderer3D.prototype.pMatrix = function () {
220
220
  return this.states.uPMatrix.clone();
221
221
  };
222
222
 
223
223
  /**
224
224
  * Returns the current projection matrix (immutable copy).
225
- * Requires WEBGL.
225
+ * Requires 3D renderer.
226
226
  * @returns {p5.Matrix}
227
227
  */
228
228
  fn.pMatrix = function () {
229
- return _rendererGL(this).pMatrix();
229
+ return _renderer3D(this).pMatrix();
230
230
  };
231
231
 
232
232
  /**
233
233
  * Returns the current model matrix (immutable copy).
234
234
  * @returns {p5.Matrix}
235
235
  */
236
- p5.RendererGL.prototype.mMatrix = function () {
236
+ p5.Renderer3D.prototype.mMatrix = function () {
237
237
  return this.states.uModelMatrix.clone();
238
238
  };
239
239
 
240
240
  /**
241
241
  * Returns the current model matrix (immutable copy).
242
- * Requires WEBGL.
242
+ * Requires 3D renderer.
243
243
  * @returns {p5.Matrix}
244
244
  */
245
245
  fn.mMatrix = function () {
246
- return _rendererGL(this).mMatrix();
246
+ return _renderer3D(this).mMatrix();
247
247
  };
248
248
 
249
249
  /**
@@ -267,34 +267,34 @@ p5.registerAddon((p5, fn, lifecycles) => {
267
267
  * Prefers the renderer cached view matrix when available.
268
268
  * @returns {p5.Matrix}
269
269
  */
270
- p5.RendererGL.prototype.vMatrix = function () {
270
+ p5.Renderer3D.prototype.vMatrix = function () {
271
271
  return (this.states.uViewMatrix || this.states.curCamera.cameraMatrix).clone();
272
272
  };
273
273
 
274
274
  /**
275
275
  * Returns the current view matrix (world -> camera) (immutable copy).
276
- * Requires WEBGL.
276
+ * Requires 3D renderer.
277
277
  * @returns {p5.Matrix}
278
278
  */
279
279
  fn.vMatrix = function () {
280
- return _rendererGL(this).vMatrix();
280
+ return _renderer3D(this).vMatrix();
281
281
  };
282
282
 
283
283
  /**
284
284
  * Returns the current eye matrix (camera -> world) (immutable).
285
285
  * @returns {p5.Matrix}
286
286
  */
287
- p5.RendererGL.prototype.eMatrix = function () {
287
+ p5.Renderer3D.prototype.eMatrix = function () {
288
288
  return _invert(this.states.uViewMatrix || this.states.curCamera.cameraMatrix);
289
289
  };
290
290
 
291
291
  /**
292
292
  * Returns the current eye matrix (camera -> world) (immutable).
293
- * Requires WEBGL.
293
+ * Requires 3D renderer.
294
294
  * @returns {p5.Matrix}
295
295
  */
296
296
  fn.eMatrix = function () {
297
- return _rendererGL(this).eMatrix();
297
+ return _renderer3D(this).eMatrix();
298
298
  };
299
299
 
300
300
  /**
@@ -306,7 +306,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
306
306
  * @param {p5.Matrix} [opts.to=this.eMatrix()] Target frame matrix.
307
307
  * @returns {p5.Matrix}
308
308
  */
309
- p5.RendererGL.prototype.lMatrix = function ({
309
+ p5.Renderer3D.prototype.lMatrix = function ({
310
310
  from = new p5.Matrix(4),
311
311
  to = this.eMatrix()
312
312
  } = {}) {
@@ -316,14 +316,14 @@ p5.registerAddon((p5, fn, lifecycles) => {
316
316
  /**
317
317
  * lMatrix({ from, to }):
318
318
  * Location transform (mat4) mapping points from `from` space to `to` space.
319
- * Requires WEBGL.
319
+ * Requires 3D renderer.
320
320
  * @param {object} [opts]
321
321
  * @param {p5.Matrix} [opts.from]
322
322
  * @param {p5.Matrix} [opts.to]
323
323
  * @returns {p5.Matrix}
324
324
  */
325
325
  fn.lMatrix = function (opts = {}) {
326
- return _rendererGL(this).lMatrix(opts);
326
+ return _renderer3D(this).lMatrix(opts);
327
327
  };
328
328
 
329
329
  /**
@@ -337,7 +337,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
337
337
  * @param {p5.Matrix} [opts.matrix] Precomputed mat4 override.
338
338
  * @returns {p5.Matrix} mat3
339
339
  */
340
- p5.RendererGL.prototype.dMatrix = function ({
340
+ p5.Renderer3D.prototype.dMatrix = function ({
341
341
  from = new p5.Matrix(4),
342
342
  to = this.eMatrix(),
343
343
  matrix
@@ -355,7 +355,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
355
355
  /**
356
356
  * dMatrix({ from, to, matrix }):
357
357
  * Direction transform (mat3) mapping vectors from `from` space to `to` space.
358
- * Requires WEBGL.
358
+ * Requires 3D renderer.
359
359
  * @param {object} [opts]
360
360
  * @param {p5.Matrix} [opts.from]
361
361
  * @param {p5.Matrix} [opts.to]
@@ -363,7 +363,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
363
363
  * @returns {p5.Matrix} mat3
364
364
  */
365
365
  fn.dMatrix = function (opts = {}) {
366
- return _rendererGL(this).dMatrix(opts);
366
+ return _renderer3D(this).dMatrix(opts);
367
367
  };
368
368
 
369
369
  /**
@@ -374,7 +374,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
374
374
  * @param {p5.Matrix} [opts.mMatrix=this.mMatrix()] Model matrix.
375
375
  * @returns {p5.Matrix}
376
376
  */
377
- p5.RendererGL.prototype.mvMatrix = function ({
377
+ p5.Renderer3D.prototype.mvMatrix = function ({
378
378
  vMatrix = this.vMatrix(),
379
379
  mMatrix
380
380
  } = {}) {
@@ -384,14 +384,14 @@ p5.registerAddon((p5, fn, lifecycles) => {
384
384
  /**
385
385
  * mvMatrix({ vMatrix, mMatrix }):
386
386
  * ModelView matrix (mat4) = M * V (p5-v2 convention).
387
- * Requires WEBGL.
387
+ * Requires 3D renderer.
388
388
  * @param {object} [opts]
389
389
  * @param {p5.Matrix} [opts.vMatrix]
390
390
  * @param {p5.Matrix} [opts.mMatrix]
391
391
  * @returns {p5.Matrix}
392
392
  */
393
393
  fn.mvMatrix = function (opts = {}) {
394
- return _rendererGL(this).mvMatrix(opts);
394
+ return _renderer3D(this).mvMatrix(opts);
395
395
  };
396
396
 
397
397
  /**
@@ -403,7 +403,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
403
403
  * @param {p5.Matrix} [opts.mvMatrix=this.mvMatrix({ mMatrix, vMatrix })] Optional MV matrix override.
404
404
  * @returns {p5.Matrix} mat3
405
405
  */
406
- p5.RendererGL.prototype.nMatrix = function ({
406
+ p5.Renderer3D.prototype.nMatrix = function ({
407
407
  vMatrix,
408
408
  mMatrix,
409
409
  mvMatrix = this.mvMatrix({ mMatrix, vMatrix })
@@ -414,7 +414,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
414
414
  /**
415
415
  * nMatrix({ vMatrix, mMatrix, mvMatrix }):
416
416
  * Normal matrix (mat3) = inverseTranspose(linear_part(MV)).
417
- * Requires WEBGL.
417
+ * Requires 3D renderer.
418
418
  * @param {object} [opts]
419
419
  * @param {p5.Matrix} [opts.vMatrix]
420
420
  * @param {p5.Matrix} [opts.mMatrix]
@@ -422,7 +422,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
422
422
  * @returns {p5.Matrix} mat3
423
423
  */
424
424
  fn.nMatrix = function (opts = {}) {
425
- return _rendererGL(this).nMatrix(opts);
425
+ return _renderer3D(this).nMatrix(opts);
426
426
  };
427
427
 
428
428
  /**
@@ -435,7 +435,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
435
435
  * @param {p5.Matrix} [opts.mvMatrix=this.mvMatrix({ mMatrix, vMatrix })] Optional MV matrix override.
436
436
  * @returns {p5.Matrix}
437
437
  */
438
- p5.RendererGL.prototype.pmvMatrix = function ({
438
+ p5.Renderer3D.prototype.pmvMatrix = function ({
439
439
  pMatrix = this.pMatrix(),
440
440
  vMatrix,
441
441
  mMatrix,
@@ -447,7 +447,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
447
447
  /**
448
448
  * pmvMatrix({ pMatrix, vMatrix, mMatrix, mvMatrix }):
449
449
  * PMV (mat4) = M * V * P (p5-v2 convention).
450
- * Requires WEBGL.
450
+ * Requires 3D renderer.
451
451
  * @param {object} [opts]
452
452
  * @param {p5.Matrix} [opts.pMatrix]
453
453
  * @param {p5.Matrix} [opts.vMatrix]
@@ -456,7 +456,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
456
456
  * @returns {p5.Matrix}
457
457
  */
458
458
  fn.pmvMatrix = function (opts = {}) {
459
- return _rendererGL(this).pmvMatrix(opts);
459
+ return _renderer3D(this).pmvMatrix(opts);
460
460
  };
461
461
 
462
462
  /**
@@ -467,7 +467,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
467
467
  * @param {p5.Matrix} [opts.vMatrix=this.vMatrix()] View matrix.
468
468
  * @returns {p5.Matrix}
469
469
  */
470
- p5.RendererGL.prototype.pvMatrix = function ({
470
+ p5.Renderer3D.prototype.pvMatrix = function ({
471
471
  pMatrix = this.pMatrix(),
472
472
  vMatrix
473
473
  } = {}) {
@@ -477,14 +477,14 @@ p5.registerAddon((p5, fn, lifecycles) => {
477
477
  /**
478
478
  * pvMatrix({ pMatrix, vMatrix }):
479
479
  * PV (mat4) = V * P (p5-v2 convention).
480
- * Requires WEBGL.
480
+ * Requires 3D renderer.
481
481
  * @param {object} [opts]
482
482
  * @param {p5.Matrix} [opts.pMatrix]
483
483
  * @param {p5.Matrix} [opts.vMatrix]
484
484
  * @returns {p5.Matrix}
485
485
  */
486
486
  fn.pvMatrix = function (opts = {}) {
487
- return _rendererGL(this).pvMatrix(opts);
487
+ return _renderer3D(this).pvMatrix(opts);
488
488
  };
489
489
 
490
490
  /**
@@ -496,7 +496,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
496
496
  * @param {p5.Matrix} [opts.pvMatrix=this.pvMatrix({ pMatrix, vMatrix })] Optional PV matrix override.
497
497
  * @returns {p5.Matrix}
498
498
  */
499
- p5.RendererGL.prototype.ipvMatrix = function ({
499
+ p5.Renderer3D.prototype.ipvMatrix = function ({
500
500
  pMatrix,
501
501
  vMatrix,
502
502
  pvMatrix = this.pvMatrix({ pMatrix, vMatrix })
@@ -506,12 +506,12 @@ p5.registerAddon((p5, fn, lifecycles) => {
506
506
 
507
507
  /**
508
508
  * ipvMatrix({ pMatrix, vMatrix, pvMatrix }):
509
- * Inverse(PV) (mat4). Requires WEBGL.
509
+ * Inverse(PV) (mat4). Requires 3D renderer.
510
510
  * @param {object} [opts]
511
511
  * @returns {p5.Matrix}
512
512
  */
513
513
  fn.ipvMatrix = function (opts = {}) {
514
- return _rendererGL(this).ipvMatrix(opts);
514
+ return _renderer3D(this).ipvMatrix(opts);
515
515
  };
516
516
 
517
517
  // ---------------------------------------------------------------------------
@@ -530,17 +530,17 @@ p5.registerAddon((p5, fn, lifecycles) => {
530
530
  * Returns true if the current projection is orthographic.
531
531
  * @returns {boolean}
532
532
  */
533
- p5.RendererGL.prototype.isOrtho = function () {
533
+ p5.Renderer3D.prototype.isOrtho = function () {
534
534
  return this.pMatrix().isOrtho();
535
535
  };
536
536
 
537
537
  /**
538
538
  * Returns true if the current projection is orthographic.
539
- * Requires WEBGL.
539
+ * Requires 3D renderer.
540
540
  * @returns {boolean}
541
541
  */
542
542
  fn.isOrtho = function () {
543
- return _rendererGL(this).isOrtho();
543
+ return _renderer3D(this).isOrtho();
544
544
  };
545
545
 
546
546
  /**
@@ -601,7 +601,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
601
601
  * Near plane distance for the current projection.
602
602
  * @returns {number}
603
603
  */
604
- p5.RendererGL.prototype.nPlane = function () {
604
+ p5.Renderer3D.prototype.nPlane = function () {
605
605
  return this.pMatrix().nPlane();
606
606
  };
607
607
 
@@ -609,7 +609,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
609
609
  * Far plane distance for the current projection.
610
610
  * @returns {number}
611
611
  */
612
- p5.RendererGL.prototype.fPlane = function () {
612
+ p5.Renderer3D.prototype.fPlane = function () {
613
613
  return this.pMatrix().fPlane();
614
614
  };
615
615
 
@@ -617,7 +617,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
617
617
  * Left plane for the current projection.
618
618
  * @returns {number}
619
619
  */
620
- p5.RendererGL.prototype.lPlane = function () {
620
+ p5.Renderer3D.prototype.lPlane = function () {
621
621
  return this.pMatrix().lPlane();
622
622
  };
623
623
 
@@ -625,7 +625,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
625
625
  * Right plane for the current projection.
626
626
  * @returns {number}
627
627
  */
628
- p5.RendererGL.prototype.rPlane = function () {
628
+ p5.Renderer3D.prototype.rPlane = function () {
629
629
  return this.pMatrix().rPlane();
630
630
  };
631
631
 
@@ -633,7 +633,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
633
633
  * Top plane for the current projection.
634
634
  * @returns {number}
635
635
  */
636
- p5.RendererGL.prototype.tPlane = function () {
636
+ p5.Renderer3D.prototype.tPlane = function () {
637
637
  return this.pMatrix().tPlane();
638
638
  };
639
639
 
@@ -641,62 +641,62 @@ p5.registerAddon((p5, fn, lifecycles) => {
641
641
  * Bottom plane for the current projection.
642
642
  * @returns {number}
643
643
  */
644
- p5.RendererGL.prototype.bPlane = function () {
644
+ p5.Renderer3D.prototype.bPlane = function () {
645
645
  return this.pMatrix().bPlane();
646
646
  };
647
647
 
648
648
  /**
649
649
  * Near plane distance for the current projection.
650
- * Requires WEBGL.
650
+ * Requires 3D renderer.
651
651
  * @returns {number}
652
652
  */
653
653
  fn.nPlane = function () {
654
- return _rendererGL(this).nPlane();
654
+ return _renderer3D(this).nPlane();
655
655
  };
656
656
 
657
657
  /**
658
658
  * Far plane distance for the current projection.
659
- * Requires WEBGL.
659
+ * Requires 3D renderer.
660
660
  * @returns {number}
661
661
  */
662
662
  fn.fPlane = function () {
663
- return _rendererGL(this).fPlane();
663
+ return _renderer3D(this).fPlane();
664
664
  };
665
665
 
666
666
  /**
667
667
  * Left plane for the current projection.
668
- * Requires WEBGL.
668
+ * Requires 3D renderer.
669
669
  * @returns {number}
670
670
  */
671
671
  fn.lPlane = function () {
672
- return _rendererGL(this).lPlane();
672
+ return _renderer3D(this).lPlane();
673
673
  };
674
674
 
675
675
  /**
676
676
  * Right plane for the current projection.
677
- * Requires WEBGL.
677
+ * Requires 3D renderer.
678
678
  * @returns {number}
679
679
  */
680
680
  fn.rPlane = function () {
681
- return _rendererGL(this).rPlane();
681
+ return _renderer3D(this).rPlane();
682
682
  };
683
683
 
684
684
  /**
685
685
  * Top plane for the current projection.
686
- * Requires WEBGL.
686
+ * Requires 3D renderer.
687
687
  * @returns {number}
688
688
  */
689
689
  fn.tPlane = function () {
690
- return _rendererGL(this).tPlane();
690
+ return _renderer3D(this).tPlane();
691
691
  };
692
692
 
693
693
  /**
694
694
  * Bottom plane for the current projection.
695
- * Requires WEBGL.
695
+ * Requires 3D renderer.
696
696
  * @returns {number}
697
697
  */
698
698
  fn.bPlane = function () {
699
- return _rendererGL(this).bPlane();
699
+ return _renderer3D(this).bPlane();
700
700
  };
701
701
 
702
702
  /**
@@ -727,7 +727,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
727
727
  * Vertical field of view (radians) of the current projection.
728
728
  * @returns {number|undefined}
729
729
  */
730
- p5.RendererGL.prototype.fov = function () {
730
+ p5.Renderer3D.prototype.fov = function () {
731
731
  return this.pMatrix().fov();
732
732
  };
733
733
 
@@ -735,26 +735,26 @@ p5.registerAddon((p5, fn, lifecycles) => {
735
735
  * Horizontal field of view (radians) of the current projection.
736
736
  * @returns {number|undefined}
737
737
  */
738
- p5.RendererGL.prototype.hfov = function () {
738
+ p5.Renderer3D.prototype.hfov = function () {
739
739
  return this.pMatrix().hfov();
740
740
  };
741
741
 
742
742
  /**
743
743
  * Vertical field of view (radians) of the current projection.
744
- * Requires WEBGL.
744
+ * Requires 3D renderer.
745
745
  * @returns {number|undefined}
746
746
  */
747
747
  fn.fov = function () {
748
- return _rendererGL(this).fov();
748
+ return _renderer3D(this).fov();
749
749
  };
750
750
 
751
751
  /**
752
752
  * Horizontal field of view (radians) of the current projection.
753
- * Requires WEBGL.
753
+ * Requires 3D renderer.
754
754
  * @returns {number|undefined}
755
755
  */
756
756
  fn.hfov = function () {
757
- return _rendererGL(this).hfov();
757
+ return _renderer3D(this).hfov();
758
758
  };
759
759
 
760
760
  // --- private keys (shared internal state across protos) ---
@@ -1337,7 +1337,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1337
1337
 
1338
1338
  /*
1339
1339
  // treegl approach:
1340
- p5.RendererGL.prototype.beginHUD = function () {
1340
+ p5.Renderer3D.prototype.beginHUD = function () {
1341
1341
  if (this._hudActive === true) return;
1342
1342
  const p = this._pInst;
1343
1343
  const gl = this.drawingContext;
@@ -1374,7 +1374,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1374
1374
  this._hudActive = true;
1375
1375
  };
1376
1376
 
1377
- p5.RendererGL.prototype.endHUD = function () {
1377
+ p5.Renderer3D.prototype.endHUD = function () {
1378
1378
  if (this._hudActive !== true) return;
1379
1379
  const p = this._pInst;
1380
1380
  const gl = this.drawingContext;
@@ -1395,46 +1395,54 @@ p5.registerAddon((p5, fn, lifecycles) => {
1395
1395
  };
1396
1396
  */
1397
1397
 
1398
- p5.RendererGL.prototype.beginHUD = function () {
1398
+ p5.Renderer3D.prototype.beginHUD = function () {
1399
1399
  if (this._hudActive === true) return;
1400
1400
  const p = this._pInst;
1401
- if (!p) return;
1402
- const gl = this.drawingContext;
1403
1401
  const states = this.states;
1404
- if (!gl || !states) return;
1405
- p.push(); // isolate all subsequent HUD drawing from caller state
1402
+ if (!p || !states) return;
1403
+ p.push();
1406
1404
  p.resetShader();
1407
- // Ensure HUD space does NOT inherit the user's current model transforms
1408
- // (e.g. push()/translate()
1409
1405
  p.resetMatrix();
1410
- // ---------------------
1411
- // --- HUD setup ---
1412
1406
  this._hudPrevCam = states.curCamera;
1413
- this._hudDepthWasEnabled = gl.isEnabled(gl.DEPTH_TEST);
1414
- gl.flush();
1415
- gl.disable(gl.DEPTH_TEST);
1407
+ this._hudDepthMode = undefined;
1408
+ this._hudDepthWasEnabled = undefined;
1409
+ if (typeof this.clearDepth === 'function') {
1410
+ this.flushDraw?.();
1411
+ this.clearDepth(1);
1412
+ this._hudDepthMode = 'clearDepth';
1413
+ } else {
1414
+ const gl = this.drawingContext;
1415
+ if (gl && typeof gl.isEnabled === 'function' && gl.DEPTH_TEST !== undefined) {
1416
+ this._hudDepthWasEnabled = gl.isEnabled(gl.DEPTH_TEST);
1417
+ gl.flush?.();
1418
+ gl.disable(gl.DEPTH_TEST);
1419
+ this._hudDepthMode = 'depthTestToggle';
1420
+ }
1421
+ }
1416
1422
  if (this._hudCam === undefined) this._hudCam = p.createCamera();
1417
1423
  const z = 1e6;
1418
- // HUD coordinates: x in [0, width], y in [0, height]
1419
1424
  this._hudCam.ortho(0, p.width, -p.height, 0, -z, z);
1420
- // this._hudCam.ortho(0, p.width, 0, -p.height, -z, z); // <- flipped
1421
1425
  this._hudCam.camera(0, 0, 1, 0, 0, 0, 0, 1, 0);
1422
1426
  p.setCamera(this._hudCam);
1423
1427
  this._hudActive = true;
1424
1428
  };
1425
1429
 
1426
- p5.RendererGL.prototype.endHUD = function () {
1430
+ p5.Renderer3D.prototype.endHUD = function () {
1427
1431
  if (this._hudActive !== true) return;
1428
1432
  const p = this._pInst;
1429
- const gl = this.drawingContext;
1430
- const states = this.states;
1431
- if (p === undefined || gl === undefined || states === undefined) return;
1432
- gl.flush();
1433
- this._hudDepthWasEnabled ? gl.enable(gl.DEPTH_TEST) : gl.disable(gl.DEPTH_TEST);
1434
- p.pop(); // calls: this.pop(this._rendererState);
1433
+ if (!p) return;
1434
+ if (this._hudDepthMode === 'depthTestToggle') {
1435
+ const gl = this.drawingContext;
1436
+ if (gl && gl.DEPTH_TEST !== undefined) {
1437
+ gl.flush?.();
1438
+ this._hudDepthWasEnabled ? gl.enable(gl.DEPTH_TEST) : gl.disable(gl.DEPTH_TEST);
1439
+ }
1440
+ }
1441
+ p.pop();
1435
1442
  this._hudPrevCam !== undefined && p.setCamera(this._hudPrevCam);
1436
1443
  this._hudPrevCam = undefined;
1437
1444
  this._hudDepthWasEnabled = undefined;
1445
+ this._hudDepthMode = undefined;
1438
1446
  this._hudActive = false;
1439
1447
  };
1440
1448
 
@@ -1442,7 +1450,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1442
1450
  // Space transforms: mapLocation / mapDirection
1443
1451
  // ---------------------------------------------------------------------------
1444
1452
 
1445
- p5.RendererGL.prototype._parseTransformArgs = function (defaultMainArg, ...args) {
1453
+ p5.Renderer3D.prototype._parseTransformArgs = function (defaultMainArg, ...args) {
1446
1454
  let mainArg = defaultMainArg;
1447
1455
  const options = {};
1448
1456
  for (const arg of args) {
@@ -1460,7 +1468,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1460
1468
  // ---------------------------------------------------------------------------
1461
1469
 
1462
1470
  fn.mapLocation = function (...args) {
1463
- return _rendererGL(this)?.mapLocation(...args);
1471
+ return _renderer3D(this)?.mapLocation(...args);
1464
1472
  };
1465
1473
 
1466
1474
  /**
@@ -1477,12 +1485,12 @@ p5.registerAddon((p5, fn, lifecycles) => {
1477
1485
  * @param {p5.Matrix} [opts.ipvMatrix]
1478
1486
  * @returns {p5.Vector}
1479
1487
  */
1480
- p5.RendererGL.prototype.mapLocation = function (...args) {
1488
+ p5.Renderer3D.prototype.mapLocation = function (...args) {
1481
1489
  const { mainArg, options } = this._parseTransformArgs(p5.Tree.ORIGIN, ...args);
1482
1490
  return this._location(mainArg, options);
1483
1491
  };
1484
1492
 
1485
- p5.RendererGL.prototype._location = function (
1493
+ p5.Renderer3D.prototype._location = function (
1486
1494
  point = p5.Tree.ORIGIN,
1487
1495
  {
1488
1496
  from = p5.Tree.EYE,
@@ -1600,7 +1608,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1600
1608
  return point;
1601
1609
  };
1602
1610
 
1603
- p5.RendererGL.prototype._ndcToScreenLocation = function (point) {
1611
+ p5.Renderer3D.prototype._ndcToScreenLocation = function (point) {
1604
1612
  return new p5.Vector(
1605
1613
  p5.prototype.map(point.x, -1, 1, 0, this.width),
1606
1614
  p5.prototype.map(point.y, -1, 1, 0, this.height),
@@ -1608,7 +1616,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1608
1616
  );
1609
1617
  };
1610
1618
 
1611
- p5.RendererGL.prototype._screenToNDCLocation = function (point) {
1619
+ p5.Renderer3D.prototype._screenToNDCLocation = function (point) {
1612
1620
  return new p5.Vector(
1613
1621
  p5.prototype.map(point.x, 0, this.width, -1, 1),
1614
1622
  p5.prototype.map(point.y, 0, this.height, -1, 1),
@@ -1616,7 +1624,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1616
1624
  );
1617
1625
  };
1618
1626
 
1619
- p5.RendererGL.prototype._worldToScreenLocation = function ({
1627
+ p5.Renderer3D.prototype._worldToScreenLocation = function ({
1620
1628
  point = new p5.Vector(0, 0, 0.5),
1621
1629
  pMatrix,
1622
1630
  vMatrix,
@@ -1639,7 +1647,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1639
1647
  return new p5.Vector(target[0], target[1], target[2]);
1640
1648
  };
1641
1649
 
1642
- p5.RendererGL.prototype._screenToWorldLocation = function ({
1650
+ p5.Renderer3D.prototype._screenToWorldLocation = function ({
1643
1651
  point = new p5.Vector(this.width / 2, this.height / 2, 0.5),
1644
1652
  pMatrix,
1645
1653
  vMatrix,
@@ -1669,7 +1677,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1669
1677
  // ---------------------------------------------------------------------------
1670
1678
 
1671
1679
  fn.mapDirection = function (...args) {
1672
- return _rendererGL(this)?.mapDirection(...args);
1680
+ return _renderer3D(this)?.mapDirection(...args);
1673
1681
  };
1674
1682
 
1675
1683
  /**
@@ -1684,12 +1692,12 @@ p5.registerAddon((p5, fn, lifecycles) => {
1684
1692
  * @param {p5.Matrix} [opts.pMatrix]
1685
1693
  * @returns {p5.Vector}
1686
1694
  */
1687
- p5.RendererGL.prototype.mapDirection = function (...args) {
1695
+ p5.Renderer3D.prototype.mapDirection = function (...args) {
1688
1696
  const { mainArg, options } = this._parseTransformArgs(p5.Tree._k, ...args);
1689
1697
  return this._direction(mainArg, options);
1690
1698
  };
1691
1699
 
1692
- p5.RendererGL.prototype._direction = function (
1700
+ p5.Renderer3D.prototype._direction = function (
1693
1701
  vector = p5.Tree._k,
1694
1702
  {
1695
1703
  from = p5.Tree.EYE,
@@ -1783,7 +1791,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1783
1791
  return vector;
1784
1792
  };
1785
1793
 
1786
- p5.RendererGL.prototype._worldToScreenDirection = function (vector, pMatrix) {
1794
+ p5.Renderer3D.prototype._worldToScreenDirection = function (vector, pMatrix) {
1787
1795
  pMatrix = pMatrix ?? this.pMatrix();
1788
1796
  const eyeVector = this._direction(vector, { from: p5.Tree.WORLD, to: p5.Tree.EYE });
1789
1797
  let dx = eyeVector.x;
@@ -1804,7 +1812,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1804
1812
  return new p5.Vector(dx, dy, dz);
1805
1813
  };
1806
1814
 
1807
- p5.RendererGL.prototype._screenToWorldDirection = function (vector, pMatrix) {
1815
+ p5.Renderer3D.prototype._screenToWorldDirection = function (vector, pMatrix) {
1808
1816
  pMatrix = pMatrix ?? this.pMatrix();
1809
1817
 
1810
1818
  let dx = vector.x;
@@ -1828,11 +1836,11 @@ p5.registerAddon((p5, fn, lifecycles) => {
1828
1836
  return this._direction(new p5.Vector(dx, dy, dz), { from: p5.Tree.EYE, to: p5.Tree.WORLD });
1829
1837
  };
1830
1838
 
1831
- p5.RendererGL.prototype._ndcToScreenDirection = function (vector) {
1839
+ p5.Renderer3D.prototype._ndcToScreenDirection = function (vector) {
1832
1840
  return new p5.Vector(this.width * vector.x / 2, this.height * vector.y / 2, vector.z / 2);
1833
1841
  };
1834
1842
 
1835
- p5.RendererGL.prototype._screenToNDCDirection = function (vector) {
1843
+ p5.Renderer3D.prototype._screenToNDCDirection = function (vector) {
1836
1844
  return new p5.Vector(2 * vector.x / this.width, 2 * vector.y / this.height, 2 * vector.z);
1837
1845
  };
1838
1846
 
@@ -1849,13 +1857,13 @@ p5.registerAddon((p5, fn, lifecycles) => {
1849
1857
  * - In orthographic projection, the ratio is constant.
1850
1858
  * - In perspective projection, the ratio depends on eye-space depth.
1851
1859
  *
1852
- * Requires WEBGL.
1860
+ * Requires 3D renderer.
1853
1861
  *
1854
1862
  * @param {p5.Vector|number[]} [point=p5.Tree.ORIGIN] World-space point.
1855
1863
  * @returns {number|undefined} World units per pixel at the given point.
1856
1864
  */
1857
1865
  fn.pixelRatio = function (point) {
1858
- return _rendererGL(this)?.pixelRatio(point);
1866
+ return _renderer3D(this)?.pixelRatio(point);
1859
1867
  };
1860
1868
 
1861
1869
  /**
@@ -1863,7 +1871,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1863
1871
  * @param {p5.Vector|number[]} [point=p5.Tree.ORIGIN]
1864
1872
  * @returns {number}
1865
1873
  */
1866
- p5.RendererGL.prototype.pixelRatio = function (point = p5.Tree.ORIGIN) {
1874
+ p5.Renderer3D.prototype.pixelRatio = function (point = p5.Tree.ORIGIN) {
1867
1875
  return this.isOrtho()
1868
1876
  ? Math.abs(this.tPlane() - this.bPlane()) / this.height
1869
1877
  : 2 * Math.abs(
@@ -1896,27 +1904,27 @@ p5.registerAddon((p5, fn, lifecycles) => {
1896
1904
 
1897
1905
  /**
1898
1906
  * Returns a pointer position in *pixel* coordinates from an arbitrary (x, y) pair.
1899
- * Delegates to the WEBGL renderer.
1907
+ * Delegates to the active 3D renderer.
1900
1908
  *
1901
1909
  * Accepts parameters in any order:
1902
1910
  * - `number, number` → pointerX, pointerY
1903
1911
  * - optional `boolean` → `flip`
1904
1912
  *
1905
1913
  * @param {...(number|boolean)} args
1906
- * @returns {number[]|undefined} `[x, y]` in pixels, or undefined if not in WEBGL.
1914
+ * @returns {number[]|undefined} `[x, y]` in pixels, or undefined if no 3D renderer is active.
1907
1915
  */
1908
1916
  fn.pointerPosition = function (...args) {
1909
- return _rendererGL(this)?.pointerPosition(...args);
1917
+ return _renderer3D(this)?.pointerPosition(...args);
1910
1918
  };
1911
1919
 
1912
1920
  /**
1913
1921
  * Returns the canvas resolution in *pixel* coordinates.
1914
- * Delegates to the WEBGL renderer.
1922
+ * Delegates to the active 3D renderer.
1915
1923
  *
1916
- * @returns {number[]|undefined} `[width, height]` in pixels, or undefined if not in WEBGL.
1924
+ * @returns {number[]|undefined} `[width, height]` in pixels, or undefined if no 3D renderer is active.
1917
1925
  */
1918
1926
  fn.resolution = function () {
1919
- return _rendererGL(this)?.resolution();
1927
+ return _renderer3D(this)?.resolution();
1920
1928
  };
1921
1929
 
1922
1930
  /**
@@ -1929,7 +1937,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1929
1937
  * @param {...(number|boolean)} args
1930
1938
  * @returns {number[]} `[x, y]` in pixels (includes pixelDensity scaling).
1931
1939
  */
1932
- p5.RendererGL.prototype.pointerPosition = function (...args) {
1940
+ p5.Renderer3D.prototype.pointerPosition = function (...args) {
1933
1941
  let pointerX;
1934
1942
  let pointerY;
1935
1943
  let flip = true;
@@ -1949,7 +1957,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
1949
1957
  * Returns the canvas resolution in *pixel* coordinates.
1950
1958
  * @returns {number[]} `[width, height]` in pixels (includes pixelDensity scaling).
1951
1959
  */
1952
- p5.RendererGL.prototype.resolution = function () {
1960
+ p5.Renderer3D.prototype.resolution = function () {
1953
1961
  const pd = this.pixelDensity();
1954
1962
  return [pd * this.width, pd * this.height];
1955
1963
  };
@@ -1959,22 +1967,19 @@ p5.registerAddon((p5, fn, lifecycles) => {
1959
1967
  // -------------------------------------------------------------------------
1960
1968
 
1961
1969
  fn.axes = function (opts) {
1962
- _rendererGL(this)?.axes(opts);
1970
+ _renderer3D(this)?.axes(opts);
1963
1971
  return this;
1964
1972
  };
1965
1973
 
1966
1974
  /**
1967
- * Draws 3D reference axes (X, Y, Z) centered at the origin in model space.
1975
+ * Draws 3D reference axes (X, Y, Z) centered at the origin in model space,
1976
+ * using the current stroke settings.
1968
1977
  *
1969
1978
  * Each axis can be enabled independently using bitwise flags, and optional
1970
1979
  * axis labels (X, Y, Z) can be rendered near the positive ends.
1971
1980
  *
1972
- * This is a WEBGL-only utility intended for debugging, teaching, and spatial
1973
- * orientation. Axes are drawn on the current Z=0 plane using the current
1974
- * stroke settings.
1975
- *
1976
1981
  * @method axes
1977
- * @for p5.RendererGL
1982
+ * @for p5.Renderer3D
1978
1983
  * @param {Object} [opts] Axes options.
1979
1984
  * @param {Number} [opts.size=100] Length of each axis in world units.
1980
1985
  * @param {Array<String>} [opts.colors=['Red','Lime','DodgerBlue']]
@@ -2006,7 +2011,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2006
2011
  * p5.Tree.LABELS
2007
2012
  * });
2008
2013
  */
2009
- p5.RendererGL.prototype.axes = function ({
2014
+ p5.Renderer3D.prototype.axes = function ({
2010
2015
  size = 100,
2011
2016
  colors = ['Red', 'Lime', 'DodgerBlue'],
2012
2017
  bits = p5.Tree.LABELS | p5.Tree.X | p5.Tree.Y | p5.Tree.Z
@@ -2051,7 +2056,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2051
2056
  };
2052
2057
 
2053
2058
  fn.grid = function (opts) {
2054
- _rendererGL(this)?.grid(opts);
2059
+ _renderer3D(this)?.grid(opts);
2055
2060
  return this;
2056
2061
  };
2057
2062
 
@@ -2061,10 +2066,8 @@ p5.registerAddon((p5, fn, lifecycles) => {
2061
2066
  * The grid is centered at the origin and spans from `-size` to `+size` on both X and Y.
2062
2067
  * It draws `subdivisions + 1` lines in each direction (including the borders).
2063
2068
  *
2064
- * This is a WEBGL-only utility intended for debugging and spatial reference.
2065
- *
2066
2069
  * @method grid
2067
- * @for p5.RendererGL
2070
+ * @for p5.Renderer3D
2068
2071
  * @param {Object} [opts] Grid options.
2069
2072
  * @param {Number} [opts.size=100] Half-extent of the grid in world units.
2070
2073
  * @param {Number} [opts.subdivisions=10] Number of subdivisions per side (must be >= 1).
@@ -2075,7 +2078,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2075
2078
  * grid({ size: 300, subdivisions: 20 });
2076
2079
  * }
2077
2080
  */
2078
- p5.RendererGL.prototype.grid = function ({
2081
+ p5.Renderer3D.prototype.grid = function ({
2079
2082
  size = 100,
2080
2083
  subdivisions = 10
2081
2084
  } = {}) {
@@ -2102,7 +2105,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2102
2105
  * `p5.Tree.SCREEN`. In that case, `size` is interpreted in *world units* and
2103
2106
  * converted to pixels using `pixelRatio()` at the corresponding world point.
2104
2107
  *
2105
- * Requires WEBGL.
2108
+ * Requires 3D renderer.
2106
2109
  *
2107
2110
  * @param {object} [opts]
2108
2111
  * @param {p5.Matrix} [opts.mMatrix] Model-space matrix origin to compute (x, y) from.
@@ -2117,7 +2120,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2117
2120
  * @returns {boolean|undefined}
2118
2121
  */
2119
2122
  fn.mousePicking = function (opts) {
2120
- return _rendererGL(this)?.mousePicking(opts);
2123
+ return _renderer3D(this)?.mousePicking(opts);
2121
2124
  };
2122
2125
 
2123
2126
  /**
@@ -2127,16 +2130,16 @@ p5.registerAddon((p5, fn, lifecycles) => {
2127
2130
  * `p5.Tree.SCREEN`. In that case, `size` is interpreted in *world units* and
2128
2131
  * converted to pixels using `pixelRatio()` at the corresponding world point.
2129
2132
  *
2130
- * Requires WEBGL.
2133
+ * Requires 3D renderer.
2131
2134
  *
2132
2135
  * @param {...any} args
2133
2136
  * @returns {boolean|undefined}
2134
2137
  */
2135
2138
  fn.pointerPicking = function (...args) {
2136
- return _rendererGL(this)?.pointerPicking(...args);
2139
+ return _renderer3D(this)?.pointerPicking(...args);
2137
2140
  };
2138
2141
 
2139
- p5.RendererGL.prototype.mousePicking = function ({
2142
+ p5.Renderer3D.prototype.mousePicking = function ({
2140
2143
  mMatrix = this.mMatrix(),
2141
2144
  x,
2142
2145
  y,
@@ -2162,7 +2165,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2162
2165
  * @param {...any} args
2163
2166
  * @returns {boolean}
2164
2167
  */
2165
- p5.RendererGL.prototype.pointerPicking = function (...args) {
2168
+ p5.Renderer3D.prototype.pointerPicking = function (...args) {
2166
2169
  let pointerX;
2167
2170
  let pointerY;
2168
2171
  const config = {};
@@ -2224,7 +2227,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2224
2227
  * @param {number} [opts.radius=100] Radius in current space.
2225
2228
  * @param {number} [opts.detail=50] Segment count.
2226
2229
  */
2227
- p5.RendererGL.prototype._circle = function ({
2230
+ p5.Renderer3D.prototype._circle = function ({
2228
2231
  filled = false,
2229
2232
  x = this.width / 2,
2230
2233
  y = this.height / 2,
@@ -2276,11 +2279,11 @@ p5.registerAddon((p5, fn, lifecycles) => {
2276
2279
  * @param {p5.Matrix} [opts.pvMatrix] Projection-view matrix override.
2277
2280
  */
2278
2281
  fn.cross = function (opts) {
2279
- _rendererGL(this)?.cross(opts);
2282
+ _renderer3D(this)?.cross(opts);
2280
2283
  return this;
2281
2284
  };
2282
2285
 
2283
- p5.RendererGL.prototype.cross = function ({
2286
+ p5.Renderer3D.prototype.cross = function ({
2284
2287
  mMatrix = this.mMatrix(),
2285
2288
  x,
2286
2289
  y,
@@ -2329,11 +2332,11 @@ p5.registerAddon((p5, fn, lifecycles) => {
2329
2332
  * @param {p5.Matrix} [opts.pvMatrix] Projection-view matrix override.
2330
2333
  */
2331
2334
  fn.bullsEye = function (opts) {
2332
- _rendererGL(this)?.bullsEye(opts);
2335
+ _renderer3D(this)?.bullsEye(opts);
2333
2336
  return this;
2334
2337
  };
2335
2338
 
2336
- p5.RendererGL.prototype.bullsEye = function ({
2339
+ p5.Renderer3D.prototype.bullsEye = function ({
2337
2340
  mMatrix = this.mMatrix(),
2338
2341
  x,
2339
2342
  y,
@@ -2380,22 +2383,22 @@ p5.registerAddon((p5, fn, lifecycles) => {
2380
2383
  // ---------------------------------------------------------------------------
2381
2384
 
2382
2385
  fn.viewFrustum = function (opts) {
2383
- _rendererGL(this)?.viewFrustum(opts);
2386
+ _renderer3D(this)?.viewFrustum(opts);
2384
2387
  return this;
2385
2388
  };
2386
2389
 
2387
2390
  /**
2388
- * Displays a view frustum, either from a pg (p5.Graphics / p5.RendererGL) or from eMatrix/pMatrix.
2391
+ * Displays a view frustum, either from a pg (p5.Graphics / p5.Renderer3D) or from eMatrix/pMatrix.
2389
2392
  *
2390
2393
  * @param {Object} [opts]
2391
2394
  * @param {p5.Matrix} [opts.vMatrix=this.vMatrix()] desired view matrix (world -> this eye) for drawing the frustum.
2392
- * @param {p5.RendererGL|p5.Graphics} [opts.pg] renderer/pg whose frustum is to be displayed.
2395
+ * @param {p5.Renderer3D|p5.Graphics} [opts.pg] renderer/pg whose frustum is to be displayed.
2393
2396
  * @param {p5.Matrix} [opts.eMatrix=pg?.eMatrix()] eye matrix defining frustum pose (eye -> world).
2394
2397
  * @param {p5.Matrix} [opts.pMatrix=pg?.pMatrix()] projection matrix defining frustum projection.
2395
2398
  * @param {number} [opts.bits=p5.Tree.NEAR|p5.Tree.FAR] bitmask (NEAR/FAR/BODY/APEX).
2396
2399
  * @param {Function|false|null} [opts.viewer=...] callback drawn at the frustum origin (in frustum space).
2397
2400
  */
2398
- p5.RendererGL.prototype.viewFrustum = function ({
2401
+ p5.Renderer3D.prototype.viewFrustum = function ({
2399
2402
  vMatrix = this.vMatrix(),
2400
2403
  pg,
2401
2404
  eMatrix = pg?.eMatrix(),
@@ -2526,7 +2529,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2526
2529
  * @returns {number} One of p5.Tree.VISIBLE, p5.Tree.INVISIBLE, p5.Tree.SEMIVISIBLE.
2527
2530
  */
2528
2531
  fn.visibility = function (...args) {
2529
- return _rendererGL(this).visibility(...args);
2532
+ return _renderer3D(this).visibility(...args);
2530
2533
  };
2531
2534
 
2532
2535
  /**
@@ -2534,7 +2537,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2534
2537
  * @returns {Object}
2535
2538
  */
2536
2539
  fn.bounds = function (opts = {}) {
2537
- return _rendererGL(this).bounds(opts);
2540
+ return _renderer3D(this).bounds(opts);
2538
2541
  };
2539
2542
 
2540
2543
  /**
@@ -2542,7 +2545,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2542
2545
  * @returns {number}
2543
2546
  */
2544
2547
  fn.distanceToBound = function (...args) {
2545
- return _rendererGL(this).distanceToBound(...args);
2548
+ return _renderer3D(this).distanceToBound(...args);
2546
2549
  };
2547
2550
 
2548
2551
  /**
@@ -2554,7 +2557,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2554
2557
  *
2555
2558
  * @private
2556
2559
  */
2557
- p5.RendererGL.prototype._parseVisibilityArgs = function (...args) {
2560
+ p5.Renderer3D.prototype._parseVisibilityArgs = function (...args) {
2558
2561
  let corner1;
2559
2562
  let corner2;
2560
2563
  let center;
@@ -2623,7 +2626,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2623
2626
  * @param {Object} [opts.bounds] Frustum plane equations (defaults to this.bounds()).
2624
2627
  * @returns {number} One of p5.Tree.VISIBLE, p5.Tree.INVISIBLE, p5.Tree.SEMIVISIBLE.
2625
2628
  */
2626
- p5.RendererGL.prototype.visibility = function (...args) {
2629
+ p5.Renderer3D.prototype.visibility = function (...args) {
2627
2630
  const { corner1, corner2, center, radius, bounds } = this._parseVisibilityArgs(...args);
2628
2631
  const b = bounds ?? this.bounds();
2629
2632
  return center ? (radius ? this._ballVisibility(center, radius, b) : this._pointVisibility(center, b))
@@ -2631,7 +2634,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2631
2634
  : (console.error('[p5.tree] visibility: could not parse query.'), p5.Tree.INVISIBLE));
2632
2635
  };
2633
2636
 
2634
- p5.RendererGL.prototype._pointVisibility = function (point, bounds = this.bounds()) {
2637
+ p5.Renderer3D.prototype._pointVisibility = function (point, bounds = this.bounds()) {
2635
2638
  for (const key in bounds) {
2636
2639
  const d = this.distanceToBound(point, key, bounds);
2637
2640
  if (d > 0) return p5.Tree.INVISIBLE;
@@ -2640,7 +2643,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2640
2643
  return p5.Tree.VISIBLE;
2641
2644
  };
2642
2645
 
2643
- p5.RendererGL.prototype._ballVisibility = function (center, radius, bounds = this.bounds()) {
2646
+ p5.Renderer3D.prototype._ballVisibility = function (center, radius, bounds = this.bounds()) {
2644
2647
  let allInForAllPlanes = true;
2645
2648
  for (const key in bounds) {
2646
2649
  const d = this.distanceToBound(center, key, bounds);
@@ -2650,7 +2653,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2650
2653
  return allInForAllPlanes ? p5.Tree.VISIBLE : p5.Tree.SEMIVISIBLE;
2651
2654
  };
2652
2655
 
2653
- p5.RendererGL.prototype._boxVisibility = function (corner1, corner2, bounds = this.bounds()) {
2656
+ p5.Renderer3D.prototype._boxVisibility = function (corner1, corner2, bounds = this.bounds()) {
2654
2657
  const asVec3 = v =>
2655
2658
  v instanceof p5.Vector ? v : new p5.Vector(v?.[0] ?? 0, v?.[1] ?? 0, v?.[2] ?? 0);
2656
2659
  corner1 = asVec3(corner1);
@@ -2685,7 +2688,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2685
2688
  * @param {p5.Matrix} [opts.eMatrix] Eye matrix (eye -> world).
2686
2689
  * @returns {Object} Object keyed by p5.Tree.LEFT/RIGHT/NEAR/FAR/TOP/BOTTOM.
2687
2690
  */
2688
- p5.RendererGL.prototype.bounds = function ({
2691
+ p5.Renderer3D.prototype.bounds = function ({
2689
2692
  vMatrix,
2690
2693
  eMatrix
2691
2694
  } = {}) {
@@ -2757,7 +2760,7 @@ p5.registerAddon((p5, fn, lifecycles) => {
2757
2760
  * @param {Object} [bounds] Plane equations (defaults to this.bounds()).
2758
2761
  * @returns {number}
2759
2762
  */
2760
- p5.RendererGL.prototype.distanceToBound = function (...args) {
2763
+ p5.Renderer3D.prototype.distanceToBound = function (...args) {
2761
2764
  let point;
2762
2765
  let key;
2763
2766
  let bounds = this.bounds();