@driftengine/physics 3.61.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 (136) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +9 -0
  3. package/README.md +503 -0
  4. package/dist/bodies.d.ts +121 -0
  5. package/dist/bodies.js +298 -0
  6. package/dist/buoyancy.d.ts +46 -0
  7. package/dist/buoyancy.js +45 -0
  8. package/dist/cloth.d.ts +226 -0
  9. package/dist/cloth.js +587 -0
  10. package/dist/collide/aabb.d.ts +10 -0
  11. package/dist/collide/aabb.js +11 -0
  12. package/dist/collide/body.d.ts +202 -0
  13. package/dist/collide/body.js +142 -0
  14. package/dist/collide/eject.d.ts +39 -0
  15. package/dist/collide/eject.js +142 -0
  16. package/dist/collide/index.d.ts +18 -0
  17. package/dist/collide/index.js +5 -0
  18. package/dist/collide/scratch.d.ts +8 -0
  19. package/dist/collide/scratch.js +9 -0
  20. package/dist/collide/segment.d.ts +12 -0
  21. package/dist/collide/segment.js +109 -0
  22. package/dist/collide/sweep.d.ts +3 -0
  23. package/dist/collide/sweep.js +1036 -0
  24. package/dist/colliderSet.d.ts +239 -0
  25. package/dist/colliderSet.js +546 -0
  26. package/dist/compoundContact.d.ts +70 -0
  27. package/dist/compoundContact.js +221 -0
  28. package/dist/controller.d.ts +351 -0
  29. package/dist/controller.js +641 -0
  30. package/dist/cylinder.d.ts +78 -0
  31. package/dist/cylinder.js +294 -0
  32. package/dist/cylinderContact.d.ts +7 -0
  33. package/dist/cylinderContact.js +704 -0
  34. package/dist/decompose.d.ts +105 -0
  35. package/dist/decompose.js +979 -0
  36. package/dist/events.d.ts +43 -0
  37. package/dist/events.js +95 -0
  38. package/dist/executor.d.ts +147 -0
  39. package/dist/executor.js +173 -0
  40. package/dist/faces.d.ts +26 -0
  41. package/dist/faces.js +34 -0
  42. package/dist/fingerprint.d.ts +61 -0
  43. package/dist/fingerprint.js +139 -0
  44. package/dist/groundMotor.d.ts +34 -0
  45. package/dist/groundMotor.js +41 -0
  46. package/dist/heightfieldShape.d.ts +128 -0
  47. package/dist/heightfieldShape.js +328 -0
  48. package/dist/index.d.ts +73 -0
  49. package/dist/index.js +47 -0
  50. package/dist/island.d.ts +55 -0
  51. package/dist/island.js +227 -0
  52. package/dist/islandSolve.d.ts +70 -0
  53. package/dist/islandSolve.js +171 -0
  54. package/dist/islandWorker.d.ts +18 -0
  55. package/dist/islandWorker.js +125 -0
  56. package/dist/joints.d.ts +180 -0
  57. package/dist/joints.js +1094 -0
  58. package/dist/manifold.d.ts +89 -0
  59. package/dist/manifold.js +608 -0
  60. package/dist/mass.d.ts +53 -0
  61. package/dist/mass.js +353 -0
  62. package/dist/meshContact.d.ts +57 -0
  63. package/dist/meshContact.js +393 -0
  64. package/dist/meshShape.d.ts +76 -0
  65. package/dist/meshShape.js +175 -0
  66. package/dist/pairs.d.ts +62 -0
  67. package/dist/pairs.js +154 -0
  68. package/dist/query.d.ts +71 -0
  69. package/dist/query.js +683 -0
  70. package/dist/ragdoll.d.ts +135 -0
  71. package/dist/ragdoll.js +489 -0
  72. package/dist/shape.d.ts +177 -0
  73. package/dist/shape.js +533 -0
  74. package/dist/solver.d.ts +136 -0
  75. package/dist/solver.js +601 -0
  76. package/dist/stage.d.ts +167 -0
  77. package/dist/stage.js +350 -0
  78. package/dist/stallEscape.d.ts +141 -0
  79. package/dist/stallEscape.js +254 -0
  80. package/dist/sweptStep.d.ts +173 -0
  81. package/dist/sweptStep.js +472 -0
  82. package/dist/tree.d.ts +61 -0
  83. package/dist/tree.js +348 -0
  84. package/dist/vehicle.d.ts +154 -0
  85. package/dist/vehicle.js +343 -0
  86. package/dist/workerPool.d.ts +107 -0
  87. package/dist/workerPool.js +239 -0
  88. package/dist/workers.d.ts +37 -0
  89. package/dist/workers.js +35 -0
  90. package/dist/world.d.ts +298 -0
  91. package/dist/world.js +712 -0
  92. package/package.json +55 -0
  93. package/src/bodies.ts +369 -0
  94. package/src/buoyancy.ts +78 -0
  95. package/src/cloth.ts +734 -0
  96. package/src/collide/aabb.ts +28 -0
  97. package/src/collide/body.ts +336 -0
  98. package/src/collide/eject.ts +156 -0
  99. package/src/collide/index.ts +26 -0
  100. package/src/collide/scratch.ts +10 -0
  101. package/src/collide/segment.ts +127 -0
  102. package/src/collide/sweep.ts +1132 -0
  103. package/src/colliderSet.ts +637 -0
  104. package/src/compoundContact.ts +284 -0
  105. package/src/controller.ts +817 -0
  106. package/src/cylinder.ts +340 -0
  107. package/src/cylinderContact.ts +825 -0
  108. package/src/decompose.ts +1198 -0
  109. package/src/events.ts +108 -0
  110. package/src/executor.ts +224 -0
  111. package/src/faces.ts +37 -0
  112. package/src/fingerprint.ts +146 -0
  113. package/src/groundMotor.ts +53 -0
  114. package/src/heightfieldShape.ts +395 -0
  115. package/src/index.ts +164 -0
  116. package/src/island.ts +219 -0
  117. package/src/islandSolve.ts +218 -0
  118. package/src/islandWorker.ts +141 -0
  119. package/src/joints.ts +1367 -0
  120. package/src/manifold.ts +798 -0
  121. package/src/mass.ts +424 -0
  122. package/src/meshContact.ts +443 -0
  123. package/src/meshShape.ts +261 -0
  124. package/src/pairs.ts +169 -0
  125. package/src/query.ts +844 -0
  126. package/src/ragdoll.ts +662 -0
  127. package/src/shape.ts +656 -0
  128. package/src/solver.ts +873 -0
  129. package/src/stage.ts +406 -0
  130. package/src/stallEscape.ts +362 -0
  131. package/src/sweptStep.ts +609 -0
  132. package/src/tree.ts +366 -0
  133. package/src/vehicle.ts +489 -0
  134. package/src/workerPool.ts +283 -0
  135. package/src/workers.ts +38 -0
  136. package/src/world.ts +961 -0
