melonjs 19.5.0 → 19.7.0

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.
Files changed (120) hide show
  1. package/README.md +5 -4
  2. package/build/application/application.d.ts +34 -2
  3. package/build/application/application.d.ts.map +1 -1
  4. package/build/application/settings.d.ts +37 -1
  5. package/build/application/settings.d.ts.map +1 -1
  6. package/build/camera/camera2d.d.ts +59 -7
  7. package/build/camera/camera2d.d.ts.map +1 -1
  8. package/build/camera/camera3d.d.ts +335 -0
  9. package/build/camera/camera3d.d.ts.map +1 -0
  10. package/build/camera/frustum.d.ts +162 -0
  11. package/build/camera/frustum.d.ts.map +1 -0
  12. package/build/const.d.ts +30 -3
  13. package/build/const.d.ts.map +1 -1
  14. package/build/geometries/sphere.d.ts +105 -0
  15. package/build/geometries/sphere.d.ts.map +1 -0
  16. package/build/index.d.ts +6 -4
  17. package/build/index.d.ts.map +1 -1
  18. package/build/index.js +27639 -24686
  19. package/build/index.js.map +4 -4
  20. package/build/input/keyboard.d.ts.map +1 -1
  21. package/build/input/pointerevent.d.ts.map +1 -1
  22. package/build/lang/deprecated.d.ts +18 -0
  23. package/build/lang/deprecated.d.ts.map +1 -1
  24. package/build/loader/loadingscreen.d.ts +8 -0
  25. package/build/loader/loadingscreen.d.ts.map +1 -1
  26. package/build/loader/parsers/mtl.d.ts.map +1 -1
  27. package/build/loader/parsers/obj.d.ts.map +1 -1
  28. package/build/math/color.d.ts +43 -5
  29. package/build/math/color.d.ts.map +1 -1
  30. package/build/math/math.d.ts +44 -0
  31. package/build/math/math.d.ts.map +1 -1
  32. package/build/math/observableVector2d.d.ts +14 -2
  33. package/build/math/observableVector2d.d.ts.map +1 -1
  34. package/build/math/observableVector3d.d.ts +14 -2
  35. package/build/math/observableVector3d.d.ts.map +1 -1
  36. package/build/math/vector2d.d.ts +16 -2
  37. package/build/math/vector2d.d.ts.map +1 -1
  38. package/build/math/vector3d.d.ts +16 -2
  39. package/build/math/vector3d.d.ts.map +1 -1
  40. package/build/particles/emitter.d.ts.map +1 -1
  41. package/build/physics/adapter.d.ts +77 -0
  42. package/build/physics/adapter.d.ts.map +1 -1
  43. package/build/physics/broadphase/aabb3d.d.ts +115 -0
  44. package/build/physics/broadphase/aabb3d.d.ts.map +1 -0
  45. package/build/physics/broadphase/broadphase.d.ts +74 -0
  46. package/build/physics/broadphase/broadphase.d.ts.map +1 -0
  47. package/build/physics/broadphase/factory.d.ts +30 -0
  48. package/build/physics/broadphase/factory.d.ts.map +1 -0
  49. package/build/physics/broadphase/octree.d.ts +325 -0
  50. package/build/physics/broadphase/octree.d.ts.map +1 -0
  51. package/build/physics/broadphase/quadtree.d.ts +184 -0
  52. package/build/physics/broadphase/quadtree.d.ts.map +1 -0
  53. package/build/physics/builtin/body.d.ts +7 -3
  54. package/build/physics/builtin/body.d.ts.map +1 -1
  55. package/build/physics/builtin/builtin-adapter.d.ts +6 -1
  56. package/build/physics/builtin/builtin-adapter.d.ts.map +1 -1
  57. package/build/physics/builtin/raycast.d.ts.map +1 -1
  58. package/build/physics/world.d.ts +15 -4
  59. package/build/physics/world.d.ts.map +1 -1
  60. package/build/renderable/container.d.ts +51 -5
  61. package/build/renderable/container.d.ts.map +1 -1
  62. package/build/renderable/mesh.d.ts +85 -10
  63. package/build/renderable/mesh.d.ts.map +1 -1
  64. package/build/renderable/renderable.d.ts +9 -4
  65. package/build/renderable/renderable.d.ts.map +1 -1
  66. package/build/state/stage.d.ts +8 -0
  67. package/build/state/stage.d.ts.map +1 -1
  68. package/build/state/state.d.ts.map +1 -1
  69. package/build/system/device.d.ts +196 -310
  70. package/build/system/device.d.ts.map +1 -1
  71. package/build/system/event.d.ts +49 -0
  72. package/build/system/event.d.ts.map +1 -1
  73. package/build/system/fullscreen.d.ts +16 -0
  74. package/build/system/fullscreen.d.ts.map +1 -0
  75. package/build/system/platform.d.ts +32 -4
  76. package/build/system/platform.d.ts.map +1 -1
  77. package/build/system/timer.d.ts.map +1 -1
  78. package/build/utils/function.d.ts +7 -1
  79. package/build/utils/function.d.ts.map +1 -1
  80. package/build/utils/types.d.ts +5 -0
  81. package/build/utils/types.d.ts.map +1 -1
  82. package/build/video/buffer/vertex.d.ts +19 -4
  83. package/build/video/buffer/vertex.d.ts.map +1 -1
  84. package/build/video/canvas/canvas_renderer.d.ts +4 -4
  85. package/build/video/canvas/canvas_renderer.d.ts.map +1 -1
  86. package/build/video/canvas_factory.d.ts +25 -0
  87. package/build/video/canvas_factory.d.ts.map +1 -0
  88. package/build/video/renderer.d.ts +89 -15
  89. package/build/video/renderer.d.ts.map +1 -1
  90. package/build/video/renderstate.d.ts +12 -0
  91. package/build/video/renderstate.d.ts.map +1 -1
  92. package/build/video/rendertarget/rendertarget.d.ts +3 -1
  93. package/build/video/rendertarget/rendertarget.d.ts.map +1 -1
  94. package/build/video/texture/cache.d.ts +5 -0
  95. package/build/video/texture/cache.d.ts.map +1 -1
  96. package/build/video/texture/resource.d.ts +22 -14
  97. package/build/video/texture/resource.d.ts.map +1 -1
  98. package/build/video/video.d.ts +3 -1
  99. package/build/video/video.d.ts.map +1 -1
  100. package/build/video/webgl/batchers/batcher.d.ts.map +1 -1
  101. package/build/video/webgl/batchers/lit_quad_batcher.d.ts.map +1 -1
  102. package/build/video/webgl/batchers/material_batcher.d.ts +9 -0
  103. package/build/video/webgl/batchers/material_batcher.d.ts.map +1 -1
  104. package/build/video/webgl/batchers/mesh_batcher.d.ts +45 -1
  105. package/build/video/webgl/batchers/mesh_batcher.d.ts.map +1 -1
  106. package/build/video/webgl/batchers/primitive_batcher.d.ts.map +1 -1
  107. package/build/video/webgl/batchers/quad_batcher.d.ts +2 -2
  108. package/build/video/webgl/batchers/quad_batcher.d.ts.map +1 -1
  109. package/build/video/webgl/glshader.d.ts +46 -16
  110. package/build/video/webgl/glshader.d.ts.map +1 -1
  111. package/build/video/webgl/renderers/tmxlayer/orthogonal.d.ts.map +1 -1
  112. package/build/video/webgl/shadereffect.d.ts +23 -4
  113. package/build/video/webgl/shadereffect.d.ts.map +1 -1
  114. package/build/video/webgl/utils/uniforms.d.ts +8 -0
  115. package/build/video/webgl/utils/uniforms.d.ts.map +1 -1
  116. package/build/video/webgl/webgl_renderer.d.ts +2 -2
  117. package/build/video/webgl/webgl_renderer.d.ts.map +1 -1
  118. package/package.json +3 -2
  119. package/build/physics/builtin/quadtree.d.ts +0 -112
  120. package/build/physics/builtin/quadtree.d.ts.map +0 -1
