@codexo/exojs-physics 0.13.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 (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/dist/esm/Aabb.d.ts +14 -0
  4. package/dist/esm/Aabb.js +12 -0
  5. package/dist/esm/Aabb.js.map +1 -0
  6. package/dist/esm/Collider.d.ts +77 -0
  7. package/dist/esm/Collider.js +138 -0
  8. package/dist/esm/Collider.js.map +1 -0
  9. package/dist/esm/ContactGraph.d.ts +34 -0
  10. package/dist/esm/ContactGraph.js +157 -0
  11. package/dist/esm/ContactGraph.js.map +1 -0
  12. package/dist/esm/PhysicsBody.d.ts +103 -0
  13. package/dist/esm/PhysicsBody.js +186 -0
  14. package/dist/esm/PhysicsBody.js.map +1 -0
  15. package/dist/esm/PhysicsWorld.d.ts +126 -0
  16. package/dist/esm/PhysicsWorld.js +253 -0
  17. package/dist/esm/PhysicsWorld.js.map +1 -0
  18. package/dist/esm/TimeStepper.d.ts +39 -0
  19. package/dist/esm/TimeStepper.js +70 -0
  20. package/dist/esm/TimeStepper.js.map +1 -0
  21. package/dist/esm/backend/NativePhysicsBackend.d.ts +19 -0
  22. package/dist/esm/backend/NativePhysicsBackend.js +31 -0
  23. package/dist/esm/backend/NativePhysicsBackend.js.map +1 -0
  24. package/dist/esm/backend/PhysicsBackend.d.ts +23 -0
  25. package/dist/esm/binding/BindingRegistry.d.ts +21 -0
  26. package/dist/esm/binding/BindingRegistry.js +40 -0
  27. package/dist/esm/binding/BindingRegistry.js.map +1 -0
  28. package/dist/esm/binding/PhysicsBinding.d.ts +27 -0
  29. package/dist/esm/binding/PhysicsBinding.js +24 -0
  30. package/dist/esm/binding/PhysicsBinding.js.map +1 -0
  31. package/dist/esm/broadphase/BroadPhase.d.ts +22 -0
  32. package/dist/esm/broadphase/SweepAndPrune.d.ts +14 -0
  33. package/dist/esm/broadphase/SweepAndPrune.js +48 -0
  34. package/dist/esm/broadphase/SweepAndPrune.js.map +1 -0
  35. package/dist/esm/broadphase/index.d.ts +2 -0
  36. package/dist/esm/collision/CollisionProxy.d.ts +14 -0
  37. package/dist/esm/collision/Manifold.d.ts +33 -0
  38. package/dist/esm/collision/Manifold.js +28 -0
  39. package/dist/esm/collision/Manifold.js.map +1 -0
  40. package/dist/esm/collision/index.d.ts +3 -0
  41. package/dist/esm/collision/narrowphase.d.ts +14 -0
  42. package/dist/esm/collision/narrowphase.js +377 -0
  43. package/dist/esm/collision/narrowphase.js.map +1 -0
  44. package/dist/esm/debug/PhysicsDebugDraw.d.ts +46 -0
  45. package/dist/esm/debug/PhysicsDebugDraw.js +171 -0
  46. package/dist/esm/debug/PhysicsDebugDraw.js.map +1 -0
  47. package/dist/esm/debug/index.d.ts +1 -0
  48. package/dist/esm/debug/index.js +2 -0
  49. package/dist/esm/debug/index.js.map +1 -0
  50. package/dist/esm/events.d.ts +35 -0
  51. package/dist/esm/index.d.ts +1 -0
  52. package/dist/esm/index.js +12 -0
  53. package/dist/esm/index.js.map +1 -0
  54. package/dist/esm/math.d.ts +32 -0
  55. package/dist/esm/math.js +48 -0
  56. package/dist/esm/math.js.map +1 -0
  57. package/dist/esm/physicsBuildInfo.d.ts +15 -0
  58. package/dist/esm/physicsBuildInfo.js +8 -0
  59. package/dist/esm/physicsBuildInfo.js.map +1 -0
  60. package/dist/esm/public.d.ts +21 -0
  61. package/dist/esm/query/QueryEngine.d.ts +51 -0
  62. package/dist/esm/query/QueryEngine.js +246 -0
  63. package/dist/esm/query/QueryEngine.js.map +1 -0
  64. package/dist/esm/shapes/BoxShape.d.ts +11 -0
  65. package/dist/esm/shapes/BoxShape.js +29 -0
  66. package/dist/esm/shapes/BoxShape.js.map +1 -0
  67. package/dist/esm/shapes/CircleShape.d.ts +16 -0
  68. package/dist/esm/shapes/CircleShape.js +30 -0
  69. package/dist/esm/shapes/CircleShape.js.map +1 -0
  70. package/dist/esm/shapes/PolygonShape.d.ts +26 -0
  71. package/dist/esm/shapes/PolygonShape.js +156 -0
  72. package/dist/esm/shapes/PolygonShape.js.map +1 -0
  73. package/dist/esm/shapes/Shape.d.ts +26 -0
  74. package/dist/esm/shapes/Shape.js +16 -0
  75. package/dist/esm/shapes/Shape.js.map +1 -0
  76. package/dist/esm/shapes/index.d.ts +4 -0
  77. package/dist/esm/types.d.ts +39 -0
  78. package/dist/esm/types.js +28 -0
  79. package/dist/esm/types.js.map +1 -0
  80. package/package.json +51 -0
@@ -0,0 +1,156 @@
1
+ import { Shape } from './Shape.js';
2
+
3
+ /** Vertices closer than this (px) are treated as coincident → degenerate. */
4
+ const weldEpsilon = 1e-4;
5
+ /**
6
+ * A convex polygon defined by ≥3 local-space vertices. Input vertices may be
7
+ * given in either winding; they are canonicalised to counter-clockwise and the
8
+ * outward edge normals are precomputed. Construction throws on any non-convex,
9
+ * degenerate, or under-specified input — there is no silent repair.
10
+ *
11
+ * Vertices and normals are exposed as flat `[x0, y0, x1, y1, …]` arrays to keep
12
+ * the narrow phase allocation-free; both are frozen.
13
+ */
14
+ class PolygonShape extends Shape {
15
+ type = 'polygon';
16
+ /** Local-space vertices, CCW, flattened. */
17
+ vertices;
18
+ /** Outward unit edge normals (edge `i` spans vertex `i → i+1`), flattened. */
19
+ normals;
20
+ count;
21
+ boundingRadius;
22
+ area;
23
+ centroidX;
24
+ centroidY;
25
+ unitInertia;
26
+ constructor(vertices) {
27
+ super();
28
+ if (vertices.length < 3) {
29
+ throw new RangeError(`PolygonShape: needs at least 3 vertices, received ${vertices.length}.`);
30
+ }
31
+ const points = [];
32
+ for (const vertex of vertices) {
33
+ if (!Number.isFinite(vertex.x) || !Number.isFinite(vertex.y)) {
34
+ throw new RangeError(`PolygonShape: vertex has a non-finite component (${vertex.x}, ${vertex.y}).`);
35
+ }
36
+ // Reject coincident consecutive (and wrap-around) vertices.
37
+ const px = points.length >= 2 ? points[points.length - 2] : NaN;
38
+ const py = points.length >= 2 ? points[points.length - 1] : NaN;
39
+ if (Math.hypot(vertex.x - px, vertex.y - py) < weldEpsilon) {
40
+ continue;
41
+ }
42
+ points.push(vertex.x, vertex.y);
43
+ }
44
+ let count = points.length / 2;
45
+ // Drop a wrap-around duplicate (last ≈ first).
46
+ if (count >= 2 && Math.hypot(points[0] - points[points.length - 2], points[1] - points[points.length - 1]) < weldEpsilon) {
47
+ points.length -= 2;
48
+ count -= 1;
49
+ }
50
+ if (count < 3) {
51
+ throw new RangeError(`PolygonShape: needs at least 3 distinct vertices after welding, received ${count}.`);
52
+ }
53
+ // Canonicalise to CCW (positive signed area). Screen space is +Y down, so a
54
+ // mathematically CCW polygon appears clockwise — the math stays consistent.
55
+ if (signedArea(points) < 0) {
56
+ reverseWinding(points);
57
+ }
58
+ const signed = signedArea(points);
59
+ if (signed <= weldEpsilon) {
60
+ throw new RangeError('PolygonShape: vertices are degenerate (zero/near-zero area).');
61
+ }
62
+ const normals = computeNormals(points);
63
+ assertConvex(points);
64
+ // Area, centroid and inertia via the standard polygon integrals.
65
+ let cx = 0;
66
+ let cy = 0;
67
+ let inertiaOrigin = 0;
68
+ for (let i = 0; i < count; i++) {
69
+ const ix = points[i * 2];
70
+ const iy = points[i * 2 + 1];
71
+ const j = (i + 1) % count;
72
+ const jx = points[j * 2];
73
+ const jy = points[j * 2 + 1];
74
+ const cross = ix * jy - jx * iy;
75
+ cx += (ix + jx) * cross;
76
+ cy += (iy + jy) * cross;
77
+ inertiaOrigin += cross * (ix * ix + ix * jx + jx * jx + iy * iy + iy * jy + jy * jy);
78
+ }
79
+ const area = signed;
80
+ cx /= 6 * area;
81
+ cy /= 6 * area;
82
+ this.count = count;
83
+ this.vertices = Object.freeze(points);
84
+ this.normals = Object.freeze(normals);
85
+ this.area = area;
86
+ this.centroidX = cx;
87
+ this.centroidY = cy;
88
+ // ∫ r² dA about the origin, then shifted to the centroid (parallel axis).
89
+ this.unitInertia = inertiaOrigin / 12 - area * (cx * cx + cy * cy);
90
+ this.boundingRadius = boundingRadiusOf(points);
91
+ // The vertex/normal arrays are frozen; the instance itself is not, so
92
+ // BoxShape (and any future convex helper) can extend this class.
93
+ }
94
+ }
95
+ /** Signed area (positive = CCW). */
96
+ const signedArea = (points) => {
97
+ const count = points.length / 2;
98
+ let sum = 0;
99
+ for (let i = 0; i < count; i++) {
100
+ const j = (i + 1) % count;
101
+ sum += points[i * 2] * points[j * 2 + 1] - points[j * 2] * points[i * 2 + 1];
102
+ }
103
+ return sum / 2;
104
+ };
105
+ const reverseWinding = (points) => {
106
+ const count = points.length / 2;
107
+ for (let i = 0; i < Math.floor(count / 2); i++) {
108
+ const j = count - 1 - i;
109
+ const ix = points[i * 2];
110
+ const iy = points[i * 2 + 1];
111
+ points[i * 2] = points[j * 2];
112
+ points[i * 2 + 1] = points[j * 2 + 1];
113
+ points[j * 2] = ix;
114
+ points[j * 2 + 1] = iy;
115
+ }
116
+ };
117
+ /** Outward unit normals for a CCW polygon: normal of edge `i→i+1` is `(eY, -eX)`. */
118
+ const computeNormals = (points) => {
119
+ const count = points.length / 2;
120
+ const normals = [];
121
+ for (let i = 0; i < count; i++) {
122
+ const j = (i + 1) % count;
123
+ const ex = points[j * 2] - points[i * 2];
124
+ const ey = points[j * 2 + 1] - points[i * 2 + 1];
125
+ const length = Math.hypot(ex, ey);
126
+ normals.push(ey / length, -ex / length);
127
+ }
128
+ return normals;
129
+ };
130
+ /** Throw unless every interior turn has the same (CCW) orientation. */
131
+ const assertConvex = (points) => {
132
+ const count = points.length / 2;
133
+ for (let i = 0; i < count; i++) {
134
+ const a = i;
135
+ const b = (i + 1) % count;
136
+ const c = (i + 2) % count;
137
+ const e1x = points[b * 2] - points[a * 2];
138
+ const e1y = points[b * 2 + 1] - points[a * 2 + 1];
139
+ const e2x = points[c * 2] - points[b * 2];
140
+ const e2y = points[c * 2 + 1] - points[b * 2 + 1];
141
+ // CCW polygon ⇒ every cross product must be ≥ 0 (strictly > 0 for no collinear run).
142
+ if (e1x * e2y - e1y * e2x <= 0) {
143
+ throw new RangeError('PolygonShape: vertices are not strictly convex (or contain collinear edges).');
144
+ }
145
+ }
146
+ };
147
+ const boundingRadiusOf = (points) => {
148
+ let max = 0;
149
+ for (let i = 0; i < points.length; i += 2) {
150
+ max = Math.max(max, Math.hypot(points[i], points[i + 1]));
151
+ }
152
+ return max;
153
+ };
154
+
155
+ export { PolygonShape };
156
+ //# sourceMappingURL=PolygonShape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PolygonShape.js","sources":["../../../../src/shapes/PolygonShape.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /** Discriminant for the concrete shape kinds supported in the MVP. */
2
+ export type ShapeType = 'circle' | 'polygon';
3
+ /**
4
+ * Immutable local-space collision geometry. A `Shape` carries no transform — a
5
+ * {@link Collider} positions it in a body. Shapes also expose the area-based
6
+ * mass properties (`area`, `centroid`, `unitInertia`) the body uses to derive
7
+ * mass and rotational inertia from a density; these are computed once at
8
+ * construction and frozen.
9
+ *
10
+ * `unitInertia` is the second moment of area about the shape's own centroid
11
+ * (∫ r² dA). Multiplying by density yields the rotational inertia contribution
12
+ * of the shape about its centroid.
13
+ */
14
+ export declare abstract class Shape {
15
+ abstract readonly type: ShapeType;
16
+ /** Radius of the smallest circle about the local origin enclosing the shape. */
17
+ abstract readonly boundingRadius: number;
18
+ /** Surface area in px². `mass = density × area`. */
19
+ abstract readonly area: number;
20
+ /** X of the area centroid in local space. */
21
+ abstract readonly centroidX: number;
22
+ /** Y of the area centroid in local space. */
23
+ abstract readonly centroidY: number;
24
+ /** Second moment of area (∫ r² dA) about the centroid; `inertia = density × unitInertia`. */
25
+ abstract readonly unitInertia: number;
26
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Immutable local-space collision geometry. A `Shape` carries no transform — a
3
+ * {@link Collider} positions it in a body. Shapes also expose the area-based
4
+ * mass properties (`area`, `centroid`, `unitInertia`) the body uses to derive
5
+ * mass and rotational inertia from a density; these are computed once at
6
+ * construction and frozen.
7
+ *
8
+ * `unitInertia` is the second moment of area about the shape's own centroid
9
+ * (∫ r² dA). Multiplying by density yields the rotational inertia contribution
10
+ * of the shape about its centroid.
11
+ */
12
+ class Shape {
13
+ }
14
+
15
+ export { Shape };
16
+ //# sourceMappingURL=Shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Shape.js","sources":["../../../../src/shapes/Shape.ts"],"sourcesContent":[null],"names":[],"mappings":"AAGA;;;;;;;;;;AAUG;MACmB,KAAK,CAAA;AAiB1B;;;;"}
@@ -0,0 +1,4 @@
1
+ export { BoxShape } from './BoxShape';
2
+ export { CircleShape } from './CircleShape';
3
+ export { PolygonShape } from './PolygonShape';
4
+ export { Shape, type ShapeType } from './Shape';
@@ -0,0 +1,39 @@
1
+ /** A read-only two-component point/vector. `Vector` from core satisfies this. */
2
+ export interface VectorLike {
3
+ readonly x: number;
4
+ readonly y: number;
5
+ }
6
+ /**
7
+ * Simulation role of a {@link PhysicsBody}.
8
+ *
9
+ * - `dynamic` — fully simulated (finite mass); moved by the solver once
10
+ * dynamics ship, and by `setTransform` meanwhile.
11
+ * - `static` — never moves; infinite mass. Ground, walls, level geometry.
12
+ * - `kinematic` — moved only by `setTransform` (game-driven); infinite mass,
13
+ * unaffected by contacts. Platforms, doors.
14
+ */
15
+ export type BodyType = 'dynamic' | 'static' | 'kinematic';
16
+ /**
17
+ * Per-collider collision filter. A pair is considered for collision only when
18
+ * each collider's {@link mask} includes the other's {@link category}. A
19
+ * non-zero {@link group} overrides category/mask: identical positive groups
20
+ * always collide, identical negative groups never do.
21
+ */
22
+ export interface CollisionFilter {
23
+ /** Category bits this collider belongs to. Default `0x0001`. */
24
+ category: number;
25
+ /** Categories this collider collides with. Default `0xffff`. */
26
+ mask: number;
27
+ /** Signed override group; `0` defers to category/mask. Default `0`. */
28
+ group: number;
29
+ }
30
+ /** The default collider filter: category 1, collides with everything, no group. */
31
+ export declare const defaultFilter: Readonly<CollisionFilter>;
32
+ /** Normalise a partial filter against {@link defaultFilter}. */
33
+ export declare const resolveFilter: (filter?: Partial<CollisionFilter>) => CollisionFilter;
34
+ /**
35
+ * Decide whether two filters permit a collision/overlap. Implements the
36
+ * standard category/mask rule with the signed-group override (Box2D/Matter
37
+ * semantics).
38
+ */
39
+ export declare const shouldCollide: (a: CollisionFilter, b: CollisionFilter) => boolean;
@@ -0,0 +1,28 @@
1
+ // Shared value types for the physics package. Kept dependency-light so the
2
+ // shapes, colliders and world modules can all reference them without cycles.
3
+ /** The default collider filter: category 1, collides with everything, no group. */
4
+ const defaultFilter = Object.freeze({
5
+ category: 0x0001,
6
+ mask: 0xffff,
7
+ group: 0,
8
+ });
9
+ /** Normalise a partial filter against {@link defaultFilter}. */
10
+ const resolveFilter = (filter) => ({
11
+ category: filter?.category ?? defaultFilter.category,
12
+ mask: filter?.mask ?? defaultFilter.mask,
13
+ group: filter?.group ?? defaultFilter.group,
14
+ });
15
+ /**
16
+ * Decide whether two filters permit a collision/overlap. Implements the
17
+ * standard category/mask rule with the signed-group override (Box2D/Matter
18
+ * semantics).
19
+ */
20
+ const shouldCollide = (a, b) => {
21
+ if (a.group !== 0 && a.group === b.group) {
22
+ return a.group > 0;
23
+ }
24
+ return (a.mask & b.category) !== 0 && (b.mask & a.category) !== 0;
25
+ };
26
+
27
+ export { defaultFilter, resolveFilter, shouldCollide };
28
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":["../../../src/types.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AAkCA;AACO,MAAM,aAAa,GAA8B,MAAM,CAAC,MAAM,CAAC;AACpE,IAAA,QAAQ,EAAE,MAAM;AAChB,IAAA,IAAI,EAAE,MAAM;AACZ,IAAA,KAAK,EAAE,CAAC;AACT,CAAA;AAED;MACa,aAAa,GAAG,CAAC,MAAiC,MAAuB;AACpF,IAAA,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,aAAa,CAAC,QAAQ;AACpD,IAAA,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,aAAa,CAAC,IAAI;AACxC,IAAA,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,aAAa,CAAC,KAAK;AAC5C,CAAA;AAED;;;;AAIG;MACU,aAAa,GAAG,CAAC,CAAkB,EAAE,CAAkB,KAAa;AAC/E,IAAA,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE;AACxC,QAAA,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC;IACpB;IAEA,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,MAAM,CAAC;AACnE;;;;"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@codexo/exojs-physics",
3
+ "version": "0.13.0",
4
+ "description": "Native 2D collision, query and sensor runtime for ExoJS.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/Exoridus/ExoJS.git",
8
+ "directory": "packages/exojs-physics"
9
+ },
10
+ "type": "module",
11
+ "sideEffects": false,
12
+ "main": "./dist/esm/index.js",
13
+ "module": "./dist/esm/index.js",
14
+ "types": "./dist/esm/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/esm/index.d.ts",
18
+ "import": "./dist/esm/index.js",
19
+ "default": "./dist/esm/index.js"
20
+ },
21
+ "./debug": {
22
+ "types": "./dist/esm/debug/index.d.ts",
23
+ "import": "./dist/esm/debug/index.js",
24
+ "default": "./dist/esm/debug/index.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "dist/esm/",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "peerDependencies": {
34
+ "@codexo/exojs": "0.13.x"
35
+ },
36
+ "devDependencies": {
37
+ "@codexo/exojs": "0.13.0",
38
+ "@codexo/exojs-config": "0.0.0"
39
+ },
40
+ "license": "MIT",
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "scripts": {
45
+ "build": "tsx ../../node_modules/rollup/dist/bin/rollup -c --environment EXOJS_ENV:production",
46
+ "build:dev": "tsx ../../node_modules/rollup/dist/bin/rollup -c --environment EXOJS_ENV:development",
47
+ "typecheck": "tsc --noEmit",
48
+ "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",
49
+ "test": "vitest run --root ../.. --project=exojs-physics"
50
+ }
51
+ }