@@ -0,0 +1,177 @@
1
+ import type { Aabb } from './collide/index.ts';
2
+ import type { TriangleMesh } from './meshShape.ts';
3
+ /**
4
+ * Convex collision shapes: the volume an element actually occupies, rather than
5
+ * a world-axis box around it.
6
+ *
7
+ * One representation covers every convex solid — a point cloud plus two kinds of
8
+ * rounding. A box is its eight corners; a sphere is one point and a radius; a
9
+ * stretch of banked track is its own drawn cross-sections, so the geometry a
10
+ * player sees is the geometry that stops them. Face normals and edge directions
11
+ * are enumerated once, at build time, because they are the separating-axis
12
+ * candidates the sweep in `collide.ts` tests — a fixed, data-driven axis list
13
+ * per shape pair is what lets two machines replay the same run bit for bit,
14
+ * where an iterate-to-tolerance method would not.
15
+ *
16
+ * **Two kinds of rounding rather than one, as of 2026-08-27.** `radius` grows a
17
+ * shape by a ball and is what makes a sphere and a capsule; `sideRadius` grows
18
+ * it by a disc perpendicular to the segment through its first two points, and is
19
+ * what makes a cylinder. The second exists because the first cannot express a
20
+ * cylinder at all: a uniform radius rounds the rim along with the side, and the
21
+ * rim is what a wheel rolls on. Everything that consumes a shape reads both, and
22
+ * a shape carrying neither is a plain polytope, which is most of them.
23
+ *
24
+ * Build-time only: nothing here may be called per frame or per tick. The hull
25
+ * builder is O(n^4) in the point count — trivial for the intended n (a slab is
26
+ * 8–16 points, a body part 8), wrong for a render mesh, hence the cap. Shapes
27
+ * come from the few points that *define* an element, not from its triangles.
28
+ */
29
+ export interface ConvexShape {
30
+ /**
31
+ * xyz-packed points whose convex hull is the shape. Local space for a body's
32
+ * shape, world space for a static collider's — the sweep never needs to know
33
+ * which, because bodies carry a frame and colliders are baked.
34
+ */
35
+ readonly vertices: Float32Array;
36
+ /** xyz-packed unit face normals, one per direction (a line: n and −n once). */
37
+ readonly faceNormals: Float32Array;
38
+ /** xyz-packed unit edge directions, one per direction. */
39
+ readonly edgeDirs: Float32Array;
40
+ /** Rounding grown around the points — a sphere is one point and this. */
41
+ readonly radius: number;
42
+ /**
43
+ * Rounding grown around the points **only perpendicular to the segment through them**, in
44
+ * metres. Zero for everything but a cylinder, which is what it exists for.
45
+ *
46
+ * `radius` grows a shape uniformly, which is why it cannot express a cylinder: it would round
47
+ * the rim as well as the side. This one grows a shape by a disc rather than by a ball, so the
48
+ * two points of `cylinderShape` become two flat cap discs joined by a curved side, with a sharp
49
+ * rim between them. The two are independent and compose — a shape with both is a cylinder with
50
+ * a filleted rim — and every constructor but `cylinderShape` leaves this at zero.
51
+ *
52
+ * The axis is the shape's own first two points, not a stored vector, so a cylinder baked into
53
+ * world space by a collider carries its orientation the same way its position is carried.
54
+ */
55
+ readonly sideRadius: number;
56
+ /** Distance from the local origin enclosing the whole shape, for broad bounds. */
57
+ readonly boundRadius: number;
58
+ /**
59
+ * xyzw-packed outward face planes, four floats per face: normal then offset, so a point `p` lies
60
+ * on the face when `dot(n, p) === d`.
61
+ *
62
+ * **One entry per face, where `faceNormals` has one per direction.** A box has six here and three
63
+ * there, and they are separate arrays because conflating them is what left the gap: SAT wants
64
+ * directions, while clipping and an inertia tensor want faces. Empty for a shape with no faces.
65
+ */
66
+ readonly facePlanes: Float32Array;
67
+ /** CSR offsets into `faceVertexIndices`, length `faceCount + 1`. Empty when there are no faces. */
68
+ readonly faceVertexStart: Uint16Array;
69
+ /** Vertex indices, each face's loop wound counter-clockwise seen from outside. */
70
+ readonly faceVertexIndices: Uint16Array;
71
+ /**
72
+ * A **static triangle mesh**, where this shape is one, or absent where it is a convex solid.
73
+ *
74
+ * **The one thing in this file that is not convex, and it is a field rather than a second type
75
+ * on purpose.** A union would put a narrowing at every call site that takes a shape — the broad
76
+ * phase, the bounds, the collider set, the sweep, the mass, the queries, the cloth — for a shape
77
+ * only the narrow phase and the raycast can act on, and every one of those narrowings would be a
78
+ * place to forget one. A discriminating field is what `sideRadius` already is, one line up, and
79
+ * this reads the same way: the shape carries what it is and the two places that care ask.
80
+ *
81
+ * A mesh's `vertices` are the eight corners of its bounding box, so everything that measures a
82
+ * shape measures the right box; its `faceNormals` and `edgeDirs` are **empty**, so nothing
83
+ * mistakes a hollow level for a solid brick. See `meshShape`.
84
+ */
85
+ readonly triangles?: TriangleMesh;
86
+ }
87
+ /** The exact shape `MeshBuilder.addBox` draws: eight corners, three axes. */
88
+ export declare function boxShape(hx: number, hy: number, hz: number): ConvexShape;
89
+ /** A ball: one point, all radius. It separates on other shapes' features. */
90
+ export declare function sphereShape(radius: number): ConvexShape;
91
+ /**
92
+ * A capsule: a segment along y with a rounding radius.
93
+ *
94
+ * **No new representation.** Point-cloud-plus-radius already expresses a capsule exactly, so this
95
+ * is a named constructor over `hullShape` rather than a shape type. A named thing is discoverable
96
+ * and an idiom is not. It stands along y because that is the axis a character capsule uses, and a
97
+ * rotation nobody has to apply is a rotation nobody gets wrong.
98
+ *
99
+ * At `halfHeight` zero the two points dedupe to one and the result *is* a sphere, which is the
100
+ * right degenerate case rather than an error.
101
+ *
102
+ * **A cylinder is a different shape and has its own constructor**, `cylinderShape` below. The
103
+ * rounding radius here grows uniformly around every feature, so applying it to a segment can only
104
+ * ever give a capsule: it would round a cylinder's rim as well as its side. `sideRadius` is the
105
+ * field that expresses the difference, and it was added on 2026-08-27 with the second condition
106
+ * this file had been recording — a wheel rim, a rolling barrel — as its reason.
107
+ *
108
+ * The advice until then was "build one as an n-gon prism with `hullShape` and accept the facets",
109
+ * and it had a measured ceiling: `hullShape` refuses more than 64 points, a prism spends two a
110
+ * side, so thirty-two sides was the wall, and a thirty-two-sided wheel of radius 1 rolling at
111
+ * 6 m/s bobbed 16 mm that no side count could reduce. `prismRoll.test.ts` still measures that,
112
+ * beside the same wheel built as a cylinder, because the comparison is the reason the shape kind
113
+ * exists.
114
+ */
115
+ export declare function capsuleShape(radius: number, halfHeight: number): ConvexShape;
116
+ /**
117
+ * A cylinder: a segment along y, grown by a disc rather than by a ball.
118
+ *
119
+ * **The one shape a point cloud plus a rounding radius cannot express**, and the reason it needed
120
+ * a second kind of rounding rather than a second shape type. `radius` grows a shape uniformly, so
121
+ * applying it to a segment gives a capsule; `sideRadius` grows it only perpendicular to that
122
+ * segment, which gives two flat cap discs, a curved side, and a sharp rim between them. That rim
123
+ * is the whole difference, and it is what a wheel rolls on.
124
+ *
125
+ * **What this replaces is an n-gon prism with a measured floor.** `prismRoll.test.ts` had the
126
+ * numbers: `hullShape` refuses more than 64 points, a prism spends two a side, so thirty-two sides
127
+ * was the wall, and a thirty-two-sided wheel of radius 1 rolling at 6 m/s bobbed **16 mm** — which
128
+ * no side count could reduce. A cylinder's support along any direction perpendicular to its axis
129
+ * is exactly `sideRadius`, at every angle, so the same wheel bobs by nothing at all. The same test
130
+ * file now measures both and compares them.
131
+ *
132
+ * It stands along y for `capsuleShape`'s reason: a rotation nobody has to apply is a rotation
133
+ * nobody gets wrong. A wheel wants its axis across the vehicle, and the body carries a quaternion
134
+ * for exactly that. A static collider baked into world space carries its axis in its own two
135
+ * points, so nothing stores a direction that could disagree with them.
136
+ *
137
+ * **`halfHeight` must be positive**, unlike `capsuleShape`, whose zero case degenerates into a
138
+ * sphere and is right. A cylinder of zero height is a disc: a shape with no interior, whose mass
139
+ * properties are zero and whose contact normal is undefined on its rim. Refused rather than
140
+ * silently produced.
141
+ */
142
+ export declare function cylinderShape(radius: number, halfHeight: number): ConvexShape;
143
+ /**
144
+ * The convex hull of a point cloud, with its separating features enumerated.
145
+ *
146
+ * Brute force by design: every point triple proposes a plane, and a plane with
147
+ * every point on one side is a face. Edges are point pairs lying on two
148
+ * distinct faces. No incremental hull, no floating-point pivoting — the same
149
+ * input yields the same features in the same order on every machine, which the
150
+ * replay contract needs from anything that feeds collision.
151
+ *
152
+ * **Every length here is `Math.sqrt` of a sum of squares rather than `Math.hypot`**, and that is
153
+ * what makes the sentence above true rather than merely intended. ECMAScript declines to specify
154
+ * `hypot` precisely, so two engines may differ by an ulp — and an ulp here is not a slightly
155
+ * different axis. `proposePlane`'s normal classifies every point against `COPLANAR_M`, so it
156
+ * decides whether a plane becomes a face at all; `appendDirection`'s is compared against
157
+ * `DIR_DEDUP`, so it decides how many separating axes exist and in what order. SAT then takes a
158
+ * minimum over that list.
159
+ *
160
+ * `hypot` is the more accurate of the two, guarding against intermediate overflow at magnitudes a
161
+ * collision shape does not reach. **What would make this wrong** is a shape built at astronomical
162
+ * or atomic scale, where that guard is worth more than the reproducibility; the answer then is an
163
+ * explicit rescale rather than the call back. Asserted by `scripts/determinism.test.mjs`.
164
+ */
165
+ export declare function hullShape(points: ArrayLike<number>, radius?: number): ConvexShape;
166
+ /**
167
+ * World-axis bounds of a shape as placed (its points are its placement).
168
+ *
169
+ * **`radius` and `sideRadius` grow the box differently, and the second one is not `sideRadius` on
170
+ * every axis.** A ball grows a box by its radius along all three; a disc perpendicular to a unit
171
+ * axis `a` grows it by `sideRadius * sqrt(1 - a[i]^2)` along axis `i` — the disc's own extent seen
172
+ * down that axis, which is the full radius across the axis and exactly nothing along it. Using
173
+ * `sideRadius` on all three instead would bound a lying cylinder as if it were a sphere, which is
174
+ * conservative and therefore not wrong, and would cost the broad phase the difference on every
175
+ * cylinder in the world.
176
+ */
177
+ export declare function shapeBounds(shape: ConvexShape, out: Aabb): Aabb;