@@ -0,0 +1,115 @@
1
+ import { Vector3d } from "../../math/vector3d.ts";
2
+ import type { XYZPoint } from "../../utils/types.ts";
3
+ /**
4
+ * A 3D axis-aligned bounding box — the 3D sibling of {@link Bounds}.
5
+ *
6
+ * Used by {@link Octree} as the bounding primitive of every node
7
+ * (root, subnodes, queries). Intentionally minimal: only the
8
+ * operations the {@link Octree} hot path needs are implemented, with
9
+ * a small handful of helpers ({@link AABB3d#contains},
10
+ * {@link AABB3d#overlaps}, {@link AABB3d#overlapsSphere}) for
11
+ * test-driven `querySphere` / `queryAABB` callers.
12
+ *
13
+ * Coordinate convention matches the rest of melonJS 3D code (see
14
+ * {@link Camera3d}): **Y-down, +Z forward / away from the camera.**
15
+ *
16
+ * Lives next to {@link Octree} under `physics/broadphase/` rather
17
+ * than `math/` to mirror {@link Bounds} (which lives in `physics/`,
18
+ * not `math/`). Aabb is a primitive of the broadphase, not a generic
19
+ * math primitive — it never escapes a query result.
20
+ * @category Geometry
21
+ */
22
+ export declare class AABB3d {
23
+ min: XYZPoint;
24
+ max: XYZPoint;
25
+ /**
26
+ * Construct an empty AABB (min = +∞, max = −∞). The empty AABB
27
+ * satisfies `addPoint(p)` => `min = max = p` for the first point
28
+ * added, and `overlaps(b)` => `false` against any other AABB —
29
+ * same convention as {@link Bounds}.
30
+ * @param [min] - optional initial minimum corner
31
+ * @param [max] - optional initial maximum corner
32
+ */
33
+ constructor(min?: XYZPoint, max?: XYZPoint);
34
+ /**
35
+ * Reset the AABB to its empty state.
36
+ */
37
+ clear(): void;
38
+ /**
39
+ * Set min and max corners directly. Mirror of `Bounds.setMinMax`.
40
+ * @param minX - minimum corner x
41
+ * @param minY - minimum corner y
42
+ * @param minZ - minimum corner z
43
+ * @param maxX - maximum corner x
44
+ * @param maxY - maximum corner y
45
+ * @param maxZ - maximum corner z
46
+ */
47
+ setMinMax(minX: number, minY: number, minZ: number, maxX: number, maxY: number, maxZ: number): void;
48
+ get x(): number;
49
+ get y(): number;
50
+ get z(): number;
51
+ get width(): number;
52
+ get height(): number;
53
+ get depth(): number;
54
+ get left(): number;
55
+ get right(): number;
56
+ get top(): number;
57
+ get bottom(): number;
58
+ get front(): number;
59
+ get back(): number;
60
+ get centerX(): number;
61
+ get centerY(): number;
62
+ get centerZ(): number;
63
+ /**
64
+ * True if every coordinate is a finite number. Used by the
65
+ * {@link Octree} to reject inserts whose bounding box is the
66
+ * empty AABB (a sprite with no shape and never updated) — without
67
+ * this guard a `±Infinity` corner would silently classify into
68
+ * an arbitrary octant and never come back out via `remove`.
69
+ */
70
+ isFinite(): boolean;
71
+ /**
72
+ * True if this AABB fully encloses the given point.
73
+ * @param x - point x
74
+ * @param y - point y
75
+ * @param z - point z
76
+ */
77
+ contains(x: number, y: number, z: number): boolean;
78
+ /**
79
+ * True if this AABB overlaps the given AABB on every axis. The
80
+ * intersection includes the boundary (shared face/edge/corner
81
+ * counts as overlap), same convention as {@link Bounds.overlaps}
82
+ * so {@link Octree} candidate sets don't drop items that sit
83
+ * exactly on an octant boundary.
84
+ * @param aabb - the other AABB to test against
85
+ */
86
+ overlaps(aabb: AABB3d): boolean;
87
+ /**
88
+ * True if this AABB overlaps a sphere. Computes the squared
89
+ * distance from the sphere center to the nearest point on the
90
+ * AABB and compares against `r²` — avoids the `sqrt` on the hot
91
+ * path. Used by `Octree.querySphere`.
92
+ * @param cx - sphere center x
93
+ * @param cy - sphere center y
94
+ * @param cz - sphere center z
95
+ * @param r - sphere radius (must be ≥ 0; `r=0` becomes a point-in-AABB test)
96
+ */
97
+ overlapsSphere(cx: number, cy: number, cz: number, r: number): boolean;
98
+ /**
99
+ * Expand this AABB to include the given point.
100
+ * @param p - the point to fold in
101
+ */
102
+ addPoint(p: XYZPoint | Vector3d): void;
103
+ /**
104
+ * Expand this AABB to include the given AABB. With `clear=true`,
105
+ * copies the input AABB directly — same shape as {@link Bounds.addBounds}.
106
+ * @param aabb - the AABB to fold in
107
+ * @param [clear] - reset this AABB before folding
108
+ */
109
+ addAABB(aabb: AABB3d, clear?: boolean): void;
110
+ /**
111
+ * Returns a deep copy of this AABB.
112
+ */
113
+ clone(): AABB3d;
114
+ }
115
+ //# sourceMappingURL=aabb3d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aabb3d.d.ts","sourceRoot":"","sources":["../../../src/physics/broadphase/aabb3d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,MAAM;IAClB,GAAG,EAAE,QAAQ,CAAC;IACd,GAAG,EAAE,QAAQ,CAAC;IAEd;;;;;;;OAOG;gBACS,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,QAAQ;IAQ1C;;OAEG;IACH,KAAK;IASL;;;;;;;;OAQG;IACH,SAAS,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM;IAUb,IAAI,CAAC,IAAI,MAAM,CAEd;IACD,IAAI,CAAC,IAAI,MAAM,CAEd;IACD,IAAI,CAAC,IAAI,MAAM,CAEd;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IACD,IAAI,MAAM,IAAI,MAAM,CAEnB;IACD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,KAAK,IAAI,MAAM,CAElB;IACD,IAAI,GAAG,IAAI,MAAM,CAEhB;IACD,IAAI,MAAM,IAAI,MAAM,CAEnB;IACD,IAAI,KAAK,IAAI,MAAM,CAElB;IACD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IACD,IAAI,OAAO,IAAI,MAAM,CAEpB;IACD,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;;;;;OAMG;IACH,QAAQ;IAWR;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAWxC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM;IAWrB;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAW5D;;;OAGG;IACH,QAAQ,CAAC,CAAC,EAAE,QAAQ,GAAG,QAAQ;IAS/B;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,UAAQ;IAkBnC;;OAEG;IACH,KAAK;CAGL"}
@@ -0,0 +1,74 @@
1
+ import type Container from "../../renderable/container.js";
2
+ /**
3
+ * Common surface shared by every broadphase implementation in
4
+ * melonJS. Selected at runtime by {@link World.broadphase} based on
5
+ * `world.sortOn`:
6
+ * - 2D (`sortOn` ∈ `"x"` / `"y"` / `"z"`) → {@link QuadTree}
7
+ * - 3D (`sortOn === "depth"`) → {@link Octree}
8
+ *
9
+ * Internal contract — not exported from the package entry. The
10
+ * documented user-facing 3D spatial-query surface is
11
+ * `world.adapter.queryAABB(rect)`, `world.adapter.querySphere(sphere)`,
12
+ * `world.adapter.raycast(from, to)`, `world.adapter.raycast3d?(from, to)`.
13
+ * `world.broadphase` is reachable for engine internals and tooling
14
+ * (e.g. `@melonjs/debug-plugin` reads it to draw the spatial overlay),
15
+ * but user game code shouldn't need it directly.
16
+ *
17
+ * The generic `TItem` lets each implementation narrow to its own
18
+ * item shape (`QuadTreeItem` / `OctreeItem`) without losing the
19
+ * shared contract. The 3D `Octree`-only region queries
20
+ * (`queryAABB`, `querySphere`, `queryFrustum`, `queryRay`) are NOT
21
+ * part of this interface — they live on `Octree` directly because
22
+ * `QuadTree` has no equivalent.
23
+ */
24
+ export interface Broadphase<TItem = unknown> {
25
+ /** depth in the tree; 0 at the root. */
26
+ readonly level: number;
27
+ /** node-capacity threshold; exceeding it triggers a split. */
28
+ max_objects: number;
29
+ /** maximum subdivision depth; the root won't split past this. */
30
+ max_levels: number;
31
+ /** items held at this node level (not in subnodes). */
32
+ objects: TItem[];
33
+ /** subnodes (empty until {@link Broadphase.split} fires). */
34
+ nodes: Broadphase<TItem>[];
35
+ /**
36
+ * Total items in this subtree (own `objects` + descendants).
37
+ * Maintained by `insert` / `remove` so {@link Broadphase.isPrunable}
38
+ * and {@link Broadphase.hasChildren} are O(1) reads.
39
+ * @ignore
40
+ */
41
+ _subtreeCount: number;
42
+ /** Insert one item. Splits + redistributes if `max_objects` is exceeded. */
43
+ insert(item: TItem): void;
44
+ /**
45
+ * Remove one item. Returns `true` if the item was found.
46
+ * Includes a stale-bounds fallback walk for items that moved
47
+ * between insert and remove without a rebuild in between.
48
+ */
49
+ remove(item: TItem): boolean;
50
+ /**
51
+ * Return every item that could collide with `item`. Re-entrancy
52
+ * contract: the no-`result` form reuses a shared scratch array;
53
+ * pass an explicit `result` to be re-entrancy-safe.
54
+ */
55
+ retrieve(item: TItem, fn?: (a: TItem, b: TItem) => number, result?: TItem[]): TItem[];
56
+ /** Recursively insert every non-kinematic child of `container`. */
57
+ insertContainer(container: Container): void;
58
+ /** Inverse of {@link Broadphase.insertContainer}. */
59
+ removeContainer(container: Container): void;
60
+ /** Empty this node + every subnode; optionally resize the root bounds. */
61
+ clear(bounds?: unknown): void;
62
+ /** True if this subtree holds no items at any level. */
63
+ isPrunable(): boolean;
64
+ /** True if this node has any descendants (items in subnodes). */
65
+ hasChildren(): boolean;
66
+ /**
67
+ * Classify `item` into a subnode index, or `-1` if it spans a
68
+ * midpoint / sits outside the node's bounds.
69
+ */
70
+ getIndex(item: TItem): number;
71
+ /** Subdivide this node into its subnodes (4 for 2D, 8 for 3D). */
72
+ split(): void;
73
+ }
74
+ //# sourceMappingURL=broadphase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadphase.d.ts","sourceRoot":"","sources":["../../../src/physics/broadphase/broadphase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,UAAU,CAAC,KAAK,GAAG,OAAO;IAC1C,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,OAAO,EAAE,KAAK,EAAE,CAAC;IACjB,6DAA6D;IAC7D,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;IAC3B;;;;;OAKG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB,4EAA4E;IAC5E,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IAC1B;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CACP,IAAI,EAAE,KAAK,EACX,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,KAAK,MAAM,EACnC,MAAM,CAAC,EAAE,KAAK,EAAE,GACd,KAAK,EAAE,CAAC;IACX,mEAAmE;IACnE,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5C,qDAAqD;IACrD,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5C,0EAA0E;IAC1E,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,wDAAwD;IACxD,UAAU,IAAI,OAAO,CAAC;IACtB,iEAAiE;IACjE,WAAW,IAAI,OAAO,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IAC9B,kEAAkE;IAClE,KAAK,IAAI,IAAI,CAAC;CACd"}
@@ -0,0 +1,30 @@
1
+ import type World from "../world.js";
2
+ import type { Broadphase } from "./broadphase.ts";
3
+ /**
4
+ * Build the spatial broadphase that matches `world.sortOn`. Called
5
+ * by `World` on construction and on every 2D↔3D sortOn flip; not
6
+ * part of the user-facing surface.
7
+ *
8
+ * - `sortOn === "depth"` → {@link Octree} rooted at an origin-
9
+ * centred ±10000 box. Camera3d games conventionally centre the
10
+ * play area on the world origin (items at e.g.
11
+ * `x ∈ [-PLAY_BOUND_X, PLAY_BOUND_X]`); `world.getBounds()` returns
12
+ * the 2D viewport rect `(0..w, 0..h)` which doesn't contain those
13
+ * items. Using viewport bounds as the octree root would
14
+ * misclassify negative-coord items into octants whose AABBs don't
15
+ * contain them, breaking `querySphere`'s spatial pruning. ±10000
16
+ * covers arcade-3D scales (AfterBurner ≈ ±350 xy, ±1000 z); items
17
+ * outside still work — `getIndex` keeps them at `root.objects` so
18
+ * queries walk them via the root-level pass, just without the
19
+ * spatial-partition win.
20
+ * - any other sortOn → {@link QuadTree} rooted at
21
+ * `world.getBounds().clone()` (the viewport rect).
22
+ *
23
+ * Lives in `physics/broadphase/` (not on `World`) so the World class
24
+ * doesn't need to know which concrete tree class implements the
25
+ * spatial index, or what bounds shape each class wants — those are
26
+ * broadphase concerns.
27
+ * @param world - the world this broadphase will index
28
+ */
29
+ export declare function createBroadphase(world: World): Broadphase;
30
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/physics/broadphase/factory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,aAAa,CAAC;AAErC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAIlD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,UAAU,CAYzD"}
@@ -0,0 +1,325 @@
1
+ import { Sphere } from "../../geometries/sphere.ts";
2
+ import type World from "../world.js";
3
+ import { AABB3d } from "./aabb3d.ts";
4
+ import type { Broadphase } from "./broadphase.ts";
5
+ /**
6
+ * 8-octant spatial subdivision for `Camera3d` workloads. Sibling to
7
+ * {@link QuadTree}: same public surface (`insert`, `remove`,
8
+ * `retrieve`, `insertContainer`, `removeContainer`, `clear`,
9
+ * `getIndex`, `isPrunable`, `hasChildren`), plus 3D-specific
10
+ * region queries (`queryAABB`, `querySphere`). Selected
11
+ * automatically by {@link World} when `world.sortOn === "depth"`
12
+ * (which `Camera3d.defaultSortOn` sets on stage reset).
13
+ *
14
+ * Implementation notes:
15
+ * - Bounding primitive is {@link AABB3d}; subnode bounds are POJOs
16
+ * with the same shape so node split is allocation-free apart from
17
+ * the eight literal objects (recycled via the global node pool).
18
+ * - Per-frame clear/insert reuses both an octree-node pool
19
+ * (`OT_ARRAY`) and a result scratch (`_retrieveScratch`), so the
20
+ * steady state allocates nothing.
21
+ * - Item z is read via `getAbsolutePosition()` — same convention as
22
+ * `Camera3d.isVisible` and the container depth sort, so the
23
+ * broadphase agrees with the renderer on which octant an item
24
+ * lives in even under nested transforms.
25
+ */
26
+ /**
27
+ * Minimal axis-aligned box shape consumed by `Octree`. Both
28
+ * {@link AABB3d} and the POJOs emitted by `split` satisfy it
29
+ * structurally.
30
+ */
31
+ export interface OctRect {
32
+ left: number;
33
+ top: number;
34
+ front: number;
35
+ width: number;
36
+ height: number;
37
+ depth: number;
38
+ }
39
+ /**
40
+ * Structural shape for an item inserted into the `Octree`. Same
41
+ * shape as {@link QuadTree}'s item, with the addition that
42
+ * `getAbsolutePosition()` is consulted for z (so nested transforms
43
+ * still classify into the right octant).
44
+ */
45
+ export interface OctreeItem {
46
+ getBounds(): {
47
+ left: number;
48
+ top: number;
49
+ width: number;
50
+ height: number;
51
+ };
52
+ getAbsolutePosition?(): {
53
+ x: number;
54
+ y: number;
55
+ z: number;
56
+ };
57
+ /**
58
+ * 2D items expose Vector2d here (no z); 3D items expose Vector3d.
59
+ * `getAbsolutePosition()` is the preferred path; this fallback
60
+ * applies only to test doubles that skip `getAbsolutePosition`.
61
+ */
62
+ pos?: {
63
+ x: number;
64
+ y: number;
65
+ z?: number;
66
+ };
67
+ isFloating?: boolean;
68
+ isKinematic?: boolean;
69
+ name?: string;
70
+ }
71
+ export type OctreeSortFn = (a: OctreeItem, b: OctreeItem) => number;
72
+ /**
73
+ * Structural shape consumed by {@link Octree.queryFrustum} —
74
+ * matches the shape exposed by `Frustum#planes` (see
75
+ * `camera/frustum.ts`). Each plane satisfies `nx·x + ny·y + nz·z + d = 0`;
76
+ * positive side is the interior of the frustum.
77
+ */
78
+ export interface FrustumPlane {
79
+ nx: number;
80
+ ny: number;
81
+ nz: number;
82
+ d: number;
83
+ }
84
+ /**
85
+ * an Octree implementation for 3D broadphase / spatial queries
86
+ * under `Camera3d`.
87
+ * @category Physics
88
+ * @see World.broadphase
89
+ */
90
+ export default class Octree implements Broadphase<OctreeItem> {
91
+ world: World;
92
+ bounds: OctRect | AABB3d;
93
+ max_objects: number;
94
+ max_levels: number;
95
+ level: number;
96
+ objects: OctreeItem[];
97
+ nodes: Octree[];
98
+ /**
99
+ * see {@link QuadTree._subtreeCount} — same invariant.
100
+ * @ignore
101
+ */
102
+ _subtreeCount: number;
103
+ /**
104
+ * see {@link QuadTree._retrieveScratch} — same contract.
105
+ * @ignore
106
+ */
107
+ _retrieveScratch: OctreeItem[] | null;
108
+ /**
109
+ * @param world - the physic world this Octree belongs to
110
+ * @param bounds - bounds of the node
111
+ * @param [max_objects=4] - max objects a node can hold before splitting into 8 subnodes
112
+ * @param [max_levels=4] - total max levels inside root Octree
113
+ * @param [level] - depth level, required for subnodes
114
+ */
115
+ constructor(world: World, bounds: OctRect | AABB3d, max_objects?: number, max_levels?: number, level?: number);
116
+ /**
117
+ * Split this node into 8 octants. The naming mirrors the
118
+ * QuadTree's `top` / `bottom` / `left` / `right` ordering, with
119
+ * `near` (smaller z) before `far` (larger z) — matches the
120
+ * Y-down + +Z forward convention from {@link Camera3d}.
121
+ *
122
+ * Octant index layout (used by `getIndex`):
123
+ * ```
124
+ * near (lower z) far (higher z)
125
+ * 0: TR-near 1: TL-near 4: TR-far 5: TL-far
126
+ * 3: BR-near 2: BL-near 7: BR-far 6: BL-far
127
+ * ```
128
+ */
129
+ split(): void;
130
+ /**
131
+ * Classify an item into an octant.
132
+ *
133
+ * Returns -1 (keep at this level) when the item straddles ANY
134
+ * midpoint OR sits outside this node's bounds entirely. The
135
+ * out-of-bounds guard matters for `querySphere`: a sphere walks
136
+ * subnodes by AABB overlap, so an item assigned to a subnode
137
+ * whose bounds don't actually contain it would be invisible to
138
+ * any query whose sphere doesn't overlap that subnode's AABB.
139
+ * Items outside the root live at `root.objects` and are visited
140
+ * by every query unconditionally — they degrade to a linear scan
141
+ * but stay findable.
142
+ * @param item - the object to classify
143
+ * @returns octant index (0-7) or -1
144
+ */
145
+ getIndex(item: OctreeItem): number;
146
+ /**
147
+ * Insert the given object container into the node — recursively
148
+ * walks `Container.getChildren()` and inserts each non-kinematic
149
+ * leaf. Mirrors `QuadTree.insertContainer`.
150
+ * @param container - group of objects to be added
151
+ */
152
+ insertContainer(container: ContainerLike): void;
153
+ /**
154
+ * Insert the given object into the node. If this node exceeds
155
+ * `max_objects`, it splits and redistributes existing items into
156
+ * subnodes. Mirrors `QuadTree.insert` — same subtree-count
157
+ * accounting (bump on insert, no bump on redistribution).
158
+ * @param item - object to be added
159
+ */
160
+ insert(item: OctreeItem): void;
161
+ /**
162
+ * Recursively remove the given container and its descendants from
163
+ * the octree. Mirror of `QuadTree.removeContainer`.
164
+ * @param container - group of objects to be removed
165
+ */
166
+ removeContainer(container: ContainerLikeOptional): void;
167
+ /**
168
+ * Return every object that could collide with the given item.
169
+ * Re-entrancy contract identical to {@link QuadTree.retrieve}: the
170
+ * default (scratch) path is allocation-free but cannot be safely
171
+ * re-entered while iterating; pass an explicit `result` for safe
172
+ * re-entry.
173
+ * @param item - object to be checked against
174
+ * @param [fn] - sorter applied to the returned array (root only)
175
+ * @param [result] - caller-supplied result array (re-entrancy-safe)
176
+ * @returns the collected candidates
177
+ */
178
+ retrieve(item: OctreeItem, fn?: OctreeSortFn, result?: OctreeItem[]): OctreeItem[];
179
+ /**
180
+ * Return every object whose subtree overlaps the given AABB.
181
+ * Walks only octants whose bounds overlap the query — same
182
+ * pruning shape as `retrieve(item)`, just driven by an explicit
183
+ * region instead of an item's own bounds.
184
+ *
185
+ * Re-entrancy: same contract as {@link Octree.retrieve}. Pass an
186
+ * explicit `result` for safe re-entry.
187
+ * @param aabb - the AABB region to query
188
+ * @param [result] - caller-supplied result array (re-entrancy-safe)
189
+ * @returns the collected candidates
190
+ */
191
+ queryAABB(aabb: AABB3d, result?: OctreeItem[]): OctreeItem[];
192
+ /**
193
+ * Return every object whose containing octant overlaps the given
194
+ * sphere. Replaces the hand-rolled O(n²) sphere-vs-sphere loops
195
+ * common in arcade 3D code with a broadphase that scales.
196
+ *
197
+ * Two call shapes — both forms route to the same internal walk:
198
+ * - `querySphere(cx, cy, cz, r, result?)` — loose floats
199
+ * - `querySphere(sphere, result?)` — packaged {@link Sphere}
200
+ *
201
+ * Re-entrancy: same contract as {@link Octree.retrieve}.
202
+ */
203
+ querySphere(sphere: Sphere, result?: OctreeItem[]): OctreeItem[];
204
+ /**
205
+ * @param cx - sphere center x
206
+ * @param cy - sphere center y
207
+ * @param cz - sphere center z
208
+ * @param r - sphere radius (must be ≥ 0; r=0 becomes a point query)
209
+ * @param [result] - caller-supplied result array (re-entrancy-safe)
210
+ * @returns the collected candidates
211
+ */
212
+ querySphere(cx: number, cy: number, cz: number, r: number, result?: OctreeItem[]): OctreeItem[];
213
+ /**
214
+ * Loose-floats implementation. Recursive subnode walks call this
215
+ * directly to bypass the Sphere/floats dispatch on every node.
216
+ * @ignore
217
+ */
218
+ _querySphereInternal(cx: number, cy: number, cz: number, r: number, result?: OctreeItem[]): OctreeItem[];
219
+ /**
220
+ * Return every object whose containing octant lies on the
221
+ * positive side of all six frustum planes — i.e. every potential
222
+ * candidate the frustum can see. Uses Gribb–Hartmann positive-
223
+ * vertex pruning at each node: a subtree is skipped iff its
224
+ * octant's most-positive corner along a plane normal is on that
225
+ * plane's negative side (i.e. wholly outside the frustum).
226
+ *
227
+ * Mirrors {@link Frustum#intersectsSphere} on the renderer side —
228
+ * use this as the broadphase pass before per-item narrow-phase
229
+ * checks (sphere / OBB / etc.).
230
+ *
231
+ * Re-entrancy: same contract as {@link Octree.retrieve}. Pass an
232
+ * explicit `result` for safe re-entry.
233
+ * @param planes - 6 frustum planes (left, right, bottom, top, near, far) — `Frustum#planes` shape
234
+ * @param [result] - caller-supplied result array (re-entrancy-safe)
235
+ * @returns the collected candidates
236
+ */
237
+ queryFrustum(planes: FrustumPlane[], result?: OctreeItem[]): OctreeItem[];
238
+ /**
239
+ * Return every object whose containing octant the ray segment
240
+ * `from + t·dir`, `t ∈ [0, tMax]`, crosses. Slab AABB test prunes
241
+ * subtrees the ray misses entirely — much tighter than enclosing
242
+ * the segment in a single AABB and walking `queryAABB`. The
243
+ * candidates aren't sorted by hit-distance (front-to-back walk
244
+ * would require a per-octant DDA step); callers that need
245
+ * nearest-hit sort the narrow-phase results themselves.
246
+ *
247
+ * Re-entrancy: same contract as {@link Octree.retrieve}.
248
+ * @param fromX - ray origin x
249
+ * @param fromY - ray origin y
250
+ * @param fromZ - ray origin z
251
+ * @param dirX - ray direction x (`to - from`; not unit-length)
252
+ * @param dirY - ray direction y
253
+ * @param dirZ - ray direction z
254
+ * @param tMax - maximum t along the ray (usually `1` if `dir = to - from`)
255
+ * @param [result] - caller-supplied result array (re-entrancy-safe)
256
+ * @returns the collected candidates
257
+ */
258
+ queryRay(fromX: number, fromY: number, fromZ: number, dirX: number, dirY: number, dirZ: number, tMax: number, result?: OctreeItem[]): OctreeItem[];
259
+ /**
260
+ * Remove the given item from the octree. Mirror of
261
+ * `QuadTree.remove` — same stale-bounds fallback walk, same
262
+ * collapse-on-removal pool recycling.
263
+ * @param item - object to be removed
264
+ * @returns true if the item was found and removed.
265
+ */
266
+ remove(item: OctreeItem): boolean;
267
+ /**
268
+ * @returns true if this subtree holds no items at any level.
269
+ */
270
+ isPrunable(): boolean;
271
+ /**
272
+ * @returns true if this node has any descendants (items in
273
+ * subnodes, not at this level).
274
+ */
275
+ hasChildren(): boolean;
276
+ /**
277
+ * Empty this octree and recycle every subnode back to the pool.
278
+ * If `bounds` is supplied, resizes the root bounds to match —
279
+ * called by `World` on `LEVEL_LOADED` so the broadphase tracks
280
+ * level boundary changes.
281
+ * @param [bounds] - the new root bounds (resize on clear)
282
+ */
283
+ clear(bounds?: AABB3d): void;
284
+ /**
285
+ * Conservative outside-frustum test using the positive-vertex
286
+ * method (Gribb–Hartmann). Returns true iff the octant is
287
+ * provably outside ANY one plane, i.e. wholly outside the
288
+ * frustum.
289
+ * @ignore
290
+ */
291
+ _outsideFrustum(planes: FrustumPlane[]): boolean;
292
+ /**
293
+ * Slab method for ray–AABB intersection. Returns true iff the
294
+ * segment `from + t·dir`, `t ∈ [0, tMax]`, intersects this
295
+ * node's octant. dir components may be zero; the axis with zero
296
+ * direction degenerates to a point-in-slab test.
297
+ * @ignore
298
+ */
299
+ _overlapsRay(fromX: number, fromY: number, fromZ: number, dirX: number, dirY: number, dirZ: number, tMax: number): boolean;
300
+ /** @ignore */
301
+ _overlapsAABB(aabb: AABB3d): boolean;
302
+ /** @ignore */
303
+ _overlapsSphere(cx: number, cy: number, cz: number, r: number): boolean;
304
+ }
305
+ /**
306
+ * Structural shape consumed by `insertContainer` / `removeContainer`
307
+ * — captures only the fields the walk inspects. Same approach as
308
+ * QuadTree. `getChildren` is optional because leaf renderables don't
309
+ * have it; the recursive walk narrows via {@link hasGetChildren}.
310
+ * @ignore
311
+ */
312
+ interface ContainerOrChild extends OctreeItem {
313
+ addChild?: (...args: unknown[]) => unknown;
314
+ getChildren?: () => ContainerOrChild[];
315
+ }
316
+ /** @ignore */
317
+ type ContainerLike = {
318
+ getChildren(): ContainerOrChild[];
319
+ };
320
+ /** @ignore */
321
+ type ContainerLikeOptional = {
322
+ getChildren?(): ContainerOrChild[];
323
+ };
324
+ export {};
325
+ //# sourceMappingURL=octree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"octree.d.ts","sourceRoot":"","sources":["../../../src/physics/broadphase/octree.ts"],"names":[],"mappings":"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"}